{"name":"base","version":"moc-0.14.13","files":{"Nat.mo":{"content":"/// Natural numbers with infinite precision.\n///\n/// :::note\n/// Most operations on integer numbers (e.g. addition) are available as built-in operators (e.g. `1 + 1`).\n/// This module provides equivalent functions and `Text` conversion.\n/// :::\n///\n/// :::info Function form for higher-order use\n///\n/// Several arithmetic and comparison functions (e.g. `add`, `sub`, `equal`, `less`, `pow`) are defined in this module to enable their use as first-class function values, which is not possible with operators like `+`, `-`, `==`, etc., in Motoko. This allows you to pass these operations to higher-order functions such as `map`, `foldLeft`, or `sort`.\n/// :::\n///\n/// Import from the base library to use this module.\n///\n/// ```motoko name=import\n/// import Nat \"mo:base/Nat\";\n/// ```\n\nimport Int \"Int\";\nimport Order \"Order\";\nimport Prim \"mo:⛔\";\nimport Char \"Char\";\n\nmodule {\n\n  /// Infinite precision natural numbers.\n  public type Nat = Prim.Types.Nat;\n\n  /// Converts a natural number to its textual representation. Textual\n  /// representation _does not_ contain underscores to represent commas.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat.toText 1234 // => \"1234\"\n  /// ```\n  public func toText(n : Nat) : Text = Int.toText n;\n\n  /// Creates a natural number from its textual representation. Returns `null`\n  /// if the input is not a valid natural number.\n  ///\n  /// :::note\n  /// The textual representation _must not_ contain underscores.\n  /// :::\n  /// Example:\n  /// ```motoko include=import\n  /// Nat.fromText \"1234\" // => ?1234\n  /// ```\n  public func fromText(text : Text) : ?Nat {\n    if (text == \"\") {\n      return null\n    };\n    var n = 0;\n    for (c in text.chars()) {\n      if (Char.isDigit(c)) {\n        let charAsNat = Prim.nat32ToNat(Prim.charToNat32(c) -% Prim.charToNat32('0'));\n        n := n * 10 + charAsNat\n      } else {\n        return null\n      }\n    };\n    ?n\n  };\n\n  /// Returns the minimum of `x` and `y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat.min(1, 2) // => 1\n  /// ```\n  public func min(x : Nat, y : Nat) : Nat {\n    if (x < y) { x } else { y }\n  };\n\n  /// Returns the maximum of `x` and `y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat.max(1, 2) // => 2\n  /// ```\n  public func max(x : Nat, y : Nat) : Nat {\n    if (x < y) { y } else { x }\n  };\n\n  /// Equality function for Nat types.\n  /// This is equivalent to `x == y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat.equal(1, 1); // => true\n  /// 1 == 1 // => true\n  /// ```\n  ///\n\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// import Buffer \"mo:base/Buffer\";\n  ///\n  /// let buffer1 = Buffer.Buffer<Nat>(3);\n  /// let buffer2 = Buffer.Buffer<Nat>(3);\n  /// Buffer.equal(buffer1, buffer2, Nat.equal) // => true\n  /// ```\n  public func equal(x : Nat, y : Nat) : Bool { x == y };\n\n  /// Inequality function for Nat types.\n  /// This is equivalent to `x != y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat.notEqual(1, 2); // => true\n  /// 1 != 2 // => true\n  /// ```\n  ///\n\n  public func notEqual(x : Nat, y : Nat) : Bool { x != y };\n\n  /// \"Less than\" function for Nat types.\n  /// This is equivalent to `x < y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat.less(1, 2); // => true\n  /// 1 < 2 // => true\n  /// ```\n  ///\n\n  public func less(x : Nat, y : Nat) : Bool { x < y };\n\n  /// \"Less than or equal\" function for Nat types.\n  /// This is equivalent to `x <= y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat.lessOrEqual(1, 2); // => true\n  /// 1 <= 2 // => true\n  /// ```\n  ///\n\n  public func lessOrEqual(x : Nat, y : Nat) : Bool { x <= y };\n\n  /// \"Greater than\" function for Nat types.\n  /// This is equivalent to `x > y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat.greater(2, 1); // => true\n  /// 2 > 1 // => true\n  /// ```\n  ///\n\n  public func greater(x : Nat, y : Nat) : Bool { x > y };\n\n  /// \"Greater than or equal\" function for Nat types.\n  /// This is equivalent to `x >= y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat.greaterOrEqual(2, 1); // => true\n  /// 2 >= 1 // => true\n  /// ```\n  ///\n\n  public func greaterOrEqual(x : Nat, y : Nat) : Bool { x >= y };\n\n  /// General purpose comparison function for `Nat`. Returns the `Order` (\n  /// either `#less`, `#equal`, or `#greater`) of comparing `x` with `y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat.compare(2, 3) // => #less\n  /// ```\n  ///\n  /// This function can be used as value for a high order function, such as a sort function.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// import Array \"mo:base/Array\";\n  /// Array.sort([2, 3, 1], Nat.compare) // => [1, 2, 3]\n  /// ```\n  public func compare(x : Nat, y : Nat) : { #less; #equal; #greater } {\n    if (x < y) { #less } else if (x == y) { #equal } else { #greater }\n  };\n\n  /// Returns the sum of `x` and `y`, `x + y`. This operator will never overflow\n  /// because `Nat` is infinite precision.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat.add(1, 2); // => 3\n  /// 1 + 2 // => 3\n  /// ```\n  ///\n\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// import Array \"mo:base/Array\";\n  /// Array.foldLeft([2, 3, 1], 0, Nat.add) // => 6\n  /// ```\n  public func add(x : Nat, y : Nat) : Nat { x + y };\n\n  /// Returns the difference of `x` and `y`, `x - y`.\n  /// Traps on underflow below `0`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat.sub(2, 1); // => 1\n  /// // Add a type annotation to avoid a warning about the subtraction\n  /// 2 - 1 : Nat // => 1\n  /// ```\n  ///\n\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// import Array \"mo:base/Array\";\n  /// Array.foldLeft([2, 3, 1], 10, Nat.sub) // => 4\n  /// ```\n  public func sub(x : Nat, y : Nat) : Nat { x - y };\n\n  /// Returns the product of `x` and `y`, `x * y`. This operator will never\n  /// overflow because `Nat` is infinite precision.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat.mul(2, 3); // => 6\n  /// 2 * 3 // => 6\n  /// ```\n  ///\n\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// import Array \"mo:base/Array\";\n  /// Array.foldLeft([2, 3, 1], 1, Nat.mul) // => 6\n  /// ```\n  public func mul(x : Nat, y : Nat) : Nat { x * y };\n\n  /// Returns the unsigned integer division of `x` by `y`,  `x / y`.\n  /// Traps when `y` is zero.\n  ///\n  /// The quotient is rounded down, which is equivalent to truncating the\n  /// decimal places of the quotient.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat.div(6, 2); // => 3\n  /// 6 / 2 // => 3\n  /// ```\n  ///\n\n  public func div(x : Nat, y : Nat) : Nat { x / y };\n\n  /// Returns the remainder of unsigned integer division of `x` by `y`,  `x % y`.\n  /// Traps when `y` is zero.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat.rem(6, 4); // => 2\n  /// 6 % 4 // => 2\n  /// ```\n  ///\n\n  public func rem(x : Nat, y : Nat) : Nat { x % y };\n\n  /// Returns `x` to the power of `y`, `x ** y`. Traps when `y > 2^32`. This operator\n  /// will never overflow because `Nat` is infinite precision.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat.pow(2, 3); // => 8\n  /// 2 ** 3 // => 8\n  /// ```\n  ///\n\n  public func pow(x : Nat, y : Nat) : Nat { x ** y };\n\n  /// Returns the (conceptual) bitwise shift left of `x` by `y`, `x * (2 ** y)`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat.bitshiftLeft(1, 3); // => 8\n  /// ```\n  ///\n\n  public func bitshiftLeft(x : Nat, y : Nat32) : Nat { Prim.shiftLeft(x, y) };\n\n  /// Returns the (conceptual) bitwise shift right of `x` by `y`, `x / (2 ** y)`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat.bitshiftRight(8, 3); // => 1\n  /// ```\n  ///\n\n  public func bitshiftRight(x : Nat, y : Nat32) : Nat { Prim.shiftRight(x, y) };\n\n}\n"},"Nat8.mo":{"content":"/// Provides utility functions on 8-bit unsigned integers.\n///\n/// :::note\n/// Most operations on integer numbers (e.g. addition) are available as built-in operators (e.g. `1 + 1`).\n/// This module provides equivalent functions and `Text` conversion.\n/// :::\n///\n/// :::info Function form for higher-order use\n///\n/// Several arithmetic and comparison functions (e.g. `add`, `sub`, `equal`, `less`, `pow`) are defined in this module to enable their use as first-class function values, which is not possible with operators like `+`, `-`, `==`, etc., in Motoko. This allows you to pass these operations to higher-order functions such as `map`, `foldLeft`, or `sort`.\n/// :::\n///\n/// Import from the base library to use this module.\n///\n/// ```motoko name=import\n/// import Nat8 \"mo:base/Nat8\";\n/// ```\nimport Nat \"Nat\";\nimport Prim \"mo:⛔\";\n\nmodule {\n\n  /// 8-bit natural numbers.\n  public type Nat8 = Prim.Types.Nat8;\n\n  /// Maximum 8-bit natural number. `2 ** 8 - 1`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat8.maximumValue; // => 255 : Nat8\n  /// ```\n  public let maximumValue = 255 : Nat8;\n\n  /// Converts an 8-bit unsigned integer to an unsigned integer with infinite precision.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat8.toNat(123); // => 123 : Nat\n  /// ```\n  public let toNat : Nat8 -> Nat = Prim.nat8ToNat;\n\n  /// Converts an unsigned integer with infinite precision to an 8-bit unsigned integer.\n  ///\n  /// Traps on overflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat8.fromNat(123); // => 123 : Nat8\n  /// ```\n  public let fromNat : Nat -> Nat8 = Prim.natToNat8;\n\n  /// Converts a 16-bit unsigned integer to a 8-bit unsigned integer.\n  ///\n  /// Traps on overflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat8.fromNat16(123); // => 123 : Nat8\n  /// ```\n  public let fromNat16 : Nat16 -> Nat8 = Prim.nat16ToNat8;\n\n  /// Converts an 8-bit unsigned integer to a 16-bit unsigned integer.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat8.toNat16(123); // => 123 : Nat16\n  /// ```\n  public let toNat16 : Nat8 -> Nat16 = Prim.nat8ToNat16;\n\n  /// Converts a signed integer with infinite precision to an 8-bit unsigned integer.\n  ///\n  /// Wraps on overflow/underflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat8.fromIntWrap(123); // => 123 : Nat8\n  /// ```\n  public let fromIntWrap : Int -> Nat8 = Prim.intToNat8Wrap;\n\n  /// Converts `x` to its textual representation.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat8.toText(123); // => \"123\" : Text\n  /// ```\n  public func toText(x : Nat8) : Text {\n    Nat.toText(toNat(x))\n  };\n\n  /// Returns the minimum of `x` and `y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat8.min(123, 200); // => 123 : Nat8\n  /// ```\n  public func min(x : Nat8, y : Nat8) : Nat8 {\n    if (x < y) { x } else { y }\n  };\n\n  /// Returns the maximum of `x` and `y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat8.max(123, 200); // => 200 : Nat8\n  /// ```\n  public func max(x : Nat8, y : Nat8) : Nat8 {\n    if (x < y) { y } else { x }\n  };\n\n  /// Equality function for Nat8 types.\n  /// This is equivalent to `x == y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat8.equal(1, 1); // => true\n  /// (1 : Nat8) == (1 : Nat8) // => true\n  /// ```\n  ///\n\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// import Buffer \"mo:base/Buffer\";\n  ///\n  /// let buffer1 = Buffer.Buffer<Nat8>(3);\n  /// let buffer2 = Buffer.Buffer<Nat8>(3);\n  /// Buffer.equal(buffer1, buffer2, Nat8.equal) // => true\n  /// ```\n  public func equal(x : Nat8, y : Nat8) : Bool { x == y };\n\n  /// Inequality function for Nat8 types.\n  /// This is equivalent to `x != y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat8.notEqual(1, 2); // => true\n  /// (1 : Nat8) != (2 : Nat8) // => true\n  /// ```\n  ///\n\n  public func notEqual(x : Nat8, y : Nat8) : Bool { x != y };\n\n  /// \"Less than\" function for Nat8 types.\n  /// This is equivalent to `x < y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat8.less(1, 2); // => true\n  /// (1 : Nat8) < (2 : Nat8) // => true\n  /// ```\n  ///\n\n  public func less(x : Nat8, y : Nat8) : Bool { x < y };\n\n  /// \"Less than or equal\" function for Nat8 types.\n  /// This is equivalent to `x <= y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat.lessOrEqual(1, 2); // => true\n  /// 1 <= 2 // => true\n  /// ```\n  ///\n\n  public func lessOrEqual(x : Nat8, y : Nat8) : Bool { x <= y };\n\n  /// \"Greater than\" function for Nat8 types.\n  /// This is equivalent to `x > y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat8.greater(2, 1); // => true\n  /// (2 : Nat8) > (1 : Nat8) // => true\n  /// ```\n  ///\n\n  public func greater(x : Nat8, y : Nat8) : Bool { x > y };\n\n  /// \"Greater than or equal\" function for Nat8 types.\n  /// This is equivalent to `x >= y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat8.greaterOrEqual(2, 1); // => true\n  /// (2 : Nat8) >= (1 : Nat8) // => true\n  /// ```\n  ///\n\n  public func greaterOrEqual(x : Nat8, y : Nat8) : Bool { x >= y };\n\n  /// General purpose comparison function for `Nat8`. Returns the `Order` (\n  /// either `#less`, `#equal`, or `#greater`) of comparing `x` with `y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat8.compare(2, 3) // => #less\n  /// ```\n  ///\n  /// This function can be used as value for a high order function, such as a sort function.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// import Array \"mo:base/Array\";\n  /// Array.sort([2, 3, 1] : [Nat8], Nat8.compare) // => [1, 2, 3]\n  /// ```\n  public func compare(x : Nat8, y : Nat8) : { #less; #equal; #greater } {\n    if (x < y) { #less } else if (x == y) { #equal } else { #greater }\n  };\n\n  /// Returns the sum of `x` and `y`, `x + y`.\n  /// Traps on overflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat8.add(1, 2); // => 3\n  /// (1 : Nat8) + (2 : Nat8) // => 3\n  /// ```\n  ///\n\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// import Array \"mo:base/Array\";\n  /// Array.foldLeft<Nat8, Nat8>([2, 3, 1], 0, Nat8.add) // => 6\n  /// ```\n  public func add(x : Nat8, y : Nat8) : Nat8 { x + y };\n\n  /// Returns the difference of `x` and `y`, `x - y`.\n  /// Traps on underflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat8.sub(2, 1); // => 1\n  /// (2 : Nat8) - (1 : Nat8) // => 1\n  /// ```\n  ///\n\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// import Array \"mo:base/Array\";\n  /// Array.foldLeft<Nat8, Nat8>([2, 3, 1], 20, Nat8.sub) // => 14\n  /// ```\n  public func sub(x : Nat8, y : Nat8) : Nat8 { x - y };\n\n  /// Returns the product of `x` and `y`, `x * y`.\n  /// Traps on overflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat8.mul(2, 3); // => 6\n  /// (2 : Nat8) * (3 : Nat8) // => 6\n  /// ```\n  ///\n\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// import Array \"mo:base/Array\";\n  /// Array.foldLeft<Nat8, Nat8>([2, 3, 1], 1, Nat8.mul) // => 6\n  /// ```\n  public func mul(x : Nat8, y : Nat8) : Nat8 { x * y };\n\n  /// Returns the quotient of `x` divided by `y`, `x / y`.\n  /// Traps when `y` is zero.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat8.div(6, 2); // => 3\n  /// (6 : Nat8) / (2 : Nat8) // => 3\n  /// ```\n  ///\n\n  public func div(x : Nat8, y : Nat8) : Nat8 { x / y };\n\n  /// Returns the remainder of `x` divided by `y`, `x % y`.\n  /// Traps when `y` is zero.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat8.rem(6, 4); // => 2\n  /// (6 : Nat8) % (4 : Nat8) // => 2\n  /// ```\n  ///\n\n  public func rem(x : Nat8, y : Nat8) : Nat8 { x % y };\n\n  /// Returns `x` to the power of `y`, `x ** y`.\n  /// Traps on overflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat8.pow(2, 3); // => 8\n  /// (2 : Nat8) ** (3 : Nat8) // => 8\n  /// ```\n  ///\n\n  public func pow(x : Nat8, y : Nat8) : Nat8 { x ** y };\n\n  /// Returns the bitwise negation of `x`, `^x`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat8.bitnot(0); // => 255\n  /// ^(0 : Nat8) // => 255\n  /// ```\n  ///\n\n  public func bitnot(x : Nat8) : Nat8 { ^x };\n\n  /// Returns the bitwise and of `x` and `y`, `x & y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat8.bitand(3, 2); // => 2\n  /// (3 : Nat8) & (2 : Nat8) // => 2\n  /// ```\n  ///\n\n  public func bitand(x : Nat8, y : Nat8) : Nat8 { x & y };\n\n  /// Returns the bitwise or of `x` and `y`, `x | y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat8.bitor(3, 2); // => 3\n  /// (3 : Nat8) | (2 : Nat8) // => 3\n  /// ```\n  ///\n\n  public func bitor(x : Nat8, y : Nat8) : Nat8 { x | y };\n\n  /// Returns the bitwise exclusive or of `x` and `y`, `x ^ y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat8.bitxor(3, 2); // => 1\n  /// (3 : Nat8) ^ (2 : Nat8) // => 1\n  /// ```\n  ///\n\n  public func bitxor(x : Nat8, y : Nat8) : Nat8 { x ^ y };\n\n  /// Returns the bitwise shift left of `x` by `y`, `x << y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat8.bitshiftLeft(1, 2); // => 4\n  /// (1 : Nat8) << (2 : Nat8) // => 4\n  /// ```\n  ///\n\n  public func bitshiftLeft(x : Nat8, y : Nat8) : Nat8 { x << y };\n\n  /// Returns the bitwise shift right of `x` by `y`, `x >> y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat8.bitshiftRight(4, 2); // => 1\n  /// (4 : Nat8) >> (2 : Nat8) // => 1\n  /// ```\n  ///\n\n  public func bitshiftRight(x : Nat8, y : Nat8) : Nat8 { x >> y };\n\n  /// Returns the bitwise rotate left of `x` by `y`, `x <<> y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat8.bitrotLeft(128, 1); // => 1\n  /// (128 : Nat8) <<> (1 : Nat8) // => 1\n  /// ```\n  ///\n\n  public func bitrotLeft(x : Nat8, y : Nat8) : Nat8 { x <<> y };\n\n  /// Returns the bitwise rotate right of `x` by `y`, `x <>> y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat8.bitrotRight(1, 1); // => 128\n  /// (1 : Nat8) <>> (1 : Nat8) // => 128\n  /// ```\n  ///\n\n  public func bitrotRight(x : Nat8, y : Nat8) : Nat8 { x <>> y };\n\n  /// Returns the value of bit `p mod 8` in `x`, `(x & 2^(p mod 8)) == 2^(p mod 8)`.\n  /// This is equivalent to checking if the `p`-th bit is set in `x`, using 0 indexing.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat8.bittest(5, 2); // => true\n  /// ```\n  public func bittest(x : Nat8, p : Nat) : Bool {\n    Prim.btstNat8(x, Prim.natToNat8(p))\n  };\n\n  /// Returns the value of setting bit `p mod 8` in `x` to `1`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat8.bitset(5, 1); // => 7\n  /// ```\n  public func bitset(x : Nat8, p : Nat) : Nat8 {\n    x | (1 << Prim.natToNat8(p))\n  };\n\n  /// Returns the value of clearing bit `p mod 8` in `x` to `0`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat8.bitclear(5, 2); // => 1\n  /// ```\n  public func bitclear(x : Nat8, p : Nat) : Nat8 {\n    x & ^(1 << Prim.natToNat8(p))\n  };\n\n  /// Returns the value of flipping bit `p mod 8` in `x`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat8.bitflip(5, 2); // => 1\n  /// ```\n  public func bitflip(x : Nat8, p : Nat) : Nat8 {\n    x ^ (1 << Prim.natToNat8(p))\n  };\n\n  /// Returns the count of non-zero bits in `x`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat8.bitcountNonZero(5); // => 2\n  /// ```\n  public let bitcountNonZero : (x : Nat8) -> Nat8 = Prim.popcntNat8;\n\n  /// Returns the count of leading zero bits in `x`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat8.bitcountLeadingZero(5); // => 5\n  /// ```\n  public let bitcountLeadingZero : (x : Nat8) -> Nat8 = Prim.clzNat8;\n\n  /// Returns the count of trailing zero bits in `x`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat8.bitcountTrailingZero(6); // => 1\n  /// ```\n  public let bitcountTrailingZero : (x : Nat8) -> Nat8 = Prim.ctzNat8;\n\n  /// Returns the sum of `x` and `y`, `x +% y`. Wraps on overflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat8.addWrap(230, 26); // => 0\n  /// (230 : Nat8) +% (26 : Nat8) // => 0\n  /// ```\n  ///\n\n  public func addWrap(x : Nat8, y : Nat8) : Nat8 { x +% y };\n\n  /// Returns the difference of `x` and `y`, `x -% y`. Wraps on underflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat8.subWrap(0, 1); // => 255\n  /// (0 : Nat8) -% (1 : Nat8) // => 255\n  /// ```\n\n  public func subWrap(x : Nat8, y : Nat8) : Nat8 { x -% y };\n\n  /// Returns the product of `x` and `y`, `x *% y`. Wraps on overflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat8.mulWrap(230, 26); // => 92\n  /// (230 : Nat8) *% (26 : Nat8) // => 92\n  /// ```\n  ///\n\n  public func mulWrap(x : Nat8, y : Nat8) : Nat8 { x *% y };\n\n  /// Returns `x` to the power of `y`, `x **% y`. Wraps on overflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat8.powWrap(2, 8); // => 0\n  /// (2 : Nat8) **% (8 : Nat8) // => 0\n  /// ```\n  ///\n\n  public func powWrap(x : Nat8, y : Nat8) : Nat8 { x **% y };\n\n}\n"},"Prelude.mo":{"content":"/// This prelude file proposes standard library features that _may_\n/// belong in the _language_ (compiler-internal) prelude sometime, after\n/// some further experience and discussion.  Until then, they live here.\n\nimport Debug \"Debug\";\n\nmodule {\n\n  /// :::warning\n  /// Not yet implemented\n  /// :::\n  ///\n  /// Mark incomplete code with the `nyi` and `xxx` functions.\n  ///\n  /// Each have calls that are well-typed in all typing contexts, which\n  /// trap in all execution contexts.\n  public func nyi() : None {\n    Debug.trap(\"Prelude.nyi()\")\n  };\n\n  public func xxx() : None {\n    Debug.trap(\"Prelude.xxx()\")\n  };\n\n  /// Mark unreachable code with the `unreachable` function.\n  ///\n  /// Calls are well-typed in all typing contexts, and they\n  /// trap in all execution contexts.\n  public func unreachable() : None {\n    Debug.trap(\"Prelude.unreachable()\")\n  };\n\n}\n"},"Int8.mo":{"content":"/// Provides utility functions on 8-bit signed integers.\n///\n/// :::info Function form for higher-order use\n///\n/// Several arithmetic and comparison functions (e.g. `add`, `sub`, `bitor`, `bitand`, `pow`) are defined in this module to enable their use as first-class function values, which is not possible with operators like `+`, `-`, `==`, etc., in Motoko. This allows you to pass these operations to higher-order functions such as `map`, `foldLeft`, or `sort`.\n/// :::\n///\n/// :::note\n/// Most operations are available as built-in operators (e.g. `1 + 1`).\n/// :::\n/// Import from the base library to use this module.\n///\n/// ```motoko name=import\n/// import Int8 \"mo:base/Int8\";\n/// ```\nimport Int \"Int\";\nimport Prim \"mo:⛔\";\n\nmodule {\n\n  /// 8-bit signed integers.\n  public type Int8 = Prim.Types.Int8;\n\n  /// Minimum 8-bit integer value, `-2 ** 7`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int8.minimumValue // => -128\n  /// ```\n  public let minimumValue = -128 : Int8;\n\n  /// Maximum 8-bit integer value, `+2 ** 7 - 1`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int8.maximumValue // => +127\n  /// ```\n  public let maximumValue = 127 : Int8;\n\n  /// Converts an 8-bit signed integer to a signed integer with infinite precision.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int8.toInt(123) // => 123 : Int\n  /// ```\n  public let toInt : Int8 -> Int = Prim.int8ToInt;\n\n  /// Converts a signed integer with infinite precision to an 8-bit signed integer.\n  ///\n  /// Traps on overflow/underflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int8.fromInt(123) // => +123 : Int8\n  /// ```\n  public let fromInt : Int -> Int8 = Prim.intToInt8;\n\n  /// Converts a signed integer with infinite precision to an 8-bit signed integer.\n  ///\n  /// Wraps on overflow/underflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int8.fromIntWrap(-123) // => -123 : Int\n  /// ```\n  public let fromIntWrap : Int -> Int8 = Prim.intToInt8Wrap;\n\n  /// Converts a 16-bit signed integer to an 8-bit signed integer.\n  ///\n  /// Traps on overflow/underflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int8.fromInt16(123) // => +123 : Int8\n  /// ```\n  public let fromInt16 : Int16 -> Int8 = Prim.int16ToInt8;\n\n  /// Converts an 8-bit signed integer to a 16-bit signed integer.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int8.toInt16(123) // => +123 : Int16\n  /// ```\n  public let toInt16 : Int8 -> Int16 = Prim.int8ToInt16;\n\n  /// Converts an unsigned 8-bit integer to a signed 8-bit integer.\n  ///\n  /// Wraps on overflow/underflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int8.fromNat8(123) // => +123 : Int8\n  /// ```\n  public let fromNat8 : Nat8 -> Int8 = Prim.nat8ToInt8;\n\n  /// Converts a signed 8-bit integer to an unsigned 8-bit integer.\n  ///\n  /// Wraps on overflow/underflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int8.toNat8(-1) // => 255 : Nat8 // underflow\n  /// ```\n  public let toNat8 : Int8 -> Nat8 = Prim.int8ToNat8;\n\n  /// Converts an integer number to its textual representation.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int8.toText(-123) // => \"-123\"\n  /// ```\n  public func toText(x : Int8) : Text {\n    Int.toText(toInt(x))\n  };\n\n  /// Returns the absolute value of `x`.\n  ///\n  /// Traps when `x == -2 ** 7` (the minimum `Int8` value).\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int8.abs(-123) // => +123\n  /// ```\n  public func abs(x : Int8) : Int8 {\n    fromInt(Int.abs(toInt(x)))\n  };\n\n  /// Returns the minimum of `x` and `y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int8.min(+2, -3) // => -3\n  /// ```\n  public func min(x : Int8, y : Int8) : Int8 {\n    if (x < y) { x } else { y }\n  };\n\n  /// Returns the maximum of `x` and `y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int8.max(+2, -3) // => +2\n  /// ```\n  public func max(x : Int8, y : Int8) : Int8 {\n    if (x < y) { y } else { x }\n  };\n\n  /// Equality function for Int8 types.\n  /// This is equivalent to `x == y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int8.equal(-1, -1); // => true\n  /// ```\n  ///\n\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// import Buffer \"mo:base/Buffer\";\n  ///\n  /// let buffer1 = Buffer.Buffer<Int8>(1);\n  /// buffer1.add(-3);\n  /// let buffer2 = Buffer.Buffer<Int8>(1);\n  /// buffer2.add(-3);\n  /// Buffer.equal(buffer1, buffer2, Int8.equal) // => true\n  /// ```\n  public func equal(x : Int8, y : Int8) : Bool { x == y };\n\n  /// Inequality function for Int8 types.\n  /// This is equivalent to `x != y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int8.notEqual(-1, -2); // => true\n  /// ```\n  ///\n\n  public func notEqual(x : Int8, y : Int8) : Bool { x != y };\n\n  /// \"Less than\" function for Int8 types.\n  /// This is equivalent to `x < y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int8.less(-2, 1); // => true\n  /// ```\n  ///\n\n  public func less(x : Int8, y : Int8) : Bool { x < y };\n\n  /// \"Less than or equal\" function for Int8 types.\n  /// This is equivalent to `x <= y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int8.lessOrEqual(-2, -2); // => true\n  /// ```\n  ///\n\n  public func lessOrEqual(x : Int8, y : Int8) : Bool { x <= y };\n\n  /// \"Greater than\" function for Int8 types.\n  /// This is equivalent to `x > y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int8.greater(-2, -3); // => true\n  /// ```\n  ///\n\n  public func greater(x : Int8, y : Int8) : Bool { x > y };\n\n  /// \"Greater than or equal\" function for Int8 types.\n  /// This is equivalent to `x >= y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int8.greaterOrEqual(-2, -2); // => true\n  /// ```\n  ///\n\n  public func greaterOrEqual(x : Int8, y : Int8) : Bool { x >= y };\n\n  /// General-purpose comparison function for `Int8`. Returns the `Order` (\n  /// either `#less`, `#equal`, or `#greater`) of comparing `x` with `y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int8.compare(-3, 2) // => #less\n  /// ```\n  ///\n  /// This function can be used as value for a high order function, such as a sort function.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// import Array \"mo:base/Array\";\n  /// Array.sort([1, -2, -3] : [Int8], Int8.compare) // => [-3, -2, 1]\n  /// ```\n  public func compare(x : Int8, y : Int8) : { #less; #equal; #greater } {\n    if (x < y) { #less } else if (x == y) { #equal } else { #greater }\n  };\n\n  /// Returns the negation of `x`, `-x`.\n  ///\n  /// Traps on overflow, i.e. for `neg(-2 ** 7)`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int8.neg(123) // => -123\n  /// ```\n  ///\n\n  public func neg(x : Int8) : Int8 { -x };\n\n  /// Returns the sum of `x` and `y`, `x + y`.\n  ///\n  /// Traps on overflow/underflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int8.add(100, 23) // => +123\n  /// ```\n  ///\n\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// import Array \"mo:base/Array\";\n  /// Array.foldLeft<Int8, Int8>([1, -2, -3], 0, Int8.add) // => -4\n  /// ```\n  public func add(x : Int8, y : Int8) : Int8 { x + y };\n\n  /// Returns the difference of `x` and `y`, `x - y`.\n  ///\n  /// Traps on overflow/underflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int8.sub(123, 23) // => +100\n  /// ```\n  ///\n\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// import Array \"mo:base/Array\";\n  /// Array.foldLeft<Int8, Int8>([1, -2, -3], 0, Int8.sub) // => 4\n  /// ```\n  public func sub(x : Int8, y : Int8) : Int8 { x - y };\n\n  /// Returns the product of `x` and `y`, `x * y`.\n  ///\n  /// Traps on overflow/underflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int8.mul(12, 10) // => +120\n  /// ```\n  ///\n\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// import Array \"mo:base/Array\";\n  /// Array.foldLeft<Int8, Int8>([1, -2, -3], 1, Int8.mul) // => 6\n  /// ```\n  public func mul(x : Int8, y : Int8) : Int8 { x * y };\n\n  /// Returns the signed integer division of `x` by `y`, `x / y`.\n  /// Rounds the quotient towards zero, which is the same as truncating the decimal places of the quotient.\n  ///\n  /// Traps when `y` is zero.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int8.div(123, 10) // => +12\n  /// ```\n  ///\n\n  public func div(x : Int8, y : Int8) : Int8 { x / y };\n\n  /// Returns the remainder of the signed integer division of `x` by `y`, `x % y`,\n  /// which is defined as `x - x / y * y`.\n  ///\n  /// Traps when `y` is zero.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int8.rem(123, 10) // => +3\n  /// ```\n  ///\n\n  public func rem(x : Int8, y : Int8) : Int8 { x % y };\n\n  /// Returns `x` to the power of `y`, `x ** y`.\n  ///\n  /// Traps on overflow/underflow and when `y < 0 or y >= 8`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int8.pow(2, 6) // => +64\n  /// ```\n  ///\n\n  public func pow(x : Int8, y : Int8) : Int8 { x ** y };\n\n  /// Returns the bitwise negation of `x`, `^x`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int8.bitnot(-16 /* 0xf0 */) // => +15 // 0x0f\n  /// ```\n  ///\n\n  public func bitnot(x : Int8) : Int8 { ^x };\n\n  /// Returns the bitwise \"and\" of `x` and `y`, `x & y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int8.bitand(0x1f, 0x70) // => +16 // 0x10\n  /// ```\n  ///\n\n  public func bitand(x : Int8, y : Int8) : Int8 { x & y };\n\n  /// Returns the bitwise \"or\" of `x` and `y`, `x | y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int8.bitor(0x0f, 0x70) // => +127 // 0x7f\n  /// ```\n  ///\n\n  public func bitor(x : Int8, y : Int8) : Int8 { x | y };\n\n  /// Returns the bitwise \"exclusive or\" of `x` and `y`, `x ^ y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int8.bitxor(0x70, 0x7f) // => +15 // 0x0f\n  /// ```\n  ///\n\n  public func bitxor(x : Int8, y : Int8) : Int8 { x ^ y };\n\n  /// Returns the bitwise left shift of `x` by `y`, `x << y`.\n  /// The right bits of the shift filled with zeros.\n  /// Left-overflowing bits, including the sign bit, are discarded.\n  ///\n  /// For `y >= 8`, the semantics is the same as for `bitshiftLeft(x, y % 8)`.\n  /// For `y < 0`,  the semantics is the same as for `bitshiftLeft(x, y + y % 8)`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int8.bitshiftLeft(1, 4) // => +16 // 0x10 equivalent to `2 ** 4`.\n  /// ```\n  ///\n\n  public func bitshiftLeft(x : Int8, y : Int8) : Int8 { x << y };\n\n  /// Returns the signed bitwise right shift of `x` by `y`, `x >> y`.\n  /// The sign bit is retained and the left side is filled with the sign bit.\n  /// Right-underflowing bits are discarded, i.e. not rotated to the left side.\n  ///\n  /// For `y >= 8`, the semantics is the same as for `bitshiftRight(x, y % 8)`.\n  /// For `y < 0`,  the semantics is the same as for `bitshiftRight (x, y + y % 8)`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int8.bitshiftRight(64, 4) // => +4 // equivalent to `64 / (2 ** 4)`\n  /// ```\n  ///\n\n  public func bitshiftRight(x : Int8, y : Int8) : Int8 { x >> y };\n\n  /// Returns the bitwise left rotatation of `x` by `y`, `x <<> y`.\n  /// Each left-overflowing bit is inserted again on the right side.\n  /// The sign bit is rotated like other bits, i.e. the rotation interprets the number as unsigned.\n  ///\n  /// Changes the direction of rotation for negative `y`.\n  /// For `y >= 8`, the semantics is the same as for `bitrotLeft(x, y % 8)`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int8.bitrotLeft(0x11 /* 0b0001_0001 */, 2) // => +68 // 0b0100_0100 == 0x44.\n  /// ```\n  ///\n\n  public func bitrotLeft(x : Int8, y : Int8) : Int8 { x <<> y };\n\n  /// Returns the bitwise right rotation of `x` by `y`, `x <>> y`.\n  /// Each right-underflowing bit is inserted again on the right side.\n  /// The sign bit is rotated like other bits, i.e. the rotation interprets the number as unsigned.\n  ///\n  /// Changes the direction of rotation for negative `y`.\n  /// For `y >= 8`, the semantics is the same as for `bitrotRight(x, y % 8)`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int8.bitrotRight(0x11 /* 0b0001_0001 */, 1) // => -120 // 0b1000_1000 == 0x88.\n  /// ```\n  ///\n\n  public func bitrotRight(x : Int8, y : Int8) : Int8 { x <>> y };\n\n  /// Returns the value of bit `p` in `x`, `x & 2**p == 2**p`.\n  /// If `p >= 8`, the semantics is the same as for `bittest(x, p % 8)`.\n  /// This is equivalent to checking if the `p`-th bit is set in `x`, using 0 indexing.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int8.bittest(64, 6) // => true\n  /// ```\n  public func bittest(x : Int8, p : Nat) : Bool {\n    Prim.btstInt8(x, Prim.intToInt8(p))\n  };\n\n  /// Returns the value of setting bit `p` in `x` to `1`.\n  /// If `p >= 8`, the semantics is the same as for `bitset(x, p % 8)`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int8.bitset(0, 6) // => +64\n  /// ```\n  public func bitset(x : Int8, p : Nat) : Int8 {\n    x | (1 << Prim.intToInt8(p))\n  };\n\n  /// Returns the value of clearing bit `p` in `x` to `0`.\n  /// If `p >= 8`, the semantics is the same as for `bitclear(x, p % 8)`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int8.bitclear(-1, 6) // => -65\n  /// ```\n  public func bitclear(x : Int8, p : Nat) : Int8 {\n    x & ^(1 << Prim.intToInt8(p))\n  };\n\n  /// Returns the value of flipping bit `p` in `x`.\n  /// If `p >= 8`, the semantics is the same as for `bitclear(x, p % 8)`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int8.bitflip(127, 6) // => +63\n  /// ```\n  public func bitflip(x : Int8, p : Nat) : Int8 {\n    x ^ (1 << Prim.intToInt8(p))\n  };\n\n  /// Returns the count of non-zero bits in `x`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int8.bitcountNonZero(0x0f) // => +4\n  /// ```\n  public let bitcountNonZero : (x : Int8) -> Int8 = Prim.popcntInt8;\n\n  /// Returns the count of leading zero bits in `x`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int8.bitcountLeadingZero(0x08) // => +4\n  /// ```\n  public let bitcountLeadingZero : (x : Int8) -> Int8 = Prim.clzInt8;\n\n  /// Returns the count of trailing zero bits in `x`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int8.bitcountTrailingZero(0x10) // => +4\n  /// ```\n  public let bitcountTrailingZero : (x : Int8) -> Int8 = Prim.ctzInt8;\n\n  /// Returns the sum of `x` and `y`, `x +% y`.\n  ///\n  /// Wraps on overflow/underflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int8.addWrap(2 ** 6, 2 ** 6) // => -128 // overflow\n  /// ```\n  ///\n\n  public func addWrap(x : Int8, y : Int8) : Int8 { x +% y };\n\n  /// Returns the difference of `x` and `y`, `x -% y`.\n  ///\n  /// Wraps on overflow/underflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int8.subWrap(-2 ** 7, 1) // => +127 // underflow\n  /// ```\n  ///\n\n  public func subWrap(x : Int8, y : Int8) : Int8 { x -% y };\n\n  /// Returns the product of `x` and `y`, `x *% y`. Wraps on overflow.\n  ///\n  /// Wraps on overflow/underflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int8.mulWrap(2 ** 4, 2 ** 4) // => 0 // overflow\n  /// ```\n  ///\n\n  public func mulWrap(x : Int8, y : Int8) : Int8 { x *% y };\n\n  /// Returns `x` to the power of `y`, `x **% y`.\n  ///\n  /// Wraps on overflow/underflow.\n  /// Traps if `y < 0 or y >= 8`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int8.powWrap(2, 7) // => -128 // overflow\n  /// ```\n  ///\n\n  public func powWrap(x : Int8, y : Int8) : Int8 { x **% y };\n\n}\n"},"Heap.mo":{"content":"/// Class `Heap<X>` provides a priority queue of elements of type `X`.\n///\n/// The class wraps a purely-functional implementation based on a leftist heap.\n///\n/// :::note Constructor details\n/// The constructor takes in a comparison function `compare` that defines the ordering between elements of type `X`. Most primitive types have a default version of this comparison function defined in their modules (e.g. `Nat.compare`). The runtime analysis in this documentation assumes that the `compare` function runs in `O(1)` time and space.\n/// :::\n///\n/// Example:\n///\n/// ```motoko name=initialize\n/// import Heap \"mo:base/Heap\";\n/// import Text \"mo:base/Text\";\n///\n/// let heap = Heap.Heap<Text>(Text.compare);\n/// ```\n///\n/// | Runtime   | Space     |\n/// |-----------|-----------|\n/// | `O(1)`    | `O(1)`    |\n\nimport O \"Order\";\nimport P \"Prelude\";\nimport L \"List\";\nimport I \"Iter\";\n\nmodule {\n\n  public type Tree<X> = ?(Int, X, Tree<X>, Tree<X>);\n\n  public class Heap<X>(compare : (X, X) -> O.Order) {\n    var heap : Tree<X> = null;\n\n    /// Inserts an element into the heap.\n    ///\n    /// Example:\n    /// ```motoko include=initialize\n    /// heap.put(\"apple\");\n    /// heap.peekMin() // => ?\"apple\"\n    /// ```\n    ///\n    /// | Runtime   | Space     |\n    /// |-----------|-----------|\n    /// | `O(1)`    | `O(1)`    |\n    public func put(x : X) {\n      heap := merge(heap, ?(1, x, null, null), compare)\n    };\n\n    /// Return the minimal element in the heap, or `null` if the heap is empty.\n    ///\n    /// Example:\n    /// ```motoko include=initialize\n    /// heap.put(\"apple\");\n    /// heap.put(\"banana\");\n    /// heap.put(\"cantaloupe\");\n    /// heap.peekMin() // => ?\"apple\"\n    /// ```\n    ///\n    /// | Runtime   | Space     |\n    /// |-----------|-----------|\n    /// | `O(1)`    | `O(1)`    |\n    public func peekMin() : ?X {\n      switch heap {\n        case (null) { null };\n        case (?(_, x, _, _)) { ?x }\n      }\n    };\n\n    /// Delete the minimal element in the heap, if it exists.\n    ///\n    /// Example:\n    /// ```motoko include=initialize\n    /// heap.put(\"apple\");\n    /// heap.put(\"banana\");\n    /// heap.put(\"cantaloupe\");\n    /// heap.deleteMin();\n    /// heap.peekMin(); // => ?\"banana\"\n    /// ```\n    ///\n    /// | Runtime      | Space       |\n    /// |--------------|-------------|\n    /// | `O(log(n))`  | `O(log(n))` |\n    public func deleteMin() {\n      switch heap {\n        case null {};\n        case (?(_, _, a, b)) { heap := merge(a, b, compare) }\n      }\n    };\n\n    /// Delete and return the minimal element in the heap, if it exists.\n    ///\n    /// Example:\n    /// ```motoko include=initialize\n    /// heap.put(\"apple\");\n    /// heap.put(\"banana\");\n    /// heap.put(\"cantaloupe\");\n    /// heap.removeMin(); // => ?\"apple\"\n    /// ```\n    ///\n    /// | Runtime      | Space       |\n    /// |--------------|-------------|\n    /// | `O(log(n))`  | `O(log(n))` |\n    public func removeMin() : (minElement : ?X) {\n      switch heap {\n        case null { null };\n        case (?(_, x, a, b)) {\n          heap := merge(a, b, compare);\n          ?x\n        }\n      }\n    };\n\n    /// Return a snapshot of the internal functional tree representation as sharable data.\n    /// The returned tree representation is not affected by subsequent changes of the `Heap` instance.\n    ///\n    /// Example:\n    /// ```motoko include=initialize\n    /// heap.put(\"banana\");\n    /// heap.share();\n    /// ```\n    ///\n    /// Useful for storing the heap as a stable variable, pretty-printing, and sharing it across async function calls,\n    /// i.e. passing it in async arguments or async results.\n    ///\n    /// | Runtime   | Space     |\n    /// |-----------|-----------|\n    /// | `O(1)`    | `O(1)`    |\n    public func share() : Tree<X> {\n      heap\n    };\n\n    /// Rewraps a snapshot of a heap (obtained by `share()`) in a `Heap` instance.\n    /// The wrapping instance must be initialized with the same `compare`\n    /// function that created the snapshot.\n    ///\n    /// Example:\n    /// ```motoko include=initialize\n    /// heap.put(\"apple\");\n    /// heap.put(\"banana\");\n    /// let snapshot = heap.share();\n    /// let heapCopy = Heap.Heap<Text>(Text.compare);\n    /// heapCopy.unsafeUnshare(snapshot);\n    /// heapCopy.peekMin() // => ?\"apple\"\n    /// ```\n    ///\n    /// Useful for loading a stored heap from a stable variable or accesing a heap\n    /// snapshot passed from an async function call.\n    ///\n    /// | Runtime   | Space     |\n    /// |-----------|-----------|\n    /// | `O(1)`    | `O(1)`    |\n    public func unsafeUnshare(tree : Tree<X>) {\n      heap := tree\n    };\n\n  };\n\n  func rank<X>(heap : Tree<X>) : Int {\n    switch heap {\n      case null { 0 };\n      case (?(r, _, _, _)) { r }\n    }\n  };\n\n  func makeT<X>(x : X, a : Tree<X>, b : Tree<X>) : Tree<X> {\n    if (rank(a) >= rank(b)) {\n      ?(rank(b) + 1, x, a, b)\n    } else {\n      ?(rank(a) + 1, x, b, a)\n    }\n  };\n\n  func merge<X>(h1 : Tree<X>, h2 : Tree<X>, compare : (X, X) -> O.Order) : Tree<X> {\n    switch (h1, h2) {\n      case (null, h) { h };\n      case (h, null) { h };\n      case (?(_, x, a, b), ?(_, y, c, d)) {\n        switch (compare(x, y)) {\n          case (#less) { makeT(x, a, merge(b, h2, compare)) };\n          case _ { makeT(y, c, merge(d, h1, compare)) }\n        }\n      }\n    }\n  };\n\n  /// Returns a new `Heap`, containing all entries given by the iterator `iter`.\n  /// The new map is initialized with the provided `compare` function.\n  ///\n  /// Example:\n  /// ```motoko include=initialize\n  /// let entries = [\"banana\", \"apple\", \"cantaloupe\"];\n  /// let iter = entries.vals();\n  ///\n  /// let newHeap = Heap.fromIter<Text>(iter, Text.compare);\n  /// newHeap.peekMin() // => ?\"apple\"\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size)` | `O(size)` |\n  public func fromIter<X>(iter : I.Iter<X>, compare : (X, X) -> O.Order) : Heap<X> {\n    let heap = Heap<X>(compare);\n    func build(xs : L.List<Tree<X>>) : Tree<X> {\n      func join(xs : L.List<Tree<X>>) : L.List<Tree<X>> {\n        switch (xs) {\n          case (null) { null };\n          case (?(hd, null)) { ?(hd, null) };\n          case (?(h1, ?(h2, tl))) { ?(merge(h1, h2, compare), join(tl)) }\n        }\n      };\n      switch (xs) {\n        case null { P.unreachable() };\n        case (?(hd, null)) { hd };\n        case _ { build(join(xs)) }\n      }\n    };\n    let list = I.toList(I.map(iter, func(x : X) : Tree<X> { ?(1, x, null, null) }));\n    if (not L.isNil(list)) {\n      let t = build(list);\n      heap.unsafeUnshare(t)\n    };\n    heap\n  };\n\n}\n"},"Float.mo":{"content":"/// Double precision (64-bit) floating-point numbers in IEEE 754 representation.\n///\n/// This module contains common floating-point constants and utility functions.\n///\n/// Notation for special values in the documentation below:\n///\n/// `+inf`: Positive infinity\n///\n/// `-inf`: Negative infinity\n///\n/// `NaN`: \"not a number\" (can have different sign bit values, but `NaN != NaN` regardless of the sign).\n///\n/// :::note\n/// Floating point numbers have limited precision and operations may inherently result in numerical errors.\n/// :::\n///\n/// Examples of numerical errors:\n///   ```motoko\n///   0.1 + 0.1 + 0.1 == 0.3 // => false\n///   ```\n///\n///   ```motoko\n///  1e16 + 1.0 != 1e16 // => false\n///   ```\n///\n///\n/// Advice:\n/// * Floating point number comparisons by `==` or `!=` are discouraged. Instead, it is better to compare\n///   floating-point numbers with a numerical tolerance, called epsilon.\n///\n///   Example:\n///   ```motoko\n///   import Float \"mo:base/Float\";\n///   let x = 0.1 + 0.1 + 0.1;\n///   let y = 0.3;\n///\n///   let epsilon = 1e-6; // This depends on the application case (needs a numerical error analysis).\n///   Float.equalWithin(x, y, epsilon) // => true\n///   ```\n///\n/// * For absolute precision, it is recommend to encode the fraction number as a pair of a `Nat` for the base\n///   and a `Nat` for the exponent (decimal point).\n///\n/// `NaN` sign:\n/// * The `NaN` sign is only applied by `abs`, `neg`, and `copySign`. Other operations can have an arbitrary\n///   sign bit for `NaN` results.\n\nimport Prim \"mo:⛔\";\nimport Int \"Int\";\n\nmodule {\n\n  /// 64-bit floating point number type.\n  public type Float = Prim.Types.Float;\n\n  /// Ratio of the circumference of a circle to its diameter.\n  /// Note: Limited precision.\n  public let pi : Float = 3.14159265358979323846; // taken from musl math.h\n\n  /// Base of the natural logarithm.\n  /// Note: Limited precision.\n  public let e : Float = 2.7182818284590452354; // taken from musl math.h\n\n  /// Determines whether the `number` is a `NaN` (\"not a number\" in the floating point representation).\n  /// Notes:\n  /// * Equality test of `NaN` with itself or another number is always `false`.\n  /// * There exist many internal `NaN` value representations, such as positive and negative `NaN`,\n  ///   signalling and quiet `NaN`s, each with many different bit representations.\n  ///\n  /// Example:\n  /// ```motoko\n  /// import Float \"mo:base/Float\";\n  ///\n  /// Float.isNaN(0.0/0.0) // => true\n  /// ```\n  public func isNaN(number : Float) : Bool {\n    number != number\n  };\n\n  /// Returns the absolute value of `x`.\n  ///\n  /// Special cases:\n  /// ```\n  /// abs(+inf) => +inf\n  /// abs(-inf) => +inf\n  /// abs(-NaN)  => +NaN\n  /// abs(-0.0) => 0.0\n  /// ```\n  ///\n  /// Example:\n  /// ```motoko\n  /// import Float \"mo:base/Float\";\n  ///\n  /// Float.abs(-1.2) // => 1.2\n  /// ```\n  public let abs : (x : Float) -> Float = Prim.floatAbs;\n\n  /// Returns the square root of `x`.\n  ///\n  /// Special cases:\n  /// ```\n  /// sqrt(+inf) => +inf\n  /// sqrt(-0.0) => -0.0\n  /// sqrt(x)    => NaN if x < 0.0\n  /// sqrt(NaN)  => NaN\n  /// ```\n  ///\n  /// Example:\n  /// ```motoko\n  /// import Float \"mo:base/Float\";\n  ///\n  /// Float.sqrt(6.25) // => 2.5\n  /// ```\n  public let sqrt : (x : Float) -> Float = Prim.floatSqrt;\n\n  /// Returns the smallest integral float greater than or equal to `x`.\n  ///\n  /// Special cases:\n  /// ```\n  /// ceil(+inf) => +inf\n  /// ceil(-inf) => -inf\n  /// ceil(NaN)  => NaN\n  /// ceil(0.0)  => 0.0\n  /// ceil(-0.0) => -0.0\n  /// ```\n  ///\n  /// Example:\n  /// ```motoko\n  /// import Float \"mo:base/Float\";\n  ///\n  /// Float.ceil(1.2) // => 2.0\n  /// ```\n  public let ceil : (x : Float) -> Float = Prim.floatCeil;\n\n  /// Returns the largest integral float less than or equal to `x`.\n  ///\n  /// Special cases:\n  /// ```\n  /// floor(+inf) => +inf\n  /// floor(-inf) => -inf\n  /// floor(NaN)  => NaN\n  /// floor(0.0)  => 0.0\n  /// floor(-0.0) => -0.0\n  /// ```\n  ///\n  /// Example:\n  /// ```motoko\n  /// import Float \"mo:base/Float\";\n  ///\n  /// Float.floor(1.2) // => 1.0\n  /// ```\n  public let floor : (x : Float) -> Float = Prim.floatFloor;\n\n  /// Returns the nearest integral float not greater in magnitude than `x`.\n  /// This is equivalent to returning `x` with truncating its decimal places.\n  ///\n  /// Special cases:\n  /// ```\n  /// trunc(+inf) => +inf\n  /// trunc(-inf) => -inf\n  /// trunc(NaN)  => NaN\n  /// trunc(0.0)  => 0.0\n  /// trunc(-0.0) => -0.0\n  /// ```\n  ///\n  /// Example:\n  /// ```motoko\n  /// import Float \"mo:base/Float\";\n  ///\n  /// Float.trunc(2.75) // => 2.0\n  /// ```\n  public let trunc : (x : Float) -> Float = Prim.floatTrunc;\n\n  /// Returns the nearest integral float to `x`.\n  /// A decimal place of exactly .5 is rounded up for `x > 0`\n  /// and rounded down for `x < 0`\n  ///\n  /// Special cases:\n  /// ```\n  /// nearest(+inf) => +inf\n  /// nearest(-inf) => -inf\n  /// nearest(NaN)  => NaN\n  /// nearest(0.0)  => 0.0\n  /// nearest(-0.0) => -0.0\n  /// ```\n  ///\n  /// Example:\n  /// ```motoko\n  /// import Float \"mo:base/Float\";\n  ///\n  /// Float.nearest(2.75) // => 3.0\n  /// ```\n  public let nearest : (x : Float) -> Float = Prim.floatNearest;\n\n  /// Returns `x` if `x` and `y` have same sign, otherwise `x` with negated sign.\n  ///\n  /// The sign bit of zero, infinity, and `NaN` is considered.\n  ///\n  /// Example:\n  /// ```motoko\n  /// import Float \"mo:base/Float\";\n  ///\n  /// Float.copySign(1.2, -2.3) // => -1.2\n  /// ```\n  public let copySign : (x : Float, y : Float) -> Float = Prim.floatCopySign;\n\n  /// Returns the smaller value of `x` and `y`.\n  ///\n  /// Special cases:\n  /// ```\n  /// min(NaN, y) => NaN for any Float y\n  /// min(x, NaN) => NaN for any Float x\n  /// ```\n  ///\n  /// Example:\n  /// ```motoko\n  /// import Float \"mo:base/Float\";\n  ///\n  /// Float.min(1.2, -2.3) // => -2.3 (with numerical imprecision)\n  /// ```\n  public let min : (x : Float, y : Float) -> Float = Prim.floatMin;\n\n  /// Returns the larger value of `x` and `y`.\n  ///\n  /// Special cases:\n  /// ```\n  /// max(NaN, y) => NaN for any Float y\n  /// max(x, NaN) => NaN for any Float x\n  /// ```\n  ///\n  /// Example:\n  /// ```motoko\n  /// import Float \"mo:base/Float\";\n  ///\n  /// Float.max(1.2, -2.3) // => 1.2\n  /// ```\n  public let max : (x : Float, y : Float) -> Float = Prim.floatMax;\n\n  /// Returns the sine of the radian angle `x`.\n  ///\n  /// Special cases:\n  /// ```\n  /// sin(+inf) => NaN\n  /// sin(-inf) => NaN\n  /// sin(NaN) => NaN\n  /// ```\n  ///\n  /// Example:\n  /// ```motoko\n  /// import Float \"mo:base/Float\";\n  ///\n  /// Float.sin(Float.pi / 2) // => 1.0\n  /// ```\n  public let sin : (x : Float) -> Float = Prim.sin;\n\n  /// Returns the cosine of the radian angle `x`.\n  ///\n  /// Special cases:\n  /// ```\n  /// cos(+inf) => NaN\n  /// cos(-inf) => NaN\n  /// cos(NaN)  => NaN\n  /// ```\n  ///\n  /// Example:\n  /// ```motoko\n  /// import Float \"mo:base/Float\";\n  ///\n  /// Float.cos(Float.pi / 2) // => 0.0 (with numerical imprecision)\n  /// ```\n  public let cos : (x : Float) -> Float = Prim.cos;\n\n  /// Returns the tangent of the radian angle `x`.\n  ///\n  /// Special cases:\n  /// ```\n  /// tan(+inf) => NaN\n  /// tan(-inf) => NaN\n  /// tan(NaN)  => NaN\n  /// ```\n  ///\n  /// Example:\n  /// ```motoko\n  /// import Float \"mo:base/Float\";\n  ///\n  /// Float.tan(Float.pi / 4) // => 1.0 (with numerical imprecision)\n  /// ```\n  public let tan : (x : Float) -> Float = Prim.tan;\n\n  /// Returns the arc sine of `x` in radians.\n  ///\n  /// Special cases:\n  /// ```\n  /// arcsin(x)   => NaN if x > 1.0\n  /// arcsin(x)   => NaN if x < -1.0\n  /// arcsin(NaN) => NaN\n  /// ```\n  ///\n  /// Example:\n  /// ```motoko\n  /// import Float \"mo:base/Float\";\n  ///\n  /// Float.arcsin(1.0) // => Float.pi / 2\n  /// ```\n  public let arcsin : (x : Float) -> Float = Prim.arcsin;\n\n  /// Returns the arc cosine of `x` in radians.\n  ///\n  /// Special cases:\n  /// ```\n  /// arccos(x)  => NaN if x > 1.0\n  /// arccos(x)  => NaN if x < -1.0\n  /// arcos(NaN) => NaN\n  /// ```\n  ///\n  /// Example:\n  /// ```motoko\n  /// import Float \"mo:base/Float\";\n  ///\n  /// Float.arccos(1.0) // => 0.0\n  /// ```\n  public let arccos : (x : Float) -> Float = Prim.arccos;\n\n  /// Returns the arc tangent of `x` in radians.\n  ///\n  /// Special cases:\n  /// ```\n  /// arctan(+inf) => pi / 2\n  /// arctan(-inf) => -pi / 2\n  /// arctan(NaN)  => NaN\n  /// ```\n  ///\n  /// Example:\n  /// ```motoko\n  /// import Float \"mo:base/Float\";\n  ///\n  /// Float.arctan(1.0) // => Float.pi / 4\n  /// ```\n  public let arctan : (x : Float) -> Float = Prim.arctan;\n\n  /// Given `(y,x)`, returns the arc tangent in radians of `y/x` based on the signs of both values to determine the correct quadrant.\n  ///\n  /// Special cases:\n  /// ```\n  /// arctan2(0.0, 0.0)   => 0.0\n  /// arctan2(-0.0, 0.0)  => -0.0\n  /// arctan2(0.0, -0.0)  => pi\n  /// arctan2(-0.0, -0.0) => -pi\n  /// arctan2(+inf, +inf) => pi / 4\n  /// arctan2(+inf, -inf) => 3 * pi / 4\n  /// arctan2(-inf, +inf) => -pi / 4\n  /// arctan2(-inf, -inf) => -3 * pi / 4\n  /// arctan2(NaN, x)     => NaN for any Float x\n  /// arctan2(y, NaN)     => NaN for any Float y\n  /// ```\n  ///\n  /// Example:\n  /// ```motoko\n  /// import Float \"mo:base/Float\";\n  ///\n  /// let sqrt2over2 = Float.sqrt(2) / 2;\n  /// Float.arctan2(sqrt2over2, sqrt2over2) // => Float.pi / 4\n  /// ```\n  public let arctan2 : (y : Float, x : Float) -> Float = Prim.arctan2;\n\n  /// Returns the value of `e` raised to the `x`-th power.\n  ///\n  /// Special cases:\n  /// ```\n  /// exp(+inf) => +inf\n  /// exp(-inf) => 0.0\n  /// exp(NaN)  => NaN\n  /// ```\n  ///\n  /// Example:\n  /// ```motoko\n  /// import Float \"mo:base/Float\";\n  ///\n  /// Float.exp(1.0) // => Float.e\n  /// ```\n  public let exp : (x : Float) -> Float = Prim.exp;\n\n  /// Returns the natural logarithm (base-`e`) of `x`.\n  ///\n  /// Special cases:\n  /// ```\n  /// log(0.0)  => -inf\n  /// log(-0.0) => -inf\n  /// log(x)    => NaN if x < 0.0\n  /// log(+inf) => +inf\n  /// log(NaN)  => NaN\n  /// ```\n  ///\n  /// Example:\n  /// ```motoko\n  /// import Float \"mo:base/Float\";\n  ///\n  /// Float.log(Float.e) // => 1.0\n  /// ```\n  public let log : (x : Float) -> Float = Prim.log;\n\n  /// Formatting. `format(fmt, x)` formats `x` to `Text` according to the\n  /// formatting directive `fmt`, which can take one of the following forms:\n  ///\n  /// * `#fix prec` as fixed-point format with `prec` digits\n  /// * `#exp prec` as exponential format with `prec` digits\n  /// * `#gen prec` as generic format with `prec` digits\n  /// * `#exact` as exact format that can be decoded without loss.\n  ///\n  /// `-0.0` is formatted with negative sign bit.\n  /// Positive infinity is formatted as \"inf\".\n  /// Negative infinity is formatted as \"-inf\".\n  ///\n  /// :::info\n  /// The numerical precision and the text format can vary between\n  /// Motoko versions and runtime configuration. Moreover, `NaN` can be printed\n  /// differently, i.e. \"NaN\" or \"nan\", potentially omitting the `NaN` sign.\n  ///\n  /// Example:\n  /// ```motoko\n  /// import Float \"mo:base/Float\";\n  ///\n  /// Float.format(#exp 3, 123.0) // => \"1.230e+02\"\n  /// ```\n  public func format(fmt : { #fix : Nat8; #exp : Nat8; #gen : Nat8; #exact }, x : Float) : Text = switch fmt {\n    case (#fix(prec)) { Prim.floatToFormattedText(x, prec, 0) };\n    case (#exp(prec)) { Prim.floatToFormattedText(x, prec, 1) };\n    case (#gen(prec)) { Prim.floatToFormattedText(x, prec, 2) };\n    case (#exact) { Prim.floatToFormattedText(x, 17, 2) }\n  };\n\n  /// Conversion to `Text`. Use `format(fmt, x)` for more detailed control.\n  ///\n  /// `-0.0` is formatted with negative sign bit.\n  /// Positive infinity is formatted as `inf`.\n  /// Negative infinity is formatted as `-inf`.\n  /// `NaN` is formatted as `NaN` or `-NaN` depending on its sign bit.\n  ///\n  /// Example:\n  /// ```motoko\n  /// import Float \"mo:base/Float\";\n  ///\n  /// Float.toText(0.12) // => \"0.12\"\n  /// ```\n  public let toText : Float -> Text = Prim.floatToText;\n\n  /// Conversion to `Int64` by truncating Float, equivalent to `toInt64(trunc(f))`\n  ///\n  /// Traps if the floating point number is larger or smaller than the representable Int64.\n  /// Also traps for `inf`, `-inf`, and `NaN`.\n  ///\n  /// Example:\n  /// ```motoko\n  /// import Float \"mo:base/Float\";\n  ///\n  /// Float.toInt64(-12.3) // => -12\n  /// ```\n  public let toInt64 : Float -> Int64 = Prim.floatToInt64;\n\n  /// Conversion from `Int64`.\n  ///\n  /// :::note\n  /// The floating point number may be imprecise for large or small `Int64`.\n  /// :::\n  ///\n  /// Example:\n  /// ```motoko\n  /// import Float \"mo:base/Float\";\n  ///\n  /// Float.fromInt64(-42) // => -42.0\n  /// ```\n  public let fromInt64 : Int64 -> Float = Prim.int64ToFloat;\n\n  /// Conversion to `Int`.\n  ///\n  /// Traps for `inf`, `-inf`, and `NaN`.\n  ///\n  /// Example:\n  /// ```motoko\n  /// import Float \"mo:base/Float\";\n  ///\n  /// Float.toInt(1.2e6) // => +1_200_000\n  /// ```\n  public let toInt : Float -> Int = Prim.floatToInt;\n\n  /// Conversion from `Int`. May result in `Inf`.\n  ///\n  /// :::note\n  /// The floating point number may be imprecise for large or small Int values.\n  /// Returns `inf` if the integer is greater than the maximum floating point number.\n  /// Returns `-inf` if the integer is less than the minimum floating point number.\n  /// :::\n  ///\n  /// Example:\n  /// ```motoko\n  /// import Float \"mo:base/Float\";\n  ///\n  /// Float.fromInt(-123) // => -123.0\n  /// ```\n  public let fromInt : Int -> Float = Prim.intToFloat;\n\n  /// Returns `x == y`.\n  ///\n  /// @deprecated `Float.equalWithin()` as this function does not consider numerical errors.\n  public func equal(x : Float, y : Float) : Bool { x == y };\n\n  /// Returns `x != y`.\n  ///\n  /// @deprecated Use `Float.notEqualWithin()` as this function does not consider numerical errors.\n  public func notEqual(x : Float, y : Float) : Bool { x != y };\n\n  /// Determines whether `x` is equal to `y` within the defined tolerance of `epsilon`.\n  /// The `epsilon` considers numerical errors, see comment above.\n  /// Equivalent to `Float.abs(x - y) <= epsilon` for a non-negative epsilon.\n  ///\n  /// Traps if `epsilon` is negative or `NaN`.\n  ///\n  /// Special cases:\n  /// ```\n  /// equalWithin(+0.0, -0.0, epsilon) => true for any `epsilon >= 0.0`\n  /// equalWithin(-0.0, +0.0, epsilon) => true for any `epsilon >= 0.0`\n  /// equalWithin(+inf, +inf, epsilon) => true for any `epsilon >= 0.0`\n  /// equalWithin(-inf, -inf, epsilon) => true for any `epsilon >= 0.0`\n  /// equalWithin(x, NaN, epsilon)     => false for any x and `epsilon >= 0.0`\n  /// equalWithin(NaN, y, epsilon)     => false for any y and `epsilon >= 0.0`\n  /// ```\n  ///\n  /// Example:\n  /// ```motoko\n  /// import Float \"mo:base/Float\";\n  ///\n  /// let epsilon = 1e-6;\n  /// Float.equalWithin(-12.3, -1.23e1, epsilon) // => true\n  /// ```\n  public func equalWithin(x : Float, y : Float, epsilon : Float) : Bool {\n    if (not (epsilon >= 0.0)) {\n      // also considers NaN, not identical to `epsilon < 0.0`\n      Prim.trap(\"epsilon must be greater or equal 0.0\")\n    };\n    x == y or abs(x - y) <= epsilon // `x == y` to also consider infinity equal\n  };\n\n  /// Determines whether `x` is not equal to `y` within the defined tolerance of `epsilon`.\n  /// The `epsilon` considers numerical errors, see comment above.\n  /// Equivalent to `not equal(x, y, epsilon)`.\n  ///\n  /// Traps if `epsilon` is negative or `NaN`.\n  ///\n  /// Special cases:\n  /// ```\n  /// notEqualWithin(+0.0, -0.0, epsilon) => false for any `epsilon >= 0.0`\n  /// notEqualWithin(-0.0, +0.0, epsilon) => false for any `epsilon >= 0.0`\n  /// notEqualWithin(+inf, +inf, epsilon) => false for any `epsilon >= 0.0`\n  /// notEqualWithin(-inf, -inf, epsilon) => false for any `epsilon >= 0.0`\n  /// notEqualWithin(x, NaN, epsilon)     => true for any x and `epsilon >= 0.0`\n  /// notEqualWithin(NaN, y, epsilon)     => true for any y and `epsilon >= 0.0`\n  /// ```\n  ///\n  /// Example:\n  /// ```motoko\n  /// import Float \"mo:base/Float\";\n  ///\n  /// let epsilon = 1e-6;\n  /// Float.notEqualWithin(-12.3, -1.23e1, epsilon) // => false\n  /// ```\n  public func notEqualWithin(x : Float, y : Float, epsilon : Float) : Bool {\n    not equalWithin(x, y, epsilon)\n  };\n\n  /// Returns `x < y`.\n  ///\n  /// Special cases:\n  /// ```\n  /// less(+0.0, -0.0) => false\n  /// less(-0.0, +0.0) => false\n  /// less(NaN, y)     => false for any Float y\n  /// less(x, NaN)     => false for any Float x\n  /// ```\n  ///\n  /// Example:\n  /// ```motoko\n  /// import Float \"mo:base/Float\";\n  ///\n  /// Float.less(Float.e, Float.pi) // => true\n  /// ```\n  public func less(x : Float, y : Float) : Bool { x < y };\n\n  /// Returns `x <= y`.\n  ///\n  /// Special cases:\n  /// ```\n  /// lessOrEqual(+0.0, -0.0) => true\n  /// lessOrEqual(-0.0, +0.0) => true\n  /// lessOrEqual(NaN, y)     => false for any Float y\n  /// lessOrEqual(x, NaN)     => false for any Float x\n  /// ```\n  ///\n  /// Example:\n  /// ```motoko\n  /// import Float \"mo:base/Float\";\n  ///\n  /// Float.lessOrEqual(0.123, 0.1234) // => true\n  /// ```\n  public func lessOrEqual(x : Float, y : Float) : Bool { x <= y };\n\n  /// Returns `x > y`.\n  ///\n  /// Special cases:\n  /// ```\n  /// greater(+0.0, -0.0) => false\n  /// greater(-0.0, +0.0) => false\n  /// greater(NaN, y)     => false for any Float y\n  /// greater(x, NaN)     => false for any Float x\n  /// ```\n  ///\n  /// Example:\n  /// ```motoko\n  /// import Float \"mo:base/Float\";\n  ///\n  /// Float.greater(Float.pi, Float.e) // => true\n  /// ```\n  public func greater(x : Float, y : Float) : Bool { x > y };\n\n  /// Returns `x >= y`.\n  ///\n  /// Special cases:\n  /// ```\n  /// greaterOrEqual(+0.0, -0.0) => true\n  /// greaterOrEqual(-0.0, +0.0) => true\n  /// greaterOrEqual(NaN, y)     => false for any Float y\n  /// greaterOrEqual(x, NaN)     => false for any Float x\n  /// ```\n  ///\n  /// Example:\n  /// ```motoko\n  /// import Float \"mo:base/Float\";\n  ///\n  /// Float.greaterOrEqual(0.1234, 0.123) // => true\n  /// ```\n  public func greaterOrEqual(x : Float, y : Float) : Bool { x >= y };\n\n  /// Defines a total order of `x` and `y` for use in sorting.\n  ///\n  /// :::note\n  /// Using this operation to determine equality or inequality is discouraged for two reasons:\n  /// * It does not consider numerical errors, see comment above. Use `equalWithin(x, y, espilon)` or\n  ///   `notEqualWithin(x, y, epsilon)` to test for equality or inequality, respectively.\n  /// * `NaN` are here considered equal if their sign matches, which is different to the standard equality\n  ///    by `==` or when using `equal()` or `notEqual()`.\n  /// :::\n  ///\n  /// Total order:\n  /// * negative `NaN` (no distinction between signalling and quiet negative `NaN`)\n  /// * negative infinity\n  /// * negative numbers (including negative subnormal numbers in standard order)\n  /// * negative zero (`-0.0`)\n  /// * positive zero (`+0.0`)\n  /// * positive numbers (including positive subnormal numbers in standard order)\n  /// * positive infinity\n  /// * positive `NaN` (no distinction between signalling and quiet positive `NaN`)\n  ///\n  /// Example:\n  /// ```motoko\n  /// import Float \"mo:base/Float\";\n  ///\n  /// Float.compare(0.123, 0.1234) // => #less\n  /// ```\n  public func compare(x : Float, y : Float) : { #less; #equal; #greater } {\n    if (isNaN(x)) {\n      if (isNegative(x)) {\n        if (isNaN(y) and isNegative(y)) { #equal } else { #less }\n      } else {\n        if (isNaN(y) and not isNegative(y)) { #equal } else { #greater }\n      }\n    } else if (isNaN(y)) {\n      if (isNegative(y)) {\n        #greater\n      } else {\n        #less\n      }\n    } else {\n      if (x == y) { #equal } else if (x < y) { #less } else { #greater }\n    }\n  };\n\n  func isNegative(number : Float) : Bool {\n    copySign(1.0, number) < 0.0\n  };\n\n  /// Returns the negation of `x`, `-x` .\n  ///\n  /// Changes the sign bit for infinity.\n  ///\n  /// Special cases:\n  /// ```\n  /// neg(+inf) => -inf\n  /// neg(-inf) => +inf\n  /// neg(+NaN) => -NaN\n  /// neg(-NaN) => +NaN\n  /// neg(+0.0) => -0.0\n  /// neg(-0.0) => +0.0\n  /// ```\n  ///\n  /// Example:\n  /// ```motoko\n  /// import Float \"mo:base/Float\";\n  ///\n  /// Float.neg(1.23) // => -1.23\n  /// ```\n  public func neg(x : Float) : Float { -x };\n\n  /// Returns the sum of `x` and `y`, `x + y`.\n  ///\n  /// :::info\n  /// Numerical errors may occur, see comment above.\n  /// :::\n  ///\n  /// Special cases:\n  /// ```\n  /// add(+inf, y)    => +inf if y is any Float except -inf and NaN\n  /// add(-inf, y)    => -inf if y is any Float except +inf and NaN\n  /// add(+inf, -inf) => NaN\n  /// add(NaN, y)     => NaN for any Float y\n  /// ```\n  /// The same cases apply commutatively, i.e. for `add(y, x)`.\n  ///\n  /// Example:\n  /// ```motoko\n  /// import Float \"mo:base/Float\";\n  ///\n  /// Float.add(1.23, 0.123) // => 1.353\n  /// ```\n  public func add(x : Float, y : Float) : Float { x + y };\n\n  /// Returns the difference of `x` and `y`, `x - y`.\n  ///\n  /// Note: Numerical errors may occur, see comment above.\n  ///\n  /// Special cases:\n  /// ```\n  /// sub(+inf, y)    => +inf if y is any Float except +inf or NaN\n  /// sub(-inf, y)    => -inf if y is any Float except -inf and NaN\n  /// sub(x, +inf)    => -inf if x is any Float except +inf and NaN\n  /// sub(x, -inf)    => +inf if x is any Float except -inf and NaN\n  /// sub(+inf, +inf) => NaN\n  /// sub(-inf, -inf) => NaN\n  /// sub(NaN, y)     => NaN for any Float y\n  /// sub(x, NaN)     => NaN for any Float x\n  /// ```\n  ///\n  /// Example:\n  /// ```motoko\n  /// import Float \"mo:base/Float\";\n  ///\n  /// Float.sub(1.23, 0.123) // => 1.107\n  /// ```\n  public func sub(x : Float, y : Float) : Float { x - y };\n\n  /// Returns the product of `x` and `y`, `x * y`.\n  ///\n  /// :::info\n  /// Numerical errors may occur, see comment above.\n  /// :::\n  ///\n  /// Special cases:\n  /// ```\n  /// mul(+inf, y) => +inf if y > 0.0\n  /// mul(-inf, y) => -inf if y > 0.0\n  /// mul(+inf, y) => -inf if y < 0.0\n  /// mul(-inf, y) => +inf if y < 0.0\n  /// mul(+inf, 0.0) => NaN\n  /// mul(-inf, 0.0) => NaN\n  /// mul(NaN, y) => NaN for any Float y\n  /// ```\n  /// The same cases apply commutatively, i.e. for `mul(y, x)`.\n  ///\n  /// Example:\n  /// ```motoko\n  /// import Float \"mo:base/Float\";\n  ///\n  /// Float.mul(1.23, 1e2) // => 123.0\n  /// ```\n  public func mul(x : Float, y : Float) : Float { x * y };\n\n  /// Returns the division of `x` by `y`, `x / y`.\n  ///\n  /// :::info\n  /// Numerical errors may occur, see comment above.\n  /// :::\n  ///\n  /// Special cases:\n  /// ```\n  /// div(0.0, 0.0) => NaN\n  /// div(x, 0.0)   => +inf for x > 0.0\n  /// div(x, 0.0)   => -inf for x < 0.0\n  /// div(x, +inf)  => 0.0 for any x except +inf, -inf, and NaN\n  /// div(x, -inf)  => 0.0 for any x except +inf, -inf, and NaN\n  /// div(+inf, y)  => +inf if y >= 0.0\n  /// div(+inf, y)  => -inf if y < 0.0\n  /// div(-inf, y)  => -inf if y >= 0.0\n  /// div(-inf, y)  => +inf if y < 0.0\n  /// div(NaN, y)   => NaN for any Float y\n  /// div(x, NaN)   => NaN for any Float x\n  /// ```\n  ///\n  /// Example:\n  /// ```motoko\n  /// import Float \"mo:base/Float\";\n  ///\n  /// Float.div(1.23, 1e2) // => 0.0123\n  /// ```\n  public func div(x : Float, y : Float) : Float { x / y };\n\n  /// Returns the floating point division remainder `x % y`,\n  /// which is defined as `x - trunc(x / y) * y`.\n  ///\n  /// :::info\n  /// Numerical errors may occur, see comment above.\n  /// :::\n  ///\n  /// Special cases:\n  /// ```\n  /// rem(0.0, 0.0) => NaN\n  /// rem(x, y)     => +inf if sign(x) == sign(y) for any x and y not being +inf, -inf, or NaN\n  /// rem(x, y)     => -inf if sign(x) != sign(y) for any x and y not being +inf, -inf, or NaN\n  /// rem(x, +inf)  => x for any x except +inf, -inf, and NaN\n  /// rem(x, -inf)  => x for any x except +inf, -inf, and NaN\n  /// rem(+inf, y)  => NaN for any Float y\n  /// rem(-inf, y)  => NaN for any Float y\n  /// rem(NaN, y)   => NaN for any Float y\n  /// rem(x, NaN)   => NaN for any Float x\n  /// ```\n  ///\n  /// Example:\n  /// ```motoko\n  /// import Float \"mo:base/Float\";\n  ///\n  /// Float.rem(7.2, 2.3) // => 0.3 (with numerical imprecision)\n  /// ```\n  public func rem(x : Float, y : Float) : Float { x % y };\n\n  /// Returns `x` to the power of `y`, `x ** y`.\n  ///\n  /// :::info\n  /// Numerical errors may occur, see comment above.\n  /// :::\n  ///\n  /// Special cases:\n  /// ```\n  /// pow(+inf, y)    => +inf for any y > 0.0 including +inf\n  /// pow(+inf, 0.0)  => 1.0\n  /// pow(+inf, y)    => 0.0 for any y < 0.0 including -inf\n  /// pow(x, +inf)    => +inf if x > 0.0 or x < 0.0\n  /// pow(0.0, +inf)  => 0.0\n  /// pow(x, -inf)    => 0.0 if x > 0.0 or x < 0.0\n  /// pow(0.0, -inf)  => +inf\n  /// pow(x, y)       => NaN if x < 0.0 and y is a non-integral Float\n  /// pow(-inf, y)    => +inf if y > 0.0 and y is a non-integral or an even integral Float\n  /// pow(-inf, y)    => -inf if y > 0.0 and y is an odd integral Float\n  /// pow(-inf, 0.0)  => 1.0\n  /// pow(-inf, y)    => 0.0 if y < 0.0\n  /// pow(-inf, +inf) => +inf\n  /// pow(-inf, -inf) => 1.0\n  /// pow(NaN, y)     => NaN if y != 0.0\n  /// pow(NaN, 0.0)   => 1.0\n  /// pow(x, NaN)     => NaN for any Float x\n  /// ```\n  ///\n  /// Example:\n  /// ```motoko\n  /// import Float \"mo:base/Float\";\n  ///\n  /// Float.pow(2.5, 2.0) // => 6.25\n  /// ```\n  public func pow(x : Float, y : Float) : Float { x ** y };\n\n}\n"},"Func.mo":{"content":"/// Create functions from simpler inputs, most commonly used when programming in functional style using higher-order functions.\n\nmodule {\n  /// Import from the base library to use this module.\n  ///\n  /// ```motoko name=import\n  /// import { compose; const; identity } = \"mo:base/Func\";\n  /// import Text = \"mo:base/Text\";\n  /// import Char = \"mo:base/Char\";\n  /// ```\n\n  /// The composition of two functions `f` and `g` is a function that applies `g` and then `f`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// let textFromNat32 = compose(Text.fromChar, Char.fromNat32);\n  /// assert textFromNat32(65) == \"A\";\n  /// ```\n  public func compose<A, B, C>(f : B -> C, g : A -> B) : A -> C {\n    func(x : A) : C {\n      f(g(x))\n    }\n  };\n\n  /// The `identity` function returns its argument.\n  /// Example:\n  /// ```motoko include=import\n  /// assert identity(10) == 10;\n  /// assert identity(true) == true;\n  /// ```\n  public func identity<A>(x : A) : A = x;\n\n  /// The const function is a _curried_ function that accepts an argument `x`,\n  /// and then returns a function that discards its argument and always returns\n  /// the `x`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// assert const<Nat, Text>(10)(\"hello\") == 10;\n  /// assert const(true)(20) == true;\n  /// ```\n  public func const<A, B>(x : A) : B -> A = func _ = x\n}\n"},"List.mo":{"content":"/// Purely-functional, singly-linked lists.\n/// A list of type `List<T>` is either `null` or an optional pair of a value of type `T` and a tail, itself of type `List<T>`.\n///\n/// :::note Assumptions\n///\n/// Runtime and space complexity assumes that `equal`, and other functions execute in `O(1)` time and space.\n/// :::\n///\n/// To use this library, import it using:\n///\n/// ```motoko name=initialize\n/// import List \"mo:base/List\";\n/// ```\n\nimport Array \"Array\";\nimport Iter \"IterType\";\nimport Option \"Option\";\nimport Order \"Order\";\nimport Result \"Result\";\n\nmodule {\n\n  // A singly-linked list consists of zero or more _cons cells_, wherein\n  // each cell contains a single list element (the cell's _head_), and a pointer to the\n  // remainder of the list (the cell's _tail_).\n  public type List<T> = ?(T, List<T>);\n\n  /// Create an empty list.\n  ///\n  /// Example:\n  /// ```motoko include=initialize\n  /// List.nil<Nat>() // => null\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(1)` | `O(1)` |\n  public func nil<T>() : List<T> = null;\n\n  /// Check whether a list is empty and return true if the list is empty.\n  ///\n  /// Example:\n  /// ```motoko include=initialize\n  /// List.isNil<Nat>(null) // => true\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(1)` | `O(1)` |\n  public func isNil<T>(l : List<T>) : Bool {\n    switch l {\n      case null { true };\n      case _ { false }\n    }\n  };\n\n  /// Add `x` to the head of `list`, and return the new list.\n  ///\n  /// Example:\n  /// ```motoko include=initialize\n  /// List.push<Nat>(0, null) // => ?(0, null);\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(1)` | `O(1)` |\n  public func push<T>(x : T, l : List<T>) : List<T> = ?(x, l);\n\n  /// Return the last element of the list, if present.\n  /// Example:\n  /// ```motoko include=initialize\n  /// List.last<Nat>(?(0, ?(1, null))) // => ?1\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size)` | `O(1)` |\n  public func last<T>(l : List<T>) : ?T {\n    switch l {\n      case null { null };\n      case (?(x, null)) { ?x };\n      case (?(_, t)) { last<T>(t) }\n    }\n  };\n\n  /// Remove the head of the list, returning the optioned head and the tail of the list in a pair.\n  /// Returns `(null, null)` if the list is empty.\n  ///\n  /// Example:\n  /// ```motoko include=initialize\n  /// List.pop<Nat>(?(0, ?(1, null))) // => (?0, ?(1, null))\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(1)` | `O(1)` |\n  public func pop<T>(l : List<T>) : (?T, List<T>) {\n    switch l {\n      case null { (null, null) };\n      case (?(h, t)) { (?h, t) }\n    }\n  };\n\n  /// Return the length of the list.\n  ///\n  /// Example:\n  /// ```motoko include=initialize\n  /// List.size<Nat>(?(0, ?(1, null))) // => 2\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size)` | `O(1)` |\n  public func size<T>(l : List<T>) : Nat {\n    func rec(l : List<T>, n : Nat) : Nat {\n      switch l {\n        case null { n };\n        case (?(_, t)) { rec(t, n + 1) }\n      }\n    };\n    rec(l, 0)\n  };\n  /// Access any item in a list, zero-based.\n  ///\n  /// :::note Consideration\n  /// Indexing into a list is a linear operation, and usually an\n  /// indication that a list might not be the best data structure\n  /// to use.\n  /// :::\n  ///\n  /// Example:\n  ///\n  /// ```motoko include=initialize\n  /// List.get<Nat>(?(0, ?(1, null)), 1) // => ?1\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size)` | `O(1)` |\n  public func get<T>(l : List<T>, n : Nat) : ?T {\n    switch (n, l) {\n      case (_, null) { null };\n      case (0, (?(h, _))) { ?h };\n      case (_, (?(_, t))) { get<T>(t, n - 1) }\n    }\n  };\n\n  /// Reverses the list.\n  ///\n  /// Example:\n  /// ```motoko include=initialize\n  /// List.reverse<Nat>(?(0, ?(1, ?(2, null)))) // => ?(2, ?(1, ?(0, null)))\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size)` | `O(size)` |\n  public func reverse<T>(l : List<T>) : List<T> {\n    func rec(l : List<T>, r : List<T>) : List<T> {\n      switch l {\n        case null { r };\n        case (?(h, t)) { rec(t, ?(h, r)) }\n      }\n    };\n    rec(l, null)\n  };\n\n  /// Call the given function for its side effect, with each list element in turn.\n  ///\n  /// Example:\n  /// ```motoko include=initialize\n  /// var sum = 0;\n  /// List.iterate<Nat>(?(0, ?(1, ?(2, null))), func n { sum += n });\n  /// sum // => 3\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size)` | `O(size)` |\n  ///\n  public func iterate<T>(l : List<T>, f : T -> ()) {\n    switch l {\n      case null { () };\n      case (?(h, t)) { f(h); iterate<T>(t, f) }\n    }\n  };\n\n  /// Call the given function `f` on each list element and collect the results\n  /// in a new list.\n  ///\n  /// Example:\n  /// ```motoko include=initialize\n  /// import Nat = \"mo:base/Nat\"\n  /// List.map<Nat, Text>(?(0, ?(1, ?(2, null))), Nat.toText) // => ?(\"0\", ?(\"1\", ?(\"2\", null))\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size)` | `O(size)` |\n\n  public func map<T, U>(l : List<T>, f : T -> U) : List<U> {\n    switch l {\n      case null { null };\n      case (?(h, t)) { ?(f(h), map<T, U>(t, f)) }\n    }\n  };\n\n  /// Create a new list with only those elements of the original list for which\n  /// the given function (often called the _predicate_) returns true.\n  ///\n  /// Example:\n  /// ```motoko include=initialize\n  /// List.filter<Nat>(?(0, ?(1, ?(2, null))), func n { n != 1 }) // => ?(0, ?(2, null))\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size)` | `O(size)` |\n  public func filter<T>(l : List<T>, f : T -> Bool) : List<T> {\n    switch l {\n      case null { null };\n      case (?(h, t)) {\n        if (f(h)) {\n          ?(h, filter<T>(t, f))\n        } else {\n          filter<T>(t, f)\n        }\n      }\n    }\n  };\n\n  /// Create two new lists from the results of a given function (`f`).\n  /// The first list only includes the elements for which the given\n  /// function `f` returns true and the second list only includes\n  /// the elements for which the function returns false.\n  ///\n  /// Example:\n  /// ```motoko include=initialize\n  /// List.partition<Nat>(?(0, ?(1, ?(2, null))), func n { n != 1 }) // => (?(0, ?(2, null)), ?(1, null))\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size)` | `O(size)` |\n  ///\n  public func partition<T>(l : List<T>, f : T -> Bool) : (List<T>, List<T>) {\n    switch l {\n      case null { (null, null) };\n      case (?(h, t)) {\n        if (f(h)) {\n          // call f in-order\n          let (l, r) = partition<T>(t, f);\n          (?(h, l), r)\n        } else {\n          let (l, r) = partition<T>(t, f);\n          (l, ?(h, r))\n        }\n      }\n    }\n  };\n\n  /// Call the given function on each list element, and collect the non-null results\n  /// in a new list.\n  ///\n  /// Example:\n  /// ```motoko include=initialize\n  /// List.mapFilter<Nat, Nat>(\n  ///   ?(1, ?(2, ?(3, null))),\n  ///   func n {\n  ///     if (n > 1) {\n  ///       ?(n * 2);\n  ///     } else {\n  ///       null\n  ///     }\n  ///   }\n  /// ) // => ?(4, ?(6, null))\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size)` | `O(size)` |\n  ///\n  public func mapFilter<T, U>(l : List<T>, f : T -> ?U) : List<U> {\n    switch l {\n      case null { null };\n      case (?(h, t)) {\n        switch (f(h)) {\n          case null { mapFilter<T, U>(t, f) };\n          case (?h_) { ?(h_, mapFilter<T, U>(t, f)) }\n        }\n      }\n    }\n  };\n\n  /// Maps a Result-returning function `f` over a List and returns either\n  /// the first error or a list of successful values.\n  ///\n  /// Example:\n  /// ```motoko include=initialize\n  /// List.mapResult<Nat, Nat, Text>(\n  ///   ?(1, ?(2, ?(3, null))),\n  ///   func n {\n  ///     if (n > 0) {\n  ///       #ok(n * 2);\n  ///     } else {\n  ///       #err(\"Some element is zero\")\n  ///     }\n  ///   }\n  /// ); // => #ok ?(2, ?(4, ?(6, null))\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size)` | `O(size)` |\n  ///\n  public func mapResult<T, R, E>(xs : List<T>, f : T -> Result.Result<R, E>) : Result.Result<List<R>, E> {\n    func go(xs : List<T>, acc : List<R>) : Result.Result<List<R>, E> {\n      switch xs {\n        case null { #ok(acc) };\n        case (?(head, tail)) {\n          switch (f(head)) {\n            case (#err(err)) { #err(err) };\n            case (#ok(ok)) { go(tail, ?(ok, acc)) }\n          }\n        }\n      }\n    };\n    Result.mapOk(go(xs, null), func(xs : List<R>) : List<R> = reverse(xs))\n  };\n\n  /// Append the elements from the reverse of one list, 'l', to another list, 'm'.\n  ///\n  /// Example:\n  /// ```motoko include=initialize\n  /// List.revAppend<Nat>(\n  ///   ?(2, ?(1, ?(0, null))),\n  ///   ?(3, ?(4, ?(5, null)))\n  /// ); // => ?(0, ?(1, ?(2, ?(3, ?(4, ?(5, null))))))\n  /// ```\n  ///\n  /// | Runtime     | Space       |\n  /// |-------------|-------------|\n  /// | `O(size(l))`  | `O(size(l))`  |\n  func revAppend<T>(l : List<T>, m : List<T>) : List<T> {\n    switch l {\n      case null { m };\n      case (?(h, t)) { revAppend(t, ?(h, m)) }\n    }\n  };\n\n  /// Append the elements from one list to another list.\n  ///\n  /// Example:\n  /// ```motoko include=initialize\n  /// List.append<Nat>(\n  ///   ?(0, ?(1, ?(2, null))),\n  ///   ?(3, ?(4, ?(5, null)))\n  /// ) // => ?(0, ?(1, ?(2, ?(3, ?(4, ?(5, null))))))\n  /// ```\n  ///\n  /// | Runtime     | Space       |\n  /// |-------------|-------------|\n  /// | `O(size(l))`  | `O(size(l))`  |\n  public func append<T>(l : List<T>, m : List<T>) : List<T> {\n    revAppend(reverse(l), m)\n  };\n\n  /// Flatten, or concatenate, a list of lists as a list.\n  ///\n  /// Example:\n  /// ```motoko include=initialize\n  /// List.flatten<Nat>(\n  ///   ?(?(0, ?(1, ?(2, null))),\n  ///     ?(?(3, ?(4, ?(5, null))),\n  ///       null))\n  /// ); // => ?(0, ?(1, ?(2, ?(3, ?(4, ?(5, null))))))\n  /// ```\n  ///\n  /// | Runtime     | Space       |\n  /// |-------------|-------------|\n  /// | `O(size*size)`  | `O(size*size)`  |\n  public func flatten<T>(l : List<List<T>>) : List<T> {\n    //FIXME: this is quadratic, not linear https://github.com/dfinity/motoko-base/issues/459\n    foldLeft<List<T>, List<T>>(l, null, func(a, b) { append<T>(a, b) })\n  };\n\n  /// Returns the first `n` elements of the given list.\n  /// If the given list has fewer than `n` elements, this function returns\n  /// a copy of the full input list.\n  ///\n  /// Example:\n  /// ```motoko include=initialize\n  /// List.take<Nat>(\n  ///   ?(0, ?(1, ?(2, null))),\n  ///   2\n  /// ); // => ?(0, ?(1, null))\n  /// ```\n  ///\n  /// | Runtime     | Space       |\n  /// |-------------|-------------|\n  /// | `O(n)`  | `O(n)`  |\n  public func take<T>(l : List<T>, n : Nat) : List<T> {\n    switch (l, n) {\n      case (_, 0) { null };\n      case (null, _) { null };\n      case (?(h, t), m) { ?(h, take<T>(t, m - 1)) }\n    }\n  };\n\n  /// Drop the first `n` elements from the given list.\n  ///\n  /// Example:\n  /// ```motoko include=initialize\n  /// List.drop<Nat>(\n  ///   ?(0, ?(1, ?(2, null))),\n  ///   2\n  /// ); // => ?(2, null)\n  /// ```\n  ///\n  /// | Runtime     | Space       |\n  /// |-------------|-------------|\n  /// | `O(n)`  | `O(1)`  |\n  public func drop<T>(l : List<T>, n : Nat) : List<T> {\n    switch (l, n) {\n      case (l_, 0) { l_ };\n      case (null, _) { null };\n      case ((?(_, t)), m) { drop<T>(t, m - 1) }\n    }\n  };\n\n  /// Collapses the elements in `list` into a single value by starting with `base`\n  /// and progessively combining elements into `base` with `combine`. Iteration runs\n  /// left to right.\n  ///\n  /// Example:\n  /// ```motoko include=initialize\n  /// import Nat \"mo:base/Nat\";\n  /// List.foldLeft<Nat, Text>(\n  ///   ?(1, ?(2, ?(3, null))),\n  ///   \"\",\n  ///   func (acc, x) { acc # Nat.toText(x)}\n  /// ) // => \"123\"\n  /// ```\n  ///\n  /// | Runtime        | Space (Heap) | Space (Stack) |\n  /// |----------------|--------------|----------------|\n  /// | `O(size(list))`  | `O(1)`         | `O(1)`    |\n  ///\n\n  public func foldLeft<T, S>(list : List<T>, base : S, combine : (S, T) -> S) : S {\n    switch list {\n      case null { base };\n      case (?(h, t)) { foldLeft(t, combine(base, h), combine) }\n    }\n  };\n\n  /// Collapses the elements in `buffer` into a single value by starting with `base`\n  /// and progessively combining elements into `base` with `combine`. Iteration runs\n  /// right to left.\n  ///\n  /// Example:\n  /// ```motoko include=initialize\n  /// import Nat \"mo:base/Nat\";\n  /// List.foldRight<Nat, Text>(\n  ///   ?(1, ?(2, ?(3, null))),\n  ///   \"\",\n  ///   func (x, acc) { Nat.toText(x) # acc}\n  /// ) // => \"123\"\n  /// ```\n  ///\n  /// | Runtime       | Space (Heap) | Space (Stack)     |\n  /// |---------------|--------------|-------------------|\n  /// | `O(size(list))` | `O(1)`         | `O(size(list))`  |\n  ///\n  public func foldRight<T, S>(list : List<T>, base : S, combine : (T, S) -> S) : S {\n    switch list {\n      case null { base };\n      case (?(h, t)) { combine(h, foldRight<T, S>(t, base, combine)) }\n    }\n  };\n\n  /// Return the first element for which the given predicate `f` is true,\n  /// if such an element exists.\n  ///\n  /// Example:\n  /// ```motoko include=initialize\n  /// List.find<Nat>(\n  ///   ?(1, ?(2, ?(3, null))),\n  ///   func n { n > 1 }\n  /// ); // => ?2\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size)` | `O(1)` |\n  ///\n\n  public func find<T>(l : List<T>, f : T -> Bool) : ?T {\n    switch l {\n      case null { null };\n      case (?(h, t)) { if (f(h)) { ?h } else { find<T>(t, f) } }\n    }\n  };\n\n  /// Return true if there exists a list element for which\n  /// the given predicate `f` is true.\n  ///\n  /// Example:\n  /// ```motoko include=initialize\n  /// List.some<Nat>(\n  ///   ?(1, ?(2, ?(3, null))),\n  ///   func n { n > 1 }\n  /// ) // => true\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size)` | `O(1)` |\n  ///\n\n  public func some<T>(l : List<T>, f : T -> Bool) : Bool {\n    switch l {\n      case null { false };\n      case (?(h, t)) { f(h) or some<T>(t, f) }\n    }\n  };\n\n  /// Return true if the given predicate `f` is true for all list\n  /// elements.\n  ///\n  /// Example:\n  /// ```motoko include=initialize\n  /// List.all<Nat>(\n  ///   ?(1, ?(2, ?(3, null))),\n  ///   func n { n > 1 }\n  /// ); // => false\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size)` | `O(1)` |\n  ///\n\n  public func all<T>(l : List<T>, f : T -> Bool) : Bool {\n    switch l {\n      case null { true };\n      case (?(h, t)) { f(h) and all<T>(t, f) }\n    }\n  };\n\n  /// Merge two ordered lists into a single ordered list.\n  /// This function requires both list to be ordered as specified\n  /// by the given relation `lessThanOrEqual`.\n  ///\n  /// Example:\n  /// ```motoko include=initialize\n  /// List.merge<Nat>(\n  ///   ?(1, ?(2, ?(4, null))),\n  ///   ?(2, ?(4, ?(6, null))),\n  ///   func (n1, n2) { n1 <= n2 }\n  /// ); // => ?(1, ?(2, ?(2, ?(4, ?(4, ?(6, null))))))),\n  /// ```\n  ///\n  /// | Runtime                    | Space                  |\n  /// |----------------------------|------------------------|\n  /// | `O(size(l1) + size(l2))`     | `O(size(l1) + size(l2))` |\n  ///\n\n  // TODO: replace by merge taking a compare : (T, T) -> Order.Order function?\n  public func merge<T>(l1 : List<T>, l2 : List<T>, lessThanOrEqual : (T, T) -> Bool) : List<T> {\n    switch (l1, l2) {\n      case (null, _) { l2 };\n      case (_, null) { l1 };\n      case (?(h1, t1), ?(h2, t2)) {\n        if (lessThanOrEqual(h1, h2)) {\n          ?(h1, merge<T>(t1, l2, lessThanOrEqual))\n        } else {\n          ?(h2, merge<T>(l1, t2, lessThanOrEqual))\n        }\n      }\n    }\n  };\n\n  private func compareAux<T>(l1 : List<T>, l2 : List<T>, compare : (T, T) -> Order.Order) : Order.Order {\n    switch (l1, l2) {\n      case (null, null) { #equal };\n      case (null, _) { #less };\n      case (_, null) { #greater };\n      case (?(h1, t1), ?(h2, t2)) {\n        switch (compare(h1, h2)) {\n          case (#equal) { compareAux<T>(t1, t2, compare) };\n          case other { other }\n        }\n      }\n    }\n  };\n\n  /// Compare two lists using lexicographic ordering specified by argument function `compare`.\n  ///\n  /// Example:\n  /// ```motoko include=initialize\n  /// import Nat \"mo:base/Nat\";\n  ///\n  /// List.compare<Nat>(\n  ///   ?(1, ?(2, null)),\n  ///   ?(3, ?(4, null)),\n  ///   Nat.compare\n  /// ) // => #less\n  /// ```\n  ///\n  /// | Runtime                    | Space                  |\n  /// |----------------------------|------------------------|\n  /// | `O(size(l1))`     | `O(1)` |\n  ///\n\n  public func compare<T>(l1 : List<T>, l2 : List<T>, compare : (T, T) -> Order.Order) : Order.Order {\n    compareAux<T>(l1, l2, compare)\n  };\n\n  private func equalAux<T>(l1 : List<T>, l2 : List<T>, equal : (T, T) -> Bool) : Bool {\n    switch (l1, l2) {\n      case (?(h1, t1), ?(h2, t2)) {\n        equal(h1, h2) and equalAux<T>(t1, t2, equal)\n      };\n      case (null, null) { true };\n      case _ { false }\n    }\n  };\n  /// Compare two lists for equality using the argument function `equal` to determine equality of their elements.\n  ///\n  /// Example:\n  /// ```motoko include=initialize\n  /// import Nat \"mo:base/Nat\";\n  ///\n  /// List.equal<Nat>(\n  ///   ?(1, ?(2, null)),\n  ///   ?(3, ?(4, null)),\n  ///   Nat.equal\n  /// ); // => false\n  /// ```\n  ///\n  /// | Runtime                    | Space                  |\n  /// |----------------------------|------------------------|\n  /// | `O(size(l1))`     | `O(1)` |\n  ///\n  public func equal<T>(l1 : List<T>, l2 : List<T>, equal : (T, T) -> Bool) : Bool {\n    equalAux<T>(l1, l2, equal)\n  };\n\n  /// Generate a list based on a length and a function that maps from\n  /// a list index to a list element.\n  ///\n  /// Example:\n  /// ```motoko include=initialize\n  /// List.tabulate<Nat>(\n  ///   3,\n  ///   func n { n * 2 }\n  /// ) // => ?(0, ?(2, (?4, null)))\n  /// ```\n  ///\n  /// | Runtime                    | Space                  |\n  /// |----------------------------|------------------------|\n  /// | `O(n)`     | `O(n)` |\n  ///\n\n  public func tabulate<T>(n : Nat, f : Nat -> T) : List<T> {\n    var i = 0;\n    var l : List<T> = null;\n    while (i < n) {\n      l := ?(f(i), l);\n      i += 1\n    };\n    reverse(l)\n  };\n\n  /// Create a list with exactly one element.\n  ///\n  /// Example:\n  /// ```motoko include=initialize\n  /// List.make<Nat>(\n  ///   0\n  /// ) // => ?(0, null)\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(1)` | `O(1)` |\n  public func make<T>(x : T) : List<T> = ?(x, null);\n\n  /// Create a list of the given length with the same value in each position.\n  ///\n  /// Example:\n  /// ```motoko include=initialize\n  /// List.replicate<Nat>(\n  ///   3,\n  ///   0\n  /// ) // => ?(0, ?(0, ?(0, null)))\n  /// ```\n  ///\n  /// | Runtime                    | Space                  |\n  /// |----------------------------|------------------------|\n  /// | `O(n)`     | `O(n)` |\n  public func replicate<T>(n : Nat, x : T) : List<T> {\n    var i = 0;\n    var l : List<T> = null;\n    while (i < n) {\n      l := ?(x, l);\n      i += 1\n    };\n    l\n  };\n\n  /// Create a list of pairs from a pair of lists.\n  ///\n  /// If the given lists have different lengths, then the created list will have a\n  /// length equal to the length of the smaller list.\n  ///\n  /// Example:\n  /// ```motoko include=initialize\n  /// List.zip<Nat, Text>(\n  ///   ?(0, ?(1, ?(2, null))),\n  ///   ?(\"0\", ?(\"1\", null)),\n  /// ) // => ?((0, \"0\"), ?((1, \"1\"), null))\n  /// ```\n  ///\n  /// | Runtime                    | Space                  |\n  /// |----------------------------|------------------------|\n  /// | `O(min(size(xs), size(ys)))`     | `O(min(size(xs), size(ys)))` |\n  public func zip<T, U>(xs : List<T>, ys : List<U>) : List<(T, U)> = zipWith<T, U, (T, U)>(xs, ys, func(x, y) { (x, y) });\n\n  /// Create a list in which elements are created by applying function `f` to each pair `(x, y)` of elements\n  /// occuring at the same position in list `xs` and list `ys`.\n  ///\n  /// If the given lists have different lengths, then the created list will have a\n  /// length equal to the length of the smaller list.\n  ///\n  /// Example:\n  /// ```motoko include=initialize\n  /// import Nat = \"mo:base/Nat\";\n  /// import Char = \"mo:base/Char\";\n  ///\n  /// List.zipWith<Nat, Char, Text>(\n  ///   ?(0, ?(1, ?(2, null))),\n  ///   ?('a', ?('b', null)),\n  ///   func (n, c) { Nat.toText(n) # Char.toText(c) }\n  /// ) // => ?(\"0a\", ?(\"1b\", null))\n  /// ```\n  ///\n  /// | Runtime                    | Space                  |\n  /// |----------------------------|------------------------|\n  /// | `O(min(size(xs), size(ys)))`     | `O(min(size(xs), size(ys)))` |\n  ///\n\n  public func zipWith<T, U, V>(\n    xs : List<T>,\n    ys : List<U>,\n    f : (T, U) -> V\n  ) : List<V> {\n    switch (pop<T>(xs)) {\n      case (null, _) { null };\n      case (?x, xt) {\n        switch (pop<U>(ys)) {\n          case (null, _) { null };\n          case (?y, yt) {\n            push<V>(f(x, y), zipWith<T, U, V>(xt, yt, f))\n          }\n        }\n      }\n    }\n  };\n\n  /// Split the given list at the given zero-based index.\n  ///\n  /// Example:\n  /// ```motoko include=initialize\n  /// List.split<Nat>(\n  ///   2,\n  ///   ?(0, ?(1, ?(2, null)))\n  /// ) // => (?(0, ?(1, null)), ?(2, null))\n  /// ```\n  ///\n  /// | Runtime     | Space       |\n  /// |-------------|-------------|\n  /// | `O(n)`  | `O(n)`  |\n  public func split<T>(n : Nat, xs : List<T>) : (List<T>, List<T>) {\n    if (n == 0) { (null, xs) } else {\n      func rec(n : Nat, xs : List<T>) : (List<T>, List<T>) {\n        switch (pop<T>(xs)) {\n          case (null, _) { (null, null) };\n          case (?h, t) {\n            if (n == 1) { (make<T>(h), t) } else {\n              let (l, r) = rec(n - 1, t);\n              (push<T>(h, l), r)\n            }\n          }\n        }\n      };\n      rec(n, xs)\n    }\n  };\n\n  /// Split the given list into chunks of length `n`.\n  /// The last chunk will be shorter if the length of the given list\n  /// does not divide by `n` evenly.\n  ///\n  /// Example:\n  /// ```motoko include=initialize\n  /// List.chunks<Nat>(\n  ///   2,\n  ///   ?(0, ?(1, ?(2, ?(3, ?(4, null)))))\n  /// )\n  /// /* => ?(?(0, ?(1, null)),\n  ///         ?(?(2, ?(3, null)),\n  ///           ?(?(4, null),\n  ///             null)))\n  /// */\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size)` | `O(size)` |\n  public func chunks<T>(n : Nat, xs : List<T>) : List<List<T>> {\n    let (l, r) = split<T>(n, xs);\n    if (isNil<T>(l)) {\n      null\n    } else {\n      push<List<T>>(l, chunks<T>(n, r))\n    }\n  };\n\n  /// Convert an array into a list.\n  ///\n  /// Example:\n  /// ```motoko include=initialize\n  /// List.fromArray<Nat>([ 0, 1, 2, 3, 4])\n  /// // =>  ?(0, ?(1, ?(2, ?(3, ?(4, null)))))\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size)` | `O(size)` |\n  public func fromArray<T>(xs : [T]) : List<T> {\n    Array.foldRight<T, List<T>>(\n      xs,\n      null,\n      func(x : T, ys : List<T>) : List<T> {\n        push<T>(x, ys)\n      }\n    )\n  };\n\n  /// Convert a mutable array into a list.\n  ///\n  /// Example:\n  /// ```motoko include=initialize\n  /// List.fromVarArray<Nat>([var 0, 1, 2, 3, 4])\n  /// // =>  ?(0, ?(1, ?(2, ?(3, ?(4, null)))))\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size)` | `O(size)` |\n  public func fromVarArray<T>(xs : [var T]) : List<T> = fromArray<T>(Array.freeze<T>(xs));\n\n  /// Create an array from a list.\n  /// Example:\n  /// ```motoko include=initialize\n  /// List.toArray<Nat>(?(0, ?(1, ?(2, ?(3, ?(4, null))))))\n  /// // => [0, 1, 2, 3, 4]\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size)` | `O(size)` |\n  public func toArray<T>(xs : List<T>) : [T] {\n    let length = size<T>(xs);\n    var list = xs;\n    Array.tabulate<T>(\n      length,\n      func(i) {\n        let popped = pop<T>(list);\n        list := popped.1;\n        switch (popped.0) {\n          case null { loop { assert false } };\n          case (?x) x\n        }\n      }\n    )\n  };\n\n  /// Create a mutable array from a list.\n  /// Example:\n  /// ```motoko include=initialize\n  /// List.toVarArray<Nat>(?(0, ?(1, ?(2, ?(3, ?(4, null))))))\n  /// // => [var 0, 1, 2, 3, 4]\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size)` | `O(size)` |\n  public func toVarArray<T>(xs : List<T>) : [var T] = Array.thaw<T>(toArray<T>(xs));\n\n  /// Create an iterator from a list.\n  /// Example:\n  /// ```motoko include=initialize\n  /// var sum = 0;\n  /// for (n in List.toIter<Nat>(?(0, ?(1, ?(2, ?(3, ?(4, null))))))) {\n  ///   sum += n;\n  /// };\n  /// sum\n  /// // => 10\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(1)` | `O(1)` |\n  public func toIter<T>(xs : List<T>) : Iter.Iter<T> {\n    var state = xs;\n    object {\n      public func next() : ?T = switch state {\n        case (?(hd, tl)) { state := tl; ?hd };\n        case _ null\n      }\n    }\n  }\n\n}\n"},"IterType.mo":{"content":"\n// Just here to break cyclic module definitions\n\nmodule {\n  public type Iter<T> = { next : () -> ?T }\n}\n"},"ExperimentalCycles.mo":{"content":"/// Managing cycles within actors on the Internet Computer (ICP).\n///\n/// The usage of the Internet Computer is measured, and paid for, in _cycles_.\n/// This library provides imperative operations for observing cycles, transferring cycles, and observing refunds of cycles.\n///\n/// :::warning Experimental API\n///\n/// This low-level API is experimental and may change or be removed in the future.\n/// Dedicated syntactic support for manipulating cycles may be added to the language, which would make this library obsolete.\n/// :::\n///\n/// :::note Volatile cycle balance\n///\n/// Since cycles measure computational resources, the value of `balance()` can change from one call to the next.\n/// :::\n///\n/// Example:\n///\n/// ```motoko no-repl\n/// import Cycles \"mo:base/ExperimentalCycles\";\n/// import Debug \"mo:base/Debug\";\n///\n/// actor {\n///  public func main() : async() {\n///    Debug.print(\"Main balance: \" # debug_show(Cycles.balance()));\n///    Cycles.add<system>(15_000_000);\n///    await operation(); // accepts 10_000_000 cycles\n///    Debug.print(\"Main refunded: \" # debug_show(Cycles.refunded())); // 5_000_000\n///    Debug.print(\"Main balance: \" # debug_show(Cycles.balance())); // decreased by around 10_000_000\n///  };\n///\n///  func operation() : async() {\n///    Debug.print(\"Operation balance: \" # debug_show(Cycles.balance()));\n///    Debug.print(\"Operation available: \" # debug_show(Cycles.available()));\n///    let obtained = Cycles.accept<system>(10_000_000);\n///    Debug.print(\"Operation obtained: \" # debug_show(obtained)); // => 10_000_000\n///    Debug.print(\"Operation balance: \" # debug_show(Cycles.balance())); // increased by 10_000_000\n///    Debug.print(\"Operation available: \" # debug_show(Cycles.available())); // decreased by 10_000_000\n///  }\n/// }\n/// ```\nimport Prim \"mo:⛔\";\nmodule {\n\n  /// Returns the actor's current balance of cycles as `amount`.\n  ///\n  /// Example:\n  /// ```motoko no-repl\n  /// import Cycles \"mo:base/ExperimentalCycles\";\n  /// import Debug \"mo:base/Debug\";\n  ///\n  /// actor {\n  ///   public func main() : async() {\n  ///     let balance = Cycles.balance();\n  ///     Debug.print(\"Balance: \" # debug_show(balance));\n  ///   }\n  /// }\n  /// ```\n  public let balance : () -> (amount : Nat) = Prim.cyclesBalance;\n\n  /// Returns the currently available `amount` of cycles.\n  /// The amount available is the amount received in the current call,\n  /// minus the cumulative amount `accept`ed by this call.\n  /// On exit from the current shared function or async expression via `return` or `throw`,\n  /// any remaining available amount is automatically refunded to the caller/context.\n  ///\n  /// Example:\n  /// ```motoko no-repl\n  /// import Cycles \"mo:base/ExperimentalCycles\";\n  /// import Debug \"mo:base/Debug\";\n  ///\n  /// actor {\n  ///   public func main() : async() {\n  ///     let available = Cycles.available();\n  ///     Debug.print(\"Available: \" # debug_show(available));\n  ///   }\n  /// }\n  /// ```\n  public let available : () -> (amount : Nat) = Prim.cyclesAvailable;\n\n  /// Transfers up to `amount` from `available()` to `balance()`.\n  /// Returns the amount actually transferred, which may be less than\n  /// requested, for example, if less is available, or if canister balance limits are reached.\n  ///\n  /// Example (for simplicity, only transferring cycles to itself):\n  /// ```motoko no-repl\n  /// import Cycles \"mo:base/ExperimentalCycles\";\n  /// import Debug \"mo:base/Debug\";\n  ///\n  /// actor {\n  ///   public func main() : async() {\n  ///     Cycles.add<system>(15_000_000);\n  ///     await operation(); // accepts 10_000_000 cycles\n  ///   };\n  ///\n  ///   func operation() : async() {\n  ///     let obtained = Cycles.accept<system>(10_000_000);\n  ///     Debug.print(\"Obtained: \" # debug_show(obtained)); // => 10_000_000\n  ///   }\n  /// }\n  /// ```\n  public let accept : <system>(amount : Nat) -> (accepted : Nat) = Prim.cyclesAccept;\n\n  /// Indicates additional `amount` of cycles to be transferred in\n  /// the next call, that is, evaluation of a shared function call or\n  /// async expression.\n  /// Traps if the current total would exceed `2 ** 128` cycles.\n  /// Upon the call, but not before, the total amount of cycles ``add``ed since\n  /// the last call is deducted from `balance()`.\n  /// If this total exceeds `balance()`, the caller traps, aborting the call.\n  ///\n  /// :::note Reset behavior\n  ///\n  /// The implicit register of added amounts is reset to zero on entry to a shared function and after each shared function call or resume from an await.\n  /// :::\n  ///\n  /// Example (for simplicity, only transferring cycles to itself):\n  /// ```motoko no-repl\n  /// import Cycles \"mo:base/ExperimentalCycles\";\n  ///\n  /// actor {\n  ///   func operation() : async() {\n  ///     ignore Cycles.accept<system>(10_000_000);\n  ///   };\n  ///\n  ///   public func main() : async() {\n  ///     Cycles.add<system>(15_000_000);\n  ///     await operation();\n  ///   }\n  /// }\n  /// ```\n  ///\n  /// @deprecated This function will be removed in future. Use the parenthetical syntax on message sends and `async` expressions to attach cycles: `(with cycles = <amount>) C.send(...)`.\n  public let add : <system>(amount : Nat) -> () = Prim.cyclesAdd;\n\n  /// Reports `amount` of cycles refunded in the last `await` of the current\n  /// context, or zero if no await has occurred yet.\n  /// Calling `refunded()` is solely informational and does not affect `balance()`.\n  /// Instead, refunds are automatically added to the current balance,\n  /// whether or not `refunded` is used to observe them.\n  ///\n  /// Example (for simplicity, only transferring cycles to itself):\n  /// ```motoko no-repl\n  /// import Cycles \"mo:base/ExperimentalCycles\";\n  /// import Debug \"mo:base/Debug\";\n  ///\n  /// actor {\n  ///   func operation() : async() {\n  ///     ignore Cycles.accept<system>(10_000_000);\n  ///   };\n  ///\n  ///   public func main() : async() {\n  ///     Cycles.add<system>(15_000_000);\n  ///     await operation(); // accepts 10_000_000 cycles\n  ///     Debug.print(\"Refunded: \" # debug_show(Cycles.refunded())); // 5_000_000\n  ///   }\n  /// }\n  /// ```\n  public let refunded : () -> (amount : Nat) = Prim.cyclesRefunded;\n\n  /// Attempts to burn `amount` of cycles, deducting `burned` from the canister's\n  /// cycle balance. The burned cycles are irrevocably lost and not available to any\n  /// other principal either.\n  ///\n  /// Example:\n  /// ```motoko no-repl\n  /// import Cycles \"mo:base/ExperimentalCycles\";\n  /// import Debug \"mo:base/Debug\";\n  ///\n  /// actor {\n  ///   public func main() : async() {\n  ///     let burnt = Cycles.burn<system>(10_000_000);\n  ///     Debug.print(\"Burned: \" # debug_show burnt); // 10_000_000\n  ///   }\n  /// }\n  /// ```\n  public let burn : <system>(amount : Nat) -> (burned : Nat) = Prim.cyclesBurn;\n\n}\n"},"Nat64.mo":{"content":"/// Provides utility functions on 64-bit unsigned integers.\n///\n/// :::note\n/// Most operations on integer numbers (e.g. addition) are available as built-in operators (e.g. `1 + 1`).\n/// This module provides equivalent functions and `Text` conversion.\n/// :::\n///\n/// :::info Function form for higher-order use\n///\n/// Several arithmetic and comparison functions (e.g. `add`, `sub`, `equal`, `less`, `pow`) are defined in this module to enable their use as first-class function values, which is not possible with operators like `+`, `-`, `==`, etc., in Motoko. This allows you to pass these operations to higher-order functions such as `map`, `foldLeft`, or `sort`.\n/// :::\n///\n/// Import from the base library to use this module.\n///\n/// ```motoko name=import\n/// import Nat64 \"mo:base/Nat64\";\n/// ```\n///\nimport Nat \"Nat\";\nimport Prim \"mo:⛔\";\n\nmodule {\n\n  /// 64-bit natural numbers.\n  public type Nat64 = Prim.Types.Nat64;\n\n  /// Maximum 64-bit natural number. `2 ** 64 - 1`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat64.maximumValue; // => 18446744073709551615 : Nat64\n  /// ```\n\n  public let maximumValue = 18446744073709551615 : Nat64;\n\n  /// Converts a 64-bit unsigned integer to an unsigned integer with infinite precision.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat64.toNat(123); // => 123 : Nat\n  /// ```\n  public let toNat : Nat64 -> Nat = Prim.nat64ToNat;\n\n  /// Converts an unsigned integer with infinite precision to a 64-bit unsigned integer.\n  ///\n  /// Traps on overflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat64.fromNat(123); // => 123 : Nat64\n  /// ```\n  public let fromNat : Nat -> Nat64 = Prim.natToNat64;\n\n  /// Converts a 32-bit unsigned integer to a 64-bit unsigned integer.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat64.fromNat32(123); // => 123 : Nat64\n  /// ```\n  public func fromNat32(x : Nat32) : Nat64 {\n    Prim.nat32ToNat64(x)\n  };\n\n  /// Converts a 64-bit unsigned integer to a 32-bit unsigned integer.\n  ///\n  /// Traps on overflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat64.toNat32(123); // => 123 : Nat32\n  /// ```\n  public func toNat32(x : Nat64) : Nat32 {\n    Prim.nat64ToNat32(x)\n  };\n\n  /// Converts a signed integer with infinite precision to a 64-bit unsigned integer.\n  ///\n  /// Traps on overflow/underflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat64.fromIntWrap(123); // => 123 : Nat64\n  /// ```\n  public let fromIntWrap : Int -> Nat64 = Prim.intToNat64Wrap;\n\n  /// Converts `x` to its textual representation. Textual representation _do not_\n  /// contain underscores to represent commas.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat64.toText(1234); // => \"1234\" : Text\n  /// ```\n  public func toText(x : Nat64) : Text {\n    Nat.toText(toNat(x))\n  };\n\n  /// Returns the minimum of `x` and `y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat64.min(123, 456); // => 123 : Nat64\n  /// ```\n  public func min(x : Nat64, y : Nat64) : Nat64 {\n    if (x < y) { x } else { y }\n  };\n\n  /// Returns the maximum of `x` and `y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat64.max(123, 456); // => 456 : Nat64\n  /// ```\n  public func max(x : Nat64, y : Nat64) : Nat64 {\n    if (x < y) { y } else { x }\n  };\n\n  /// Equality function for Nat64 types.\n  /// This is equivalent to `x == y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat64.equal(1, 1); // => true\n  /// (1 : Nat64) == (1 : Nat64) // => true\n  /// ```\n  ///\n\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// import Buffer \"mo:base/Buffer\";\n  ///\n  /// let buffer1 = Buffer.Buffer<Nat64>(3);\n  /// let buffer2 = Buffer.Buffer<Nat64>(3);\n  /// Buffer.equal(buffer1, buffer2, Nat64.equal) // => true\n  /// ```\n  public func equal(x : Nat64, y : Nat64) : Bool { x == y };\n\n  /// Inequality function for Nat64 types.\n  /// This is equivalent to `x != y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat64.notEqual(1, 2); // => true\n  /// (1 : Nat64) != (2 : Nat64) // => true\n  /// ```\n  ///\n\n  public func notEqual(x : Nat64, y : Nat64) : Bool { x != y };\n\n  /// \"Less than\" function for Nat64 types.\n  /// This is equivalent to `x < y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat64.less(1, 2); // => true\n  /// (1 : Nat64) < (2 : Nat64) // => true\n  /// ```\n  ///\n\n  public func less(x : Nat64, y : Nat64) : Bool { x < y };\n\n  /// \"Less than or equal\" function for Nat64 types.\n  /// This is equivalent to `x <= y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat64.lessOrEqual(1, 2); // => true\n  /// (1 : Nat64) <= (2 : Nat64) // => true\n  /// ```\n  ///\n\n  public func lessOrEqual(x : Nat64, y : Nat64) : Bool { x <= y };\n\n  /// \"Greater than\" function for Nat64 types.\n  /// This is equivalent to `x > y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat64.greater(2, 1); // => true\n  /// (2 : Nat64) > (1 : Nat64) // => true\n  /// ```\n  ///\n\n  public func greater(x : Nat64, y : Nat64) : Bool { x > y };\n\n  /// \"Greater than or equal\" function for Nat64 types.\n  /// This is equivalent to `x >= y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat64.greaterOrEqual(2, 1); // => true\n  /// (2 : Nat64) >= (1 : Nat64) // => true\n  /// ```\n  ///\n\n  public func greaterOrEqual(x : Nat64, y : Nat64) : Bool { x >= y };\n\n  /// General purpose comparison function for `Nat64`. Returns the `Order` (\n  /// either `#less`, `#equal`, or `#greater`) of comparing `x` with `y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat64.compare(2, 3) // => #less\n  /// ```\n  ///\n  /// This function can be used as value for a high order function, such as a sort function.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// import Array \"mo:base/Array\";\n  /// Array.sort([2, 3, 1] : [Nat64], Nat64.compare) // => [1, 2, 3]\n  /// ```\n  public func compare(x : Nat64, y : Nat64) : { #less; #equal; #greater } {\n    if (x < y) { #less } else if (x == y) { #equal } else { #greater }\n  };\n\n  /// Returns the sum of `x` and `y`, `x + y`.\n  /// Traps on overflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat64.add(1, 2); // => 3\n  /// (1 : Nat64) + (2 : Nat64) // => 3\n  /// ```\n  ///\n\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// import Array \"mo:base/Array\";\n  /// Array.foldLeft<Nat64, Nat64>([2, 3, 1], 0, Nat64.add) // => 6\n  /// ```\n  public func add(x : Nat64, y : Nat64) : Nat64 { x + y };\n\n  /// Returns the difference of `x` and `y`, `x - y`.\n  /// Traps on underflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat64.sub(3, 1); // => 2\n  /// (3 : Nat64) - (1 : Nat64) // => 2\n  /// ```\n  ///\n\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// import Array \"mo:base/Array\";\n  /// Array.foldLeft<Nat64, Nat64>([2, 3, 1], 10, Nat64.sub) // => 4\n  /// ```\n  public func sub(x : Nat64, y : Nat64) : Nat64 { x - y };\n\n  /// Returns the product of `x` and `y`, `x * y`.\n  /// Traps on overflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat64.mul(2, 3); // => 6\n  /// (2 : Nat64) * (3 : Nat64) // => 6\n  /// ```\n  ///\n\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// import Array \"mo:base/Array\";\n  /// Array.foldLeft<Nat64, Nat64>([2, 3, 1], 1, Nat64.mul) // => 6\n  /// ```\n  public func mul(x : Nat64, y : Nat64) : Nat64 { x * y };\n\n  /// Returns the quotient of `x` divided by `y`, `x / y`.\n  /// Traps when `y` is zero.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat64.div(6, 2); // => 3\n  /// (6 : Nat64) / (2 : Nat64) // => 3\n  /// ```\n  ///\n\n  public func div(x : Nat64, y : Nat64) : Nat64 { x / y };\n\n  /// Returns the remainder of `x` divided by `y`, `x % y`.\n  /// Traps when `y` is zero.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat64.rem(6, 4); // => 2\n  /// (6 : Nat64) % (4 : Nat64) // => 2\n  /// ```\n  ///\n\n  public func rem(x : Nat64, y : Nat64) : Nat64 { x % y };\n\n  /// Returns `x` to the power of `y`, `x ** y`. Traps on overflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat64.pow(2, 3); // => 8\n  /// (2 : Nat64) ** (3 : Nat64) // => 8\n  /// ```\n  ///\n\n  public func pow(x : Nat64, y : Nat64) : Nat64 { x ** y };\n\n  /// Returns the bitwise negation of `x`, `^x`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat64.bitnot(0); // => 18446744073709551615\n  /// ^(0 : Nat64) // => 18446744073709551615\n  /// ```\n  ///\n\n  public func bitnot(x : Nat64) : Nat64 { ^x };\n\n  /// Returns the bitwise and of `x` and `y`, `x & y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat64.bitand(1, 3); // => 1\n  /// (1 : Nat64) & (3 : Nat64) // => 1\n  /// ```\n  ///\n\n  public func bitand(x : Nat64, y : Nat64) : Nat64 { x & y };\n\n  /// Returns the bitwise or of `x` and `y`, `x | y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat64.bitor(1, 3); // => 3\n  /// (1 : Nat64) | (3 : Nat64) // => 3\n  /// ```\n  ///\n\n  public func bitor(x : Nat64, y : Nat64) : Nat64 { x | y };\n\n  /// Returns the bitwise exclusive or of `x` and `y`, `x ^ y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat64.bitxor(1, 3); // => 2\n  /// (1 : Nat64) ^ (3 : Nat64) // => 2\n  /// ```\n  ///\n\n  public func bitxor(x : Nat64, y : Nat64) : Nat64 { x ^ y };\n\n  /// Returns the bitwise shift left of `x` by `y`, `x << y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat64.bitshiftLeft(1, 3); // => 8\n  /// (1 : Nat64) << (3 : Nat64) // => 8\n  /// ```\n  ///\n\n  public func bitshiftLeft(x : Nat64, y : Nat64) : Nat64 { x << y };\n\n  /// Returns the bitwise shift right of `x` by `y`, `x >> y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat64.bitshiftRight(8, 3); // => 1\n  /// (8 : Nat64) >> (3 : Nat64) // => 1\n  /// ```\n  ///\n\n  public func bitshiftRight(x : Nat64, y : Nat64) : Nat64 { x >> y };\n\n  /// Returns the bitwise rotate left of `x` by `y`, `x <<> y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat64.bitrotLeft(1, 3); // => 8\n  /// (1 : Nat64) <<> (3 : Nat64) // => 8\n  /// ```\n  ///\n\n  public func bitrotLeft(x : Nat64, y : Nat64) : Nat64 { x <<> y };\n\n  /// Returns the bitwise rotate right of `x` by `y`, `x <>> y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat64.bitrotRight(8, 3); // => 1\n  /// (8 : Nat64) <>> (3 : Nat64) // => 1\n  /// ```\n  ///\n\n  public func bitrotRight(x : Nat64, y : Nat64) : Nat64 { x <>> y };\n\n  /// Returns the value of bit `p mod 64` in `x`, `(x & 2^(p mod 64)) == 2^(p mod 64)`.\n  /// This is equivalent to checking if the `p`-th bit is set in `x`, using 0 indexing.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat64.bittest(5, 2); // => true\n  /// ```\n  public func bittest(x : Nat64, p : Nat) : Bool {\n    Prim.btstNat64(x, Prim.natToNat64(p))\n  };\n\n  /// Returns the value of setting bit `p mod 64` in `x` to `1`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat64.bitset(5, 1); // => 7\n  /// ```\n  public func bitset(x : Nat64, p : Nat) : Nat64 {\n    x | (1 << Prim.natToNat64(p))\n  };\n\n  /// Returns the value of clearing bit `p mod 64` in `x` to `0`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat64.bitclear(5, 2); // => 1\n  /// ```\n  public func bitclear(x : Nat64, p : Nat) : Nat64 {\n    x & ^(1 << Prim.natToNat64(p))\n  };\n\n  /// Returns the value of flipping bit `p mod 64` in `x`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat64.bitflip(5, 2); // => 1\n  /// ```\n  public func bitflip(x : Nat64, p : Nat) : Nat64 {\n    x ^ (1 << Prim.natToNat64(p))\n  };\n\n  /// Returns the count of non-zero bits in `x`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat64.bitcountNonZero(5); // => 2\n  /// ```\n  public let bitcountNonZero : (x : Nat64) -> Nat64 = Prim.popcntNat64;\n\n  /// Returns the count of leading zero bits in `x`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat64.bitcountLeadingZero(5); // => 61\n  /// ```\n  public let bitcountLeadingZero : (x : Nat64) -> Nat64 = Prim.clzNat64;\n\n  /// Returns the count of trailing zero bits in `x`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat64.bitcountTrailingZero(16); // => 4\n  /// ```\n  public let bitcountTrailingZero : (x : Nat64) -> Nat64 = Prim.ctzNat64;\n\n  /// Returns the upper (i.e. most significant), lower (least significant)\n  /// and in-between bytes of `x`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat64.explode 0xbb772266aa885511 // => (187, 119, 34, 102, 170, 136, 85, 17)\n  /// ```\n  public let explode : (x : Nat64) -> (msb : Nat8, Nat8, Nat8, Nat8, Nat8, Nat8, Nat8, lsb : Nat8) = Prim.explodeNat64;\n\n  /// Returns the sum of `x` and `y`, `x +% y`. Wraps on overflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat64.addWrap(Nat64.maximumValue, 1); // => 0\n  /// Nat64.maximumValue +% (1 : Nat64) // => 0\n  /// ```\n  ///\n  /// :::info\n  /// The reason why this function is defined in this library (in addition\n  /// to the existing `+%` operator) is so that you can use it as a function\n  /// value to pass to a higher order function. It is not possible to use `+%`\n  /// as a function value at the moment.\n  /// :::\n  public func addWrap(x : Nat64, y : Nat64) : Nat64 { x +% y };\n\n  /// Returns the difference of `x` and `y`, `x -% y`. Wraps on underflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat64.subWrap(0, 1); // => 18446744073709551615\n  /// (0 : Nat64) -% (1 : Nat64) // => 18446744073709551615\n  /// ```\n  ///\n\n  public func subWrap(x : Nat64, y : Nat64) : Nat64 { x -% y };\n\n  /// Returns the product of `x` and `y`, `x *% y`. Wraps on overflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat64.mulWrap(4294967296, 4294967296); // => 0\n  /// (4294967296 : Nat64) *% (4294967296 : Nat64) // => 0\n  /// ```\n  ///\n\n  public func mulWrap(x : Nat64, y : Nat64) : Nat64 { x *% y };\n\n  /// Returns `x` to the power of `y`, `x **% y`. Wraps on overflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat64.powWrap(2, 64); // => 0\n  /// (2 : Nat64) **% (64 : Nat64) // => 0\n  /// ```\n  ///\n\n  public func powWrap(x : Nat64, y : Nat64) : Nat64 { x **% y };\n\n}\n"},"Random.mo":{"content":"/// A module for obtaining randomness on the Internet Computer (IC).\n///\n/// This module provides the fundamentals for user abstractions to build on.\n///\n/// Dealing with randomness on a deterministic computing platform, such\n/// as the IC, is intricate. Some basic rules need to be followed by the\n/// user of this module to obtain (and maintain) the benefits of crypto-\n/// graphic randomness:\n///\n/// - Cryptographic entropy (randomness source) is only obtainable\n///   asyncronously in discrete chunks of 256 bits (32-byte sized `Blob`s).\n/// - All bets must be closed *before* entropy is being asked for in\n///   order to decide them.\n/// - This implies that the same entropy (i.e. `Blob`) - or surplus entropy\n///   not utilised yet - cannot be used for a new round of bets without\n///   losing the cryptographic guarantees.\n///\n/// Concretely, the below class `Finite`, as well as the\n/// `*From` methods risk the carrying-over of state from previous rounds.\n/// These are provided for performance (and convenience) reasons, and need\n/// special care when used. Similar caveats apply for user-defined (pseudo)\n/// random number generators.\n///\n/// Usage:\n///\n/// ```motoko no-repl\n/// import Random \"mo:base/Random\";\n/// ```\n\nimport I \"Iter\";\nimport Option \"Option\";\nimport Prim \"mo:⛔\";\n\nmodule {\n\n  let raw_rand = (actor \"aaaaa-aa\" : actor { raw_rand : () -> async Blob }).raw_rand;\n\n  /// Obtains a full blob (32 bytes) worth of fresh entropy.\n  ///\n  /// Example:\n  /// ```motoko no-repl\n  /// let random = Random.Finite(await Random.blob());\n  /// ```\n  public let blob : shared () -> async Blob = raw_rand;\n\n  /// Drawing from a finite supply of entropy, `Finite` provides\n  /// methods to obtain random values. When the entropy is used up,\n  /// `null` is returned. Otherwise the outcomes' distributions are\n  /// stated for each method. The uniformity of outcomes is\n  /// guaranteed only when the supplied entropy is originally obtained\n  /// by the `blob()` call, and is never reused.\n  ///\n  /// Example:\n  /// ```motoko no-repl\n  /// import Random \"mo:base/Random\";\n  ///\n  /// let random = Random.Finite(await Random.blob());\n  ///\n  /// let seed : Blob = \"\\14\\C9\\72\\09\\03\\D4\\D5\\72\\82\\95\\E5\\43\\AF\\FA\\A9\\44\\49\\2F\\25\\56\\13\\F3\\6E\\C7\\B0\\87\\DC\\76\\08\\69\\14\\CF\";\n  /// let seedRandom = Random.Finite(seed);\n  /// ```\n  public class Finite(entropy : Blob) {\n    let it : I.Iter<Nat8> = entropy.vals();\n\n    /// Uniformly distributes outcomes in the numeric range [0 .. 255].\n    /// Consumes 1 byte of entropy.\n    ///\n    /// Example:\n    /// ```motoko no-repl\n    /// let seed : Blob = \"\\14\\C9\\72\\09\\03\\D4\\D5\\72\\82\\95\\E5\\43\\AF\\FA\\A9\\44\\49\\2F\\25\\56\\13\\F3\\6E\\C7\\B0\\87\\DC\\76\\08\\69\\14\\CF\";\n    /// let random = Random.Finite(seed);\n    /// random.byte() // => ?20\n    /// ```\n    public func byte() : ?Nat8 {\n      it.next()\n    };\n\n    /// Bool iterator splitting up a byte of entropy into 8 bits\n    let bit : I.Iter<Bool> = object {\n      var mask = 0x00 : Nat8;\n      var byte = 0x00 : Nat8;\n      public func next() : ?Bool {\n        if (0 : Nat8 == mask) {\n          switch (it.next()) {\n            case null { null };\n            case (?w) {\n              byte := w;\n              mask := 0x40;\n              ?(0 : Nat8 != byte & (0x80 : Nat8))\n            }\n          }\n        } else {\n          let m = mask;\n          mask >>= (1 : Nat8);\n          ?(0 : Nat8 != byte & m)\n        }\n      }\n    };\n\n    /// Simulates a coin toss. Both outcomes have equal probability.\n    /// Consumes 1 bit of entropy (amortised).\n    ///\n    /// Example:\n    /// ```motoko no-repl\n    /// let seed : Blob = \"\\14\\C9\\72\\09\\03\\D4\\D5\\72\\82\\95\\E5\\43\\AF\\FA\\A9\\44\\49\\2F\\25\\56\\13\\F3\\6E\\C7\\B0\\87\\DC\\76\\08\\69\\14\\CF\";\n    /// let random = Random.Finite(seed);\n    /// random.coin() // => ?false\n    /// ```\n    public func coin() : ?Bool {\n      bit.next()\n    };\n\n    /// Uniformly distributes outcomes in the numeric range [0 .. 2^p - 1].\n    /// Consumes ⌈p/8⌉ bytes of entropy.\n    ///\n    /// Example:\n    /// ```motoko no-repl\n    /// let seed : Blob = \"\\14\\C9\\72\\09\\03\\D4\\D5\\72\\82\\95\\E5\\43\\AF\\FA\\A9\\44\\49\\2F\\25\\56\\13\\F3\\6E\\C7\\B0\\87\\DC\\76\\08\\69\\14\\CF\";\n    /// let random = Random.Finite(seed);\n    /// random.range(32) // => ?348746249\n    /// ```\n    public func range(p : Nat8) : ?Nat {\n      var pp = p;\n      var acc : Nat = 0;\n      for (i in it) {\n        if (8 : Nat8 <= pp) {\n          acc := acc * 256 + Prim.nat8ToNat(i)\n        } else if (0 : Nat8 == pp) {\n          return ?acc\n        } else {\n          acc *= Prim.nat8ToNat(1 << pp);\n          let mask : Nat8 = 0xff >> (8 - pp);\n          return ?(acc + Prim.nat8ToNat(i & mask))\n        };\n        pp -= 8\n      };\n      if (0 : Nat8 == pp) ?acc else null\n    };\n\n    /// Counts the number of heads in `n` fair coin tosses.\n    /// Consumes ⌈n/8⌉ bytes of entropy.\n    ///\n    /// Example:\n    /// ```motoko no-repl\n    /// let seed : Blob = \"\\14\\C9\\72\\09\\03\\D4\\D5\\72\\82\\95\\E5\\43\\AF\\FA\\A9\\44\\49\\2F\\25\\56\\13\\F3\\6E\\C7\\B0\\87\\DC\\76\\08\\69\\14\\CF\";\n    /// let random = Random.Finite(seed);\n    /// random.binomial(5) // => ?1\n    /// ```\n    public func binomial(n : Nat8) : ?Nat8 {\n      var nn = n;\n      var acc : Nat8 = 0;\n      for (i in it) {\n        if (8 : Nat8 <= nn) {\n          acc +%= Prim.popcntNat8(i)\n        } else if (0 : Nat8 == nn) {\n          return ?acc\n        } else {\n          let mask : Nat8 = 0xff << (8 - nn);\n          let residue = Prim.popcntNat8(i & mask);\n          return ?(acc +% residue)\n        };\n        nn -= 8\n      };\n      if (0 : Nat8 == nn) ?acc else null\n    }\n  };\n\n  /// Distributes outcomes in the numeric range [0 .. 255].\n  /// Seed blob must contain at least a byte.\n  ///\n  /// Example:\n  /// ```motoko no-repl\n  /// let seed : Blob = \"\\14\\C9\\72\\09\\03\\D4\\D5\\72\\82\\95\\E5\\43\\AF\\FA\\A9\\44\\49\\2F\\25\\56\\13\\F3\\6E\\C7\\B0\\87\\DC\\76\\08\\69\\14\\CF\";\n  /// Random.byteFrom(seed) // => 20\n  /// ```\n  public func byteFrom(seed : Blob) : Nat8 {\n    switch (seed.vals().next()) {\n      case (?w) { w };\n      case _ { Prim.trap \"Random.byteFrom\" }\n    }\n  };\n\n  /// Simulates a coin toss.\n  /// Seed blob must contain at least a byte.\n  ///\n  /// Example:\n  /// ```motoko no-repl\n  /// let seed : Blob = \"\\14\\C9\\72\\09\\03\\D4\\D5\\72\\82\\95\\E5\\43\\AF\\FA\\A9\\44\\49\\2F\\25\\56\\13\\F3\\6E\\C7\\B0\\87\\DC\\76\\08\\69\\14\\CF\";\n  /// Random.coinFrom(seed) // => false\n  /// ```\n  public func coinFrom(seed : Blob) : Bool {\n    switch (seed.vals().next()) {\n      case (?w) { w > (127 : Nat8) };\n      case _ { Prim.trap \"Random.coinFrom\" }\n    }\n  };\n\n  /// Distributes outcomes in the numeric range [0 .. 2^p - 1].\n  /// Seed blob must contain at least ((p+7) / 8) bytes.\n  ///\n  /// Example:\n  /// ```motoko no-repl\n  /// let seed : Blob = \"\\14\\C9\\72\\09\\03\\D4\\D5\\72\\82\\95\\E5\\43\\AF\\FA\\A9\\44\\49\\2F\\25\\56\\13\\F3\\6E\\C7\\B0\\87\\DC\\76\\08\\69\\14\\CF\";\n  /// Random.rangeFrom(32, seed) // => 348746249\n  /// ```\n  public func rangeFrom(p : Nat8, seed : Blob) : Nat {\n    rangeIter(p, seed.vals())\n  };\n\n  // internal worker method, expects iterator with sufficient supply\n  func rangeIter(p : Nat8, it : I.Iter<Nat8>) : Nat {\n    var pp = p;\n    var acc : Nat = 0;\n    for (i in it) {\n      if (8 : Nat8 <= pp) {\n        acc := acc * 256 + Prim.nat8ToNat(i)\n      } else if (0 : Nat8 == pp) {\n        return acc\n      } else {\n        acc *= Prim.nat8ToNat(1 << pp);\n        let mask : Nat8 = 0xff >> (8 - pp);\n        return acc + Prim.nat8ToNat(i & mask)\n      };\n      pp -= 8\n    };\n    if (0 : Nat8 == pp) {\n      return acc\n    } else Prim.trap(\"Random.rangeFrom\")\n  };\n\n  /// Counts the number of heads in `n` coin tosses.\n  /// Seed blob must contain at least ((n+7) / 8) bytes.\n  ///\n  /// Example:\n  /// ```motoko no-repl\n  /// let seed : Blob = \"\\14\\C9\\72\\09\\03\\D4\\D5\\72\\82\\95\\E5\\43\\AF\\FA\\A9\\44\\49\\2F\\25\\56\\13\\F3\\6E\\C7\\B0\\87\\DC\\76\\08\\69\\14\\CF\";\n  /// Random.binomialFrom(5, seed) // => 1\n  /// ```\n  public func binomialFrom(n : Nat8, seed : Blob) : Nat8 {\n    binomialIter(n, seed.vals())\n  };\n\n  // internal worker method, expects iterator with sufficient supply\n  func binomialIter(n : Nat8, it : I.Iter<Nat8>) : Nat8 {\n    var nn = n;\n    var acc : Nat8 = 0;\n    for (i in it) {\n      if (8 : Nat8 <= nn) {\n        acc +%= Prim.popcntNat8(i)\n      } else if (0 : Nat8 == nn) {\n        return acc\n      } else {\n        let mask : Nat8 = 0xff << (8 - nn);\n        let residue = Prim.popcntNat8(i & mask);\n        return (acc +% residue)\n      };\n      nn -= 8\n    };\n    if (0 : Nat8 == nn) {\n      return acc\n    } else Prim.trap(\"Random.binomialFrom\")\n  }\n\n}\n"},"Int16.mo":{"content":"/// Provides utility functions on 16-bit signed integers.\n///\n/// :::note\n/// Most operations are available as built-in operators (e.g. `1 + 1`).\n/// :::\n///\n/// :::info Function form for higher-order use\n///\n/// Several arithmetic and comparison functions (e.g. `add`, `sub`, `bitor`, `bitand`, `pow`) are defined in this module to enable their use as first-class function values, which is not possible with operators like `+`, `-`, `==`, etc., in Motoko. This allows you to pass these operations to higher-order functions such as `map`, `foldLeft`, or `sort`.\n/// :::\n///\n/// Import from the base library to use this module.\n///\n/// ```motoko name=import\n/// import Int16 \"mo:base/Int16\";\n/// ```\nimport Int \"Int\";\nimport Prim \"mo:⛔\";\n\nmodule {\n\n  /// 16-bit signed integers.\n  public type Int16 = Prim.Types.Int16;\n\n  /// Minimum 16-bit integer value, `-2 ** 15`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int16.minimumValue // => -32_768 : Int16\n  /// ```\n  public let minimumValue = -32_768 : Int16;\n\n  /// Maximum 16-bit integer value, `+2 ** 15 - 1`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int16.maximumValue // => +32_767 : Int16\n  /// ```\n  public let maximumValue = 32_767 : Int16;\n\n  /// Converts a 16-bit signed integer to a signed integer with infinite precision.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int16.toInt(12_345) // => 12_345 : Int\n  /// ```\n  public let toInt : Int16 -> Int = Prim.int16ToInt;\n\n  /// Converts a signed integer with infinite precision to a 16-bit signed integer.\n  ///\n  /// Traps on overflow/underflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int16.fromInt(12_345) // => +12_345 : Int16\n  /// ```\n  public let fromInt : Int -> Int16 = Prim.intToInt16;\n\n  /// Converts a signed integer with infinite precision to a 16-bit signed integer.\n  ///\n  /// Wraps on overflow/underflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int16.fromIntWrap(-12_345) // => -12_345 : Int\n  /// ```\n  public let fromIntWrap : Int -> Int16 = Prim.intToInt16Wrap;\n\n  /// Converts a 8-bit signed integer to a 16-bit signed integer.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int16.fromInt8(-123) // => -123 : Int16\n  /// ```\n  public let fromInt8 : Int8 -> Int16 = Prim.int8ToInt16;\n\n  /// Converts a 16-bit signed integer to a 8-bit signed integer.\n  ///\n  /// Traps on overflow/underflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int16.toInt8(-123) // => -123 : Int8\n  /// ```\n  public let toInt8 : Int16 -> Int8 = Prim.int16ToInt8;\n\n  /// Converts a 32-bit signed integer to a 16-bit signed integer.\n  ///\n  /// Traps on overflow/underflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int16.fromInt32(-12_345) // => -12_345 : Int16\n  /// ```\n  public let fromInt32 : Int32 -> Int16 = Prim.int32ToInt16;\n\n  /// Converts a 16-bit signed integer to a 32-bit signed integer.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int16.toInt32(-12_345) // => -12_345 : Int32\n  /// ```\n  public let toInt32 : Int16 -> Int32 = Prim.int16ToInt32;\n\n  /// Converts an unsigned 16-bit integer to a signed 16-bit integer.\n  ///\n  /// Wraps on overflow/underflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int16.fromNat16(12_345) // => +12_345 : Int16\n  /// ```\n  public let fromNat16 : Nat16 -> Int16 = Prim.nat16ToInt16;\n\n  /// Converts a signed 16-bit integer to an unsigned 16-bit integer.\n  ///\n  /// Wraps on overflow/underflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int16.toNat16(-1) // => 65_535 : Nat16 // underflow\n  /// ```\n  public let toNat16 : Int16 -> Nat16 = Prim.int16ToNat16;\n\n  /// Returns the Text representation of `x`. Textual representation _do not_\n  /// contain underscores to represent commas.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int16.toText(-12345) // => \"-12345\"\n  /// ```\n  public func toText(x : Int16) : Text {\n    Int.toText(toInt(x))\n  };\n\n  /// Returns the absolute value of `x`.\n  ///\n  /// Traps when `x == -2 ** 15` (the minimum `Int16` value).\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int16.abs(-12345) // => +12_345\n  /// ```\n  public func abs(x : Int16) : Int16 {\n    fromInt(Int.abs(toInt(x)))\n  };\n\n  /// Returns the minimum of `x` and `y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int16.min(+2, -3) // => -3\n  /// ```\n  public func min(x : Int16, y : Int16) : Int16 {\n    if (x < y) { x } else { y }\n  };\n\n  /// Returns the maximum of `x` and `y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int16.max(+2, -3) // => +2\n  /// ```\n  public func max(x : Int16, y : Int16) : Int16 {\n    if (x < y) { y } else { x }\n  };\n\n  /// Equality function for Int16 types.\n  /// This is equivalent to `x == y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int16.equal(-1, -1); // => true\n  /// ```\n  ///\n\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// import Buffer \"mo:base/Buffer\";\n  ///\n  /// let buffer1 = Buffer.Buffer<Int16>(1);\n  /// buffer1.add(-3);\n  /// let buffer2 = Buffer.Buffer<Int16>(1);\n  /// buffer2.add(-3);\n  /// Buffer.equal(buffer1, buffer2, Int16.equal) // => true\n  /// ```\n  public func equal(x : Int16, y : Int16) : Bool { x == y };\n\n  /// Inequality function for Int16 types.\n  /// This is equivalent to `x != y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int16.notEqual(-1, -2); // => true\n  /// ```\n  ///\n\n  public func notEqual(x : Int16, y : Int16) : Bool { x != y };\n\n  /// \"Less than\" function for Int16 types.\n  /// This is equivalent to `x < y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int16.less(-2, 1); // => true\n  /// ```\n  ///\n\n  public func less(x : Int16, y : Int16) : Bool { x < y };\n\n  /// \"Less than or equal\" function for Int16 types.\n  /// This is equivalent to `x <= y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int16.lessOrEqual(-2, -2); // => true\n  /// ```\n  ///\n\n  public func lessOrEqual(x : Int16, y : Int16) : Bool { x <= y };\n\n  /// \"Greater than\" function for Int16 types.\n  /// This is equivalent to `x > y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int16.greater(-2, 1); // => false\n  /// ```\n  public func greater(x : Int16, y : Int16) : Bool { x > y };\n\n  /// \"Greater than or equal\" function for Int16 types.\n  /// This is equivalent to `x >= y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int16.greaterOrEqual(-2, -2); // => true\n  /// ```\n  public func greaterOrEqual(x : Int16, y : Int16) : Bool { x >= y };\n\n  /// General-purpose comparison function for `Int16`. Returns the `Order` (\n  /// either `#less`, `#equal`, or `#greater`) of comparing `x` with `y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int16.compare(-3, 2) // => #less\n  /// ```\n  ///\n  /// This function can be used as value for a high order function, such as a sort function.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// import Array \"mo:base/Array\";\n  /// Array.sort([1, -2, -3] : [Int16], Int16.compare) // => [-3, -2, 1]\n  /// ```\n  public func compare(x : Int16, y : Int16) : { #less; #equal; #greater } {\n    if (x < y) { #less } else if (x == y) { #equal } else { #greater }\n  };\n\n  /// Returns the negation of `x`, `-x`.\n  ///\n  /// Traps on overflow, i.e. for `neg(-2 ** 15)`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int16.neg(123) // => -123\n  /// ```\n  ///\n\n  public func neg(x : Int16) : Int16 { -x };\n\n  /// Returns the sum of `x` and `y`, `x + y`.\n  ///\n  /// Traps on overflow/underflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int16.add(100, 23) // => +123\n  /// ```\n  ///\n\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// import Array \"mo:base/Array\";\n  /// Array.foldLeft<Int16, Int16>([1, -2, -3], 0, Int16.add) // => -4\n  /// ```\n  public func add(x : Int16, y : Int16) : Int16 { x + y };\n\n  /// Returns the difference of `x` and `y`, `x - y`.\n  ///\n  /// Traps on overflow/underflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int16.sub(123, 100) // => +23\n  /// ```\n  ///\n\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// import Array \"mo:base/Array\";\n  /// Array.foldLeft<Int16, Int16>([1, -2, -3], 0, Int16.sub) // => 4\n  /// ```\n  public func sub(x : Int16, y : Int16) : Int16 { x - y };\n\n  /// Returns the product of `x` and `y`, `x * y`.\n  ///\n  /// Traps on overflow/underflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int16.mul(12, 10) // => +120\n  /// ```\n  ///\n\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// import Array \"mo:base/Array\";\n  /// Array.foldLeft<Int16, Int16>([1, -2, -3], 1, Int16.mul) // => 6\n  /// ```\n  public func mul(x : Int16, y : Int16) : Int16 { x * y };\n\n  /// Returns the signed integer division of `x` by `y`, `x / y`.\n  /// Rounds the quotient towards zero, which is the same as truncating the decimal places of the quotient.\n  ///\n  /// Traps when `y` is zero.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int16.div(123, 10) // => +12\n  /// ```\n  ///\n\n  public func div(x : Int16, y : Int16) : Int16 { x / y };\n\n  /// Returns the remainder of the signed integer division of `x` by `y`, `x % y`,\n  /// which is defined as `x - x / y * y`.\n  ///\n  /// Traps when `y` is zero.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int16.rem(123, 10) // => +3\n  /// ```\n  ///\n\n  public func rem(x : Int16, y : Int16) : Int16 { x % y };\n\n  /// Returns `x` to the power of `y`, `x ** y`.\n  ///\n  /// Traps on overflow/underflow and when `y < 0 or y >= 16`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int16.pow(2, 10) // => +1_024\n  /// ```\n  ///\n\n  public func pow(x : Int16, y : Int16) : Int16 { x ** y };\n\n  /// Returns the bitwise negation of `x`, `^x`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int16.bitnot(-256 /* 0xff00 */) // => +255 // 0xff\n  /// ```\n  ///\n\n  public func bitnot(x : Int16) : Int16 { ^x };\n\n  /// Returns the bitwise \"and\" of `x` and `y`, `x & y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int16.bitand(0x0fff, 0x00f0) // => +240 // 0xf0\n  /// ```\n  ///\n\n  public func bitand(x : Int16, y : Int16) : Int16 { x & y };\n\n  /// Returns the bitwise \"or\" of `x` and `y`, `x | y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int16.bitor(0x0f0f, 0x00f0) // => +4_095 // 0x0fff\n  /// ```\n\n  public func bitor(x : Int16, y : Int16) : Int16 { x | y };\n\n  /// Returns the bitwise \"exclusive or\" of `x` and `y`, `x ^ y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int16.bitxor(0x0fff, 0x00f0) // => +3_855 // 0x0f0f\n  /// ```\n\n  public func bitxor(x : Int16, y : Int16) : Int16 { x ^ y };\n\n  /// Returns the bitwise left shift of `x` by `y`, `x << y`.\n  /// The right bits of the shift filled with zeros.\n  /// Left-overflowing bits, including the sign bit, are discarded.\n  ///\n  /// For `y >= 16`, the semantics is the same as for `bitshiftLeft(x, y % 16)`.\n  /// For `y < 0`,  the semantics is the same as for `bitshiftLeft(x, y + y % 16)`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int16.bitshiftLeft(1, 8) // => +256 // 0x100 equivalent to `2 ** 8`.\n  /// ```\n  ///\n\n  public func bitshiftLeft(x : Int16, y : Int16) : Int16 { x << y };\n\n  /// Returns the signed bitwise right shift of `x` by `y`, `x >> y`.\n  /// The sign bit is retained and the left side is filled with the sign bit.\n  /// Right-underflowing bits are discarded, i.e. not rotated to the left side.\n  ///\n  /// For `y >= 16`, the semantics is the same as for `bitshiftRight(x, y % 16)`.\n  /// For `y < 0`,  the semantics is the same as for `bitshiftRight (x, y + y % 16)`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int16.bitshiftRight(1024, 8) // => +4 // equivalent to `1024 / (2 ** 8)`\n  /// ```\n  ///\n\n  public func bitshiftRight(x : Int16, y : Int16) : Int16 { x >> y };\n\n  /// Returns the bitwise left rotatation of `x` by `y`, `x <<> y`.\n  /// Each left-overflowing bit is inserted again on the right side.\n  /// The sign bit is rotated like other bits, i.e. the rotation interprets the number as unsigned.\n  ///\n  /// Changes the direction of rotation for negative `y`.\n  /// For `y >= 16`, the semantics is the same as for `bitrotLeft(x, y % 16)`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int16.bitrotLeft(0x2001, 4) // => +18 // 0x12.\n  /// ```\n  ///\n\n  public func bitrotLeft(x : Int16, y : Int16) : Int16 { x <<> y };\n\n  /// Returns the bitwise right rotation of `x` by `y`, `x <>> y`.\n  /// Each right-underflowing bit is inserted again on the right side.\n  /// The sign bit is rotated like other bits, i.e. the rotation interprets the number as unsigned.\n  ///\n  /// Changes the direction of rotation for negative `y`.\n  /// For `y >= 16`, the semantics is the same as for `bitrotRight(x, y % 16)`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int16.bitrotRight(0x2010, 8) // => +4_128 // 0x01020.\n  /// ```\n  ///\n\n  public func bitrotRight(x : Int16, y : Int16) : Int16 { x <>> y };\n\n  /// Returns the value of bit `p` in `x`, `x & 2**p == 2**p`.\n  /// If `p >= 16`, the semantics is the same as for `bittest(x, p % 16)`.\n  /// This is equivalent to checking if the `p`-th bit is set in `x`, using 0 indexing.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int16.bittest(128, 7) // => true\n  /// ```\n  public func bittest(x : Int16, p : Nat) : Bool {\n    Prim.btstInt16(x, Prim.intToInt16(p))\n  };\n\n  /// Returns the value of setting bit `p` in `x` to `1`.\n  /// If `p >= 16`, the semantics is the same as for `bitset(x, p % 16)`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int16.bitset(0, 7) // => +128\n  /// ```\n  public func bitset(x : Int16, p : Nat) : Int16 {\n    x | (1 << Prim.intToInt16(p))\n  };\n\n  /// Returns the value of clearing bit `p` in `x` to `0`.\n  /// If `p >= 16`, the semantics is the same as for `bitclear(x, p % 16)`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int16.bitclear(-1, 7) // => -129\n  /// ```\n  public func bitclear(x : Int16, p : Nat) : Int16 {\n    x & ^(1 << Prim.intToInt16(p))\n  };\n\n  /// Returns the value of flipping bit `p` in `x`.\n  /// If `p >= 16`, the semantics is the same as for `bitclear(x, p % 16)`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int16.bitflip(255, 7) // => +127\n  /// ```\n  public func bitflip(x : Int16, p : Nat) : Int16 {\n    x ^ (1 << Prim.intToInt16(p))\n  };\n\n  /// Returns the count of non-zero bits in `x`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int16.bitcountNonZero(0xff) // => +8\n  /// ```\n  public let bitcountNonZero : (x : Int16) -> Int16 = Prim.popcntInt16;\n\n  /// Returns the count of leading zero bits in `x`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int16.bitcountLeadingZero(0x80) // => +8\n  /// ```\n  public let bitcountLeadingZero : (x : Int16) -> Int16 = Prim.clzInt16;\n\n  /// Returns the count of trailing zero bits in `x`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int16.bitcountTrailingZero(0x0100) // => +8\n  /// ```\n  public let bitcountTrailingZero : (x : Int16) -> Int16 = Prim.ctzInt16;\n\n  /// Returns the upper (i.e. most significant) and lower (least significant) byte of `x`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int16.explode 0x77ee // => (119, 238)\n  /// ```\n  public let explode : (x : Int16) -> (msb : Nat8, lsb : Nat8) = Prim.explodeInt16;\n\n  /// Returns the sum of `x` and `y`, `x +% y`.\n  ///\n  /// Wraps on overflow/underflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int16.addWrap(2 ** 14, 2 ** 14) // => -32_768 // overflow\n  /// ```\n  ///\n  /// :::info\n  /// The reason why this function is defined in this library (in addition\n  /// to the existing `+%` operator) is so that you can use it as a function\n  /// value to pass to a higher order function. It is not possible to use `+%`\n  /// as a function value at the moment.\n  /// :::\n  public func addWrap(x : Int16, y : Int16) : Int16 { x +% y };\n\n  /// Returns the difference of `x` and `y`, `x -% y`.\n  ///\n  /// Wraps on overflow/underflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int16.subWrap(-2 ** 15, 1) // => +32_767 // underflow\n  /// ```\n  ///\n\n  public func subWrap(x : Int16, y : Int16) : Int16 { x -% y };\n\n  /// Returns the product of `x` and `y`, `x *% y`. Wraps on overflow.\n  ///\n  /// Wraps on overflow/underflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int16.mulWrap(2 ** 8, 2 ** 8) // => 0 // overflow\n  /// ```\n  ///\n\n  public func mulWrap(x : Int16, y : Int16) : Int16 { x *% y };\n\n  /// Returns `x` to the power of `y`, `x **% y`.\n  ///\n  /// Wraps on overflow/underflow.\n  /// Traps if `y < 0 or y >= 16`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  ///\n  /// Int16.powWrap(2, 15) // => -32_768 // overflow\n  /// ```\n  ///\n\n  public func powWrap(x : Int16, y : Int16) : Int16 { x **% y }\n}\n"},"Option.mo":{"content":"/// Optional values can be seen as a typesafe `null`. A value of type `?Int` can\n/// be constructed with either `null` or `?42`. The simplest way to get at the\n/// contents of an optional is to use pattern matching:\n///\n/// ```motoko\n/// let optionalInt1 : ?Int = ?42;\n/// let optionalInt2 : ?Int = null;\n///\n/// let int1orZero : Int = switch optionalInt1 {\n///   case null 0;\n///   case (?int) int;\n/// };\n/// assert int1orZero == 42;\n///\n/// let int2orZero : Int = switch optionalInt2 {\n///   case null 0;\n///   case (?int) int;\n/// };\n/// assert int2orZero == 0;\n/// ```\n///\n/// The functions in this module capture some common operations when working\n/// with optionals that can be more succinct than using pattern matching.\n\nimport P \"Prelude\";\n\nmodule {\n\n  /// Unwraps an optional value, with a default value, i.e. `get(?x, d) = x` and\n  /// `get(null, d) = d`.\n  public func get<T>(x : ?T, default : T) : T = switch x {\n    case null { default };\n    case (?x_) { x_ }\n  };\n\n  /// Unwraps an optional value using a function, or returns the default, i.e.\n  /// `option(?x, f, d) = f x` and `option(null, f, d) = d`.\n  public func getMapped<A, B>(x : ?A, f : A -> B, default : B) : B = switch x {\n    case null { default };\n    case (?x_) { f(x_) }\n  };\n\n  /// Applies a function to the wrapped value. `null`'s are left untouched.\n  /// ```motoko\n  /// import Option \"mo:base/Option\";\n  /// assert Option.map<Nat, Nat>(?42, func x = x + 1) == ?43;\n  /// assert Option.map<Nat, Nat>(null, func x = x + 1) == null;\n  /// ```\n  public func map<A, B>(x : ?A, f : A -> B) : ?B = switch x {\n    case null { null };\n    case (?x_) { ?f(x_) }\n  };\n\n  /// Applies a function to the wrapped value, but discards the result. Use\n  /// `iterate` if you're only interested in the side effect `f` produces.\n  ///\n  /// ```motoko\n  /// import Option \"mo:base/Option\";\n  /// var counter : Nat = 0;\n  /// Option.iterate(?5, func (x : Nat) { counter += x });\n  /// assert counter == 5;\n  /// Option.iterate(null, func (x : Nat) { counter += x });\n  /// assert counter == 5;\n  /// ```\n  public func iterate<A>(x : ?A, f : A -> ()) = switch x {\n    case null {};\n    case (?x_) { f(x_) }\n  };\n\n  /// Applies an optional function to an optional value. Returns `null` if at\n  /// least one of the arguments is `null`.\n  public func apply<A, B>(x : ?A, f : ?(A -> B)) : ?B {\n    switch (f, x) {\n      case (?f_, ?x_) {\n        ?f_(x_)\n      };\n      case (_, _) {\n        null\n      }\n    }\n  };\n\n  /// Applies a function to an optional value. Returns `null` if the argument is\n  /// `null`, or the function returns `null`.\n  public func chain<A, B>(x : ?A, f : A -> ?B) : ?B {\n    switch (x) {\n      case (?x_) {\n        f(x_)\n      };\n      case (null) {\n        null\n      }\n    }\n  };\n\n  /// Given an optional optional value, removes one layer of optionality.\n  /// ```motoko\n  /// import Option \"mo:base/Option\";\n  /// assert Option.flatten(?(?(42))) == ?42;\n  /// assert Option.flatten(?(null)) == null;\n  /// assert Option.flatten(null) == null;\n  /// ```\n  public func flatten<A>(x : ??A) : ?A {\n    chain<?A, A>(\n      x,\n      func(x_ : ?A) : ?A {\n        x_\n      }\n    )\n  };\n\n  /// Creates an optional value from a definite value.\n  /// ```motoko\n  /// import Option \"mo:base/Option\";\n  /// assert Option.make(42) == ?42;\n  /// ```\n  public func make<A>(x : A) : ?A = ?x;\n\n  /// Returns true if the argument is not `null`, otherwise returns false.\n  public func isSome(x : ?Any) : Bool = switch x {\n    case null { false };\n    case _ { true }\n  };\n\n  /// Returns true if the argument is `null`, otherwise returns false.\n  public func isNull(x : ?Any) : Bool = switch x {\n    case null { true };\n    case _ { false }\n  };\n\n  /// Returns true if the optional arguments are equal according to the equality function provided, otherwise returns false.\n  public func equal<A>(x : ?A, y : ?A, eq : (A, A) -> Bool) : Bool = switch (x, y) {\n    case (null, null) { true };\n    case (?x_, ?y_) { eq(x_, y_) };\n    case (_, _) { false }\n  };\n\n  /// Asserts that the value is not `null`; fails otherwise.\n  ///\n  /// @deprecated Option.assertSome will be removed soon; use an assert expression instead\n  public func assertSome(x : ?Any) = switch x {\n    case null { P.unreachable() };\n    case _ {}\n  };\n\n  /// Asserts that the value _is_ `null`; fails otherwise.\n  ///\n  /// @deprecated Option.assertNull will be removed soon; use an assert expression instead\n  public func assertNull(x : ?Any) = switch x {\n    case null {};\n    case _ { P.unreachable() }\n  };\n\n  /// Unwraps an optional value, i.e. `unwrap(?x) = x`.\n  ///\n  /// @deprecated Option.unwrap is unsafe and fails if the argument is null; it will be removed soon; use a `switch` or `do?` expression instead\n  public func unwrap<T>(x : ?T) : T = switch x {\n    case null { P.unreachable() };\n    case (?x_) { x_ }\n  }\n}\n"},"Order.mo":{"content":"\nmodule {\n\n  /// A type to represent an order.\n  public type Order = {\n    #less;\n    #equal;\n    #greater\n  };\n\n  /// Check if an order is `#less`.\n  public func isLess(order : Order) : Bool {\n    switch order {\n      case (#less) { true };\n      case _ { false }\n    }\n  };\n\n  /// Check if an order is `#equal`.\n  public func isEqual(order : Order) : Bool {\n    switch order {\n      case (#equal) { true };\n      case _ { false }\n    }\n  };\n\n  /// Check if an order is `#greater`.\n  public func isGreater(order : Order) : Bool {\n    switch order {\n      case (#greater) { true };\n      case _ { false }\n    }\n  };\n\n  /// Returns true if only if  `o1` and `o2` are the same ordering.\n  public func equal(o1 : Order, o2 : Order) : Bool {\n    switch (o1, o2) {\n      case (#less, #less) { true };\n      case (#equal, #equal) { true };\n      case (#greater, #greater) { true };\n      case _ { false }\n    }\n  };\n\n}\n"},"Timer.mo":{"content":"/// Timers for one-off or periodic tasks. Applicable as part of the default mechanism.\n///\n/// :::note Timer resolution\n///\n/// The resolution of the timers is in the order of the block rate,\n/// so durations should be chosen well above that. For frequent\n/// canister wake-ups the heartbeat mechanism should be considered.\n/// :::\n///\n/// :::note Overriding system function\n///\n/// The functionality described below is enabled only when the actor does not override it by declaring an explicit `system func timer`.\n/// :::\n///\n/// :::note Upgrade persistence\n///\n/// Timers are _not_ persisted across upgrades. One possible strategy\n/// to re-establish timers after an upgrade is to walk stable variables\n/// in the `post_upgrade` hook and distill necessary timer information\n/// from there.\n/// :::\n///\n/// :::note Security warning\n///\n/// Basing security (e.g. access control) on timers is almost always the wrong choice.\n/// Be sure to inform yourself about state-of-the-art dApp security.\n/// If you _must use_ timers for security controls, be sure to consider reentrancy issues,\n/// and the vanishing of timers on upgrades and reinstalls.\n/// :::\n///\n/// :::note Further information\n///\n/// [Further usage information for timers](https://internetcomputer.org/docs/current/developer-docs/backend/periodic-tasks#timers-library-limitations).\n/// :::\n///\n/// :::note Compilation flag\n///\n/// If `moc` is invoked with `-no-timer`, the importing will fail.\n/// :::\nimport { setTimer = setTimerNano; cancelTimer = cancel } = \"mo:⛔\";\nimport { fromIntWrap } = \"Nat64\";\n\nmodule {\n\n  public type Duration = { #seconds : Nat; #nanoseconds : Nat };\n  public type TimerId = Nat;\n\n  func toNanos(d : Duration) : Nat64 = fromIntWrap(\n    switch d {\n      case (#seconds s) s * 1000_000_000;\n      case (#nanoseconds ns) ns\n    }\n  );\n\n  /// Installs a one-off timer that upon expiration after given duration `d`\n  /// executes the future `job()`.\n  ///\n  /// ```motoko no-repl\n  /// let now = Time.now();\n  /// let thirtyMinutes = 1_000_000_000 * 60 * 30;\n  /// func alarmUser() : async () {\n  ///   // ...\n  /// };\n  /// appt.reminder = setTimer(#nanoseconds (Int.abs(appt.when - now - thirtyMinutes)), alarmUser);\n  /// ```\n  public func setTimer<system>(d : Duration, job : () -> async ()) : TimerId {\n    setTimerNano<system>(toNanos d, false, job)\n  };\n\n  /// Installs a recurring timer that upon expiration after given duration `d`\n  /// executes the future `job()` and reinserts itself for another expiration.\n  ///\n  /// :::info\n  /// A duration of 0 will only expire once.\n  /// :::\n  ///\n  /// ```motoko no-repl\n  /// func checkAndWaterPlants() : async () {\n  ///   // ...\n  /// };\n  /// let daily = recurringTimer(#seconds (24 * 60 * 60), checkAndWaterPlants);\n  /// ```\n  public func recurringTimer<system>(d : Duration, job : () -> async ()) : TimerId {\n    setTimerNano<system>(toNanos d, true, job)\n  };\n\n  /// Cancels a still active timer with `(id : TimerId)`. For expired timers\n  /// and not recognized `id`s nothing happens.\n  ///\n  /// ```motoko no-repl\n  /// func deleteAppointment(appointment : Appointment) {\n  ///   cancelTimer (appointment.reminder);\n  ///   // ...\n  /// };\n  /// ```\n  public let cancelTimer : TimerId -> () = cancel;\n\n}\n"},"Int32.mo":{"content":"/// Provides utility functions on 32-bit signed integers.\n///\n/// :::note\n/// Most operations are available as built-in operators (e.g. `1 + 1`).\n/// :::\n///\n/// :::info Function form for higher-order use\n///\n/// Several arithmetic and comparison functions (e.g. `add`, `sub`, `bitor`, `bitand`, `pow`) are defined in this module to enable their use as first-class function values, which is not possible with operators like `+`, `-`, `==`, etc., in Motoko. This allows you to pass these operations to higher-order functions such as `map`, `foldLeft`, or `sort`.\n/// :::\n///\n/// ```motoko name=import\n/// import Int32 \"mo:base/Int32\";\n/// ```\nimport Int \"Int\";\nimport Prim \"mo:⛔\";\n\nmodule {\n\n  /// 32-bit signed integers.\n  public type Int32 = Prim.Types.Int32;\n\n  /// Minimum 32-bit integer value, `-2 ** 31`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int32.minimumValue // => -2_147_483_648\n  /// ```\n  public let minimumValue = -2_147_483_648 : Int32;\n\n  /// Maximum 32-bit integer value, `+2 ** 31 - 1`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int32.maximumValue // => +2_147_483_647\n  /// ```\n  public let maximumValue = 2_147_483_647 : Int32;\n\n  /// Converts a 32-bit signed integer to a signed integer with infinite precision.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int32.toInt(123_456) // => 123_456 : Int\n  /// ```\n  public let toInt : Int32 -> Int = Prim.int32ToInt;\n\n  /// Converts a signed integer with infinite precision to a 32-bit signed integer.\n  ///\n  /// Traps on overflow/underflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int32.fromInt(123_456) // => +123_456 : Int32\n  /// ```\n  public let fromInt : Int -> Int32 = Prim.intToInt32;\n\n  /// Converts a signed integer with infinite precision to a 32-bit signed integer.\n  ///\n  /// Wraps on overflow/underflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int32.fromIntWrap(-123_456) // => -123_456 : Int\n  /// ```\n  public let fromIntWrap : Int -> Int32 = Prim.intToInt32Wrap;\n\n  /// Converts a 16-bit signed integer to a 32-bit signed integer.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int32.fromInt16(-123) // => -123 : Int32\n  /// ```\n  public let fromInt16 : Int16 -> Int32 = Prim.int16ToInt32;\n\n  /// Converts a 32-bit signed integer to a 16-bit signed integer.\n  ///\n  /// Traps on overflow/underflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int32.toInt16(-123) // => -123 : Int16\n  /// ```\n  public let toInt16 : Int32 -> Int16 = Prim.int32ToInt16;\n\n  /// Converts a 64-bit signed integer to a 32-bit signed integer.\n  ///\n  /// Traps on overflow/underflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int32.fromInt64(-123_456) // => -123_456 : Int32\n  /// ```\n  public let fromInt64 : Int64 -> Int32 = Prim.int64ToInt32;\n\n  /// Converts a 32-bit signed integer to a 64-bit signed integer.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int32.toInt64(-123_456) // => -123_456 : Int64\n  /// ```\n  public let toInt64 : Int32 -> Int64 = Prim.int32ToInt64;\n\n  /// Converts an unsigned 32-bit integer to a signed 32-bit integer.\n  ///\n  /// Wraps on overflow/underflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int32.fromNat32(123_456) // => +123_456 : Int32\n  /// ```\n  public let fromNat32 : Nat32 -> Int32 = Prim.nat32ToInt32;\n\n  /// Converts a signed 32-bit integer to an unsigned 32-bit integer.\n  ///\n  /// Wraps on overflow/underflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int32.toNat32(-1) // => 4_294_967_295 : Nat32 // underflow\n  /// ```\n  public let toNat32 : Int32 -> Nat32 = Prim.int32ToNat32;\n\n  /// Returns the Text representation of `x`. Textual representation _do not_\n  /// contain underscores to represent commas.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int32.toText(-123456) // => \"-123456\"\n  /// ```\n  public func toText(x : Int32) : Text {\n    Int.toText(toInt(x))\n  };\n\n  /// Returns the absolute value of `x`.\n  ///\n  /// Traps when `x == -2 ** 31` (the minimum `Int32` value).\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int32.abs(-123456) // => +123_456\n  /// ```\n  public func abs(x : Int32) : Int32 {\n    fromInt(Int.abs(toInt(x)))\n  };\n\n  /// Returns the minimum of `x` and `y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int32.min(+2, -3) // => -3\n  /// ```\n  public func min(x : Int32, y : Int32) : Int32 {\n    if (x < y) { x } else { y }\n  };\n\n  /// Returns the maximum of `x` and `y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int32.max(+2, -3) // => +2\n  /// ```\n  public func max(x : Int32, y : Int32) : Int32 {\n    if (x < y) { y } else { x }\n  };\n\n  /// Equality function for Int32 types.\n  /// This is equivalent to `x == y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int32.equal(-1, -1); // => true\n  /// ```\n  ///\n\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// import Buffer \"mo:base/Buffer\";\n  ///\n  /// let buffer1 = Buffer.Buffer<Int32>(1);\n  /// buffer1.add(-3);\n  /// let buffer2 = Buffer.Buffer<Int32>(1);\n  /// buffer2.add(-3);\n  /// Buffer.equal(buffer1, buffer2, Int32.equal) // => true\n  /// ```\n  public func equal(x : Int32, y : Int32) : Bool { x == y };\n\n  /// Inequality function for Int32 types.\n  /// This is equivalent to `x != y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int32.notEqual(-1, -2); // => true\n  /// ```\n  ///\n\n  public func notEqual(x : Int32, y : Int32) : Bool { x != y };\n\n  /// \"Less than\" function for Int32 types.\n  /// This is equivalent to `x < y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int32.less(-2, 1); // => true\n  /// ```\n  ///\n\n  public func less(x : Int32, y : Int32) : Bool { x < y };\n\n  /// \"Less than or equal\" function for Int32 types.\n  /// This is equivalent to `x <= y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int32.lessOrEqual(-2, -2); // => true\n  /// ```\n  ///\n\n  public func lessOrEqual(x : Int32, y : Int32) : Bool { x <= y };\n\n  /// \"Greater than\" function for Int32 types.\n  /// This is equivalent to `x > y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int32.greater(-2, -3); // => true\n  /// ```\n  ///\n\n  public func greater(x : Int32, y : Int32) : Bool { x > y };\n\n  /// \"Greater than or equal\" function for Int32 types.\n  /// This is equivalent to `x >= y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int32.greaterOrEqual(-2, -2); // => true\n  /// ```\n  ///\n\n  public func greaterOrEqual(x : Int32, y : Int32) : Bool { x >= y };\n\n  /// General-purpose comparison function for `Int32`. Returns the `Order` (\n  /// either `#less`, `#equal`, or `#greater`) of comparing `x` with `y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int32.compare(-3, 2) // => #less\n  /// ```\n  ///\n  /// This function can be used as value for a high order function, such as a sort function.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// import Array \"mo:base/Array\";\n  /// Array.sort([1, -2, -3] : [Int32], Int32.compare) // => [-3, -2, 1]\n  /// ```\n  public func compare(x : Int32, y : Int32) : { #less; #equal; #greater } {\n    if (x < y) { #less } else if (x == y) { #equal } else { #greater }\n  };\n\n  /// Returns the negation of `x`, `-x`.\n  ///\n  /// Traps on overflow, i.e. for `neg(-2 ** 31)`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int32.neg(123) // => -123\n  /// ```\n  ///\n\n  public func neg(x : Int32) : Int32 { -x };\n\n  /// Returns the sum of `x` and `y`, `x + y`.\n  ///\n  /// Traps on overflow/underflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int32.add(100, 23) // => +123\n  /// ```\n  ///\n\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// import Array \"mo:base/Array\";\n  /// Array.foldLeft<Int32, Int32>([1, -2, -3], 0, Int32.add) // => -4\n  /// ```\n  public func add(x : Int32, y : Int32) : Int32 { x + y };\n\n  /// Returns the difference of `x` and `y`, `x - y`.\n  ///\n  /// Traps on overflow/underflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int32.sub(1234, 123) // => +1_111\n  /// ```\n  ///\n\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// import Array \"mo:base/Array\";\n  /// Array.foldLeft<Int32, Int32>([1, -2, -3], 0, Int32.sub) // => 6\n  /// ```\n  public func sub(x : Int32, y : Int32) : Int32 { x - y };\n\n  /// Returns the product of `x` and `y`, `x * y`.\n  ///\n  /// Traps on overflow/underflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int32.mul(123, 100) // => +12_300\n  /// ```\n  ///\n\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// import Array \"mo:base/Array\";\n  /// Array.foldLeft<Int32, Int32>([1, -2, -3], 1, Int32.mul) // => 6\n  /// ```\n  public func mul(x : Int32, y : Int32) : Int32 { x * y };\n\n  /// Returns the signed integer division of `x` by `y`, `x / y`.\n  /// Rounds the quotient towards zero, which is the same as truncating the decimal places of the quotient.\n  ///\n  /// Traps when `y` is zero.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int32.div(123, 10) // => +12\n  /// ```\n  ///\n\n  public func div(x : Int32, y : Int32) : Int32 { x / y };\n\n  /// Returns the remainder of the signed integer division of `x` by `y`, `x % y`,\n  /// which is defined as `x - x / y * y`.\n  ///\n  /// Traps when `y` is zero.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int32.rem(123, 10) // => +3\n  /// ```\n  ///\n\n  public func rem(x : Int32, y : Int32) : Int32 { x % y };\n\n  /// Returns `x` to the power of `y`, `x ** y`.\n  ///\n  /// Traps on overflow/underflow and when `y < 0 or y >= 32`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int32.pow(2, 10) // => +1_024\n  /// ```\n  ///\n\n  public func pow(x : Int32, y : Int32) : Int32 { x ** y };\n\n  /// Returns the bitwise negation of `x`, `^x`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int32.bitnot(-256 /* 0xffff_ff00 */) // => +255 // 0xff\n  /// ```\n  ///\n\n  public func bitnot(x : Int32) : Int32 { ^x };\n\n  /// Returns the bitwise \"and\" of `x` and `y`, `x & y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int32.bitand(0xffff, 0x00f0) // => +240 // 0xf0\n  /// ```\n  ///\n\n  public func bitand(x : Int32, y : Int32) : Int32 { x & y };\n\n  /// Returns the bitwise \"or\" of `x` and `y`, `x | y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int32.bitor(0xffff, 0x00f0) // => +65_535 // 0xffff\n  /// ```\n  ///\n\n  public func bitor(x : Int32, y : Int32) : Int32 { x | y };\n\n  /// Returns the bitwise \"exclusive or\" of `x` and `y`, `x ^ y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int32.bitxor(0xffff, 0x00f0) // => +65_295 // 0xff0f\n  /// ```\n  ///\n\n  public func bitxor(x : Int32, y : Int32) : Int32 { x ^ y };\n\n  /// Returns the bitwise left shift of `x` by `y`, `x << y`.\n  /// The right bits of the shift filled with zeros.\n  /// Left-overflowing bits, including the sign bit, are discarded.\n  ///\n  /// For `y >= 32`, the semantics is the same as for `bitshiftLeft(x, y % 32)`.\n  /// For `y < 0`,  the semantics is the same as for `bitshiftLeft(x, y + y % 32)`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int32.bitshiftLeft(1, 8) // => +256 // 0x100 equivalent to `2 ** 8`.\n  /// ```\n  ///\n\n  public func bitshiftLeft(x : Int32, y : Int32) : Int32 { x << y };\n\n  /// Returns the signed bitwise right shift of `x` by `y`, `x >> y`.\n  /// The sign bit is retained and the left side is filled with the sign bit.\n  /// Right-underflowing bits are discarded, i.e. not rotated to the left side.\n  ///\n  /// For `y >= 32`, the semantics is the same as for `bitshiftRight(x, y % 32)`.\n  /// For `y < 0`,  the semantics is the same as for `bitshiftRight (x, y + y % 32)`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int32.bitshiftRight(1024, 8) // => +4 // equivalent to `1024 / (2 ** 8)`\n  /// ```\n  ///\n\n  public func bitshiftRight(x : Int32, y : Int32) : Int32 { x >> y };\n\n  /// Returns the bitwise left rotatation of `x` by `y`, `x <<> y`.\n  /// Each left-overflowing bit is inserted again on the right side.\n  /// The sign bit is rotated like other bits, i.e. the rotation interprets the number as unsigned.\n  ///\n  /// Changes the direction of rotation for negative `y`.\n  /// For `y >= 32`, the semantics is the same as for `bitrotLeft(x, y % 32)`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int32.bitrotLeft(0x2000_0001, 4) // => +18 // 0x12.\n  /// ```\n  ///\n\n  public func bitrotLeft(x : Int32, y : Int32) : Int32 { x <<> y };\n\n  /// Returns the bitwise right rotation of `x` by `y`, `x <>> y`.\n  /// Each right-underflowing bit is inserted again on the right side.\n  /// The sign bit is rotated like other bits, i.e. the rotation interprets the number as unsigned.\n  ///\n  /// Changes the direction of rotation for negative `y`.\n  /// For `y >= 32`, the semantics is the same as for `bitrotRight(x, y % 32)`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int32.bitrotRight(0x0002_0001, 8) // => +16_777_728 // 0x0100_0200.\n  /// ```\n  ///\n\n  public func bitrotRight(x : Int32, y : Int32) : Int32 { x <>> y };\n\n  /// Returns the value of bit `p` in `x`, `x & 2**p == 2**p`.\n  /// If `p >= 32`, the semantics is the same as for `bittest(x, p % 32)`.\n  /// This is equivalent to checking if the `p`-th bit is set in `x`, using 0 indexing.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int32.bittest(128, 7) // => true\n  /// ```\n  public func bittest(x : Int32, p : Nat) : Bool {\n    Prim.btstInt32(x, Prim.intToInt32(p))\n  };\n\n  /// Returns the value of setting bit `p` in `x` to `1`.\n  /// If `p >= 32`, the semantics is the same as for `bitset(x, p % 32)`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int32.bitset(0, 7) // => +128\n  /// ```\n  public func bitset(x : Int32, p : Nat) : Int32 {\n    x | (1 << Prim.intToInt32(p))\n  };\n\n  /// Returns the value of clearing bit `p` in `x` to `0`.\n  /// If `p >= 32`, the semantics is the same as for `bitclear(x, p % 32)`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int32.bitclear(-1, 7) // => -129\n  /// ```\n  public func bitclear(x : Int32, p : Nat) : Int32 {\n    x & ^(1 << Prim.intToInt32(p))\n  };\n\n  /// Returns the value of flipping bit `p` in `x`.\n  /// If `p >= 32`, the semantics is the same as for `bitclear(x, p % 32)`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int32.bitflip(255, 7) // => +127\n  /// ```\n  public func bitflip(x : Int32, p : Nat) : Int32 {\n    x ^ (1 << Prim.intToInt32(p))\n  };\n\n  /// Returns the count of non-zero bits in `x`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int32.bitcountNonZero(0xffff) // => +16\n  /// ```\n  public let bitcountNonZero : (x : Int32) -> Int32 = Prim.popcntInt32;\n\n  /// Returns the count of leading zero bits in `x`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int32.bitcountLeadingZero(0x8000) // => +16\n  /// ```\n  public let bitcountLeadingZero : (x : Int32) -> Int32 = Prim.clzInt32;\n\n  /// Returns the count of trailing zero bits in `x`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int32.bitcountTrailingZero(0x0201_0000) // => +16\n  /// ```\n  public let bitcountTrailingZero : (x : Int32) -> Int32 = Prim.ctzInt32;\n\n  /// Returns the upper (i.e. most significant), lower (least significant)\n  /// and in-between bytes of `x`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int32.explode 0x66885511 // => (102, 136, 85, 17)\n  /// ```\n  public let explode : (x : Int32) -> (msb : Nat8, Nat8, Nat8, lsb : Nat8) = Prim.explodeInt32;\n\n  /// Returns the sum of `x` and `y`, `x +% y`.\n  ///\n  /// Wraps on overflow/underflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int32.addWrap(2 ** 30, 2 ** 30) // => -2_147_483_648 // overflow\n  /// ```\n  ///\n  /// :::info\n  /// The reason why this function is defined in this library (in addition\n  /// to the existing `+%` operator) is so that you can use it as a function\n  /// value to pass to a higher order function. It is not possible to use `+%`\n  /// as a function value at the moment.\n  /// :::\n  public func addWrap(x : Int32, y : Int32) : Int32 { x +% y };\n\n  /// Returns the difference of `x` and `y`, `x -% y`.\n  ///\n  /// Wraps on overflow/underflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int32.subWrap(-2 ** 31, 1) // => +2_147_483_647 // underflow\n  /// ```\n  ///\n\n  public func subWrap(x : Int32, y : Int32) : Int32 { x -% y };\n\n  /// Returns the product of `x` and `y`, `x *% y`. Wraps on overflow.\n  ///\n  /// Wraps on overflow/underflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int32.mulWrap(2 ** 16, 2 ** 16) // => 0 // overflow\n  /// ```\n  ///\n\n  public func mulWrap(x : Int32, y : Int32) : Int32 { x *% y };\n\n  /// Returns `x` to the power of `y`, `x **% y`.\n  ///\n  /// Wraps on overflow/underflow.\n  /// Traps if `y < 0 or y >= 32`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int32.powWrap(2, 31) // => -2_147_483_648 // overflow\n  /// ```\n  ///\n\n  public func powWrap(x : Int32, y : Int32) : Int32 { x **% y };\n\n}\n"},"Nat32.mo":{"content":"/// Provides utility functions on 32-bit unsigned integers.\n///\n/// :::note\n/// Most operations on integer numbers (e.g. addition) are available as built-in operators (e.g. `1 + 1`).\n/// This module provides equivalent functions and `Text` conversion.\n/// :::\n///\n/// :::info Function form for higher-order use\n///\n/// Several arithmetic and comparison functions (e.g. `add`, `sub`, `equal`, `less`, `pow`) are defined in this module to enable their use as first-class function values, which is not possible with operators like `+`, `-`, `==`, etc., in Motoko. This allows you to pass these operations to higher-order functions such as `map`, `foldLeft`, or `sort`.\n/// :::\n///\n/// Import from the base library to use this module.\n///\n/// ```motoko name=import\n/// import Nat32 \"mo:base/Nat32\";\n/// ```\n\nimport Nat \"Nat\";\nimport Prim \"mo:⛔\";\n\nmodule {\n\n  /// 32-bit natural numbers.\n  public type Nat32 = Prim.Types.Nat32;\n\n  /// Maximum 32-bit natural number. `2 ** 32 - 1`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat32.maximumValue; // => 4294967295 : Nat32\n  /// ```\n  public let maximumValue = 4294967295 : Nat32;\n\n  /// Converts a 32-bit unsigned integer to an unsigned integer with infinite precision.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat32.toNat(123); // => 123 : Nat\n  /// ```\n  public let toNat : Nat32 -> Nat = Prim.nat32ToNat;\n\n  /// Converts an unsigned integer with infinite precision to a 32-bit unsigned integer.\n  ///\n  /// Traps on overflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat32.fromNat(123); // => 123 : Nat32\n  /// ```\n  public let fromNat : Nat -> Nat32 = Prim.natToNat32;\n\n  /// Converts a 16-bit unsigned integer to a 32-bit unsigned integer.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat32.fromNat16(123); // => 123 : Nat32\n  /// ```\n  public func fromNat16(x : Nat16) : Nat32 {\n    Prim.nat16ToNat32(x)\n  };\n\n  /// Converts a 32-bit unsigned integer to a 16-bit unsigned integer.\n  ///\n  /// Traps on overflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat32.toNat16(123); // => 123 : Nat16\n  /// ```\n  public func toNat16(x : Nat32) : Nat16 {\n    Prim.nat32ToNat16(x)\n  };\n\n  /// Converts a 64-bit unsigned integer to a 32-bit unsigned integer.\n  ///\n  /// Traps on overflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat32.fromNat64(123); // => 123 : Nat32\n  /// ```\n  public func fromNat64(x : Nat64) : Nat32 {\n    Prim.nat64ToNat32(x)\n  };\n\n  /// Converts a 32-bit unsigned integer to a 64-bit unsigned integer.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat32.toNat64(123); // => 123 : Nat64\n  /// ```\n  public func toNat64(x : Nat32) : Nat64 {\n    Prim.nat32ToNat64(x)\n  };\n\n  /// Converts a signed integer with infinite precision to a 32-bit unsigned integer.\n  ///\n  /// Traps on overflow/underflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat32.fromIntWrap(123); // => 123 : Nat32\n  /// ```\n  public let fromIntWrap : Int -> Nat32 = Prim.intToNat32Wrap;\n\n  /// Converts `x` to its textual representation. Textual representation _do not_\n  /// contain underscores to represent commas.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat32.toText(1234); // => \"1234\" : Text\n  /// ```\n  public func toText(x : Nat32) : Text {\n    Nat.toText(toNat(x))\n  };\n\n  /// Returns the minimum of `x` and `y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat32.min(123, 456); // => 123 : Nat32\n  /// ```\n  public func min(x : Nat32, y : Nat32) : Nat32 {\n    if (x < y) { x } else { y }\n  };\n\n  /// Returns the maximum of `x` and `y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat32.max(123, 456); // => 456 : Nat32\n  /// ```\n  public func max(x : Nat32, y : Nat32) : Nat32 {\n    if (x < y) { y } else { x }\n  };\n\n  /// Equality function for Nat32 types.\n  /// This is equivalent to `x == y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat32.equal(1, 1); // => true\n  /// (1 : Nat32) == (1 : Nat32) // => true\n  /// ```\n  ///\n\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// import Buffer \"mo:base/Buffer\";\n  ///\n  /// let buffer1 = Buffer.Buffer<Nat32>(3);\n  /// let buffer2 = Buffer.Buffer<Nat32>(3);\n  /// Buffer.equal(buffer1, buffer2, Nat32.equal) // => true\n  /// ```\n  public func equal(x : Nat32, y : Nat32) : Bool { x == y };\n\n  /// Inequality function for Nat32 types.\n  /// This is equivalent to `x != y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat32.notEqual(1, 2); // => true\n  /// (1 : Nat32) != (2 : Nat32) // => true\n  /// ```\n  ///\n\n  public func notEqual(x : Nat32, y : Nat32) : Bool { x != y };\n\n  /// \"Less than\" function for Nat32 types.\n  /// This is equivalent to `x < y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat32.less(1, 2); // => true\n  /// (1 : Nat32) < (2 : Nat32) // => true\n  /// ```\n  ///\n\n  public func less(x : Nat32, y : Nat32) : Bool { x < y };\n\n  /// \"Less than or equal\" function for Nat32 types.\n  /// This is equivalent to `x <= y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat32.lessOrEqual(1, 2); // => true\n  /// (1 : Nat32) <= (2 : Nat32) // => true\n  /// ```\n  ///\n\n  public func lessOrEqual(x : Nat32, y : Nat32) : Bool { x <= y };\n\n  /// \"Greater than\" function for Nat32 types.\n  /// This is equivalent to `x > y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat32.greater(2, 1); // => true\n  /// (2 : Nat32) > (1 : Nat32) // => true\n  /// ```\n  ///\n\n  public func greater(x : Nat32, y : Nat32) : Bool { x > y };\n\n  /// \"Greater than or equal\" function for Nat32 types.\n  /// This is equivalent to `x >= y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat32.greaterOrEqual(2, 1); // => true\n  /// (2 : Nat32) >= (1 : Nat32) // => true\n  /// ```\n  ///\n\n  public func greaterOrEqual(x : Nat32, y : Nat32) : Bool { x >= y };\n\n  /// General purpose comparison function for `Nat32`. Returns the `Order` (\n  /// either `#less`, `#equal`, or `#greater`) of comparing `x` with `y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat32.compare(2, 3) // => #less\n  /// ```\n  ///\n  /// This function can be used as value for a high order function, such as a sort function.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// import Array \"mo:base/Array\";\n  /// Array.sort([2, 3, 1] : [Nat32], Nat32.compare) // => [1, 2, 3]\n  /// ```\n  public func compare(x : Nat32, y : Nat32) : { #less; #equal; #greater } {\n    if (x < y) { #less } else if (x == y) { #equal } else { #greater }\n  };\n\n  /// Returns the sum of `x` and `y`, `x + y`.\n  /// Traps on overflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat32.add(1, 2); // => 3\n  /// (1 : Nat32) + (2 : Nat32) // => 3\n  /// ```\n  ///\n\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// import Array \"mo:base/Array\";\n  /// Array.foldLeft<Nat32, Nat32>([2, 3, 1], 0, Nat32.add) // => 6\n  /// ```\n  public func add(x : Nat32, y : Nat32) : Nat32 { x + y };\n\n  /// Returns the difference of `x` and `y`, `x - y`.\n  /// Traps on underflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat32.sub(2, 1); // => 1\n  /// (2 : Nat32) - (1 : Nat32) // => 1\n  /// ```\n  ///\n\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// import Array \"mo:base/Array\";\n  /// Array.foldLeft<Nat32, Nat32>([2, 3, 1], 20, Nat32.sub) // => 14\n  /// ```\n  public func sub(x : Nat32, y : Nat32) : Nat32 { x - y };\n\n  /// Returns the product of `x` and `y`, `x * y`.\n  /// Traps on overflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat32.mul(2, 3); // => 6\n  /// (2 : Nat32) * (3 : Nat32) // => 6\n  /// ```\n  ///\n\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// import Array \"mo:base/Array\";\n  /// Array.foldLeft<Nat32, Nat32>([2, 3, 1], 1, Nat32.mul) // => 6\n  /// ```\n  public func mul(x : Nat32, y : Nat32) : Nat32 { x * y };\n\n  /// Returns the division of `x by y`, `x / y`.\n  /// Traps when `y` is zero.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat32.div(6, 2); // => 3\n  /// (6 : Nat32) / (2 : Nat32) // => 3\n  /// ```\n  ///\n\n  public func div(x : Nat32, y : Nat32) : Nat32 { x / y };\n\n  /// Returns the remainder of `x` divided by `y`, `x % y`.\n  /// Traps when `y` is zero.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat32.rem(6, 4); // => 2\n  /// (6 : Nat32) % (4 : Nat32) // => 2\n  /// ```\n  ///\n\n  public func rem(x : Nat32, y : Nat32) : Nat32 { x % y };\n\n  /// Returns `x` to the power of `y`, `x ** y`. Traps on overflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat32.pow(2, 3); // => 8\n  /// (2 : Nat32) ** (3 : Nat32) // => 8\n  /// ```\n  ///\n\n  public func pow(x : Nat32, y : Nat32) : Nat32 { x ** y };\n\n  /// Returns the bitwise negation of `x`, `^x`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat32.bitnot(0) // => 4294967295\n  /// ^(0 : Nat32) // => 4294967295\n  /// ```\n  ///\n\n  public func bitnot(x : Nat32) : Nat32 { ^x };\n\n  /// Returns the bitwise and of `x` and `y`, `x & y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat32.bitand(1, 3); // => 1\n  /// (1 : Nat32) & (3 : Nat32) // => 1\n  /// ```\n  ///\n\n  public func bitand(x : Nat32, y : Nat32) : Nat32 { x & y };\n\n  /// Returns the bitwise or of `x` and `y`, `x | y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat32.bitor(1, 3); // => 3\n  /// (1 : Nat32) | (3 : Nat32) // => 3\n  /// ```\n  ///\n\n  public func bitor(x : Nat32, y : Nat32) : Nat32 { x | y };\n\n  /// Returns the bitwise exclusive or of `x` and `y`, `x ^ y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat32.bitxor(1, 3); // => 2\n  /// (1 : Nat32) ^ (3 : Nat32) // => 2\n  /// ```\n  ///\n\n  public func bitxor(x : Nat32, y : Nat32) : Nat32 { x ^ y };\n\n  /// Returns the bitwise shift left of `x` by `y`, `x << y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat32.bitshiftLeft(1, 3); // => 8\n  /// (1 : Nat32) << (3 : Nat32) // => 8\n  /// ```\n  ///\n\n  public func bitshiftLeft(x : Nat32, y : Nat32) : Nat32 { x << y };\n\n  /// Returns the bitwise shift right of `x` by `y`, `x >> y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat32.bitshiftRight(8, 3); // => 1\n  /// (8 : Nat32) >> (3 : Nat32) // => 1\n  /// ```\n  ///\n\n  public func bitshiftRight(x : Nat32, y : Nat32) : Nat32 { x >> y };\n\n  /// Returns the bitwise rotate left of `x` by `y`, `x <<> y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat32.bitrotLeft(1, 3); // => 8\n  /// (1 : Nat32) <<> (3 : Nat32) // => 8\n  /// ```\n  ///\n\n  public func bitrotLeft(x : Nat32, y : Nat32) : Nat32 { x <<> y };\n\n  /// Returns the bitwise rotate right of `x` by `y`, `x <>> y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat32.bitrotRight(1, 1); // => 2147483648\n  /// (1 : Nat32) <>> (1 : Nat32) // => 2147483648\n  /// ```\n  ///\n\n  public func bitrotRight(x : Nat32, y : Nat32) : Nat32 { x <>> y };\n\n  /// Returns the value of bit `p mod 32` in `x`, `(x & 2^(p mod 32)) == 2^(p mod 32)`.\n  /// This is equivalent to checking if the `p`-th bit is set in `x`, using 0 indexing.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat32.bittest(5, 2); // => true\n  /// ```\n  public func bittest(x : Nat32, p : Nat) : Bool {\n    Prim.btstNat32(x, Prim.natToNat32(p))\n  };\n\n  /// Returns the value of setting bit `p mod 32` in `x` to `1`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat32.bitset(5, 1); // => 7\n  /// ```\n  public func bitset(x : Nat32, p : Nat) : Nat32 {\n    x | (1 << Prim.natToNat32(p))\n  };\n\n  /// Returns the value of clearing bit `p mod 32` in `x` to `0`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat32.bitclear(5, 2); // => 1\n  /// ```\n  public func bitclear(x : Nat32, p : Nat) : Nat32 {\n    x & ^(1 << Prim.natToNat32(p))\n  };\n\n  /// Returns the value of flipping bit `p mod 32` in `x`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat32.bitflip(5, 2); // => 1\n  /// ```\n  public func bitflip(x : Nat32, p : Nat) : Nat32 {\n    x ^ (1 << Prim.natToNat32(p))\n  };\n\n  /// Returns the count of non-zero bits in `x`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat32.bitcountNonZero(5); // => 2\n  /// ```\n  public let bitcountNonZero : (x : Nat32) -> Nat32 = Prim.popcntNat32;\n\n  /// Returns the count of leading zero bits in `x`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat32.bitcountLeadingZero(5); // => 29\n  /// ```\n  public let bitcountLeadingZero : (x : Nat32) -> Nat32 = Prim.clzNat32;\n\n  /// Returns the count of trailing zero bits in `x`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat32.bitcountTrailingZero(16); // => 4\n  /// ```\n  public let bitcountTrailingZero : (x : Nat32) -> Nat32 = Prim.ctzNat32;\n\n  /// Returns the upper (i.e. most significant), lower (least significant)\n  /// and in-between bytes of `x`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat32.explode 0xaa885511 // => (170, 136, 85, 17)\n  /// ```\n  public let explode : (x : Nat32) -> (msb : Nat8, Nat8, Nat8, lsb : Nat8) = Prim.explodeNat32;\n\n  /// Returns the sum of `x` and `y`, `x +% y`. Wraps on overflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat32.addWrap(4294967295, 1); // => 0\n  /// (4294967295 : Nat32) +% (1 : Nat32) // => 0\n  /// ```\n  ///\n  /// :::info\n  /// The reason why this function is defined in this library (in addition\n  /// to the existing `+%` operator) is so that you can use it as a function\n  /// value to pass to a higher order function. It is not possible to use `+%`\n  /// as a function value at the moment.\n  /// :::\n  public func addWrap(x : Nat32, y : Nat32) : Nat32 { x +% y };\n\n  /// Returns the difference of `x` and `y`, `x -% y`. Wraps on underflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat32.subWrap(0, 1); // => 4294967295\n  /// (0 : Nat32) -% (1 : Nat32) // => 4294967295\n  /// ```\n  ///\n\n  public func subWrap(x : Nat32, y : Nat32) : Nat32 { x -% y };\n\n  /// Returns the product of `x` and `y`, `x *% y`. Wraps on overflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat32.mulWrap(2147483648, 2); // => 0\n  /// (2147483648 : Nat32) *% (2 : Nat32) // => 0\n  /// ```\n  ///\n\n  public func mulWrap(x : Nat32, y : Nat32) : Nat32 { x *% y };\n\n  /// Returns `x` to the power of `y`, `x **% y`. Wraps on overflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat32.powWrap(2, 32); // => 0\n  /// (2 : Nat32) **% (32 : Nat32) // => 0\n  /// ```\n  ///\n\n  public func powWrap(x : Nat32, y : Nat32) : Nat32 { x **% y };\n\n}\n"},"OrderedSet.mo":{"content":"/// Stable ordered set implemented as a red-black tree.\n///\n/// A red-black tree is a balanced binary search tree ordered by the elements.\n///\n/// The tree data structure internally colors each of its nodes either red or black,\n/// and uses this information to balance the tree during the modifying operations.\n///\n/// | Runtime   | Space |\n/// |----------|------------|\n/// | `O(log(n))` (worst case per insertion, removal, or retrieval)  | `O(n)` (for storing the entire tree) |\n///\n/// `n` denotes the number of key-value entries (i.e. nodes) stored in the tree.\n///\n/// :::note Garbage collection\n///\n/// Unless stated otherwise, operations that iterate over or modify the map (such as insertion, deletion, traversal, and transformation) may create temporary objects with worst-case space usage of `O(log(n))` or `O(n)`. These objects are short-lived and will be collected by the garbage collector automatically.\n///\n/// :::\n///\n/// :::note Assumptions\n///\n/// Runtime and space complexity assumes that `compare`, `equal`, and other functions execute in `O(1)` time and space.\n/// :::\n///\n/// :::info Credits\n///\n/// The core of this implementation is derived from:\n///\n/// * Ken Friis Larsen's [RedBlackMap.sml](https://github.com/kfl/mosml/blob/master/src/mosmllib/Redblackmap.sml), which itself is based on:\n/// * Stefan Kahrs, \"Red-black trees with types\", Journal of Functional Programming, 11(4): 425-432 (2001), [version 1 in web appendix](http://www.cs.ukc.ac.uk/people/staff/smk/redblack/rb.html).\n/// :::\n///\nimport Debug \"Debug\";\nimport Buffer \"Buffer\";\nimport I \"Iter\";\nimport List \"List\";\nimport Nat \"Nat\";\nimport O \"Order\";\n\nmodule {\n  /// Red-black tree of nodes with ordered set elements.\n  /// Leaves are considered implicitly black.\n  type Tree<T> = {\n    #red : (Tree<T>, T, Tree<T>);\n    #black : (Tree<T>, T, Tree<T>);\n    #leaf\n  };\n\n  /// Ordered collection of unique elements of the generic type `T`.\n  /// If type `T` is stable then `Set<T>` is also stable.\n  /// To ensure that property the `Set<T>` does not have any methods,\n  /// instead they are gathered in the functor-like class `Operations` (see example there).\n  public type Set<T> = { size : Nat; root : Tree<T> };\n\n  /// Class that captures element type `T` along with its ordering function `compare`\n  /// and provide all operations to work with a set of type `Set<T>`.\n  ///\n  /// An instance object should be created once as a canister field to ensure\n  /// that the same ordering function is used for every operation.\n  ///\n  /// Example:\n  /// ```motoko\n  /// import Set \"mo:base/OrderedSet\";\n  /// import Nat \"mo:base/Nat\";\n  ///\n  /// actor {\n  ///   let natSet = Set.Make<Nat>(Nat.compare); // : Operations<Nat>\n  ///   stable var usedIds : Set.Set<Nat> = natSet.empty();\n  ///\n  ///   public func createId(id : Nat) : async () {\n  ///     usedIds := natSet.put(usedIds, id);\n  ///   };\n  ///\n  ///   public func idIsUsed(id: Nat) : async Bool {\n  ///      natSet.contains(usedIds, id)\n  ///   }\n  /// }\n  /// ```\n  public class Operations<T>(compare : (T, T) -> O.Order) {\n\n    /// Returns a new Set, containing all entries given by the iterator `i`.\n    /// If there are multiple identical entries only one is taken.\n    ///\n    /// Example:\n    /// ```motoko\n    /// import Set \"mo:base/OrderedSet\";\n    /// import Nat \"mo:base/Nat\";\n    /// import Iter \"mo:base/Iter\";\n    /// import Debug \"mo:base/Debug\";\n    ///\n    /// let natSet = Set.Make<Nat>(Nat.compare);\n    /// let set = natSet.fromIter(Iter.fromArray([0, 2, 1]));\n    ///\n    /// Debug.print(debug_show(Iter.toArray(natSet.vals(set))));\n    /// // [0, 1, 2]\n    /// ```\n    ///\n    /// | Runtime   | Space |\n    /// |----------|------------|\n    /// | `O(n * log(n))`  | `O(n)` (retained memory + garbage) |\n    public func fromIter(i : I.Iter<T>) : Set<T> {\n      var set = empty() : Set<T>;\n      for (val in i) {\n        set := Internal.put(set, compare, val)\n      };\n      set\n    };\n\n    /// Insert the value `value` into the set `s`. Has no effect if `value` is already\n    /// present in the set. Returns a modified set.\n    ///\n    /// Example:\n    /// ```motoko\n    /// import Set \"mo:base/OrderedSet\";\n    /// import Nat \"mo:base/Nat\";\n    /// import Iter \"mo:base/Iter\";\n    /// import Debug \"mo:base/Debug\";\n    ///\n    /// let natSet = Set.Make<Nat>(Nat.compare);\n    /// var set = natSet.empty();\n    ///\n    /// set := natSet.put(set, 0);\n    /// set := natSet.put(set, 2);\n    /// set := natSet.put(set, 1);\n    ///\n    /// Debug.print(debug_show(Iter.toArray(natSet.vals(set))));\n    /// // [0, 1, 2]\n    /// ```\n    ///\n    /// Runtime: `O(log(n))`.\n    /// Space: `O(log(n))`.\n    /// where `n` denotes the number of elements stored in the set and\n    /// assuming that the `compare` function implements an `O(1)` comparison.\n    ///\n    /// Note: The returned set shares with the `s` most of the tree nodes.\n    /// Garbage collecting one of sets (e.g. after an assignment `m := natSet.delete(m, k)`)\n    /// causes collecting `O(log(n))` nodes.\n    public func put(s : Set<T>, value : T) : Set<T> = Internal.put(s, compare, value);\n\n    /// Deletes the value `value` from the set `s`. Has no effect if `value` is not\n    /// present in the set. Returns modified set.\n    ///\n    /// Example:\n    /// ```motoko\n    /// import Set \"mo:base/OrderedSet\";\n    /// import Nat \"mo:base/Nat\";\n    /// import Iter \"mo:base/Iter\";\n    /// import Debug \"mo:base/Debug\";\n    ///\n    /// let natSet = Set.Make<Nat>(Nat.compare);\n    /// let set = natSet.fromIter(Iter.fromArray([0, 2, 1]));\n    ///\n    /// Debug.print(debug_show(Iter.toArray(natSet.vals(natSet.delete(set, 1)))));\n    /// Debug.print(debug_show(Iter.toArray(natSet.vals(natSet.delete(set, 42)))));\n    /// // [0, 2]\n    /// // [0, 1, 2]\n    /// ```\n    ///\n    /// | Runtime     | Space         |\n    /// |-------------|---------------|\n    /// | `O(log(n))` | `O(log(n))`   |\n    public func delete(s : Set<T>, value : T) : Set<T> = Internal.delete(s, compare, value);\n\n    /// Test if the set 's' contains a given element.\n    ///\n    /// Example:\n    /// ```motoko\n    /// import Set \"mo:base/OrderedSet\";\n    /// import Nat \"mo:base/Nat\";\n    /// import Iter \"mo:base/Iter\";\n    /// import Debug \"mo:base/Debug\";\n    ///\n    /// let natSet = Set.Make<Nat>(Nat.compare);\n    /// let set = natSet.fromIter(Iter.fromArray([0, 2, 1]));\n    ///\n    /// Debug.print(debug_show natSet.contains(set, 1)); // => true\n    /// Debug.print(debug_show natSet.contains(set, 42)); // => false\n    /// ```\n    ///\n    /// | Runtime     | Space         |\n    /// |-------------|---------------|\n    /// | `O(log(n))` | `O(1)`   |\n    public func contains(s : Set<T>, value : T) : Bool = Internal.contains(s.root, compare, value);\n\n    /// Get a maximal element of the set `s` if it is not empty, otherwise returns `null`\n    ///\n    /// Example:\n    /// ```motoko\n    /// import Set \"mo:base/OrderedSet\";\n    /// import Nat \"mo:base/Nat\";\n    /// import Iter \"mo:base/Iter\";\n    /// import Debug \"mo:base/Debug\";\n    ///\n    /// let natSet = Set.Make<Nat>(Nat.compare);\n    /// let s1 = natSet.fromIter(Iter.fromArray([0, 2, 1]));\n    /// let s2 = natSet.empty();\n    ///\n    /// Debug.print(debug_show(natSet.max(s1))); // => ?2\n    /// Debug.print(debug_show(natSet.max(s2))); // => null\n    /// ```\n    ///\n    /// | Runtime     | Space         |\n    /// |-------------|---------------|\n    /// | `O(log(n))` | `O(1)`   |\n    public func max(s : Set<T>) : ?T = Internal.max(s.root);\n\n    /// Get a minimal element of the set `s` if it is not empty, otherwise returns `null`\n    ///\n    /// Example:\n    /// ```motoko\n    /// import Set \"mo:base/OrderedSet\";\n    /// import Nat \"mo:base/Nat\";\n    /// import Iter \"mo:base/Iter\";\n    /// import Debug \"mo:base/Debug\";\n    ///\n    /// let natSet = Set.Make<Nat>(Nat.compare);\n    /// let s1 = natSet.fromIter(Iter.fromArray([0, 2, 1]));\n    /// let s2 = natSet.empty();\n    ///\n    /// Debug.print(debug_show(natSet.min(s1))); // => ?0\n    /// Debug.print(debug_show(natSet.min(s2))); // => null\n    /// ```\n    ///\n    /// | Runtime     | Space         |\n    /// |-------------|---------------|\n    /// | `O(log(n))` | `O(log(1))`   |\n    public func min(s : Set<T>) : ?T = Internal.min(s.root);\n\n    /// [Set union](https://en.wikipedia.org/wiki/Union_(set_theory)) operation.\n    ///\n    /// Example:\n    /// ```motoko\n    /// import Set \"mo:base/OrderedSet\";\n    /// import Nat \"mo:base/Nat\";\n    /// import Iter \"mo:base/Iter\";\n    /// import Debug \"mo:base/Debug\";\n    ///\n    /// let natSet = Set.Make<Nat>(Nat.compare);\n    /// let set1 = natSet.fromIter(Iter.fromArray([0, 1, 2]));\n    /// let set2 = natSet.fromIter(Iter.fromArray([2, 3, 4]));\n    ///\n    /// Debug.print(debug_show Iter.toArray(natSet.vals(natSet.union(set1, set2))));\n    /// // [0, 1, 2, 3, 4]\n    /// ```\n    ///\n    /// | Runtime     | Space         |\n    /// |-------------|---------------|\n    /// | `O(m* log(n))` | `O(m)`retained + garbage   |\n    public func union(s1 : Set<T>, s2 : Set<T>) : Set<T> {\n      if (size(s1) < size(s2)) {\n        foldLeft(s1, s2, func(acc : Set<T>, elem : T) : Set<T> { Internal.put(acc, compare, elem) })\n      } else {\n        foldLeft(s2, s1, func(acc : Set<T>, elem : T) : Set<T> { Internal.put(acc, compare, elem) })\n      }\n    };\n\n    /// [Set intersection](https://en.wikipedia.org/wiki/Intersection_(set_theory)) operation.\n    ///\n    /// Example:\n    /// ```motoko\n    /// import Set \"mo:base/OrderedSet\";\n    /// import Nat \"mo:base/Nat\";\n    /// import Iter \"mo:base/Iter\";\n    /// import Debug \"mo:base/Debug\";\n    ///\n    /// let natSet = Set.Make<Nat>(Nat.compare);\n    /// let set1 = natSet.fromIter(Iter.fromArray([0, 1, 2]));\n    /// let set2 = natSet.fromIter(Iter.fromArray([1, 2, 3]));\n    ///\n    /// Debug.print(debug_show Iter.toArray(natSet.vals(natSet.intersect(set1, set2))));\n    /// // [1, 2]\n    /// ```\n    ///\n    /// | Runtime     | Space         |\n    /// |-------------|---------------|\n    /// | `O(m* log(n))` | `O(m)`retained + garbage   |\n    ///\n    /// Note: Creates `O(m)` temporary objects that will be collected as garbage.\n    public func intersect(s1 : Set<T>, s2 : Set<T>) : Set<T> {\n      let elems = Buffer.Buffer<T>(Nat.min(Nat.min(s1.size, s2.size), 100));\n      if (s1.size < s2.size) {\n        Internal.iterate(\n          s1.root,\n          func(x : T) {\n            if (Internal.contains(s2.root, compare, x)) {\n              elems.add(x)\n            }\n          }\n        )\n      } else {\n        Internal.iterate(\n          s2.root,\n          func(x : T) {\n            if (Internal.contains(s1.root, compare, x)) {\n              elems.add(x)\n            }\n          }\n        )\n      };\n      { root = Internal.buildFromSorted(elems); size = elems.size() }\n    };\n\n    /// [Set difference](https://en.wikipedia.org/wiki/Difference_(set_theory)).\n    ///\n    /// Example:\n    /// ```motoko\n    /// import Set \"mo:base/OrderedSet\";\n    /// import Nat \"mo:base/Nat\";\n    /// import Iter \"mo:base/Iter\";\n    /// import Debug \"mo:base/Debug\";\n    ///\n    /// let natSet = Set.Make<Nat>(Nat.compare);\n    /// let set1 = natSet.fromIter(Iter.fromArray([0, 1, 2]));\n    /// let set2 = natSet.fromIter(Iter.fromArray([1, 2, 3]));\n    ///\n    /// Debug.print(debug_show Iter.toArray(natSet.vals(natSet.diff(set1, set2))));\n    /// // [0]\n    /// ```\n    ///\n    /// | Runtime     | Space         |\n    /// |-------------|---------------|\n    /// | `O(m* log(n))` | `O(m)`retained + garbage   |\n    public func diff(s1 : Set<T>, s2 : Set<T>) : Set<T> {\n      if (size(s1) < size(s2)) {\n        let elems = Buffer.Buffer<T>(Nat.min(s1.size, 100));\n        Internal.iterate(\n          s1.root,\n          func(x : T) {\n            if (not Internal.contains(s2.root, compare, x)) {\n              elems.add(x)\n            }\n          }\n        );\n        { root = Internal.buildFromSorted(elems); size = elems.size() }\n      } else {\n        foldLeft(\n          s2,\n          s1,\n          func(acc : Set<T>, elem : T) : Set<T> {\n            if (Internal.contains(acc.root, compare, elem)) {\n              Internal.delete(acc, compare, elem)\n            } else { acc }\n          }\n        )\n      }\n    };\n\n    /// Creates a new `Set` by applying `f` to each entry in the set `s`. Each element\n    /// `x` in the old set is transformed into a new entry `x2`, where\n    /// the new value `x2` is created by applying `f` to `x`.\n    /// The result set may be smaller than the original set due to duplicate elements.\n    ///\n    /// Example:\n    /// ```motoko\n    /// import Set \"mo:base/OrderedSet\";\n    /// import Nat \"mo:base/Nat\";\n    /// import Iter \"mo:base/Iter\";\n    /// import Debug \"mo:base/Debug\";\n    ///\n    /// let natSet = Set.Make<Nat>(Nat.compare);\n    /// let set = natSet.fromIter(Iter.fromArray([0, 1, 2, 3]));\n    ///\n    /// func f(x : Nat) : Nat = if (x < 2) { x } else { 0 };\n    ///\n    /// let resSet = natSet.map(set, f);\n    ///\n    /// Debug.print(debug_show(Iter.toArray(natSet.vals(resSet))));\n    /// // [0, 1]\n    /// ```\n    ///\n    /// Cost of mapping all the elements:\n    /// | Runtime     | Space         |\n    /// |-------------|---------------|\n    /// | `O(n* log(n))` | `O(n)`retained + garbage   |\n    ///\n    public func map<T1>(s : Set<T1>, f : T1 -> T) : Set<T> = Internal.foldLeft(s.root, empty(), func(acc : Set<T>, elem : T1) : Set<T> { Internal.put(acc, compare, f(elem)) });\n\n    /// Creates a new set by applying `f` to each element in the set `s`. For each element\n    /// `x` in the old set, if `f` evaluates to `null`, the element is discarded.\n    /// Otherwise, the entry is transformed into a new entry `x2`, where\n    /// the new value `x2` is the result of applying `f` to `x`.\n    ///\n    /// Example:\n    /// ```motoko\n    /// import Set \"mo:base/OrderedSet\";\n    /// import Nat \"mo:base/Nat\";\n    /// import Iter \"mo:base/Iter\";\n    /// import Debug \"mo:base/Debug\";\n    ///\n    /// let natSet = Set.Make<Nat>(Nat.compare);\n    /// let set = natSet.fromIter(Iter.fromArray([0, 1, 2, 3]));\n    ///\n    /// func f(x : Nat) : ?Nat {\n    ///   if(x == 0) {null}\n    ///   else { ?( x * 2 )}\n    /// };\n    ///\n    /// let newRbSet = natSet.mapFilter(set, f);\n    ///\n    /// Debug.print(debug_show(Iter.toArray(natSet.vals(newRbSet))));\n    /// // [2, 4, 6]\n    /// ```\n    ///\n    /// | Runtime     | Space         |\n    /// |-------------|---------------|\n    /// | `O(n* log(n))` | `O(n)`retained + garbage   |\n    public func mapFilter<T1>(s : Set<T1>, f : T1 -> ?T) : Set<T> {\n      func combine(acc : Set<T>, elem : T1) : Set<T> {\n        switch (f(elem)) {\n          case null { acc };\n          case (?elem2) {\n            Internal.put(acc, compare, elem2)\n          }\n        }\n      };\n      Internal.foldLeft(s.root, empty(), combine)\n    };\n\n    /// Test if `set1` is subset of `set2`.\n    ///\n    /// Example:\n    /// ```motoko\n    /// import Set \"mo:base/OrderedSet\";\n    /// import Nat \"mo:base/Nat\";\n    /// import Iter \"mo:base/Iter\";\n    /// import Debug \"mo:base/Debug\";\n    ///\n    /// let natSet = Set.Make<Nat>(Nat.compare);\n    /// let set1 = natSet.fromIter(Iter.fromArray([1, 2]));\n    /// let set2 = natSet.fromIter(Iter.fromArray([0, 2, 1]));\n    ///\n    /// Debug.print(debug_show natSet.isSubset(set1, set2)); // => true\n    /// ```\n    ///\n    /// | Runtime     | Space         |\n    /// |-------------|---------------|\n    /// | `O(n* log(n))` | `O(1)`   |\n    public func isSubset(s1 : Set<T>, s2 : Set<T>) : Bool {\n      if (s1.size > s2.size) { return false };\n      isSubsetHelper(s1.root, s2.root)\n    };\n\n    /// Test if two sets are equal.\n    ///\n    /// Example:\n    /// ```motoko\n    /// import Set \"mo:base/OrderedSet\";\n    /// import Nat \"mo:base/Nat\";\n    /// import Iter \"mo:base/Iter\";\n    /// import Debug \"mo:base/Debug\";\n    ///\n    /// let natSet = Set.Make<Nat>(Nat.compare);\n    /// let set1 = natSet.fromIter(Iter.fromArray([0, 2, 1]));\n    /// let set2 = natSet.fromIter(Iter.fromArray([1, 2]));\n    ///\n    /// Debug.print(debug_show natSet.equals(set1, set1)); // => true\n    /// Debug.print(debug_show natSet.equals(set1, set2)); // => false\n    /// ```\n    ///\n    /// | Runtime     | Space         |\n    /// |-------------|---------------|\n    /// | `O(m * log(n))` | `O(1)`   |\n    public func equals(s1 : Set<T>, s2 : Set<T>) : Bool {\n      if (s1.size != s2.size) { return false };\n      isSubsetHelper(s1.root, s2.root)\n    };\n\n    func isSubsetHelper(t1 : Tree<T>, t2 : Tree<T>) : Bool {\n      switch (t1, t2) {\n        case (#leaf, _) { true };\n        case (_, #leaf) { false };\n        case ((#red(t1l, x1, t1r) or #black(t1l, x1, t1r)), (#red(t2l, x2, t2r)) or #black(t2l, x2, t2r)) {\n          switch (compare(x1, x2)) {\n            case (#equal) {\n              isSubsetHelper(t1l, t2l) and isSubsetHelper(t1r, t2r)\n            };\n            // x1 < x2 ==> x1 \\in t2l /\\ t1l \\subset t2l\n            case (#less) {\n              Internal.contains(t2l, compare, x1) and isSubsetHelper(t1l, t2l) and isSubsetHelper(t1r, t2)\n            };\n            // x2 < x1 ==> x1 \\in t2r /\\ t1r \\subset t2r\n            case (#greater) {\n              Internal.contains(t2r, compare, x1) and isSubsetHelper(t1l, t2) and isSubsetHelper(t1r, t2r)\n            }\n          }\n        }\n      }\n    };\n\n    /// Returns an Iterator (`Iter`) over the elements of the set.\n    /// Iterator provides a single method `next()`, which returns\n    /// elements in ascending order, or `null` when out of elements to iterate over.\n    ///\n    /// Example:\n    /// ```motoko\n    /// import Set \"mo:base/OrderedSet\";\n    /// import Nat \"mo:base/Nat\";\n    /// import Iter \"mo:base/Iter\";\n    /// import Debug \"mo:base/Debug\";\n    ///\n    /// let natSet = Set.Make<Nat>(Nat.compare);\n    /// let set = natSet.fromIter(Iter.fromArray([0, 2, 1]));\n    ///\n    /// Debug.print(debug_show(Iter.toArray(natSet.vals(set))));\n    /// // [0, 1, 2]\n    /// ```\n\n    /// | Runtime     | Space         |\n    /// |-------------|---------------|\n    /// | `O(n)` | `O(log(n))` retained + garbage  |\n    public func vals(s : Set<T>) : I.Iter<T> = Internal.iter(s.root, #fwd);\n\n    /// Same as `vals()` but iterates over elements of the set `s` in the descending order.\n    ///\n    /// Example:\n    /// ```motoko\n    /// import Set \"mo:base/OrderedSet\";\n    /// import Nat \"mo:base/Nat\";\n    /// import Iter \"mo:base/Iter\";\n    /// import Debug \"mo:base/Debug\";\n    ///\n    /// let natSet = Set.Make<Nat>(Nat.compare);\n    /// let set = natSet.fromIter(Iter.fromArray([0, 2, 1]));\n    ///\n    /// Debug.print(debug_show(Iter.toArray(natSet.valsRev(set))));\n    /// // [2, 1, 0]\n    /// ```\n\n    /// | Runtime     | Space         |\n    /// |-------------|---------------|\n    /// | `O(n)` | `O(log(n))` retained + garbage  |\n    public func valsRev(s : Set<T>) : I.Iter<T> = Internal.iter(s.root, #bwd);\n\n    /// Create a new empty Set.\n    ///\n    /// Example:\n    /// ```motoko\n    /// import Set \"mo:base/OrderedSet\";\n    /// import Nat \"mo:base/Nat\";\n    /// import Debug \"mo:base/Debug\";\n    ///\n    /// let natSet = Set.Make<Nat>(Nat.compare);\n    /// let set = natSet.empty();\n    ///\n    /// Debug.print(debug_show(natSet.size(set))); // => 0\n    /// ```\n    ///\n    /// Cost of empty set creation\n    /// Runtime: `O(1)`.\n    /// Space: `O(1)`\n    public func empty() : Set<T> = { root = #leaf; size = 0 };\n\n    /// Returns the number of elements in the set.\n    ///\n    /// Example:\n    /// ```motoko\n    /// import Set \"mo:base/OrderedSet\";\n    /// import Nat \"mo:base/Nat\";\n    /// import Iter \"mo:base/Iter\";\n    /// import Debug \"mo:base/Debug\";\n    ///\n    /// let natSet = Set.Make<Nat>(Nat.compare);\n    /// let set = natSet.fromIter(Iter.fromArray([0, 2, 1]));\n    ///\n    /// Debug.print(debug_show(natSet.size(set))); // => 3\n    /// ```\n    ///\n    /// | Runtime     | Space         |\n    /// |-------------|---------------|\n    /// | `O(1)` | `O(1)` |\n    public func size(s : Set<T>) : Nat = s.size;\n\n    /// Collapses the elements in `set` into a single value by starting with `base`\n    /// and progessively combining elements into `base` with `combine`. Iteration runs\n    /// left to right.\n    ///\n    /// Example:\n    /// ```motoko\n    /// import Set \"mo:base/OrderedSet\";\n    /// import Nat \"mo:base/Nat\";\n    /// import Iter \"mo:base/Iter\";\n    /// import Debug \"mo:base/Debug\";\n    ///\n    /// let natSet = Set.Make<Nat>(Nat.compare);\n    /// let set = natSet.fromIter(Iter.fromArray([0, 2, 1]));\n    ///\n    /// func folder(accum : Nat, val : Nat) : Nat = val + accum;\n    ///\n    /// Debug.print(debug_show(natSet.foldLeft(set, 0, folder)));\n    /// // 3\n    /// ```\n    ///\n\n    /// | Runtime | Space                        |\n    /// |---------|------------------------------|\n    /// | `O(n)`  | Depends on `combine` + `O(n)` garbage |\n    public func foldLeft<Accum>(\n      set : Set<T>,\n      base : Accum,\n      combine : (Accum, T) -> Accum\n    ) : Accum = Internal.foldLeft(set.root, base, combine);\n\n    /// Collapses the elements in `set` into a single value by starting with `base`\n    /// and progessively combining elements into `base` with `combine`. Iteration runs\n    /// right to left.\n    ///\n    /// Example:\n    /// ```motoko\n    /// import Set \"mo:base/OrderedSet\";\n    /// import Nat \"mo:base/Nat\";\n    /// import Iter \"mo:base/Iter\";\n    /// import Debug \"mo:base/Debug\";\n    ///\n    /// let natSet = Set.Make<Nat>(Nat.compare);\n    /// let set = natSet.fromIter(Iter.fromArray([0, 2, 1]));\n    ///\n    /// func folder(val : Nat, accum : Nat) : Nat = val + accum;\n    ///\n    /// Debug.print(debug_show(natSet.foldRight(set, 0, folder)));\n    /// // 3\n    /// ```\n    ///\n\n    /// | Runtime | Space                        |\n    /// |---------|------------------------------|\n    /// | `O(n)`  | Depends on `combine` + `O(n)` garbage |\n    public func foldRight<Accum>(\n      set : Set<T>,\n      base : Accum,\n      combine : (T, Accum) -> Accum\n    ) : Accum = Internal.foldRight(set.root, base, combine);\n\n    /// Test if the given set `s` is empty.\n    ///\n    /// Example:\n    /// ```motoko\n    /// import Set \"mo:base/OrderedSet\";\n    /// import Nat \"mo:base/Nat\";\n    /// import Debug \"mo:base/Debug\";\n    ///\n    /// let natSet = Set.Make<Nat>(Nat.compare);\n    /// let set = natSet.empty();\n    ///\n    /// Debug.print(debug_show(natSet.isEmpty(set))); // => true\n    /// ```\n    ///\n    /// Runtime: `O(1)`.\n    /// Space: `O(1)`.\n    public func isEmpty(s : Set<T>) : Bool {\n      switch (s.root) {\n        case (#leaf) { true };\n        case _ { false }\n      }\n    };\n\n    /// Test whether all values in the set `s` satisfy a given predicate `pred`.\n    ///\n    /// Example:\n    /// ```motoko\n    /// import Set \"mo:base/OrderedSet\";\n    /// import Nat \"mo:base/Nat\";\n    /// import Iter \"mo:base/Iter\";\n    /// import Debug \"mo:base/Debug\";\n    ///\n    /// let natSet = Set.Make<Nat>(Nat.compare);\n    /// let set = natSet.fromIter(Iter.fromArray([0, 2, 1]));\n    ///\n    /// Debug.print(debug_show(natSet.all(set, func (v) = (v < 10))));\n    /// // true\n    /// Debug.print(debug_show(natSet.all(set, func (v) = (v < 2))));\n    /// // false\n    /// ```\n    ///\n    /// | Runtime | Space                        |\n    /// |---------|------------------------------|\n    /// | `O(n)`  | `O(n)` |\n    public func all(s : Set<T>, pred : T -> Bool) : Bool = Internal.all(s.root, pred);\n\n    /// Test if there exists an element in the set `s` satisfying the given predicate `pred`.\n    ///\n    /// Example:\n    /// ```motoko\n    /// import Set \"mo:base/OrderedSet\";\n    /// import Nat \"mo:base/Nat\";\n    /// import Iter \"mo:base/Iter\";\n    /// import Debug \"mo:base/Debug\";\n    ///\n    /// let natSet = Set.Make<Nat>(Nat.compare);\n    /// let set = natSet.fromIter(Iter.fromArray([0, 2, 1]));\n    ///\n    /// Debug.print(debug_show(natSet.some(set, func (v) = (v >= 3))));\n    /// // false\n    /// Debug.print(debug_show(natSet.some(set, func (v) = (v >= 0))));\n    /// // true\n    /// ```\n    ///\n    /// | Runtime | Space                        |\n    /// |---------|------------------------------|\n    /// | `O(n)`  | `O(1)` |\n    public func some(s : Set<T>, pred : (T) -> Bool) : Bool = Internal.some(s.root, pred);\n\n    /// Test helper that check internal invariant for the given set `s`.\n    /// Raise an error (for a stack trace) if invariants are violated.\n    public func validate(s : Set<T>) : () {\n      Internal.validate(s, compare)\n    }\n  };\n\n  module Internal {\n    public func contains<T>(tree : Tree<T>, compare : (T, T) -> O.Order, elem : T) : Bool {\n      func f(t : Tree<T>, x : T) : Bool {\n        switch t {\n          case (#black(l, x1, r)) {\n            switch (compare(x, x1)) {\n              case (#less) { f(l, x) };\n              case (#equal) { true };\n              case (#greater) { f(r, x) }\n            }\n          };\n          case (#red(l, x1, r)) {\n            switch (compare(x, x1)) {\n              case (#less) { f(l, x) };\n              case (#equal) { true };\n              case (#greater) { f(r, x) }\n            }\n          };\n          case (#leaf) { false }\n        }\n      };\n      f(tree, elem)\n    };\n\n    public func max<V>(m : Tree<V>) : ?V {\n      func rightmost(m : Tree<V>) : V {\n        switch m {\n          case (#red(_, v, #leaf)) { v };\n          case (#red(_, _, r)) { rightmost(r) };\n          case (#black(_, v, #leaf)) { v };\n          case (#black(_, _, r)) { rightmost(r) };\n          case (#leaf) { Debug.trap \"OrderedSet.impossible\" }\n        }\n      };\n      switch m {\n        case (#leaf) { null };\n        case (_) { ?rightmost(m) }\n      }\n    };\n\n    public func min<V>(m : Tree<V>) : ?V {\n      func leftmost(m : Tree<V>) : V {\n        switch m {\n          case (#red(#leaf, v, _)) { v };\n          case (#red(l, _, _)) { leftmost(l) };\n          case (#black(#leaf, v, _)) { v };\n          case (#black(l, _, _)) { leftmost(l) };\n          case (#leaf) { Debug.trap \"OrderedSet.impossible\" }\n        }\n      };\n      switch m {\n        case (#leaf) { null };\n        case (_) { ?leftmost(m) }\n      }\n    };\n\n    public func all<V>(m : Tree<V>, pred : V -> Bool) : Bool {\n      switch m {\n        case (#red(l, v, r)) {\n          pred(v) and all(l, pred) and all(r, pred)\n        };\n        case (#black(l, v, r)) {\n          pred(v) and all(l, pred) and all(r, pred)\n        };\n        case (#leaf) { true }\n      }\n    };\n\n    public func some<V>(m : Tree<V>, pred : V -> Bool) : Bool {\n      switch m {\n        case (#red(l, v, r)) {\n          pred(v) or some(l, pred) or some(r, pred)\n        };\n        case (#black(l, v, r)) {\n          pred(v) or some(l, pred) or some(r, pred)\n        };\n        case (#leaf) { false }\n      }\n    };\n\n    public func iterate<V>(m : Tree<V>, f : V -> ()) {\n      switch m {\n        case (#leaf) {};\n        case (#black(l, v, r)) { iterate(l, f); f(v); iterate(r, f) };\n        case (#red(l, v, r)) { iterate(l, f); f(v); iterate(r, f) }\n      }\n    };\n\n    // build tree from elements arr[l]..arr[r-1]\n    public func buildFromSorted<V>(buf : Buffer.Buffer<V>) : Tree<V> {\n      var maxDepth = 0;\n      var maxSize = 1;\n      while (maxSize < buf.size()) {\n        maxDepth += 1;\n        maxSize += maxSize + 1\n      };\n      maxDepth := if (maxDepth == 0) { 1 } else { maxDepth }; // keep root black for 1 element tree\n      func buildFromSortedHelper(l : Nat, r : Nat, depth : Nat) : Tree<V> {\n        if (l + 1 == r) {\n          if (depth == maxDepth) {\n            return #red(#leaf, buf.get(l), #leaf)\n          } else {\n            return #black(#leaf, buf.get(l), #leaf)\n          }\n        };\n        if (l >= r) {\n          return #leaf\n        };\n        let m = (l + r) / 2;\n        return #black(\n          buildFromSortedHelper(l, m, depth +1),\n          buf.get(m),\n          buildFromSortedHelper(m +1, r, depth +1)\n        )\n      };\n      buildFromSortedHelper(0, buf.size(), 0)\n    };\n\n    type IterRep<T> = List.List<{ #tr : Tree<T>; #x : T }>;\n\n    type SetTraverser<T> = (Tree<T>, T, Tree<T>, IterRep<T>) -> IterRep<T>;\n\n    class IterSet<T>(tree : Tree<T>, setTraverser : SetTraverser<T>) {\n      var trees : IterRep<T> = ?(#tr(tree), null);\n      public func next() : ?T {\n        switch (trees) {\n          case (null) { null };\n          case (?(#tr(#leaf), ts)) {\n            trees := ts;\n            next()\n          };\n          case (?(#x(x), ts)) {\n            trees := ts;\n            ?x\n          };\n          case (?(#tr(#black(l, x, r)), ts)) {\n            trees := setTraverser(l, x, r, ts);\n            next()\n          };\n          case (?(#tr(#red(l, x, r)), ts)) {\n            trees := setTraverser(l, x, r, ts);\n            next()\n          }\n        }\n      }\n    };\n\n    public func iter<T>(s : Tree<T>, direction : { #fwd; #bwd }) : I.Iter<T> {\n      let turnLeftFirst : SetTraverser<T> = func(l, x, r, ts) {\n        ?(#tr(l), ?(#x(x), ?(#tr(r), ts)))\n      };\n\n      let turnRightFirst : SetTraverser<T> = func(l, x, r, ts) {\n        ?(#tr(r), ?(#x(x), ?(#tr(l), ts)))\n      };\n\n      switch direction {\n        case (#fwd) IterSet(s, turnLeftFirst);\n        case (#bwd) IterSet(s, turnRightFirst)\n      }\n    };\n\n    public func foldLeft<T, Accum>(\n      tree : Tree<T>,\n      base : Accum,\n      combine : (Accum, T) -> Accum\n    ) : Accum {\n      switch (tree) {\n        case (#leaf) { base };\n        case (#black(l, x, r)) {\n          let left = foldLeft(l, base, combine);\n          let middle = combine(left, x);\n          foldLeft(r, middle, combine)\n        };\n        case (#red(l, x, r)) {\n          let left = foldLeft(l, base, combine);\n          let middle = combine(left, x);\n          foldLeft(r, middle, combine)\n        }\n      }\n    };\n\n    public func foldRight<T, Accum>(\n      tree : Tree<T>,\n      base : Accum,\n      combine : (T, Accum) -> Accum\n    ) : Accum {\n      switch (tree) {\n        case (#leaf) { base };\n        case (#black(l, x, r)) {\n          let right = foldRight(r, base, combine);\n          let middle = combine(x, right);\n          foldRight(l, middle, combine)\n        };\n        case (#red(l, x, r)) {\n          let right = foldRight(r, base, combine);\n          let middle = combine(x, right);\n          foldRight(l, middle, combine)\n        }\n      }\n    };\n\n    func redden<T>(t : Tree<T>) : Tree<T> {\n      switch t {\n        case (#black(l, x, r)) { (#red(l, x, r)) };\n        case _ {\n          Debug.trap \"OrderedSet.red\"\n        }\n      }\n    };\n\n    func lbalance<T>(left : Tree<T>, x : T, right : Tree<T>) : Tree<T> {\n      switch (left, right) {\n        case (#red(#red(l1, x1, r1), x2, r2), r) {\n          #red(\n            #black(l1, x1, r1),\n            x2,\n            #black(r2, x, r)\n          )\n        };\n        case (#red(l1, x1, #red(l2, x2, r2)), r) {\n          #red(\n            #black(l1, x1, l2),\n            x2,\n            #black(r2, x, r)\n          )\n        };\n        case _ {\n          #black(left, x, right)\n        }\n      }\n    };\n\n    func rbalance<T>(left : Tree<T>, x : T, right : Tree<T>) : Tree<T> {\n      switch (left, right) {\n        case (l, #red(l1, x1, #red(l2, x2, r2))) {\n          #red(\n            #black(l, x, l1),\n            x1,\n            #black(l2, x2, r2)\n          )\n        };\n        case (l, #red(#red(l1, x1, r1), x2, r2)) {\n          #red(\n            #black(l, x, l1),\n            x1,\n            #black(r1, x2, r2)\n          )\n        };\n        case _ {\n          #black(left, x, right)\n        }\n      }\n    };\n\n    public func put<T>(\n      s : Set<T>,\n      compare : (T, T) -> O.Order,\n      elem : T\n    ) : Set<T> {\n      var newNodeIsCreated : Bool = false;\n      func ins(tree : Tree<T>) : Tree<T> {\n        switch tree {\n          case (#black(left, x, right)) {\n            switch (compare(elem, x)) {\n              case (#less) {\n                lbalance(ins left, x, right)\n              };\n              case (#greater) {\n                rbalance(left, x, ins right)\n              };\n              case (#equal) {\n                #black(left, x, right)\n              }\n            }\n          };\n          case (#red(left, x, right)) {\n            switch (compare(elem, x)) {\n              case (#less) {\n                #red(ins left, x, right)\n              };\n              case (#greater) {\n                #red(left, x, ins right)\n              };\n              case (#equal) {\n                #red(left, x, right)\n              }\n            }\n          };\n          case (#leaf) {\n            newNodeIsCreated := true;\n            #red(#leaf, elem, #leaf)\n          }\n        }\n      };\n      let newRoot = switch (ins(s.root)) {\n        case (#red(left, x, right)) {\n          #black(left, x, right)\n        };\n        case other { other }\n      };\n      {\n        root = newRoot;\n        size = if newNodeIsCreated { s.size + 1 } else { s.size }\n      }\n    };\n\n    func balLeft<T>(left : Tree<T>, x : T, right : Tree<T>) : Tree<T> {\n      switch (left, right) {\n        case (#red(l1, x1, r1), r) {\n          #red(#black(l1, x1, r1), x, r)\n        };\n        case (_, #black(l2, x2, r2)) {\n          rbalance(left, x, #red(l2, x2, r2))\n        };\n        case (_, #red(#black(l2, x2, r2), x3, r3)) {\n          #red(\n            #black(left, x, l2),\n            x2,\n            rbalance(r2, x3, redden r3)\n          )\n        };\n        case _ { Debug.trap \"balLeft\" }\n      }\n    };\n\n    func balRight<T>(left : Tree<T>, x : T, right : Tree<T>) : Tree<T> {\n      switch (left, right) {\n        case (l, #red(l1, x1, r1)) {\n          #red(l, x, #black(l1, x1, r1))\n        };\n        case (#black(l1, x1, r1), r) {\n          lbalance(#red(l1, x1, r1), x, r)\n        };\n        case (#red(l1, x1, #black(l2, x2, r2)), r3) {\n          #red(\n            lbalance(redden l1, x1, l2),\n            x2,\n            #black(r2, x, r3)\n          )\n        };\n        case _ { Debug.trap \"balRight\" }\n      }\n    };\n\n    func append<T>(left : Tree<T>, right : Tree<T>) : Tree<T> {\n      switch (left, right) {\n        case (#leaf, _) { right };\n        case (_, #leaf) { left };\n        case (\n          #red(l1, x1, r1),\n          #red(l2, x2, r2)\n        ) {\n          switch (append(r1, l2)) {\n            case (#red(l3, x3, r3)) {\n              #red(\n                #red(l1, x1, l3),\n                x3,\n                #red(r3, x2, r2)\n              )\n            };\n            case r1l2 {\n              #red(l1, x1, #red(r1l2, x2, r2))\n            }\n          }\n        };\n        case (t1, #red(l2, x2, r2)) {\n          #red(append(t1, l2), x2, r2)\n        };\n        case (#red(l1, x1, r1), t2) {\n          #red(l1, x1, append(r1, t2))\n        };\n        case (#black(l1, x1, r1), #black(l2, x2, r2)) {\n          switch (append(r1, l2)) {\n            case (#red(l3, x3, r3)) {\n              #red(\n                #black(l1, x1, l3),\n                x3,\n                #black(r3, x2, r2)\n              )\n            };\n            case r1l2 {\n              balLeft(\n                l1,\n                x1,\n                #black(r1l2, x2, r2)\n              )\n            }\n          }\n        }\n      }\n    };\n\n    public func delete<T>(s : Set<T>, compare : (T, T) -> O.Order, x : T) : Set<T> {\n      var changed : Bool = false;\n      func delNode(left : Tree<T>, x1 : T, right : Tree<T>) : Tree<T> {\n        switch (compare(x, x1)) {\n          case (#less) {\n            let newLeft = del left;\n            switch left {\n              case (#black(_, _, _)) {\n                balLeft(newLeft, x1, right)\n              };\n              case _ {\n                #red(newLeft, x1, right)\n              }\n            }\n          };\n          case (#greater) {\n            let newRight = del right;\n            switch right {\n              case (#black(_, _, _)) {\n                balRight(left, x1, newRight)\n              };\n              case _ {\n                #red(left, x1, newRight)\n              }\n            }\n          };\n          case (#equal) {\n            changed := true;\n            append(left, right)\n          }\n        }\n      };\n      func del(tree : Tree<T>) : Tree<T> {\n        switch tree {\n          case (#black(left, x1, right)) {\n            delNode(left, x1, right)\n          };\n          case (#red(left, x1, right)) {\n            delNode(left, x1, right)\n          };\n          case (#leaf) {\n            tree\n          }\n        }\n      };\n      let newRoot = switch (del(s.root)) {\n        case (#red(left, x1, right)) {\n          #black(left, x1, right)\n        };\n        case other { other }\n      };\n      {\n        root = newRoot;\n        size = if changed { s.size -1 } else { s.size }\n      }\n    };\n\n    // check binary search tree order of elements and black depth invariant of the RB-tree\n    public func validate<T>(s : Set<T>, comp : (T, T) -> O.Order) {\n      ignore blackDepth(s.root, comp)\n    };\n\n    func blackDepth<T>(node : Tree<T>, comp : (T, T) -> O.Order) : Nat {\n      func checkNode(left : Tree<T>, x1 : T, right : Tree<T>) : Nat {\n        checkElem(left, func(x : T) : Bool { comp(x, x1) == #less });\n        checkElem(right, func(x : T) : Bool { comp(x, x1) == #greater });\n        let leftBlacks = blackDepth(left, comp);\n        let rightBlacks = blackDepth(right, comp);\n        assert (leftBlacks == rightBlacks);\n        leftBlacks\n      };\n      switch node {\n        case (#leaf) 0;\n        case (#red(left, x1, right)) {\n          assert (not isRed(left));\n          assert (not isRed(right));\n          checkNode(left, x1, right)\n        };\n        case (#black(left, x1, right)) {\n          checkNode(left, x1, right) + 1\n        }\n      }\n    };\n\n    func isRed<T>(node : Tree<T>) : Bool {\n      switch node {\n        case (#red(_, _, _)) true;\n        case _ false\n      }\n    };\n\n    func checkElem<T>(node : Tree<T>, isValid : T -> Bool) {\n      switch node {\n        case (#leaf) {};\n        case (#black(_, elem, _)) {\n          assert (isValid(elem))\n        };\n        case (#red(_, elem, _)) {\n          assert (isValid(elem))\n        }\n      }\n    }\n  };\n\n  /// Create `OrderedSet.Operations` object capturing element type `T` and `compare` function.\n  /// It is an alias for the `Operations` constructor.\n  ///\n  /// Example:\n  /// ```motoko\n  /// import Set \"mo:base/OrderedSet\";\n  /// import Nat \"mo:base/Nat\";\n  ///\n  /// actor {\n  ///   let natSet = Set.Make<Nat>(Nat.compare);\n  ///   stable var set : Set.Set<Nat> = natSet.empty();\n  /// };\n  /// ```\n  public let Make : <T>(compare : (T, T) -> O.Order) -> Operations<T> = Operations\n}\n"},"Bool.mo":{"content":"/// Boolean type and operations.\n///\n/// While boolean operators `_ and _` and `_ or _` are short-circuiting,\n/// avoiding computation of the right argument when possible, the functions\n/// `logand(_, _)` and `logor(_, _)` are *strict* and will always evaluate *both*\n/// of their arguments.\n\nimport Prim \"mo:⛔\";\nmodule {\n\n  /// Booleans with constants `true` and `false`.\n  public type Bool = Prim.Types.Bool;\n\n  /// Conversion.\n  public func toText(x : Bool) : Text {\n    if x { \"true\" } else { \"false\" }\n  };\n\n  /// Returns `x and y`.\n  public func logand(x : Bool, y : Bool) : Bool { x and y };\n\n  /// Returns `x or y`.\n  public func logor(x : Bool, y : Bool) : Bool { x or y };\n\n  /// Returns exclusive or of `x` and `y`, `x != y`.\n  public func logxor(x : Bool, y : Bool) : Bool {\n    x != y\n  };\n\n  /// Returns `not x`.\n  public func lognot(x : Bool) : Bool { not x };\n\n  /// Returns `x == y`.\n  public func equal(x : Bool, y : Bool) : Bool { x == y };\n\n  /// Returns `x != y`.\n  public func notEqual(x : Bool, y : Bool) : Bool { x != y };\n\n  /// Returns the order of `x` and `y`, where `false < true`.\n  public func compare(x : Bool, y : Bool) : { #less; #equal; #greater } {\n    if (x == y) { #equal } else if (x) { #greater } else { #less }\n  };\n\n}\n"},"Char.mo":{"content":"import Prim \"mo:⛔\";\nmodule {\n\n  /// Characters represented as Unicode code points.\n  public type Char = Prim.Types.Char;\n\n  /// Convert character `c` to a word containing its Unicode scalar value.\n  public let toNat32 : (c : Char) -> Nat32 = Prim.charToNat32;\n\n  /// Convert `w` to a character.\n  /// Traps if `w` is not a valid Unicode scalar value.\n  /// Value `w` is valid if, and only if, `w < 0xD800 or (0xE000 <= w and w <= 0x10FFFF)`.\n  public let fromNat32 : (w : Nat32) -> Char = Prim.nat32ToChar;\n\n  /// Convert character `c` to single character text.\n  public let toText : (c : Char) -> Text = Prim.charToText;\n\n  // Not exposed pending multi-char implementation.\n  private let _toUpper : (c : Char) -> Char = Prim.charToUpper;\n\n  // Not exposed pending multi-char implementation.\n  private let _toLower : (c : Char) -> Char = Prim.charToLower;\n\n  /// Returns `true` when `c` is a decimal digit between `0` and `9`, otherwise `false`.\n  public func isDigit(c : Char) : Bool {\n    Prim.charToNat32(c) -% Prim.charToNat32('0') <= (9 : Nat32)\n  };\n\n  /// Returns the Unicode _White_Space_ property of `c`.\n  public let isWhitespace : (c : Char) -> Bool = Prim.charIsWhitespace;\n\n  /// Returns the Unicode _Lowercase_ property of `c`.\n  public let isLowercase : (c : Char) -> Bool = Prim.charIsLowercase;\n\n  /// Returns the Unicode _Uppercase_ property of `c`.\n  public let isUppercase : (c : Char) -> Bool = Prim.charIsUppercase;\n\n  /// Returns the Unicode _Alphabetic_ property of `c`.\n  public let isAlphabetic : (c : Char) -> Bool = Prim.charIsAlphabetic;\n\n  /// Returns `x == y`.\n  public func equal(x : Char, y : Char) : Bool { x == y };\n\n  /// Returns `x != y`.\n  public func notEqual(x : Char, y : Char) : Bool { x != y };\n\n  /// Returns `x < y`.\n  public func less(x : Char, y : Char) : Bool { x < y };\n\n  /// Returns `x <= y`.\n  public func lessOrEqual(x : Char, y : Char) : Bool { x <= y };\n\n  /// Returns `x > y`.\n  public func greater(x : Char, y : Char) : Bool { x > y };\n\n  /// Returns `x >= y`.\n  public func greaterOrEqual(x : Char, y : Char) : Bool { x >= y };\n\n  /// Returns the order of `x` and `y`.\n  public func compare(x : Char, y : Char) : { #less; #equal; #greater } {\n    if (x < y) { #less } else if (x == y) { #equal } else { #greater }\n  };\n\n}\n"},"None.mo":{"content":"/// The `None` type represents a type with _no_ value.\n///\n/// It is often used to type code that fails to return control (e.g. an infinite loop)\n/// or to designate impossible values (e.g. the type `?None` only contains `null`).\n\nimport Prim \"mo:⛔\";\n\nmodule {\n\n  /// The empty type. A subtype of all types.\n  public type None = Prim.Types.None;\n\n  /// Turns an absurd value into an arbitrary type.\n  public let impossible : <A> None -> A = func<A>(x : None) : A {\n    switch (x) {}\n  }\n}\n"},"OrderedMap.mo":{"content":"/// Stable key-value map implemented as a red-black tree with nodes storing key-value pairs.\n///\n/// A red-black tree is a balanced binary search tree ordered by the keys.\n///\n/// The tree data structure internally colors each of its nodes either red or black,\n/// and uses this information to balance the tree during the modifying operations.\n///\n/// | Runtime   | Space |\n/// |----------|------------|\n/// | `O(log(n))` (worst case per insertion, removal, or retrieval)  | `O(n)` (for storing the entire tree) |\n///\n/// `n` denotes the number of key-value entries (i.e. nodes) stored in the tree.\n///\n/// :::note Garbage collection\n///\n/// Unless stated otherwise, operations that iterate over or modify the map (such as insertion, deletion, traversal, and transformation) may create temporary objects with worst-case space usage of `O(log(n))` or `O(n)`. These objects are short-lived and will be collected by the garbage collector automatically.\n///\n/// :::\n///\n/// :::note Assumptions\n///\n/// Runtime and space complexity assumes that `compare`, `equal`, and other functions execute in `O(1)` time and space.\n/// :::\n///\n/// :::info Credits\n///\n/// The core of this implementation is derived from:\n///\n/// * Ken Friis Larsen's [RedBlackMap.sml](https://github.com/kfl/mosml/blob/master/src/mosmllib/Redblackmap.sml), which itself is based on:\n/// * Stefan Kahrs, \"Red-black trees with types\", Journal of Functional Programming, 11(4): 425-432 (2001), [version 1 in web appendix](http://www.cs.ukc.ac.uk/people/staff/smk/redblack/rb.html).\n/// :::\n///\n\nimport Debug \"Debug\";\nimport I \"Iter\";\nimport List \"List\";\nimport Nat \"Nat\";\nimport O \"Order\";\n\nmodule {\n  /// Collection of key-value entries, ordered by the keys and key unique.\n  /// The keys have the generic type `K` and the values the generic type `V`.\n  /// If `K` and `V` is stable types then `Map<K, V>` is also stable.\n  /// To ensure that property the `Map<K, V>` does not have any methods, instead\n  /// they are gathered in the functor-like class `Operations` (see example there).\n  public type Map<K, V> = {\n    size : Nat;\n    root : Tree<K, V>\n  };\n\n  // Note: Leaves are considered implicitly black.\n  type Tree<K, V> = {\n    #red : (Tree<K, V>, K, V, Tree<K, V>);\n    #black : (Tree<K, V>, K, V, Tree<K, V>);\n    #leaf\n  };\n\n  /// Class that captures key type `K` along with its ordering function `compare`\n  /// and provides all operations to work with a map of type `Map<K, _>`.\n  ///\n  /// An instance object should be created once as a canister field to ensure\n  /// that the same ordering function is used for every operation.\n  ///\n  /// Example:\n  /// ```motoko\n  /// import Map \"mo:base/OrderedMap\";\n  /// import Nat \"mo:base/Nat\";\n  ///\n  /// actor {\n  ///   let natMap = Map.Make<Nat>(Nat.compare); // : Operations<Nat>\n  ///   stable var keyStorage : Map.Map<Nat, Text> = natMap.empty<Text>();\n  ///\n  ///   public func addKey(id : Nat, key : Text) : async () {\n  ///     keyStorage := natMap.put(keyStorage, id, key);\n  ///   }\n  /// }\n  /// ```\n  public class Operations<K>(compare : (K, K) -> O.Order) {\n\n    /// Returns a new map, containing all entries given by the iterator `i`.\n    /// If there are multiple entries with the same key the last one is taken.\n    ///\n    /// Example:\n    /// ```motoko\n    /// import Map \"mo:base/OrderedMap\";\n    /// import Nat \"mo:base/Nat\";\n    /// import Iter \"mo:base/Iter\";\n    /// import Debug \"mo:base/Debug\";\n    ///\n    /// let natMap = Map.Make<Nat>(Nat.compare);\n    /// let m = natMap.fromIter<Text>(Iter.fromArray([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")]));\n    ///\n    /// Debug.print(debug_show(Iter.toArray(natMap.entries(m))));\n    ///\n    /// // [(0, \"Zero\"), (1, \"One\"), (2, \"Two\")]\n    /// ```\n    ///\n    /// | Runtime   | Space |\n    /// |----------|------------|\n    /// | `O(n * log(n))`  | `O(n)` (retained memory + garbage) |\n    ///\n    /// Note: Creates `O(n * log(n))` temporary objects that will be collected as garbage.\n    public func fromIter<V>(i : I.Iter<(K, V)>) : Map<K, V> = Internal.fromIter(i, compare);\n\n    /// Insert the value `value` with key `key` into the map `m`. Overwrites any existing entry with key `key`.\n    /// Returns a modified map.\n    ///\n    /// Example:\n    /// ```motoko\n    /// import Map \"mo:base/OrderedMap\";\n    /// import Nat \"mo:base/Nat\";\n    /// import Iter \"mo:base/Iter\";\n    /// import Debug \"mo:base/Debug\";\n    ///\n    /// let natMap = Map.Make<Nat>(Nat.compare);\n    /// var map = natMap.empty<Text>();\n    ///\n    /// map := natMap.put(map, 0, \"Zero\");\n    /// map := natMap.put(map, 2, \"Two\");\n    /// map := natMap.put(map, 1, \"One\");\n    ///\n    /// Debug.print(debug_show(Iter.toArray(natMap.entries(map))));\n    ///\n    /// // [(0, \"Zero\"), (1, \"One\"), (2, \"Two\")]\n    /// ```\n    ///\n    /// | Runtime     | Space         |\n    /// |-------------|---------------|\n    /// | `O(log(n))` | `O(log(n))`   |\n    public func put<V>(m : Map<K, V>, key : K, value : V) : Map<K, V> = replace(m, key, value).0;\n\n    /// Insert the value `value` with key `key` into the map `m`. Returns modified map and\n    /// the previous value associated with key `key` or `null` if no such value exists.\n    ///\n    /// Example:\n    /// ```motoko\n    /// import Map \"mo:base/OrderedMap\";\n    /// import Nat \"mo:base/Nat\";\n    /// import Iter \"mo:base/Iter\";\n    /// import Debug \"mo:base/Debug\";\n    ///\n    /// let natMap = Map.Make<Nat>(Nat.compare);\n    /// let map0 = natMap.fromIter<Text>(Iter.fromArray([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")]));\n    ///\n    /// let (map1, old1) = natMap.replace(map0, 0, \"Nil\");\n    ///\n    /// Debug.print(debug_show(Iter.toArray(natMap.entries(map1))));\n    /// Debug.print(debug_show(old1));\n    /// // [(0, \"Nil\"), (1, \"One\"), (2, \"Two\")]\n    /// // ?\"Zero\"\n    ///\n    /// let (map2, old2) = natMap.replace(map0, 3, \"Three\");\n    ///\n    /// Debug.print(debug_show(Iter.toArray(natMap.entries(map2))));\n    /// Debug.print(debug_show(old2));\n    /// // [(0, \"Zero\"), (1, \"One\"), (2, \"Two\"), (3, \"Three\")]\n    /// // null\n    /// ```\n    ///\n    /// | Runtime       | Space                       |\n    /// |---------------|-----------------------------|\n    /// | `O(log(n))`   | `O(log(n))` retained memory |\n    ///\n    public func replace<V>(m : Map<K, V>, key : K, value : V) : (Map<K, V>, ?V) {\n      switch (Internal.replace(m.root, compare, key, value)) {\n        case (t, null) { ({ root = t; size = m.size + 1 }, null) };\n        case (t, v) { ({ root = t; size = m.size }, v) }\n      }\n    };\n\n    /// Creates a new map by applying `f` to each entry in the map `m`. For each entry\n    /// `(k, v)` in the old map, if `f` evaluates to `null`, the entry is discarded.\n    /// Otherwise, the entry is transformed into a new entry `(k, v2)`, where\n    /// the new value `v2` is the result of applying `f` to `(k, v)`.\n    ///\n    /// Example:\n    /// ```motoko\n    /// import Map \"mo:base/OrderedMap\";\n    /// import Nat \"mo:base/Nat\";\n    /// import Iter \"mo:base/Iter\";\n    /// import Debug \"mo:base/Debug\";\n    ///\n    /// let natMap = Map.Make<Nat>(Nat.compare);\n    /// let map = natMap.fromIter<Text>(Iter.fromArray([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")]));\n    ///\n    /// func f(key : Nat, val : Text) : ?Text {\n    ///   if(key == 0) {null}\n    ///   else { ?(\"Twenty \" # val)}\n    /// };\n    ///\n    /// let newMap = natMap.mapFilter(map, f);\n    ///\n    /// Debug.print(debug_show(Iter.toArray(natMap.entries(newMap))));\n    ///\n    /// // [(1, \"Twenty One\"), (2, \"Twenty Two\")]\n    /// ```\n    ///\n    /// | Runtime   | Space |\n    /// |----------|------------|\n    /// | `O(n * log(n))`  | `O(n)` (retained memory + garbage) |\n    ///\n    /// Note: Creates `O(n * log(n))` temporary objects that will be collected as garbage.\n    public func mapFilter<V1, V2>(m : Map<K, V1>, f : (K, V1) -> ?V2) : Map<K, V2> = Internal.mapFilter(m, compare, f);\n\n    /// Get the value associated with key `key` in the given map `m` if present and `null` otherwise.\n    ///\n    /// Example:\n    /// ```motoko\n    /// import Map \"mo:base/OrderedMap\";\n    /// import Nat \"mo:base/Nat\";\n    /// import Iter \"mo:base/Iter\";\n    /// import Debug \"mo:base/Debug\";\n    ///\n    /// let natMap = Map.Make<Nat>(Nat.compare);\n    /// let map = natMap.fromIter<Text>(Iter.fromArray([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")]));\n    ///\n    /// Debug.print(debug_show(natMap.get(map, 1)));\n    /// Debug.print(debug_show(natMap.get(map, 42)));\n    ///\n    /// // ?\"One\"\n    /// // null\n    /// ```\n    ///\n    /// Runtime: `O(log(n))`.\n    /// Space: `O(1)`.\n    /// where `n` denotes the number of key-value entries stored in the map and\n    /// assuming that the `compare` function implements an `O(1)` comparison.\n    public func get<V>(m : Map<K, V>, key : K) : ?V = Internal.get(m.root, compare, key);\n\n    /// Test whether the map `m` contains any binding for the given `key`.\n    ///\n    /// Example:\n    /// ```motoko\n    /// import Map \"mo:base/OrderedMap\";\n    /// import Nat \"mo:base/Nat\";\n    /// import Iter \"mo:base/Iter\";\n    /// import Debug \"mo:base/Debug\";\n    ///\n    /// let natMap = Map.Make<Nat>(Nat.compare);\n    /// let map = natMap.fromIter<Text>(Iter.fromArray([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")]));\n    ///\n    /// Debug.print(debug_show natMap.contains(map, 1)); // => true\n    /// Debug.print(debug_show natMap.contains(map, 42)); // => false\n    /// ```\n    ///\n    /// | Runtime       | Space                       |\n    /// |---------------|-----------------------------|\n    /// | `O(log(n))`   | `O(1)` |\n    public func contains<V>(m : Map<K, V>, key : K) : Bool = Internal.contains(m.root, compare, key);\n\n    /// Retrieves a key-value pair from the map `m` with a maximal key. If the map is empty returns `null`.\n    ///\n    /// Example:\n    /// ```motoko\n    /// import Map \"mo:base/OrderedMap\";\n    /// import Nat \"mo:base/Nat\";\n    /// import Iter \"mo:base/Iter\";\n    /// import Debug \"mo:base/Debug\";\n    ///\n    /// let natMap = Map.Make<Nat>(Nat.compare);\n    /// let map = natMap.fromIter<Text>(Iter.fromArray([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")]));\n    ///\n    /// Debug.print(debug_show(natMap.maxEntry(map))); // => ?(2, \"Two\")\n    /// Debug.print(debug_show(natMap.maxEntry(natMap.empty()))); // => null\n    /// ```\n    ///\n    /// | Runtime       | Space                       |\n    /// |---------------|-----------------------------|\n    /// | `O(log(n))`   | `O(1)` |\n    public func maxEntry<V>(m : Map<K, V>) : ?(K, V) = Internal.maxEntry(m.root);\n\n    /// Retrieves a key-value pair from the map `m` with a minimal key. If the map is empty returns `null`.\n    ///\n    /// Example:\n    /// ```motoko\n    /// import Map \"mo:base/OrderedMap\";\n    /// import Iter \"mo:base/Iter\";\n    /// import Nat \"mo:base/Nat\";\n    /// import Debug \"mo:base/Debug\";\n    ///\n    /// let natMap = Map.Make<Nat>(Nat.compare);\n    /// let map = natMap.fromIter<Text>(Iter.fromArray([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")]));\n    ///\n    /// Debug.print(debug_show(natMap.minEntry(map))); // => ?(0, \"Zero\")\n    /// Debug.print(debug_show(natMap.minEntry(natMap.empty()))); // => null\n    /// ```\n    ///\n    /// | Runtime       | Space                       |\n    /// |---------------|-----------------------------|\n    /// | `O(log(n))`   | `O(1)` |\n    public func minEntry<V>(m : Map<K, V>) : ?(K, V) = Internal.minEntry(m.root);\n\n    /// Deletes the entry with the key `key` from the map `m`. Has no effect if `key` is not\n    /// present in the map. Returns modified map.\n    ///\n    /// Example:\n    /// ```motoko\n    /// import Map \"mo:base/OrderedMap\";\n    /// import Nat \"mo:base/Nat\";\n    /// import Iter \"mo:base/Iter\";\n    /// import Debug \"mo:base/Debug\";\n    ///\n    /// let natMap = Map.Make<Nat>(Nat.compare);\n    /// let map = natMap.fromIter<Text>(Iter.fromArray([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")]));\n    ///\n    /// Debug.print(debug_show(Iter.toArray(natMap.entries(natMap.delete(map, 1)))));\n    /// Debug.print(debug_show(Iter.toArray(natMap.entries(natMap.delete(map, 42)))));\n    ///\n    /// // [(0, \"Zero\"), (2, \"Two\")]\n    /// // [(0, \"Zero\"), (1, \"One\"), (2, \"Two\")]\n    /// ```\n    ///\n    /// | Runtime       | Space                       |\n    /// |---------------|-----------------------------|\n    /// | `O(log(n))`   | `O(log(n))` |\n    public func delete<V>(m : Map<K, V>, key : K) : Map<K, V> = remove(m, key).0;\n\n    /// Deletes the entry with the key `key`. Returns modified map and the\n    /// previous value associated with key `key` or `null` if no such value exists.\n    ///\n    /// Example:\n    /// ```motoko\n    /// import Map \"mo:base/OrderedMap\";\n    /// import Nat \"mo:base/Nat\";\n    /// import Iter \"mo:base/Iter\";\n    /// import Debug \"mo:base/Debug\";\n    ///\n    /// let natMap = Map.Make<Nat>(Nat.compare);\n    /// let map0 = natMap.fromIter<Text>(Iter.fromArray([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")]));\n    ///\n    /// let (map1, old1) = natMap.remove(map0, 0);\n    ///\n    /// Debug.print(debug_show(Iter.toArray(natMap.entries(map1))));\n    /// Debug.print(debug_show(old1));\n    /// // [(1, \"One\"), (2, \"Two\")]\n    /// // ?\"Zero\"\n    ///\n    /// let (map2, old2) = natMap.remove(map0, 42);\n    ///\n    /// Debug.print(debug_show(Iter.toArray(natMap.entries(map2))));\n    /// Debug.print(debug_show(old2));\n    /// // [(0, \"Zero\"), (1, \"One\"), (2, \"Two\")]\n    /// // null\n    /// ```\n    ///\n    /// | Runtime       | Space                       |\n    /// |---------------|-----------------------------|\n    /// | `O(log(n))`   | `O(log(n))` |\n    public func remove<V>(m : Map<K, V>, key : K) : (Map<K, V>, ?V) {\n      switch (Internal.remove(m.root, compare, key)) {\n        case (t, null) { ({ root = t; size = m.size }, null) };\n        case (t, v) { ({ root = t; size = m.size - 1 }, v) }\n      }\n    };\n\n    /// Create a new empty map.\n    ///\n    /// Example:\n    /// ```motoko\n    /// import Map \"mo:base/OrderedMap\";\n    /// import Nat \"mo:base/Nat\";\n    /// import Debug \"mo:base/Debug\";\n    ///\n    /// let natMap = Map.Make<Nat>(Nat.compare);\n    ///\n    /// let map = natMap.empty<Text>();\n    ///\n    /// Debug.print(debug_show(natMap.size(map)));\n    ///\n    /// // 0\n    /// ```\n    ///\n    /// Cost of empty map creation\n    /// Runtime: `O(1)`.\n    /// Space: `O(1)`\n    public func empty<V>() : Map<K, V> = Internal.empty();\n\n    /// Returns an Iterator (`Iter`) over the key-value pairs in the map.\n    /// Iterator provides a single method `next()`, which returns\n    /// pairs in ascending order by keys, or `null` when out of pairs to iterate over.\n    ///\n    /// Example:\n    /// ```motoko\n    /// import Map \"mo:base/OrderedMap\";\n    /// import Nat \"mo:base/Nat\";\n    /// import Iter \"mo:base/Iter\";\n    /// import Debug \"mo:base/Debug\";\n    ///\n    /// let natMap = Map.Make<Nat>(Nat.compare);\n    /// let map = natMap.fromIter<Text>(Iter.fromArray([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")]));\n    ///\n    /// Debug.print(debug_show(Iter.toArray(natMap.entries(map))));\n    /// // [(0, \"Zero\"), (1, \"One\"), (2, \"Two\")]\n    /// var sum = 0;\n    /// for ((k, _) in natMap.entries(map)) { sum += k; };\n    /// Debug.print(debug_show(sum)); // => 3\n    /// ```\n    /// | Runtime | Space                               |\n    /// |---------|-------------------------------------|\n    /// | `O(n)`  | `O(log(n))` retained + `O(n)` garbage |\n    public func entries<V>(m : Map<K, V>) : I.Iter<(K, V)> = Internal.iter(m.root, #fwd);\n\n    /// Same as `entries` but iterates in the descending order.\n    public func entriesRev<V>(m : Map<K, V>) : I.Iter<(K, V)> = Internal.iter(m.root, #bwd);\n\n    /// Returns an Iterator (`Iter`) over the keys of the map.\n    /// Iterator provides a single method `next()`, which returns\n    /// keys in ascending order, or `null` when out of keys to iterate over.\n    ///\n    /// Example:\n    /// ```motoko\n    /// import Map \"mo:base/OrderedMap\";\n    /// import Nat \"mo:base/Nat\";\n    /// import Iter \"mo:base/Iter\";\n    /// import Debug \"mo:base/Debug\";\n    ///\n    /// let natMap = Map.Make<Nat>(Nat.compare);\n    /// let map = natMap.fromIter<Text>(Iter.fromArray([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")]));\n    ///\n    /// Debug.print(debug_show(Iter.toArray(natMap.keys(map))));\n    ///\n    /// // [0, 1, 2]\n    /// ```\n    /// | Runtime | Space                               |\n    /// |---------|-------------------------------------|\n    /// | `O(n)`  | `O(log(n))` retained + `O(n)` garbage |\n    public func keys<V>(m : Map<K, V>) : I.Iter<K> = I.map(entries(m), func(kv : (K, V)) : K { kv.0 });\n\n    /// Returns an Iterator (`Iter`) over the values of the map.\n    /// Iterator provides a single method `next()`, which returns\n    /// values in ascending order of associated keys, or `null` when out of values to iterate over.\n    ///\n    /// Example:\n    /// ```motoko\n    /// import Map \"mo:base/OrderedMap\";\n    /// import Nat \"mo:base/Nat\";\n    /// import Iter \"mo:base/Iter\";\n    /// import Debug \"mo:base/Debug\";\n    ///\n    /// let natMap = Map.Make<Nat>(Nat.compare);\n    /// let map = natMap.fromIter<Text>(Iter.fromArray([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")]));\n    ///\n    /// Debug.print(debug_show(Iter.toArray(natMap.vals(map))));\n    ///\n    /// // [\"Zero\", \"One\", \"Two\"]\n    /// ```\n\n    /// | Runtime | Space                               |\n    /// |---------|-------------------------------------|\n    /// | `O(n)`  | `O(log(n))` retained + `O(n)` garbage |\n    public func vals<V>(m : Map<K, V>) : I.Iter<V> = I.map(entries(m), func(kv : (K, V)) : V { kv.1 });\n\n    /// Creates a new map by applying `f` to each entry in the map `m`. Each entry\n    /// `(k, v)` in the old map is transformed into a new entry `(k, v2)`, where\n    /// the new value `v2` is created by applying `f` to `(k, v)`.\n    ///\n    /// Example:\n    /// ```motoko\n    /// import Map \"mo:base/OrderedMap\";\n    /// import Nat \"mo:base/Nat\";\n    /// import Iter \"mo:base/Iter\";\n    /// import Debug \"mo:base/Debug\";\n    ///\n    /// let natMap = Map.Make<Nat>(Nat.compare);\n    /// let map = natMap.fromIter<Text>(Iter.fromArray([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")]));\n    ///\n    /// func f(key : Nat, _val : Text) : Nat = key * 2;\n    ///\n    /// let resMap = natMap.map(map, f);\n    ///\n    /// Debug.print(debug_show(Iter.toArray(natMap.entries(resMap))));\n    /// // [(0, 0), (1, 2), (2, 4)]\n    /// ```\n    ///\n    /// | Runtime | Space                        |\n    /// |---------|------------------------------|\n    /// | `O(n)`  | `O(n)` |\n    public func map<V1, V2>(m : Map<K, V1>, f : (K, V1) -> V2) : Map<K, V2> = Internal.map(m, f);\n\n    /// Determine the size of the map as the number of key-value entries.\n    ///\n    /// Example:\n    /// ```motoko\n    /// import Map \"mo:base/OrderedMap\";\n    /// import Nat \"mo:base/Nat\";\n    /// import Iter \"mo:base/Iter\";\n    /// import Debug \"mo:base/Debug\";\n    ///\n    /// let natMap = Map.Make<Nat>(Nat.compare);\n    /// let map = natMap.fromIter<Text>(Iter.fromArray([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")]));\n    ///\n    /// Debug.print(debug_show(natMap.size(map)));\n    /// // 3\n    /// ```\n    ///\n    /// | Runtime | Space                        |\n    /// |---------|------------------------------|\n    /// | `O(n)`  | `O(1)` |\n    public func size<V>(m : Map<K, V>) : Nat = m.size;\n\n    /// Collapses the elements in the `map` into a single value by starting with `base`\n    /// and progressively combining keys and values into `base` with `combine`. Iteration runs\n    /// left to right.\n    ///\n    /// Example:\n    /// ```motoko\n    /// import Map \"mo:base/OrderedMap\";\n    /// import Nat \"mo:base/Nat\";\n    /// import Iter \"mo:base/Iter\";\n    /// import Debug \"mo:base/Debug\";\n    ///\n    /// let natMap = Map.Make<Nat>(Nat.compare);\n    /// let map = natMap.fromIter<Text>(Iter.fromArray([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")]));\n    ///\n    /// func folder(accum : (Nat, Text), key : Nat, val : Text) : ((Nat, Text))\n    ///   = (key + accum.0, accum.1 # val);\n    ///\n    /// Debug.print(debug_show(natMap.foldLeft(map, (0, \"\"), folder)));\n    ///\n    /// // (3, \"ZeroOneTwo\")\n    /// ```\n    ///\n    /// | Runtime | Space                        |\n    /// |---------|------------------------------|\n    /// | `O(n)`  | Depends on `combine` + `O(n)` garbage |\n    public func foldLeft<Value, Accum>(\n      map : Map<K, Value>,\n      base : Accum,\n      combine : (Accum, K, Value) -> Accum\n    ) : Accum = Internal.foldLeft(map.root, base, combine);\n\n    /// Collapses the elements in the `map` into a single value by starting with `base`\n    /// and progressively combining keys and values into `base` with `combine`. Iteration runs\n    /// right to left.\n    ///\n    /// Example:\n    /// ```motoko\n    /// import Map \"mo:base/OrderedMap\";\n    /// import Nat \"mo:base/Nat\";\n    /// import Iter \"mo:base/Iter\";\n    /// import Debug \"mo:base/Debug\";\n    ///\n    /// let natMap = Map.Make<Nat>(Nat.compare);\n    /// let map = natMap.fromIter<Text>(Iter.fromArray([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")]));\n    ///\n    /// func folder(key : Nat, val : Text, accum : (Nat, Text)) : ((Nat, Text))\n    ///   = (key + accum.0, accum.1 # val);\n    ///\n    /// Debug.print(debug_show(natMap.foldRight(map, (0, \"\"), folder)));\n    ///\n    /// // (3, \"TwoOneZero\")\n    /// ```\n    ///\n    /// | Runtime | Space                        |\n    /// |---------|------------------------------|\n    /// | `O(n)`  | Depends on `combine` + `O(n)` garbage |\n    public func foldRight<Value, Accum>(\n      map : Map<K, Value>,\n      base : Accum,\n      combine : (K, Value, Accum) -> Accum\n    ) : Accum = Internal.foldRight(map.root, base, combine);\n\n    /// Test whether all key-value pairs satisfy a given predicate `pred`.\n    ///\n    /// Example:\n    /// ```motoko\n    /// import Map \"mo:base/OrderedMap\";\n    /// import Nat \"mo:base/Nat\";\n    /// import Iter \"mo:base/Iter\";\n    /// import Debug \"mo:base/Debug\";\n    ///\n    /// let natMap = Map.Make<Nat>(Nat.compare);\n    /// let map = natMap.fromIter<Text>(Iter.fromArray([(0, \"0\"), (2, \"2\"), (1, \"1\")]));\n    ///\n    /// Debug.print(debug_show(natMap.all<Text>(map, func (k, v) = (v == debug_show(k)))));\n    /// // true\n    /// Debug.print(debug_show(natMap.all<Text>(map, func (k, v) = (k < 2))));\n    /// // false\n    /// ```\n    ///\n    /// | Runtime   | Space     |\n    /// |-----------|-----------|\n    /// | `O(n)` | `O(1)` |\n    public func all<V>(m : Map<K, V>, pred : (K, V) -> Bool) : Bool = Internal.all(m.root, pred);\n\n    /// Test if there exists a key-value pair satisfying a given predicate `pred`.\n    ///\n    /// Example:\n    /// ```motoko\n    /// import Map \"mo:base/OrderedMap\";\n    /// import Nat \"mo:base/Nat\";\n    /// import Iter \"mo:base/Iter\";\n    /// import Debug \"mo:base/Debug\";\n    ///\n    /// let natMap = Map.Make<Nat>(Nat.compare);\n    /// let map = natMap.fromIter<Text>(Iter.fromArray([(0, \"0\"), (2, \"2\"), (1, \"1\")]));\n    ///\n    /// Debug.print(debug_show(natMap.some<Text>(map, func (k, v) = (k >= 3))));\n    /// // false\n    /// Debug.print(debug_show(natMap.some<Text>(map, func (k, v) = (k >= 0))));\n    /// // true\n    /// ```\n    ///\n    /// | Runtime   | Space     |\n    /// |-----------|-----------|\n    /// | `O(n)` | `O(1)` |\n    public func some<V>(m : Map<K, V>, pred : (K, V) -> Bool) : Bool = Internal.some(m.root, pred);\n\n    /// Debug helper that check internal invariants of the given map `m`.\n    /// Raise an error (for a stack trace) if invariants are violated.\n    public func validate<V>(m : Map<K, V>) : () {\n      Internal.validate(m, compare)\n    }\n  };\n\n  module Internal {\n\n    public func empty<K, V>() : Map<K, V> { { size = 0; root = #leaf } };\n\n    public func fromIter<K, V>(i : I.Iter<(K, V)>, compare : (K, K) -> O.Order) : Map<K, V> {\n      var map = #leaf : Tree<K, V>;\n      var size = 0;\n      for (val in i) {\n        map := put(map, compare, val.0, val.1);\n        size += 1\n      };\n      { root = map; size }\n    };\n\n    type IterRep<K, V> = List.List<{ #tr : Tree<K, V>; #xy : (K, V) }>;\n\n    public func iter<K, V>(map : Tree<K, V>, direction : { #fwd; #bwd }) : I.Iter<(K, V)> {\n      let turnLeftFirst : MapTraverser<K, V> = func(l, x, y, r, ts) {\n        ?(#tr(l), ?(#xy(x, y), ?(#tr(r), ts)))\n      };\n\n      let turnRightFirst : MapTraverser<K, V> = func(l, x, y, r, ts) {\n        ?(#tr(r), ?(#xy(x, y), ?(#tr(l), ts)))\n      };\n\n      switch direction {\n        case (#fwd) IterMap(map, turnLeftFirst);\n        case (#bwd) IterMap(map, turnRightFirst)\n      }\n    };\n\n    type MapTraverser<K, V> = (Tree<K, V>, K, V, Tree<K, V>, IterRep<K, V>) -> IterRep<K, V>;\n\n    class IterMap<K, V>(tree : Tree<K, V>, mapTraverser : MapTraverser<K, V>) {\n      var trees : IterRep<K, V> = ?(#tr(tree), null);\n      public func next() : ?(K, V) {\n        switch (trees) {\n          case (null) { null };\n          case (?(#tr(#leaf), ts)) {\n            trees := ts;\n            next()\n          };\n          case (?(#xy(xy), ts)) {\n            trees := ts;\n            ?xy\n          };\n          case (?(#tr(#red(l, x, y, r)), ts)) {\n            trees := mapTraverser(l, x, y, r, ts);\n            next()\n          };\n          case (?(#tr(#black(l, x, y, r)), ts)) {\n            trees := mapTraverser(l, x, y, r, ts);\n            next()\n          }\n        }\n      }\n    };\n\n    public func map<K, V1, V2>(map : Map<K, V1>, f : (K, V1) -> V2) : Map<K, V2> {\n      func mapRec(m : Tree<K, V1>) : Tree<K, V2> {\n        switch m {\n          case (#leaf) { #leaf };\n          case (#red(l, x, y, r)) {\n            #red(mapRec l, x, f(x, y), mapRec r)\n          };\n          case (#black(l, x, y, r)) {\n            #black(mapRec l, x, f(x, y), mapRec r)\n          }\n        }\n      };\n      { size = map.size; root = mapRec(map.root) }\n    };\n\n    public func foldLeft<Key, Value, Accum>(\n      map : Tree<Key, Value>,\n      base : Accum,\n      combine : (Accum, Key, Value) -> Accum\n    ) : Accum {\n      switch (map) {\n        case (#leaf) { base };\n        case (#red(l, k, v, r)) {\n          let left = foldLeft(l, base, combine);\n          let middle = combine(left, k, v);\n          foldLeft(r, middle, combine)\n        };\n        case (#black(l, k, v, r)) {\n          let left = foldLeft(l, base, combine);\n          let middle = combine(left, k, v);\n          foldLeft(r, middle, combine)\n        }\n      }\n    };\n\n    public func foldRight<Key, Value, Accum>(\n      map : Tree<Key, Value>,\n      base : Accum,\n      combine : (Key, Value, Accum) -> Accum\n    ) : Accum {\n      switch (map) {\n        case (#leaf) { base };\n        case (#red(l, k, v, r)) {\n          let right = foldRight(r, base, combine);\n          let middle = combine(k, v, right);\n          foldRight(l, middle, combine)\n        };\n        case (#black(l, k, v, r)) {\n          let right = foldRight(r, base, combine);\n          let middle = combine(k, v, right);\n          foldRight(l, middle, combine)\n        }\n      }\n    };\n\n    public func mapFilter<K, V1, V2>(map : Map<K, V1>, compare : (K, K) -> O.Order, f : (K, V1) -> ?V2) : Map<K, V2> {\n      var size = 0;\n      func combine(acc : Tree<K, V2>, key : K, value1 : V1) : Tree<K, V2> {\n        switch (f(key, value1)) {\n          case null { acc };\n          case (?value2) {\n            size += 1;\n            put(acc, compare, key, value2)\n          }\n        }\n      };\n      { root = foldLeft(map.root, #leaf, combine); size }\n    };\n\n    public func get<K, V>(t : Tree<K, V>, compare : (K, K) -> O.Order, x : K) : ?V {\n      switch t {\n        case (#red(l, x1, y1, r)) {\n          switch (compare(x, x1)) {\n            case (#less) { get(l, compare, x) };\n            case (#equal) { ?y1 };\n            case (#greater) { get(r, compare, x) }\n          }\n        };\n        case (#black(l, x1, y1, r)) {\n          switch (compare(x, x1)) {\n            case (#less) { get(l, compare, x) };\n            case (#equal) { ?y1 };\n            case (#greater) { get(r, compare, x) }\n          }\n        };\n        case (#leaf) { null }\n      }\n    };\n\n    public func contains<K, V>(m : Tree<K, V>, compare : (K, K) -> O.Order, key : K) : Bool {\n      switch (get(m, compare, key)) {\n        case (null) { false };\n        case (_) { true }\n      }\n    };\n\n    public func maxEntry<K, V>(m : Tree<K, V>) : ?(K, V) {\n      func rightmost(m : Tree<K, V>) : (K, V) {\n        switch m {\n          case (#red(_, k, v, #leaf)) { (k, v) };\n          case (#red(_, _, _, r)) { rightmost(r) };\n          case (#black(_, k, v, #leaf)) { (k, v) };\n          case (#black(_, _, _, r)) { rightmost(r) };\n          case (#leaf) { Debug.trap \"OrderedMap.impossible\" }\n        }\n      };\n      switch m {\n        case (#leaf) { null };\n        case (_) { ?rightmost(m) }\n      }\n    };\n\n    public func minEntry<K, V>(m : Tree<K, V>) : ?(K, V) {\n      func leftmost(m : Tree<K, V>) : (K, V) {\n        switch m {\n          case (#red(#leaf, k, v, _)) { (k, v) };\n          case (#red(l, _, _, _)) { leftmost(l) };\n          case (#black(#leaf, k, v, _)) { (k, v) };\n          case (#black(l, _, _, _)) { leftmost(l) };\n          case (#leaf) { Debug.trap \"OrderedMap.impossible\" }\n        }\n      };\n      switch m {\n        case (#leaf) { null };\n        case (_) { ?leftmost(m) }\n      }\n    };\n\n    public func all<K, V>(m : Tree<K, V>, pred : (K, V) -> Bool) : Bool {\n      switch m {\n        case (#red(l, k, v, r)) {\n          pred(k, v) and all(l, pred) and all(r, pred)\n        };\n        case (#black(l, k, v, r)) {\n          pred(k, v) and all(l, pred) and all(r, pred)\n        };\n        case (#leaf) { true }\n      }\n    };\n\n    public func some<K, V>(m : Tree<K, V>, pred : (K, V) -> Bool) : Bool {\n      switch m {\n        case (#red(l, k, v, r)) {\n          pred(k, v) or some(l, pred) or some(r, pred)\n        };\n        case (#black(l, k, v, r)) {\n          pred(k, v) or some(l, pred) or some(r, pred)\n        };\n        case (#leaf) { false }\n      }\n    };\n\n    func redden<K, V>(t : Tree<K, V>) : Tree<K, V> {\n      switch t {\n        case (#black(l, x, y, r)) { (#red(l, x, y, r)) };\n        case _ {\n          Debug.trap \"OrderedMap.red\"\n        }\n      }\n    };\n\n    func lbalance<K, V>(left : Tree<K, V>, x : K, y : V, right : Tree<K, V>) : Tree<K, V> {\n      switch (left, right) {\n        case (#red(#red(l1, x1, y1, r1), x2, y2, r2), r) {\n          #red(\n            #black(l1, x1, y1, r1),\n            x2,\n            y2,\n            #black(r2, x, y, r)\n          )\n        };\n        case (#red(l1, x1, y1, #red(l2, x2, y2, r2)), r) {\n          #red(\n            #black(l1, x1, y1, l2),\n            x2,\n            y2,\n            #black(r2, x, y, r)\n          )\n        };\n        case _ {\n          #black(left, x, y, right)\n        }\n      }\n    };\n\n    func rbalance<K, V>(left : Tree<K, V>, x : K, y : V, right : Tree<K, V>) : Tree<K, V> {\n      switch (left, right) {\n        case (l, #red(l1, x1, y1, #red(l2, x2, y2, r2))) {\n          #red(\n            #black(l, x, y, l1),\n            x1,\n            y1,\n            #black(l2, x2, y2, r2)\n          )\n        };\n        case (l, #red(#red(l1, x1, y1, r1), x2, y2, r2)) {\n          #red(\n            #black(l, x, y, l1),\n            x1,\n            y1,\n            #black(r1, x2, y2, r2)\n          )\n        };\n        case _ {\n          #black(left, x, y, right)\n        }\n      }\n    };\n\n    type ClashResolver<A> = { old : A; new : A } -> A;\n\n    func insertWith<K, V>(\n      m : Tree<K, V>,\n      compare : (K, K) -> O.Order,\n      key : K,\n      val : V,\n      onClash : ClashResolver<V>\n    ) : Tree<K, V> {\n      func ins(tree : Tree<K, V>) : Tree<K, V> {\n        switch tree {\n          case (#black(left, x, y, right)) {\n            switch (compare(key, x)) {\n              case (#less) {\n                lbalance(ins left, x, y, right)\n              };\n              case (#greater) {\n                rbalance(left, x, y, ins right)\n              };\n              case (#equal) {\n                let newVal = onClash({ new = val; old = y });\n                #black(left, key, newVal, right)\n              }\n            }\n          };\n          case (#red(left, x, y, right)) {\n            switch (compare(key, x)) {\n              case (#less) {\n                #red(ins left, x, y, right)\n              };\n              case (#greater) {\n                #red(left, x, y, ins right)\n              };\n              case (#equal) {\n                let newVal = onClash { new = val; old = y };\n                #red(left, key, newVal, right)\n              }\n            }\n          };\n          case (#leaf) {\n            #red(#leaf, key, val, #leaf)\n          }\n        }\n      };\n      switch (ins m) {\n        case (#red(left, x, y, right)) {\n          #black(left, x, y, right)\n        };\n        case other { other }\n      }\n    };\n\n    public func replace<K, V>(\n      m : Tree<K, V>,\n      compare : (K, K) -> O.Order,\n      key : K,\n      val : V\n    ) : (Tree<K, V>, ?V) {\n      var oldVal : ?V = null;\n      func onClash(clash : { old : V; new : V }) : V {\n        oldVal := ?clash.old;\n        clash.new\n      };\n      let res = insertWith(m, compare, key, val, onClash);\n      (res, oldVal)\n    };\n\n    public func put<K, V>(\n      m : Tree<K, V>,\n      compare : (K, K) -> O.Order,\n      key : K,\n      val : V\n    ) : Tree<K, V> = replace(m, compare, key, val).0;\n\n    func balLeft<K, V>(left : Tree<K, V>, x : K, y : V, right : Tree<K, V>) : Tree<K, V> {\n      switch (left, right) {\n        case (#red(l1, x1, y1, r1), r) {\n          #red(\n            #black(l1, x1, y1, r1),\n            x,\n            y,\n            r\n          )\n        };\n        case (_, #black(l2, x2, y2, r2)) {\n          rbalance(left, x, y, #red(l2, x2, y2, r2))\n        };\n        case (_, #red(#black(l2, x2, y2, r2), x3, y3, r3)) {\n          #red(\n            #black(left, x, y, l2),\n            x2,\n            y2,\n            rbalance(r2, x3, y3, redden r3)\n          )\n        };\n        case _ { Debug.trap \"balLeft\" }\n      }\n    };\n\n    func balRight<K, V>(left : Tree<K, V>, x : K, y : V, right : Tree<K, V>) : Tree<K, V> {\n      switch (left, right) {\n        case (l, #red(l1, x1, y1, r1)) {\n          #red(\n            l,\n            x,\n            y,\n            #black(l1, x1, y1, r1)\n          )\n        };\n        case (#black(l1, x1, y1, r1), r) {\n          lbalance(#red(l1, x1, y1, r1), x, y, r)\n        };\n        case (#red(l1, x1, y1, #black(l2, x2, y2, r2)), r3) {\n          #red(\n            lbalance(redden l1, x1, y1, l2),\n            x2,\n            y2,\n            #black(r2, x, y, r3)\n          )\n        };\n        case _ { Debug.trap \"balRight\" }\n      }\n    };\n\n    func append<K, V>(left : Tree<K, V>, right : Tree<K, V>) : Tree<K, V> {\n      switch (left, right) {\n        case (#leaf, _) { right };\n        case (_, #leaf) { left };\n        case (\n          #red(l1, x1, y1, r1),\n          #red(l2, x2, y2, r2)\n        ) {\n          switch (append(r1, l2)) {\n            case (#red(l3, x3, y3, r3)) {\n              #red(\n                #red(l1, x1, y1, l3),\n                x3,\n                y3,\n                #red(r3, x2, y2, r2)\n              )\n            };\n            case r1l2 {\n              #red(l1, x1, y1, #red(r1l2, x2, y2, r2))\n            }\n          }\n        };\n        case (t1, #red(l2, x2, y2, r2)) {\n          #red(append(t1, l2), x2, y2, r2)\n        };\n        case (#red(l1, x1, y1, r1), t2) {\n          #red(l1, x1, y1, append(r1, t2))\n        };\n        case (#black(l1, x1, y1, r1), #black(l2, x2, y2, r2)) {\n          switch (append(r1, l2)) {\n            case (#red(l3, x3, y3, r3)) {\n              #red(\n                #black(l1, x1, y1, l3),\n                x3,\n                y3,\n                #black(r3, x2, y2, r2)\n              )\n            };\n            case r1l2 {\n              balLeft(\n                l1,\n                x1,\n                y1,\n                #black(r1l2, x2, y2, r2)\n              )\n            }\n          }\n        }\n      }\n    };\n\n    public func delete<K, V>(m : Tree<K, V>, compare : (K, K) -> O.Order, key : K) : Tree<K, V> = remove(m, compare, key).0;\n\n    public func remove<K, V>(tree : Tree<K, V>, compare : (K, K) -> O.Order, x : K) : (Tree<K, V>, ?V) {\n      var y0 : ?V = null;\n      func delNode(left : Tree<K, V>, x1 : K, y1 : V, right : Tree<K, V>) : Tree<K, V> {\n        switch (compare(x, x1)) {\n          case (#less) {\n            let newLeft = del left;\n            switch left {\n              case (#black(_, _, _, _)) {\n                balLeft(newLeft, x1, y1, right)\n              };\n              case _ {\n                #red(newLeft, x1, y1, right)\n              }\n            }\n          };\n          case (#greater) {\n            let newRight = del right;\n            switch right {\n              case (#black(_, _, _, _)) {\n                balRight(left, x1, y1, newRight)\n              };\n              case _ {\n                #red(left, x1, y1, newRight)\n              }\n            }\n          };\n          case (#equal) {\n            y0 := ?y1;\n            append(left, right)\n          }\n        }\n      };\n      func del(tree : Tree<K, V>) : Tree<K, V> {\n        switch tree {\n          case (#red(left, x, y, right)) {\n            delNode(left, x, y, right)\n          };\n          case (#black(left, x, y, right)) {\n            delNode(left, x, y, right)\n          };\n          case (#leaf) {\n            tree\n          }\n        }\n      };\n      switch (del(tree)) {\n        case (#red(left, x, y, right)) { (#black(left, x, y, right), y0) };\n        case other { (other, y0) }\n      }\n    };\n\n    // Test helper\n    public func validate<K, V>(rbMap : Map<K, V>, comp : (K, K) -> O.Order) {\n      ignore blackDepth(rbMap.root, comp)\n    };\n\n    func blackDepth<K, V>(node : Tree<K, V>, comp : (K, K) -> O.Order) : Nat {\n      func checkNode(left : Tree<K, V>, key : K, right : Tree<K, V>) : Nat {\n        checkKey(left, func(x : K) : Bool { comp(x, key) == #less });\n        checkKey(right, func(x : K) : Bool { comp(x, key) == #greater });\n        let leftBlacks = blackDepth(left, comp);\n        let rightBlacks = blackDepth(right, comp);\n        assert (leftBlacks == rightBlacks);\n        leftBlacks\n      };\n      switch node {\n        case (#leaf) 0;\n        case (#red(left, key, _, right)) {\n          let leftBlacks = checkNode(left, key, right);\n          assert (not isRed(left));\n          assert (not isRed(right));\n          leftBlacks\n        };\n        case (#black(left, key, _, right)) {\n          checkNode(left, key, right) + 1\n        }\n      }\n    };\n\n    func isRed<K, V>(node : Tree<K, V>) : Bool {\n      switch node {\n        case (#red(_, _, _, _)) true;\n        case _ false\n      }\n    };\n\n    func checkKey<K, V>(node : Tree<K, V>, isValid : K -> Bool) {\n      switch node {\n        case (#leaf) {};\n        case (#red(_, key, _, _)) {\n          assert (isValid(key))\n        };\n        case (#black(_, key, _, _)) {\n          assert (isValid(key))\n        }\n      }\n    }\n  };\n\n  /// Create `OrderedMap.Operations` object capturing key type `K` and `compare` function.\n  /// It is an alias for the `Operations` constructor.\n  ///\n  /// Example:\n  /// ```motoko\n  /// import Map \"mo:base/OrderedMap\";\n  /// import Nat \"mo:base/Nat\";\n  ///\n  /// actor {\n  ///   let natMap = Map.Make<Nat>(Nat.compare);\n  ///   stable var map : Map.Map<Nat, Text> = natMap.empty<Text>();\n  /// };\n  /// ```\n  public let Make : <K>(compare : (K, K) -> O.Order) -> Operations<K> = Operations\n}\n"},"RBTree.mo":{"content":"/// Key-value map implemented as a red-black tree (RBTree) with nodes storing key-value pairs.\n///\n/// A red-black tree is a balanced binary search tree ordered by the keys.\n///\n/// The tree data structure internally colors each of its nodes either red or black,\n/// and uses this information to balance the tree during the modifying operations.\n///\n/// Creation:\n/// Instantiate class `RBTree<K, V>` that provides a map from keys of type `K` to values of type `V`.\n///\n/// Example:\n/// ```motoko\n/// import RBTree \"mo:base/RBTree\";\n/// import Nat \"mo:base/Nat\";\n/// import Debug \"mo:base/Debug\";\n///\n/// let tree = RBTree.RBTree<Nat, Text>(Nat.compare); // Create a new red-black tree mapping Nat to Text\n/// tree.put(1, \"one\");\n/// tree.put(2, \"two\");\n/// tree.put(3, \"tree\");\n/// for (entry in tree.entries()) {\n///   Debug.print(\"Entry key=\" # debug_show(entry.0) # \" value=\\\"\" # entry.1 #\"\\\"\");\n/// }\n/// ```\n///\n/// :::note Performance\n/// * Runtime: `O(log(n))` worst case cost per insertion, removal, and retrieval operation.\n/// * Heap space: `O(n)` for storing the entire tree.\n/// * Stack space: `O(log(n)) for storing the entire tree.\n/// `n` denotes the number of key-value entries (i.e. nodes) stored in the tree.\n/// :::\n///\n/// :::note\n/// Tree insertion, replacement, and removal produce `O(log(n))` garbage objects.\n/// :::\n///\n/// :::info Credits\n/// The core of this implementation is derived from:\n///\n/// * Ken Friis Larsen's [RedBlackMap.sml](https://github.com/kfl/mosml/blob/master/src/mosmllib/Redblackmap.sml), which itself is based on:\n/// * Stefan Kahrs, \"Red-black trees with types\", Journal of Functional Programming, 11(4): 425-432 (2001), [version 1 in web appendix](http://www.cs.ukc.ac.uk/people/staff/smk/redblack/rb.html).\n/// :::\n\nimport Debug \"Debug\";\nimport I \"Iter\";\nimport List \"List\";\nimport Nat \"Nat\";\nimport O \"Order\";\n\n// TODO: a faster, more compact and less indirect representation would be:\n// type Tree<K, V> = {\n//  #red : (Tree<K, V>, K, V, Tree<K, V>);\n//  #black : (Tree<K, V>, K, V, Tree<K, V>);\n//  #leaf\n//};\n// (this inlines the colors into the variant, flattens a tuple, and removes a (now) redundant optin, for considerable heap savings.)\n// It would also make sense to maintain the size in a separate root for 0(1) access.\n\n// FUTURE: deprecate RBTree.mo and replace by RedBlackMap.mo, using this new representation\n\nmodule {\n\n  /// Node color: Either red (`#R`) or black (`#B`).\n  public type Color = { #R; #B };\n\n  /// Red-black tree of nodes with key-value entries, ordered by the keys.\n  /// The keys have the generic type `K` and the values the generic type `V`.\n  /// Leaves are considered implicitly black.\n  public type Tree<K, V> = {\n    #node : (Color, Tree<K, V>, (K, ?V), Tree<K, V>);\n    #leaf\n  };\n\n  /// A map from keys of type `K` to values of type `V` implemented as a red-black tree.\n  /// The entries of key-value pairs are ordered by `compare` function applied to the keys.\n  ///\n  /// The class enables imperative usage in object-oriented-style.\n  /// However, internally, the class uses a functional implementation.\n  ///\n  /// The `compare` function should implement a consistent total order among all possible values of `K` and\n  /// for efficiency, only involves `O(1)` runtime costs without space allocation.\n  ///\n  /// Example:\n  /// ```motoko name=initialize\n  /// import RBTree \"mo:base/RBTree\";\n  /// import Nat \"mo:base/Nat\";\n  ///\n  /// let tree = RBTree.RBTree<Nat, Text>(Nat.compare); // Create a map of `Nat` to `Text` using the `Nat.compare` order\n  /// ```\n  ///\n  /// | Runtime        | Space (Heap) | Space (Stack) |\n  /// |----------------|--------------|----------------|\n  /// | `O(1)`  | `O(1))`        | `O(1))`    |\n  public class RBTree<K, V>(compare : (K, K) -> O.Order) {\n\n    var tree : Tree<K, V> = (#leaf : Tree<K, V>);\n\n    /// Return a snapshot of the internal functional tree representation as sharable data.\n    /// The returned tree representation is not affected by subsequent changes of the `RBTree` instance.\n    ///\n    ///\n    /// Example:\n    /// ```motoko include=initialize\n    /// tree.put(1, \"one\");\n    /// let treeSnapshot = tree.share();\n    /// tree.put(2, \"second\");\n    /// RBTree.size(treeSnapshot) // => 1 (Only the first insertion is part of the snapshot.)\n    /// ```\n    ///\n    /// Useful for storing the state of a tree object as a stable variable, determining its size, pretty-printing, and sharing it across async function calls,\n    /// i.e. passing it in async arguments or async results.\n    ///\n    /// | Runtime        | Space (Heap) | Space (Stack) |\n    /// |----------------|--------------|----------------|\n    /// | `O(1)`  | `O(1))`        | `O(1))`    |\n    public func share() : Tree<K, V> {\n      tree\n    };\n\n    /// Reset the current state of the tree object from a functional tree representation.\n    ///\n    /// Example:\n    /// ```motoko include=initialize\n    /// import Iter \"mo:base/Iter\";\n    ///\n    /// tree.put(1, \"one\");\n    /// let snapshot = tree.share(); // save the current state of the tree object in a snapshot\n    /// tree.put(2, \"two\");\n    /// tree.unshare(snapshot); // restore the tree object from the snapshot\n    /// Iter.toArray(tree.entries()) // => [(1, \"one\")]\n    /// ```\n    ///\n    /// Useful for restoring the state of a tree object from stable data, saved, for example, in a stable variable.\n    ///\n    /// | Runtime        | Space (Heap) | Space (Stack) |\n    /// |----------------|--------------|----------------|\n    /// | `O(1)`  | `O(1))`       | `O(1))`    |\n    public func unshare(t : Tree<K, V>) : () {\n      tree := t\n    };\n\n    /// Retrieve the value associated with a given key, if present. Returns `null`, if the key is absent.\n    /// The key is searched according to the `compare` function defined on the class instantiation.\n    ///\n    /// Example:\n    /// ```motoko include=initialize\n    ///\n    /// tree.put(1, \"one\");\n    /// tree.put(2, \"two\");\n    ///\n    /// tree.get(1) // => ?\"one\"\n    /// ```\n    ///\n    /// | Runtime        | Space (Heap) | Space (Stack) |\n    /// |----------------|--------------|----------------|\n    /// | `O(log(n))`  | `O(1))` retained + garbage        | `O(log(n))`    |\n    public func get(key : K) : ?V {\n      getRec(key, compare, tree)\n    };\n\n    /// Replace the value associated with a given key, if the key is present.\n    /// Otherwise, if the key does not yet exist, insert the key-value entry.\n    ///\n    /// Returns the previous value of the key, if the key already existed.\n    /// Otherwise, `null`, if the key did not yet exist before.\n    ///\n    /// Example:\n    /// ```motoko include=initialize\n    /// import Iter \"mo:base/Iter\";\n    ///\n    /// tree.put(1, \"old one\");\n    /// tree.put(2, \"two\");\n    ///\n    /// ignore tree.replace(1, \"new one\");\n    /// Iter.toArray(tree.entries()) // => [(1, \"new one\"), (2, \"two\")]\n    /// ```\n    ///\n    /// | Runtime        | Space (Heap) | Space (Stack) |\n    /// |----------------|--------------|----------------|\n    /// | `O(log(n))`  | `O(1))` retained + garbage        | `O(log(n))`    |\n    public func replace(key : K, value : V) : ?V {\n      let (t, res) = insert(tree, compare, key, value);\n      tree := t;\n      res\n    };\n\n    /// Insert a key-value entry in the tree. If the key already exists, it overwrites the associated value.\n    ///\n    /// Example:\n    /// ```motoko include=initialize\n    /// import Iter \"mo:base/Iter\";\n    ///\n    /// tree.put(1, \"one\");\n    /// tree.put(2, \"two\");\n    /// tree.put(3, \"three\");\n    /// Iter.toArray(tree.entries()) // now contains three entries\n    /// ```\n    ///\n    /// | Runtime        | Space (Heap) | Space (Stack) |\n    /// |----------------|--------------|----------------|\n    /// | `O(log(n))`  | `O(1))` retained + garbage        | `O(log(n))`    |\n    public func put(key : K, value : V) {\n      let (t, _res) = insert(tree, compare, key, value);\n      tree := t\n    };\n\n    /// Delete the entry associated with a given key, if the key exists.\n    /// No effect if the key is absent. Same as `remove(key)` except that it\n    /// does not have a return value.\n    ///\n    /// Example:\n    /// ```motoko include=initialize\n    /// import Iter \"mo:base/Iter\";\n    ///\n    /// tree.put(1, \"one\");\n    /// tree.put(2, \"two\");\n    ///\n    /// tree.delete(1);\n    /// Iter.toArray(tree.entries()) // => [(2, \"two\")].\n    /// ```\n    ///\n    /// | Runtime        | Space (Heap) | Space (Stack) |\n    /// |----------------|--------------|----------------|\n    /// | `O(log(n))`  | `O(1))` retained + garbage        | `O(log(n))`    |\n    public func delete(key : K) {\n      let (_res, t) = removeRec(key, compare, tree);\n      tree := t\n    };\n\n    /// Remove the entry associated with a given key, if the key exists, and return the associated value.\n    /// Returns `null` without any other effect if the key is absent.\n    ///\n    /// Example:\n    /// ```motoko include=initialize\n    /// import Iter \"mo:base/Iter\";\n    ///\n    /// tree.put(1, \"one\");\n    /// tree.put(2, \"two\");\n    ///\n    /// ignore tree.remove(1);\n    /// Iter.toArray(tree.entries()) // => [(2, \"two\")].\n    /// ```\n    ///\n    /// | Runtime        | Space (Heap) | Space (Stack) |\n    /// |----------------|--------------|----------------|\n    /// | `O(log(n))`  | `O(1))` retained + garbage        | `O(log(n))`    |\n    public func remove(key : K) : ?V {\n      let (res, t) = removeRec(key, compare, tree);\n      tree := t;\n      res\n    };\n\n    /// An iterator for the key-value entries of the map, in ascending key order.\n    /// The iterator takes a snapshot view of the tree and is not affected by concurrent modifications.\n    ///\n    /// Example:\n    /// ```motoko include=initialize\n    /// import Debug \"mo:base/Debug\";\n    ///\n    /// tree.put(1, \"one\");\n    /// tree.put(2, \"two\");\n    /// tree.put(3, \"two\");\n    ///\n    /// for (entry in tree.entries()) {\n    ///   Debug.print(\"Entry key=\" # debug_show(entry.0) # \" value=\\\"\" # entry.1 #\"\\\"\");\n    /// }\n    ///\n    /// // Entry key=1 value=\"one\"\n    /// // Entry key=2 value=\"two\"\n    /// // Entry key=3 value=\"three\"\n    /// ```\n    ///\n\n    /// | Runtime        | Space (Heap) | Space (Stack) |\n    /// |----------------|--------------|----------------|\n    /// | `O(n)`  | `O(log(n))` retained + garbage        | `O(log(n))`    |\n    public func entries() : I.Iter<(K, V)> { iter(tree, #fwd) };\n\n    /// An iterator for the key-value entries of the map, in descending key order.\n    /// The iterator takes a snapshot view of the tree and is not affected by concurrent modifications.\n    ///\n    /// Example:\n    /// ```motoko include=initialize\n    /// import Debug \"mo:base/Debug\";\n    ///\n    /// let tree = RBTree.RBTree<Nat, Text>(Nat.compare);\n    /// tree.put(1, \"one\");\n    /// tree.put(2, \"two\");\n    /// tree.put(3, \"two\");\n    ///\n    /// for (entry in tree.entriesRev()) {\n    ///   Debug.print(\"Entry key=\" # debug_show(entry.0) # \" value=\\\"\" # entry.1 #\"\\\"\");\n    /// }\n    ///\n    /// // Entry key=3 value=\"three\"\n    /// // Entry key=2 value=\"two\"\n    /// // Entry key=1 value=\"one\"\n    /// ```\n    ///\n\n    /// | Runtime        | Space (Heap) | Space (Stack) |\n    /// |----------------|--------------|----------------|\n    /// | `O(n)`  | `O(log(n))` retained + garbage        | `O(log(n))`    |\n    public func entriesRev() : I.Iter<(K, V)> { iter(tree, #bwd) };\n\n  }; // end class\n\n  type IterRep<X, Y> = List.List<{ #tr : Tree<X, Y>; #xy : (X, ?Y) }>;\n\n  /// Get an iterator for the entries of the `tree`, in ascending (`#fwd`) or descending (`#bwd`) order as specified by `direction`.\n  /// The iterator takes a snapshot view of the tree and is not affected by concurrent modifications.\n  ///\n  /// Example:\n  /// ```motoko\n  /// import RBTree \"mo:base/RBTree\";\n  /// import Nat \"mo:base/Nat\";\n  /// import Debug \"mo:base/Debug\";\n  ///\n  /// let tree = RBTree.RBTree<Nat, Text>(Nat.compare);\n  /// tree.put(1, \"one\");\n  /// tree.put(2, \"two\");\n  /// tree.put(3, \"two\");\n  ///\n  /// for (entry in RBTree.iter(tree.share(), #bwd)) { // backward iteration\n  ///   Debug.print(\"Entry key=\" # debug_show(entry.0) # \" value=\\\"\" # entry.1 #\"\\\"\");\n  /// }\n  ///\n  /// // Entry key=3 value=\"three\"\n  /// // Entry key=2 value=\"two\"\n  /// // Entry key=1 value=\"one\"\n  /// ```\n  ///\n\n  /// | Runtime        | Space (Heap) | Space (Stack) |\n  /// |----------------|--------------|----------------|\n  /// | `O(n)`  | `O(log(n))` retained + garbage        | `O(log(n))`    |\n  public func iter<X, Y>(tree : Tree<X, Y>, direction : { #fwd; #bwd }) : I.Iter<(X, Y)> {\n    object {\n      var trees : IterRep<X, Y> = ?(#tr(tree), null);\n      public func next() : ?(X, Y) {\n        switch (direction, trees) {\n          case (_, null) { null };\n          case (_, ?(#tr(#leaf), ts)) {\n            trees := ts;\n            next()\n          };\n          case (_, ?(#xy(xy), ts)) {\n            trees := ts;\n            switch (xy.1) {\n              case null { next() };\n              case (?y) { ?(xy.0, y) }\n            }\n          };\n          case (#fwd, ?(#tr(#node(_, l, xy, r)), ts)) {\n            trees := ?(#tr(l), ?(#xy(xy), ?(#tr(r), ts)));\n            next()\n          };\n          case (#bwd, ?(#tr(#node(_, l, xy, r)), ts)) {\n            trees := ?(#tr(r), ?(#xy(xy), ?(#tr(l), ts)));\n            next()\n          }\n        }\n      }\n    }\n  };\n\n  /// Remove the value associated with a given key.\n  func removeRec<X, Y>(x : X, compare : (X, X) -> O.Order, t : Tree<X, Y>) : (?Y, Tree<X, Y>) {\n    let (t1, r) = remove(t, compare, x);\n    (r, t1)\n  };\n\n  func getRec<X, Y>(x : X, compare : (X, X) -> O.Order, t : Tree<X, Y>) : ?Y {\n    switch t {\n      case (#leaf) { null };\n      case (#node(_c, l, xy, r)) {\n        switch (compare(x, xy.0)) {\n          case (#less) { getRec(x, compare, l) };\n          case (#equal) { xy.1 };\n          case (#greater) { getRec(x, compare, r) }\n        }\n      }\n    }\n  };\n\n  /// Determine the size of the tree as the number of key-value entries.\n  ///\n  /// Example:\n  /// ```motoko\n  /// import RBTree \"mo:base/RBTree\";\n  /// import Nat \"mo:base/Nat\";\n  ///\n  /// let tree = RBTree.RBTree<Nat, Text>(Nat.compare);\n  /// tree.put(1, \"one\");\n  /// tree.put(2, \"two\");\n  /// tree.put(3, \"three\");\n  ///\n  /// RBTree.size(tree.share()) // 3 entries\n  /// ```\n  ///\n  /// | Runtime        | Space (Heap) | Space (Stack) |\n  /// |----------------|--------------|----------------|\n  /// | `O(log(n))`  | `O(1)`         | `O(log(n))`    |\n  public func size<X, Y>(t : Tree<X, Y>) : Nat {\n    switch t {\n      case (#leaf) { 0 };\n      case (#node(_, l, xy, r)) {\n        size(l) + size(r) + (switch (xy.1) { case null 0; case _ 1 })\n      }\n    }\n  };\n\n  func redden<X, Y>(t : Tree<X, Y>) : Tree<X, Y> {\n    switch t {\n      case (#node(#B, l, xy, r)) { (#node(#R, l, xy, r)) };\n      case _ {\n        Debug.trap \"RBTree.red\"\n      }\n    }\n  };\n\n  func lbalance<X, Y>(left : Tree<X, Y>, xy : (X, ?Y), right : Tree<X, Y>) : Tree<X, Y> {\n    switch (left, right) {\n      case (#node(#R, #node(#R, l1, xy1, r1), xy2, r2), r) {\n        #node(\n          #R,\n          #node(#B, l1, xy1, r1),\n          xy2,\n          #node(#B, r2, xy, r)\n        )\n      };\n      case (#node(#R, l1, xy1, #node(#R, l2, xy2, r2)), r) {\n        #node(\n          #R,\n          #node(#B, l1, xy1, l2),\n          xy2,\n          #node(#B, r2, xy, r)\n        )\n      };\n      case _ {\n        #node(#B, left, xy, right)\n      }\n    }\n  };\n\n  func rbalance<X, Y>(left : Tree<X, Y>, xy : (X, ?Y), right : Tree<X, Y>) : Tree<X, Y> {\n    switch (left, right) {\n      case (l, #node(#R, l1, xy1, #node(#R, l2, xy2, r2))) {\n        #node(\n          #R,\n          #node(#B, l, xy, l1),\n          xy1,\n          #node(#B, l2, xy2, r2)\n        )\n      };\n      case (l, #node(#R, #node(#R, l1, xy1, r1), xy2, r2)) {\n        #node(\n          #R,\n          #node(#B, l, xy, l1),\n          xy1,\n          #node(#B, r1, xy2, r2)\n        )\n      };\n      case _ {\n        #node(#B, left, xy, right)\n      }\n    }\n  };\n\n  func insert<X, Y>(\n    tree : Tree<X, Y>,\n    compare : (X, X) -> O.Order,\n    x : X,\n    y : Y\n  ) : (Tree<X, Y>, ?Y) {\n    var y0 : ?Y = null;\n    func ins(tree : Tree<X, Y>) : Tree<X, Y> {\n      switch tree {\n        case (#leaf) {\n          #node(#R, #leaf, (x, ?y), #leaf)\n        };\n        case (#node(#B, left, xy, right)) {\n          switch (compare(x, xy.0)) {\n            case (#less) {\n              lbalance(ins left, xy, right)\n            };\n            case (#greater) {\n              rbalance(left, xy, ins right)\n            };\n            case (#equal) {\n              y0 := xy.1;\n              #node(#B, left, (x, ?y), right)\n            }\n          }\n        };\n        case (#node(#R, left, xy, right)) {\n          switch (compare(x, xy.0)) {\n            case (#less) {\n              #node(#R, ins left, xy, right)\n            };\n            case (#greater) {\n              #node(#R, left, xy, ins right)\n            };\n            case (#equal) {\n              y0 := xy.1;\n              #node(#R, left, (x, ?y), right)\n            }\n          }\n        }\n      }\n    };\n    switch (ins tree) {\n      case (#node(#R, left, xy, right)) {\n        (#node(#B, left, xy, right), y0)\n      };\n      case other { (other, y0) }\n    }\n  };\n\n  func balLeft<X, Y>(left : Tree<X, Y>, xy : (X, ?Y), right : Tree<X, Y>) : Tree<X, Y> {\n    switch (left, right) {\n      case (#node(#R, l1, xy1, r1), r) {\n        #node(\n          #R,\n          #node(#B, l1, xy1, r1),\n          xy,\n          r\n        )\n      };\n      case (_, #node(#B, l2, xy2, r2)) {\n        rbalance(left, xy, #node(#R, l2, xy2, r2))\n      };\n      case (_, #node(#R, #node(#B, l2, xy2, r2), xy3, r3)) {\n        #node(\n          #R,\n          #node(#B, left, xy, l2),\n          xy2,\n          rbalance(r2, xy3, redden r3)\n        )\n      };\n      case _ { Debug.trap \"balLeft\" }\n    }\n  };\n\n  func balRight<X, Y>(left : Tree<X, Y>, xy : (X, ?Y), right : Tree<X, Y>) : Tree<X, Y> {\n    switch (left, right) {\n      case (l, #node(#R, l1, xy1, r1)) {\n        #node(\n          #R,\n          l,\n          xy,\n          #node(#B, l1, xy1, r1)\n        )\n      };\n      case (#node(#B, l1, xy1, r1), r) {\n        lbalance(#node(#R, l1, xy1, r1), xy, r)\n      };\n      case (#node(#R, l1, xy1, #node(#B, l2, xy2, r2)), r3) {\n        #node(\n          #R,\n          lbalance(redden l1, xy1, l2),\n          xy2,\n          #node(#B, r2, xy, r3)\n        )\n      };\n      case _ { Debug.trap \"balRight\" }\n    }\n  };\n\n  func append<X, Y>(left : Tree<X, Y>, right : Tree<X, Y>) : Tree<X, Y> {\n    switch (left, right) {\n      case (#leaf, _) { right };\n      case (_, #leaf) { left };\n      case (\n        #node(#R, l1, xy1, r1),\n        #node(#R, l2, xy2, r2)\n      ) {\n        switch (append(r1, l2)) {\n          case (#node(#R, l3, xy3, r3)) {\n            #node(\n              #R,\n              #node(#R, l1, xy1, l3),\n              xy3,\n              #node(#R, r3, xy2, r2)\n            )\n          };\n          case r1l2 {\n            #node(#R, l1, xy1, #node(#R, r1l2, xy2, r2))\n          }\n        }\n      };\n      case (t1, #node(#R, l2, xy2, r2)) {\n        #node(#R, append(t1, l2), xy2, r2)\n      };\n      case (#node(#R, l1, xy1, r1), t2) {\n        #node(#R, l1, xy1, append(r1, t2))\n      };\n      case (#node(#B, l1, xy1, r1), #node(#B, l2, xy2, r2)) {\n        switch (append(r1, l2)) {\n          case (#node(#R, l3, xy3, r3)) {\n            #node(\n              #R,\n              #node(#B, l1, xy1, l3),\n              xy3,\n              #node(#B, r3, xy2, r2)\n            )\n          };\n          case r1l2 {\n            balLeft(\n              l1,\n              xy1,\n              #node(#B, r1l2, xy2, r2)\n            )\n          }\n        }\n      }\n    }\n  };\n\n  func remove<X, Y>(tree : Tree<X, Y>, compare : (X, X) -> O.Order, x : X) : (Tree<X, Y>, ?Y) {\n    var y0 : ?Y = null;\n    func delNode(left : Tree<X, Y>, xy : (X, ?Y), right : Tree<X, Y>) : Tree<X, Y> {\n      switch (compare(x, xy.0)) {\n        case (#less) {\n          let newLeft = del left;\n          switch left {\n            case (#node(#B, _, _, _)) {\n              balLeft(newLeft, xy, right)\n            };\n            case _ {\n              #node(#R, newLeft, xy, right)\n            }\n          }\n        };\n        case (#greater) {\n          let newRight = del right;\n          switch right {\n            case (#node(#B, _, _, _)) {\n              balRight(left, xy, newRight)\n            };\n            case _ {\n              #node(#R, left, xy, newRight)\n            }\n          }\n        };\n        case (#equal) {\n          y0 := xy.1;\n          append(left, right)\n        }\n      }\n    };\n    func del(tree : Tree<X, Y>) : Tree<X, Y> {\n      switch tree {\n        case (#leaf) {\n          tree\n        };\n        case (#node(_, left, xy, right)) {\n          delNode(left, xy, right)\n        }\n      }\n    };\n    switch (del(tree)) {\n      case (#node(#R, left, xy, right)) {\n        (#node(#B, left, xy, right), y0)\n      };\n      case other { (other, y0) }\n    }\n  }\n\n}\n"},"Region.mo":{"content":"/// Byte-level access to isolated, (virtual) stable memory _regions_.\n///\n/// This is a moderately lightweight abstraction over IC _stable memory_ and supports persisting\n/// regions of binary data across Motoko upgrades.\n/// Use of this module is fully compatible with Motoko's use of\n/// _stable variables_, whose persistence mechanism also uses (real) IC stable memory internally, but does not interfere with this API.\n/// It is also fully compatible with existing uses of the `ExperimentalStableMemory` library, which has a similar interface, but,\n/// only supported a single memory region, without isolation between different applications.\n///\n/// The `Region` type is stable and can be used in stable data structures.\n///\n/// A new, empty `Region` is allocated using function `new()`.\n///\n/// Regions are stateful objects and can be distinguished by the numeric identifier returned by function `id(region)`.\n/// Every region owns an initially empty, but growable sequence of virtual IC stable memory pages.\n/// The current size, in pages, of a region is returned by function `size(region)`.\n/// The size of a region determines the range, [ 0, ..., size(region)*2^16 ), of valid byte-offsets into the region; these offsets are used as the source and destination of `load`/`store` operations on the region.\n///\n/// Memory is allocated to a region, using function `grow(region, pages)`, sequentially and on demand, in units of 64KiB logical pages, starting with 0 allocated pages.\n/// A call to `grow` may succeed, returning the previous size of the region, or fail, returning a sentinel value. New pages are zero initialized.\n///\n/// A size of a region can only grow and never shrink.\n/// In addition, the stable memory pages allocated to a region will *not* be reclaimed by garbage collection, even\n/// if the region object itself becomes unreachable.\n///\n/// Growth is capped by a soft limit on physical page count controlled by compile-time flag\n/// `--max-stable-pages <n>` (the default is 65536, or 4GiB).\n///\n/// Each `load` operation loads from region relative byte address `offset` in little-endian\n/// format using the natural bit-width of the type in question.\n/// The operation traps if attempting to read beyond the current region size.\n///\n/// Each `store` operation stores to region relative byte address `offset` in little-endian format using the natural bit-width of the type in question.\n/// The operation traps if attempting to write beyond the current region size.\n///\n/// Text values can be handled by using `Text.decodeUtf8` and `Text.encodeUtf8`, in conjunction with `loadBlob` and `storeBlob`.\n///\n/// The current region allocation and region contents are preserved across upgrades.\n///\n/// NB: The IC's actual stable memory size (`ic0.stable_size`) may exceed the\n/// total page size reported by summing all regions sizes.\n/// This (and the cap on growth) are to accommodate Motoko's stable variables and bookkeeping for regions.\n/// Applications that plan to use Motoko stable variables sparingly or not at all can\n/// increase `--max-stable-pages` as desired, approaching the IC maximum (initially 8GiB, then 32Gib, currently 64Gib).\n/// All applications should reserve at least one page for stable variable data, even when no stable variables are used.\n///\n/// Usage:\n/// ```motoko no-repl\n/// import Region \"mo:base/Region\";\n/// ```\n\nimport Prim \"mo:⛔\";\n\nmodule {\n\n  /// A stateful handle to an isolated region of IC stable memory.\n  /// `Region` is a stable type and regions can be stored in stable variables.\n  public type Region = Prim.Types.Region;\n\n  /// Allocate a new, isolated Region of size 0.\n  ///\n  /// Example:\n  ///\n  /// ```motoko no-repl\n  /// let region = Region.new();\n  /// assert Region.size(region) == 0;\n  /// ```\n  public let new : () -> Region = Prim.regionNew;\n\n  /// Return a Nat identifying the given region.\n  /// Maybe be used for equality, comparison and hashing.\n  /// NB: Regions returned by `new()` are numbered from 16\n  /// (regions 0..15 are currently reserved for internal use).\n  /// Allocate a new, isolated Region of size 0.\n  ///\n  /// Example:\n  ///\n  /// ```motoko no-repl\n  /// let region = Region.new();\n  /// assert Region.id(region) == 16;\n  /// ```\n  public let id : Region -> Nat = Prim.regionId;\n\n  /// Current size of `region`, in pages.\n  /// Each page is 64KiB (65536 bytes).\n  /// Initially `0`.\n  /// Preserved across upgrades, together with contents of allocated\n  /// stable memory.\n  ///\n  /// Example:\n  /// ```motoko no-repl\n  /// let region = Region.new();\n  /// let beforeSize = Region.size(region);\n  /// ignore Region.grow(region, 10);\n  /// let afterSize = Region.size(region);\n  /// afterSize - beforeSize // => 10\n  /// ```\n  public let size : (region : Region) -> (pages : Nat64) = Prim.regionSize;\n\n  /// Grow current `size` of `region` by the given number of pages.\n  /// Each page is 64KiB (65536 bytes).\n  /// Returns the previous `size` when able to grow.\n  /// Returns `0xFFFF_FFFF_FFFF_FFFF` if remaining pages insufficient.\n  /// Every new page is zero-initialized, containing byte 0x00 at every offset.\n  /// Function `grow` is capped by a soft limit on `size` controlled by compile-time flag\n  ///  `--max-stable-pages <n>` (the default is 65536, or 4GiB).\n  ///\n  /// Example:\n  /// ```motoko no-repl\n  /// import Error \"mo:base/Error\";\n  ///\n  /// let region = Region.new();\n  /// let beforeSize = Region.grow(region, 10);\n  /// if (beforeSize == 0xFFFF_FFFF_FFFF_FFFF) {\n  ///   throw Error.reject(\"Out of memory\");\n  /// };\n  /// let afterSize = Region.size(region);\n  /// afterSize - beforeSize // => 10\n  /// ```\n  public let grow : (region : Region, newPages : Nat64) -> (oldPages : Nat64) = Prim.regionGrow;\n\n  /// Within `region`, load a `Nat8` value from `offset`.\n  /// Traps on an out-of-bounds access.\n  ///\n  /// Example:\n  /// ```motoko no-repl\n  /// let region = Region.new();\n  /// let offset = 0;\n  /// let value = 123;\n  /// Region.storeNat8(region, offset, value);\n  /// Region.loadNat8(region, offset) // => 123\n  /// ```\n  public let loadNat8 : (region : Region, offset : Nat64) -> Nat8 = Prim.regionLoadNat8;\n\n  /// Within `region`, store a `Nat8` value at `offset`.\n  /// Traps on an out-of-bounds access.\n  ///\n  /// Example:\n  /// ```motoko no-repl\n  /// let region = Region.new();\n  /// let offset = 0;\n  /// let value = 123;\n  /// Region.storeNat8(region, offset, value);\n  /// Region.loadNat8(region, offset) // => 123\n  /// ```\n  public let storeNat8 : (region : Region, offset : Nat64, value : Nat8) -> () = Prim.regionStoreNat8;\n\n  /// Within `region`, load a `Nat16` value from `offset`.\n  /// Traps on an out-of-bounds access.\n  ///\n  /// Example:\n  /// ```motoko no-repl\n  /// let region = Region.new();\n  /// let offset = 0;\n  /// let value = 123;\n  /// Region.storeNat16(region, offset, value);\n  /// Region.loadNat16(region, offset) // => 123\n  /// ```\n  public let loadNat16 : (region : Region, offset : Nat64) -> Nat16 = Prim.regionLoadNat16;\n\n  /// Within `region`, store a `Nat16` value at `offset`.\n  /// Traps on an out-of-bounds access.\n  ///\n  /// Example:\n  /// ```motoko no-repl\n  /// let region = Region.new();\n  /// let offset = 0;\n  /// let value = 123;\n  /// Region.storeNat16(region, offset, value);\n  /// Region.loadNat16(region, offset) // => 123\n  /// ```\n  public let storeNat16 : (region : Region, offset : Nat64, value : Nat16) -> () = Prim.regionStoreNat16;\n\n  /// Within `region`, load a `Nat32` value from `offset`.\n  /// Traps on an out-of-bounds access.\n  ///\n  /// Example:\n  /// ```motoko no-repl\n  /// let region = Region.new();\n  /// let offset = 0;\n  /// let value = 123;\n  /// Region.storeNat32(region, offset, value);\n  /// Region.loadNat32(region, offset) // => 123\n  /// ```\n  public let loadNat32 : (region : Region, offset : Nat64) -> Nat32 = Prim.regionLoadNat32;\n\n  /// Within `region`, store a `Nat32` value at `offset`.\n  /// Traps on an out-of-bounds access.\n  ///\n  /// Example:\n  /// ```motoko no-repl\n  /// let region = Region.new();\n  /// let offset = 0;\n  /// let value = 123;\n  /// Region.storeNat32(region, offset, value);\n  /// Region.loadNat32(region, offset) // => 123\n  /// ```\n  public let storeNat32 : (region : Region, offset : Nat64, value : Nat32) -> () = Prim.regionStoreNat32;\n\n  /// Within `region`, load a `Nat64` value from `offset`.\n  /// Traps on an out-of-bounds access.\n  ///\n  /// Example:\n  /// ```motoko no-repl\n  /// let region = Region.new();\n  /// let offset = 0;\n  /// let value = 123;\n  /// Region.storeNat64(region, offset, value);\n  /// Region.loadNat64(region, offset) // => 123\n  /// ```\n  public let loadNat64 : (region : Region, offset : Nat64) -> Nat64 = Prim.regionLoadNat64;\n\n  /// Within `region`, store a `Nat64` value at `offset`.\n  /// Traps on an out-of-bounds access.\n  ///\n  /// Example:\n  /// ```motoko no-repl\n  /// let region = Region.new();\n  /// let offset = 0;\n  /// let value = 123;\n  /// Region.storeNat64(region, offset, value);\n  /// Region.loadNat64(region, offset) // => 123\n  /// ```\n  public let storeNat64 : (region : Region, offset : Nat64, value : Nat64) -> () = Prim.regionStoreNat64;\n\n  /// Within `region`, load a `Int8` value from `offset`.\n  /// Traps on an out-of-bounds access.\n  ///\n  /// Example:\n  /// ```motoko no-repl\n  /// let region = Region.new();\n  /// let offset = 0;\n  /// let value = 123;\n  /// Region.storeInt8(region, offset, value);\n  /// Region.loadInt8(region, offset) // => 123\n  /// ```\n  public let loadInt8 : (region : Region, offset : Nat64) -> Int8 = Prim.regionLoadInt8;\n\n  /// Within `region`, store a `Int8` value at `offset`.\n  /// Traps on an out-of-bounds access.\n  ///\n  /// Example:\n  /// ```motoko no-repl\n  /// let region = Region.new();\n  /// let offset = 0;\n  /// let value = 123;\n  /// Region.storeInt8(region, offset, value);\n  /// Region.loadInt8(region, offset) // => 123\n  /// ```\n  public let storeInt8 : (region : Region, offset : Nat64, value : Int8) -> () = Prim.regionStoreInt8;\n\n  /// Within `region`, load a `Int16` value from `offset`.\n  /// Traps on an out-of-bounds access.\n  ///\n  /// Example:\n  /// ```motoko no-repl\n  /// let region = Region.new();\n  /// let offset = 0;\n  /// let value = 123;\n  /// Region.storeInt16(region, offset, value);\n  /// Region.loadInt16(region, offset) // => 123\n  /// ```\n  public let loadInt16 : (region : Region, offset : Nat64) -> Int16 = Prim.regionLoadInt16;\n\n  /// Within `region`, store a `Int16` value at `offset`.\n  /// Traps on an out-of-bounds access.\n  ///\n  /// Example:\n  /// ```motoko no-repl\n  /// let region = Region.new();\n  /// let offset = 0;\n  /// let value = 123;\n  /// Region.storeInt16(region, offset, value);\n  /// Region.loadInt16(region, offset) // => 123\n  /// ```\n  public let storeInt16 : (region : Region, offset : Nat64, value : Int16) -> () = Prim.regionStoreInt16;\n\n  /// Within `region`, load a `Int32` value from `offset`.\n  /// Traps on an out-of-bounds access.\n  ///\n  /// Example:\n  /// ```motoko no-repl\n  /// let region = Region.new();\n  /// let offset = 0;\n  /// let value = 123;\n  /// Region.storeInt32(region, offset, value);\n  /// Region.loadInt32(region, offset) // => 123\n  /// ```\n  public let loadInt32 : (region : Region, offset : Nat64) -> Int32 = Prim.regionLoadInt32;\n\n  /// Within `region`, store a `Int32` value at `offset`.\n  /// Traps on an out-of-bounds access.\n  ///\n  /// Example:\n  /// ```motoko no-repl\n  /// let region = Region.new();\n  /// let offset = 0;\n  /// let value = 123;\n  /// Region.storeInt32(region, offset, value);\n  /// Region.loadInt32(region, offset) // => 123\n  /// ```\n  public let storeInt32 : (region : Region, offset : Nat64, value : Int32) -> () = Prim.regionStoreInt32;\n\n  /// Within `region`, load a `Int64` value from `offset`.\n  /// Traps on an out-of-bounds access.\n  ///\n  /// Example:\n  /// ```motoko no-repl\n  /// let region = Region.new();\n  /// let offset = 0;\n  /// let value = 123;\n  /// Region.storeInt64(region, offset, value);\n  /// Region.loadInt64(region, offset) // => 123\n  /// ```\n  public let loadInt64 : (region : Region, offset : Nat64) -> Int64 = Prim.regionLoadInt64;\n\n  /// Within `region`, store a `Int64` value at `offset`.\n  /// Traps on an out-of-bounds access.\n  ///\n  /// Example:\n  /// ```motoko no-repl\n  /// let region = Region.new();\n  /// let offset = 0;\n  /// let value = 123;\n  /// Region.storeInt64(region, offset, value);\n  /// Region.loadInt64(region, offset) // => 123\n  /// ```\n  public let storeInt64 : (region : Region, offset : Nat64, value : Int64) -> () = Prim.regionStoreInt64;\n\n  /// Within `region`, loads a `Float` value from the given `offset`.\n  /// Traps on an out-of-bounds access.\n  ///\n  /// Example:\n  /// ```motoko no-repl\n  /// let region = Region.new();\n  /// let offset = 0;\n  /// let value = 1.25;\n  /// Region.storeFloat(region, offset, value);\n  /// Region.loadFloat(region, offset) // => 1.25\n  /// ```\n  public let loadFloat : (region : Region, offset : Nat64) -> Float = Prim.regionLoadFloat;\n\n  /// Within `region`, store float `value` at the given `offset`.\n  /// Traps on an out-of-bounds access.\n  ///\n  /// Example:\n  /// ```motoko no-repl\n  /// let region = Region.new();\n  /// let offset = 0;\n  /// let value = 1.25;\n  /// Region.storeFloat(region, offset, value);\n  /// Region.loadFloat(region, offset) // => 1.25\n  /// ```\n  public let storeFloat : (region : Region, offset : Nat64, value : Float) -> () = Prim.regionStoreFloat;\n\n  /// Within `region,` load `size` bytes starting from `offset` as a `Blob`.\n  /// Traps on an out-of-bounds access.\n  ///\n  /// Example:\n  /// ```motoko no-repl\n  /// import Blob \"mo:base/Blob\";\n  ///\n  /// let region = Region.new();\n  /// let offset = 0;\n  /// let value = Blob.fromArray([1, 2, 3]);\n  /// let size = value.size();\n  /// Region.storeBlob(region, offset, value);\n  /// Blob.toArray(Region.loadBlob(region, offset, size)) // => [1, 2, 3]\n  /// ```\n  public let loadBlob : (region : Region, offset : Nat64, size : Nat) -> Blob = Prim.regionLoadBlob;\n\n  /// Within `region, write `blob.size()` bytes of `blob` beginning at `offset`.\n  /// Traps on an out-of-bounds access.\n  ///\n  /// Example:\n  /// ```motoko no-repl\n  /// import Blob \"mo:base/Blob\";\n  ///\n  /// let region = Region.new();\n  /// let offset = 0;\n  /// let value = Blob.fromArray([1, 2, 3]);\n  /// let size = value.size();\n  /// Region.storeBlob(region, offset, value);\n  /// Blob.toArray(Region.loadBlob(region, offset, size)) // => [1, 2, 3]\n  /// ```\n  public let storeBlob : (region : Region, offset : Nat64, value : Blob) -> () = Prim.regionStoreBlob;\n\n}\n"},"Nat16.mo":{"content":"/// Provides utility functions on 16-bit unsigned integers.\n///\n/// :::note\n/// Most operations on integer numbers (e.g. addition) are available as built-in operators (e.g. `1 + 1`).\n/// This module provides equivalent functions and `Text` conversion.\n/// :::\n///\n/// :::info Function form for higher-order use\n///\n/// Several arithmetic and comparison functions (e.g. `add`, `sub`, `equal`, `less`, `pow`) are defined in this module to enable their use as first-class function values, which is not possible with operators like `+`, `-`, `==`, etc., in Motoko. This allows you to pass these operations to higher-order functions such as `map`, `foldLeft`, or `sort`.\n/// :::\n///\n/// Import from the base library to use this module.\n///\n/// ```motoko name=import\n/// import Nat16 \"mo:base/Nat16\";\n/// ```\nimport Nat \"Nat\";\nimport Prim \"mo:⛔\";\n\nmodule {\n\n  /// 16-bit natural numbers.\n  public type Nat16 = Prim.Types.Nat16;\n\n  /// Maximum 16-bit natural number. `2 ** 16 - 1`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat16.maximumValue; // => 65536 : Nat16\n  /// ```\n  public let maximumValue = 65535 : Nat16;\n\n  /// Converts a 16-bit unsigned integer to an unsigned integer with infinite precision.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat16.toNat(123); // => 123 : Nat\n  /// ```\n  public let toNat : Nat16 -> Nat = Prim.nat16ToNat;\n\n  /// Converts an unsigned integer with infinite precision to a 16-bit unsigned integer.\n  ///\n  /// Traps on overflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat16.fromNat(123); // => 123 : Nat16\n  /// ```\n  public let fromNat : Nat -> Nat16 = Prim.natToNat16;\n\n  /// Converts an 8-bit unsigned integer to a 16-bit unsigned integer.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat16.fromNat8(123); // => 123 : Nat16\n  /// ```\n  public func fromNat8(x : Nat8) : Nat16 {\n    Prim.nat8ToNat16(x)\n  };\n\n  /// Converts a 16-bit unsigned integer to an 8-bit unsigned integer.\n  ///\n  /// Traps on overflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat16.toNat8(123); // => 123 : Nat8\n  /// ```\n  public func toNat8(x : Nat16) : Nat8 {\n    Prim.nat16ToNat8(x)\n  };\n\n  /// Converts a 32-bit unsigned integer to a 16-bit unsigned integer.\n  ///\n  /// Traps on overflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat16.fromNat32(123); // => 123 : Nat16\n  /// ```\n  public func fromNat32(x : Nat32) : Nat16 {\n    Prim.nat32ToNat16(x)\n  };\n\n  /// Converts a 16-bit unsigned integer to a 32-bit unsigned integer.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat16.toNat32(123); // => 123 : Nat32\n  /// ```\n  public func toNat32(x : Nat16) : Nat32 {\n    Prim.nat16ToNat32(x)\n  };\n\n  /// Converts a signed integer with infinite precision to a 16-bit unsigned integer.\n  ///\n  /// Wraps on overflow/underflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat16.fromIntWrap(123 : Int); // => 123 : Nat16\n  /// ```\n  public let fromIntWrap : Int -> Nat16 = Prim.intToNat16Wrap;\n\n  /// Converts `x` to its textual representation. Textual representation _do not_\n  /// contain underscores to represent commas.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat16.toText(1234); // => \"1234\" : Text\n  /// ```\n  public func toText(x : Nat16) : Text {\n    Nat.toText(toNat(x))\n  };\n\n  /// Returns the minimum of `x` and `y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat16.min(123, 200); // => 123 : Nat16\n  /// ```\n  public func min(x : Nat16, y : Nat16) : Nat16 {\n    if (x < y) { x } else { y }\n  };\n\n  /// Returns the maximum of `x` and `y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat16.max(123, 200); // => 200 : Nat16\n  /// ```\n  public func max(x : Nat16, y : Nat16) : Nat16 {\n    if (x < y) { y } else { x }\n  };\n\n  /// Equality function for Nat16 types.\n  /// This is equivalent to `x == y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat16.equal(1, 1); // => true\n  /// (1 : Nat16) == (1 : Nat16) // => true\n  /// ```\n  ///\n\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// import Buffer \"mo:base/Buffer\";\n  ///\n  /// let buffer1 = Buffer.Buffer<Nat16>(3);\n  /// let buffer2 = Buffer.Buffer<Nat16>(3);\n  /// Buffer.equal(buffer1, buffer2, Nat16.equal) // => true\n  /// ```\n  public func equal(x : Nat16, y : Nat16) : Bool { x == y };\n\n  /// Inequality function for Nat16 types.\n  /// This is equivalent to `x != y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat16.notEqual(1, 2); // => true\n  /// (1 : Nat16) != (2 : Nat16) // => true\n  /// ```\n  ///\n\n  public func notEqual(x : Nat16, y : Nat16) : Bool { x != y };\n\n  /// \"Less than\" function for Nat16 types.\n  /// This is equivalent to `x < y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat16.less(1, 2); // => true\n  /// (1 : Nat16) < (2 : Nat16) // => true\n  /// ```\n  ///\n\n  public func less(x : Nat16, y : Nat16) : Bool { x < y };\n\n  /// \"Less than or equal\" function for Nat16 types.\n  /// This is equivalent to `x <= y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat16.lessOrEqual(1, 2); // => true\n  /// (1 : Nat16) <= (2 : Nat16) // => true\n  /// ```\n  ///\n\n  public func lessOrEqual(x : Nat16, y : Nat16) : Bool { x <= y };\n\n  /// \"Greater than\" function for Nat16 types.\n  /// This is equivalent to `x > y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat16.greater(2, 1); // => true\n  /// (2 : Nat16) > (1 : Nat16) // => true\n  /// ```\n  ///\n\n  public func greater(x : Nat16, y : Nat16) : Bool { x > y };\n\n  /// \"Greater than or equal\" function for Nat16 types.\n  /// This is equivalent to `x >= y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat16.greaterOrEqual(2, 1); // => true\n  /// (2 : Nat16) >= (1 : Nat16) // => true\n  /// ```\n  ///\n\n  public func greaterOrEqual(x : Nat16, y : Nat16) : Bool { x >= y };\n\n  /// General purpose comparison function for `Nat16`. Returns the `Order` (\n  /// either `#less`, `#equal`, or `#greater`) of comparing `x` with `y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat16.compare(2, 3) // => #less\n  /// ```\n  ///\n  /// This function can be used as value for a high order function, such as a sort function.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// import Array \"mo:base/Array\";\n  /// Array.sort([2, 3, 1] : [Nat16], Nat16.compare) // => [1, 2, 3]\n  /// ```\n  public func compare(x : Nat16, y : Nat16) : { #less; #equal; #greater } {\n    if (x < y) { #less } else if (x == y) { #equal } else { #greater }\n  };\n\n  /// Returns the sum of `x` and `y`, `x + y`.\n  /// Traps on overflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat16.add(1, 2); // => 3\n  /// (1 : Nat16) + (2 : Nat16) // => 3\n  /// ```\n  ///\n\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// import Array \"mo:base/Array\";\n  /// Array.foldLeft<Nat16, Nat16>([2, 3, 1], 0, Nat16.add) // => 6\n  /// ```\n  public func add(x : Nat16, y : Nat16) : Nat16 { x + y };\n\n  /// Returns the difference of `x` and `y`, `x - y`.\n  /// Traps on underflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat16.sub(2, 1); // => 1\n  /// (2 : Nat16) - (1 : Nat16) // => 1\n  /// ```\n  ///\n\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// import Array \"mo:base/Array\";\n  /// Array.foldLeft<Nat16, Nat16>([2, 3, 1], 20, Nat16.sub) // => 14\n  /// ```\n  public func sub(x : Nat16, y : Nat16) : Nat16 { x - y };\n\n  /// Returns the product of `x` and `y`, `x * y`.\n  /// Traps on overflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat16.mul(2, 3); // => 6\n  /// (2 : Nat16) * (3 : Nat16) // => 6\n  /// ```\n  ///\n\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// import Array \"mo:base/Array\";\n  /// Array.foldLeft<Nat16, Nat16>([2, 3, 1], 1, Nat16.mul) // => 6\n  /// ```\n  public func mul(x : Nat16, y : Nat16) : Nat16 { x * y };\n\n  /// Returns the quotient of `x` divided by `y`, `x / y`.\n  /// Traps when `y` is zero.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat16.div(6, 2); // => 3\n  /// (6 : Nat16) / (2 : Nat16) // => 3\n  /// ```\n  ///\n\n  public func div(x : Nat16, y : Nat16) : Nat16 { x / y };\n\n  /// Returns the remainder of `x` divided by `y`, `x % y`.\n  /// Traps when `y` is zero.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat16.rem(6, 4); // => 2\n  /// (6 : Nat16) % (4 : Nat16) // => 2\n  /// ```\n  ///\n\n  public func rem(x : Nat16, y : Nat16) : Nat16 { x % y };\n\n  /// Returns the power of `x` to `y`, `x ** y`.\n  /// Traps on overflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat16.pow(2, 3); // => 8\n  /// (2 : Nat16) ** (3 : Nat16) // => 8\n  /// ```\n  ///\n\n  public func pow(x : Nat16, y : Nat16) : Nat16 { x ** y };\n\n  /// Returns the bitwise negation of `x`, `^x`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat16.bitnot(0); // => 65535\n  /// ^(0 : Nat16) // => 65535\n  /// ```\n  ///\n\n  public func bitnot(x : Nat16) : Nat16 { ^x };\n\n  /// Returns the bitwise and of `x` and `y`, `x & y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat16.bitand(0, 1); // => 0\n  /// (0 : Nat16) & (1 : Nat16) // => 0\n  /// ```\n  ///\n\n  public func bitand(x : Nat16, y : Nat16) : Nat16 { x & y };\n\n  /// Returns the bitwise or of `x` and `y`, `x | y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat16.bitor(0, 1); // => 1\n  /// (0 : Nat16) | (1 : Nat16) // => 1\n  /// ```\n  public func bitor(x : Nat16, y : Nat16) : Nat16 { x | y };\n\n  /// Returns the bitwise exclusive or of `x` and `y`, `x ^ y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat16.bitxor(0, 1); // => 1\n  /// (0 : Nat16) ^ (1 : Nat16) // => 1\n  /// ```\n  public func bitxor(x : Nat16, y : Nat16) : Nat16 { x ^ y };\n\n  /// Returns the bitwise shift left of `x` by `y`, `x << y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat16.bitshiftLeft(1, 3); // => 8\n  /// (1 : Nat16) << (3 : Nat16) // => 8\n  /// ```\n  ///\n\n  public func bitshiftLeft(x : Nat16, y : Nat16) : Nat16 { x << y };\n\n  /// Returns the bitwise shift right of `x` by `y`, `x >> y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat16.bitshiftRight(8, 3); // => 1\n  /// (8 : Nat16) >> (3 : Nat16) // => 1\n  /// ```\n  ///\n\n  public func bitshiftRight(x : Nat16, y : Nat16) : Nat16 { x >> y };\n\n  /// Returns the bitwise rotate left of `x` by `y`, `x <<> y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat16.bitrotLeft(2, 1); // => 4\n  /// (2 : Nat16) <<> (1 : Nat16) // => 4\n  /// ```\n  ///\n\n  public func bitrotLeft(x : Nat16, y : Nat16) : Nat16 { x <<> y };\n\n  /// Returns the bitwise rotate right of `x` by `y`, `x <>> y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat16.bitrotRight(1, 1); // => 32768\n  /// (1 : Nat16) <>> (1 : Nat16) // => 32768\n  /// ```\n  ///\n\n  public func bitrotRight(x : Nat16, y : Nat16) : Nat16 { x <>> y };\n\n  /// Returns the value of bit `p mod 16` in `x`, `(x & 2^(p mod 16)) == 2^(p mod 16)`.\n  /// This is equivalent to checking if the `p`-th bit is set in `x`, using 0 indexing.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat16.bittest(5, 2); // => true\n  /// ```\n  public func bittest(x : Nat16, p : Nat) : Bool {\n    Prim.btstNat16(x, Prim.natToNat16(p))\n  };\n\n  /// Returns the value of setting bit `p mod 16` in `x` to `1`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat16.bitset(0, 2); // => 4\n  /// ```\n  public func bitset(x : Nat16, p : Nat) : Nat16 {\n    x | (1 << Prim.natToNat16(p))\n  };\n\n  /// Returns the value of clearing bit `p mod 16` in `x` to `0`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat16.bitclear(5, 2); // => 1\n  /// ```\n  public func bitclear(x : Nat16, p : Nat) : Nat16 {\n    x & ^(1 << Prim.natToNat16(p))\n  };\n\n  /// Returns the value of flipping bit `p mod 16` in `x`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat16.bitflip(5, 2); // => 1\n  /// ```\n  public func bitflip(x : Nat16, p : Nat) : Nat16 {\n    x ^ (1 << Prim.natToNat16(p))\n  };\n\n  /// Returns the count of non-zero bits in `x`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat16.bitcountNonZero(5); // => 2\n  /// ```\n  public let bitcountNonZero : (x : Nat16) -> Nat16 = Prim.popcntNat16;\n\n  /// Returns the count of leading zero bits in `x`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat16.bitcountLeadingZero(5); // => 13\n  /// ```\n  public let bitcountLeadingZero : (x : Nat16) -> Nat16 = Prim.clzNat16;\n\n  /// Returns the count of trailing zero bits in `x`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat16.bitcountTrailingZero(5); // => 0\n  /// ```\n  public let bitcountTrailingZero : (x : Nat16) -> Nat16 = Prim.ctzNat16;\n\n  /// Returns the upper (i.e. most significant) and lower (least significant) byte of `x`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Nat16.explode 0xaa88 // => (170, 136)\n  /// ```\n  public let explode : (x : Nat16) -> (msb : Nat8, lsb : Nat8) = Prim.explodeNat16;\n\n  /// Returns the sum of `x` and `y`, `x +% y`. Wraps on overflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat16.addWrap(65532, 5); // => 1\n  /// (65532 : Nat16) +% (5 : Nat16) // => 1\n  /// ```\n  ///\n  /// :::info\n  /// The reason why this function is defined in this library (in addition\n  /// to the existing `+%` operator) is so that you can use it as a function\n  /// value to pass to a higher order function. It is not possible to use `+%`\n  /// as a function value at the moment.\n  /// :::\n  public func addWrap(x : Nat16, y : Nat16) : Nat16 { x +% y };\n\n  /// Returns the difference of `x` and `y`, `x -% y`. Wraps on underflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat16.subWrap(1, 2); // => 65535\n  /// (1 : Nat16) -% (2 : Nat16) // => 65535\n  /// ```\n  ///\n\n  public func subWrap(x : Nat16, y : Nat16) : Nat16 { x -% y };\n\n  /// Returns the product of `x` and `y`, `x *% y`. Wraps on overflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat16.mulWrap(655, 101); // => 619\n  /// (655 : Nat16) *% (101 : Nat16) // => 619\n  /// ```\n  ///\n\n  public func mulWrap(x : Nat16, y : Nat16) : Nat16 { x *% y };\n\n  /// Returns `x` to the power of `y`, `x **% y`. Wraps on overflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// ignore Nat16.powWrap(2, 16); // => 0\n  /// (2 : Nat16) **% (16 : Nat16) // => 0\n  /// ```\n  ///\n\n  public func powWrap(x : Nat16, y : Nat16) : Nat16 { x **% y };\n\n}\n"},"Blob.mo":{"content":"/// `Blob` is an immutable, iterable sequence of bytes. Unlike `[Nat8]`, which is less compact (using 4 bytes per logical byte), `Blob` provides a more efficient representation.\n///\n/// Blobs are not indexable and can be empty. To manipulate a `Blob`, convert it to `[var Nat8]` or `Buffer<Nat8>`, perform your changes, then convert it back.\n///\n/// Import from the base library to use this module.\n///\n/// ```motoko name=import\n/// import Blob \"mo:base/Blob\";\n/// ```\n///\n/// :::note Additional features\n///\n/// Some built-in features are not listed in this module:\n///\n/// - You can create a `Blob` literal from a `Text` literal, provided the context expects an expression of type `Blob`.\n/// - `b.size() : Nat` returns the number of bytes in the blob `b`.\n/// - `b.vals() : Iter.Iter<Nat8>` returns an iterator to enumerate the bytes of the blob `b`.\n/// :::\n///\n/// For example:\n///\n/// ```motoko include=import\n/// import Debug \"mo:base/Debug\";\n/// import Nat8 \"mo:base/Nat8\";\n///\n/// let blob = \"\\00\\00\\00\\ff\" : Blob; // blob literals, where each byte is delimited by a back-slash and represented in hex\n/// let blob2 = \"charsもあり\" : Blob; // you can also use characters in the literals\n/// let numBytes = blob.size(); // => 4 (returns the number of bytes in the Blob)\n/// for (byte : Nat8 in blob.vals()) { // iterator over the Blob\n///  Debug.print(Nat8.toText(byte))\n/// }\n/// ```\n/// :::note Operator limitation\n///\n/// Comparison functions (`equal`, `notEqual`, `less`, `lessOrEqual`, `greater`, `greaterOrEqual`) are defined in this library to allow their use as function values in higher-order functions.\n/// Operators like `==`, `!=`, `<`, `<=`, `>`, and `>=` cannot currently be passed as function values.\n/// :::\nimport Prim \"mo:⛔\";\nmodule {\n  public type Blob = Prim.Types.Blob;\n  /// Creates a `Blob` from an array of bytes (`[Nat8]`) by copying each element.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// let bytes : [Nat8] = [0, 255, 0];\n  /// let blob = Blob.fromArray(bytes); // => \"\\00\\FF\\00\"\n  /// ```\n  public func fromArray(bytes : [Nat8]) : Blob = Prim.arrayToBlob bytes;\n\n  /// Creates a `Blob` from a mutable array of bytes (`[var Nat8]`) by copying each element.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// let bytes : [var Nat8] = [var 0, 255, 0];\n  /// let blob = Blob.fromArrayMut(bytes); // => \"\\00\\FF\\00\"\n  /// ```\n  public func fromArrayMut(bytes : [var Nat8]) : Blob = Prim.arrayMutToBlob bytes;\n\n  /// Converts a `Blob` to an array of bytes (`[Nat8]`) by copying each element.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// let blob = \"\\00\\FF\\00\" : Blob;\n  /// let bytes = Blob.toArray(blob); // => [0, 255, 0]\n  /// ```\n  public func toArray(blob : Blob) : [Nat8] = Prim.blobToArray blob;\n\n  /// Converts a `Blob` to a mutable array of bytes (`[var Nat8]`) by copying each element.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// let blob = \"\\00\\FF\\00\" : Blob;\n  /// let bytes = Blob.toArrayMut(blob); // => [var 0, 255, 0]\n  /// ```\n  public func toArrayMut(blob : Blob) : [var Nat8] = Prim.blobToArrayMut blob;\n\n  /// Returns the (non-cryptographic) hash of `blob`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// let blob = \"\\00\\FF\\00\" : Blob;\n  /// Blob.hash(blob) // => 1_818_567_776\n  /// ```\n  public func hash(blob : Blob) : Nat32 = Prim.hashBlob blob;\n\n  /// General purpose comparison function for `Blob` by comparing the value of\n  /// the bytes. Returns the `Order` (either `#less`, `#equal`, or `#greater`)\n  /// by comparing `blob1` with `blob2`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// let blob1 = \"\\00\\00\\00\" : Blob;\n  /// let blob2 = \"\\00\\FF\\00\" : Blob;\n  /// Blob.compare(blob1, blob2) // => #less\n  /// ```\n  public func compare(b1 : Blob, b2 : Blob) : { #less; #equal; #greater } {\n    let c = Prim.blobCompare(b1, b2);\n    if (c < 0) #less else if (c == 0) #equal else #greater\n  };\n\n  /// Equality function for `Blob` types.\n  /// This is equivalent to `blob1 == blob2`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// let blob1 = \"\\00\\FF\\00\" : Blob;\n  /// let blob2 = \"\\00\\FF\\00\" : Blob;\n  /// ignore Blob.equal(blob1, blob2);\n  /// blob1 == blob2 // => true\n  /// ```\n  ///\n  public func equal(blob1 : Blob, blob2 : Blob) : Bool { blob1 == blob2 };\n\n  /// Inequality function for `Blob` types.\n  /// This is equivalent to `blob1 != blob2`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// let blob1 = \"\\00\\AA\\AA\" : Blob;\n  /// let blob2 = \"\\00\\FF\\00\" : Blob;\n  /// ignore Blob.notEqual(blob1, blob2);\n  /// blob1 != blob2 // => true\n  /// ```\n\n  public func notEqual(blob1 : Blob, blob2 : Blob) : Bool { blob1 != blob2 };\n\n  /// \"Less than\" function for `Blob` types.\n  /// This is equivalent to `blob1 < blob2`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// let blob1 = \"\\00\\AA\\AA\" : Blob;\n  /// let blob2 = \"\\00\\FF\\00\" : Blob;\n  /// ignore Blob.less(blob1, blob2);\n  /// blob1 < blob2 // => true\n  /// ```\n\n  public func less(blob1 : Blob, blob2 : Blob) : Bool { blob1 < blob2 };\n\n  /// \"Less than or equal to\" function for `Blob` types.\n  /// This is equivalent to `blob1 <= blob2`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// let blob1 = \"\\00\\AA\\AA\" : Blob;\n  /// let blob2 = \"\\00\\FF\\00\" : Blob;\n  /// ignore Blob.lessOrEqual(blob1, blob2);\n  /// blob1 <= blob2 // => true\n  /// ```\n  public func lessOrEqual(blob1 : Blob, blob2 : Blob) : Bool { blob1 <= blob2 };\n\n  /// \"Greater than\" function for `Blob` types.\n  /// This is equivalent to `blob1 > blob2`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// let blob1 = \"\\BB\\AA\\AA\" : Blob;\n  /// let blob2 = \"\\00\\00\\00\" : Blob;\n  /// ignore Blob.greater(blob1, blob2);\n  /// blob1 > blob2 // => true\n  /// ```\n  public func greater(blob1 : Blob, blob2 : Blob) : Bool { blob1 > blob2 };\n\n  /// \"Greater than or equal to\" function for `Blob` types.\n  /// This is equivalent to `blob1 >= blob2`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// let blob1 = \"\\BB\\AA\\AA\" : Blob;\n  /// let blob2 = \"\\00\\00\\00\" : Blob;\n  /// ignore Blob.greaterOrEqual(blob1, blob2);\n  /// blob1 >= blob2 // => true\n  /// ```\n  public func greaterOrEqual(blob1 : Blob, blob2 : Blob) : Bool {\n    blob1 >= blob2\n  }\n}\n"},"ExperimentalInternetComputer.mo":{"content":"/// Low-level interface to the Internet Computer.\n///\n/// :::warning Experimental API\n/// This low-level API is **experimental** and likely to change or even disappear.\n/// :::\nimport Prim \"mo:⛔\";\n\nmodule {\n\n  /// Calls ``canister``'s update or query function, `name`, with the binary contents of `data` as IC argument.\n  /// Returns the response to the call, an IC _reply_ or _reject_, as a Motoko future:\n  ///\n  /// * The message data of an IC reply determines the binary contents of `reply`.\n  /// * The error code and textual message data of an IC reject determines the future's `Error` value.\n  ///\n  /// Asynchronous context required: `call` is an asynchronous function and can only be applied in an asynchronous context.\n\n  /// Example:\n  /// ```motoko no-repl\n  /// import IC \"mo:base/ExperimentalInternetComputer\";\n  /// import Principal \"mo:base/Principal\";\n  ///\n  /// let ledger = Principal.fromText(\"ryjl3-tyaaa-aaaaa-aaaba-cai\");\n  /// let method = \"decimals\";\n  /// let input = ();\n  /// type OutputType = { decimals : Nat32 };\n  ///\n  /// let rawReply = await IC.call(ledger, method, to_candid(input)); // serialized Candid\n  /// let output : ?OutputType = from_candid(rawReply); // { decimals = 8 }\n  /// ```\n  ///\n  /// [Learn more about Candid serialization](https://internetcomputer.org/docs/current/motoko/main/reference/language-manual#candid-serialization)\n  public let call : (canister : Principal, name : Text, data : Blob) -> async (reply : Blob) = Prim.call_raw;\n\n  /// `isReplicated` is true for update messages and for queries that passed through consensus.\n  public let isReplicated : () -> Bool = Prim.isReplicatedExecution;\n\n  /// Given computation, `comp`, counts the number of actual and (for IC system calls) notional WebAssembly\n  /// instructions performed during the execution of `comp()`.\n\n  /// More precisely, returns the difference between the state of the IC instruction counter (_performance counter_ `0`) before and after executing `comp()`\n  /// (see [Performance Counter](https://internetcomputer.org/docs/current/references/ic-interface-spec#system-api-performance-counter)).\n\n  /// :::note Garbage collection cost not included\n\n  /// `countInstructions(comp)` will _not_ account for any deferred garbage collection costs incurred by `comp()`.\n  /// :::\n\n  /// Example:\n\n  /// ```motoko no-repl\n  /// import IC \"mo:base/ExperimentalInternetComputer\";\n  ///\n  /// let count = IC.countInstructions(func() {\n  // ...\n  /// });\n  /// ```\n  public func countInstructions(comp : () -> ()) : Nat64 {\n    let init = Prim.performanceCounter(0);\n    let pre = Prim.performanceCounter(0);\n    comp();\n    let post = Prim.performanceCounter(0);\n    // performance_counter costs around 200 extra instructions, we perform an empty measurement to decide the overhead\n    let overhead = pre - init;\n    post - pre - overhead\n  };\n\n  /// Returns the current value of IC _performance counter_ `counter`.\n  ///\n  /// * Counter `0` is the _current execution instruction counter_, counting instructions only since the beginning of the current IC message.\n  ///   This counter is reset to value `0` on shared function entry and every `await`.\n  ///   It is therefore only suitable for measuring the cost of synchronous code.\n  ///\n  /// * Counter `1` is the _call context instruction counter_  for the current shared function call.\n  ///   For replicated message executing, this excludes the cost of nested IC calls (even to the current canister).\n  ///   For non-replicated messages, such as composite queries, it includes the cost of nested calls.\n  ///   The current value of this counter is preserved across `awaits` (unlike counter `0`).\n  ///\n  /// * The function (currently) traps if `counter` >= 2.\n  ///\n  /// Consult [Performance Counter](https://internetcomputer.org/docs/current/references/ic-interface-spec#system-api-performance-counter) for details.\n  ///\n  /// Example:\n  /// ```motoko no-repl\n  /// import IC \"mo:base/ExperimentalInternetComputer\";\n  ///\n  /// let c1 = IC.performanceCounter(1);\n  /// work();\n  /// let diff : Nat64 = IC.performanceCounter(1) - c1;\n  /// ```\n  public let performanceCounter : (counter : Nat32) -> (value : Nat64) = Prim.performanceCounter;\n\n  /// Returns the time (in nanoseconds from the epoch start) by when the update message should\n  /// reply to the best effort message so that it can be received by the requesting canister.\n  /// Queries and unbounded-time update messages return null.\n  public func replyDeadline() : ?Nat {\n    let raw = Prim.replyDeadline();\n    if (raw == 0) null else ?Prim.nat64ToNat(raw)\n  };\n\n  /// Returns the subnet's principal for the running actor.\n  /// Note: Due to canister migration the hosting subnet can vary with time.\n  ///\n  /// Example:\n  /// ```motoko no-repl\n  /// import IC \"mo:base/ExperimentalInternetComputer\";\n  ///\n  /// let subnetPrincipal = IC.subnet();\n  /// ```\n  public let subnet : () -> Principal = Prim.canisterSubnet;\n\n}\n"},"Int64.mo":{"content":"/// Provides utility functions on 64-bit signed integers.\n///\n/// :::note\n/// Most operations are available as built-in operators (e.g. `1 + 1`).\n/// :::\n///\n/// :::info Function form for higher-order use\n///\n/// Several arithmetic and comparison functions (e.g. `add`, `sub`, `bitor`, `bitand`, `pow`) are defined in this module to enable their use as first-class function values, which is not possible with operators like `+`, `-`, `==`, etc., in Motoko. This allows you to pass these operations to higher-order functions such as `map`, `foldLeft`, or `sort`.\n/// :::\n///\n/// Import from the base library to use this module.\n/// ```motoko name=import\n/// import Int64 \"mo:base/Int64\";\n/// ```\n\nimport Int \"Int\";\nimport Prim \"mo:⛔\";\n\nmodule {\n\n  /// 64-bit signed integers.\n  public type Int64 = Prim.Types.Int64;\n\n  /// Minimum 64-bit integer value, `-2 ** 63`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int64.minimumValue // => -9_223_372_036_854_775_808\n  /// ```\n  public let minimumValue = -9_223_372_036_854_775_808 : Int64;\n\n  /// Maximum 64-bit integer value, `+2 ** 63 - 1`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int64.maximumValue // => +9_223_372_036_854_775_807\n  /// ```\n  public let maximumValue = 9_223_372_036_854_775_807 : Int64;\n\n  /// Converts a 64-bit signed integer to a signed integer with infinite precision.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int64.toInt(123_456) // => 123_456 : Int\n  /// ```\n  public let toInt : Int64 -> Int = Prim.int64ToInt;\n\n  /// Converts a signed integer with infinite precision to a 64-bit signed integer.\n  ///\n  /// Traps on overflow/underflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int64.fromInt(123_456) // => +123_456 : Int64\n  /// ```\n  public let fromInt : Int -> Int64 = Prim.intToInt64;\n\n  /// Converts a 32-bit signed integer to a 64-bit signed integer.\n  ///\n  /// Traps on overflow/underflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int64.fromInt32(-123_456) // => -123_456 : Int64\n  /// ```\n  public let fromInt32 : Int32 -> Int64 = Prim.int32ToInt64;\n\n  /// Converts a 64-bit signed integer to a 32-bit signed integer.\n  ///\n  /// Wraps on overflow/underflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int64.toInt32(-123_456) // => -123_456 : Int32\n  /// ```\n  public let toInt32 : Int64 -> Int32 = Prim.int64ToInt32;\n\n  /// Converts a signed integer with infinite precision to a 64-bit signed integer.\n  ///\n  /// Wraps on overflow/underflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int64.fromIntWrap(-123_456) // => -123_456 : Int64\n  /// ```\n  public let fromIntWrap : Int -> Int64 = Prim.intToInt64Wrap;\n\n  /// Converts an unsigned 64-bit integer to a signed 64-bit integer.\n  ///\n  /// Wraps on overflow/underflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int64.fromNat64(123_456) // => +123_456 : Int64\n  /// ```\n  public let fromNat64 : Nat64 -> Int64 = Prim.nat64ToInt64;\n\n  /// Converts a signed 64-bit integer to an unsigned 64-bit integer.\n  ///\n  /// Wraps on overflow/underflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int64.toNat64(-1) // => 18_446_744_073_709_551_615 : Nat64 // underflow\n  /// ```\n  public let toNat64 : Int64 -> Nat64 = Prim.int64ToNat64;\n\n  /// Returns the Text representation of `x`. Textual representation _do not_\n  /// contain underscores to represent commas.\n  ///\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int64.toText(-123456) // => \"-123456\"\n  /// ```\n  public func toText(x : Int64) : Text {\n    Int.toText(toInt(x))\n  };\n\n  /// Returns the absolute value of `x`.\n  ///\n  /// Traps when `x == -2 ** 63` (the minimum `Int64` value).\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int64.abs(-123456) // => +123_456\n  /// ```\n  public func abs(x : Int64) : Int64 {\n    fromInt(Int.abs(toInt(x)))\n  };\n\n  /// Returns the minimum of `x` and `y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int64.min(+2, -3) // => -3\n  /// ```\n  public func min(x : Int64, y : Int64) : Int64 {\n    if (x < y) { x } else { y }\n  };\n\n  /// Returns the maximum of `x` and `y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int64.max(+2, -3) // => +2\n  /// ```\n  public func max(x : Int64, y : Int64) : Int64 {\n    if (x < y) { y } else { x }\n  };\n\n  /// Equality function for Int64 types.\n  /// This is equivalent to `x == y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int64.equal(-1, -1); // => true\n  /// ```\n  ///\n\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// import Buffer \"mo:base/Buffer\";\n  ///\n  /// let buffer1 = Buffer.Buffer<Int64>(1);\n  /// buffer1.add(-3);\n  /// let buffer2 = Buffer.Buffer<Int64>(1);\n  /// buffer2.add(-3);\n  /// Buffer.equal(buffer1, buffer2, Int64.equal) // => true\n  /// ```\n  public func equal(x : Int64, y : Int64) : Bool { x == y };\n\n  /// Inequality function for Int64 types.\n  /// This is equivalent to `x != y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int64.notEqual(-1, -2); // => true\n  /// ```\n  ///\n\n  public func notEqual(x : Int64, y : Int64) : Bool { x != y };\n\n  /// \"Less than\" function for Int64 types.\n  /// This is equivalent to `x < y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int64.less(-2, 1); // => true\n  /// ```\n  ///\n\n  public func less(x : Int64, y : Int64) : Bool { x < y };\n\n  /// \"Less than or equal\" function for Int64 types.\n  /// This is equivalent to `x <= y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int64.lessOrEqual(-2, -2); // => true\n  /// ```\n  ///\n\n  public func lessOrEqual(x : Int64, y : Int64) : Bool { x <= y };\n\n  /// \"Greater than\" function for Int64 types.\n  /// This is equivalent to `x > y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int64.greater(-2, -3); // => true\n  /// ```\n  ///\n\n  public func greater(x : Int64, y : Int64) : Bool { x > y };\n\n  /// \"Greater than or equal\" function for Int64 types.\n  /// This is equivalent to `x >= y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int64.greaterOrEqual(-2, -2); // => true\n  /// ```\n  ///\n\n  public func greaterOrEqual(x : Int64, y : Int64) : Bool { x >= y };\n\n  /// General-purpose comparison function for `Int64`. Returns the `Order` (\n  /// either `#less`, `#equal`, or `#greater`) of comparing `x` with `y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int64.compare(-3, 2) // => #less\n  /// ```\n  ///\n  /// This function can be used as value for a high order function, such as a sort function.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// import Array \"mo:base/Array\";\n  /// Array.sort([1, -2, -3] : [Int64], Int64.compare) // => [-3, -2, 1]\n  /// ```\n  public func compare(x : Int64, y : Int64) : { #less; #equal; #greater } {\n    if (x < y) { #less } else if (x == y) { #equal } else { #greater }\n  };\n\n  /// Returns the negation of `x`, `-x`.\n  ///\n  /// Traps on overflow, i.e. for `neg(-2 ** 63)`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int64.neg(123) // => -123\n  /// ```\n  ///\n\n  public func neg(x : Int64) : Int64 { -x };\n\n  /// Returns the sum of `x` and `y`, `x + y`.\n  ///\n  /// Traps on overflow/underflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int64.add(1234, 123) // => +1_357\n  /// ```\n  ///\n\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// import Array \"mo:base/Array\";\n  /// Array.foldLeft<Int64, Int64>([1, -2, -3], 0, Int64.add) // => -4\n  /// ```\n  public func add(x : Int64, y : Int64) : Int64 { x + y };\n\n  /// Returns the difference of `x` and `y`, `x - y`.\n  ///\n  /// Traps on overflow/underflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int64.sub(123, 100) // => +23\n  /// ```\n  ///\n\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// import Array \"mo:base/Array\";\n  /// Array.foldLeft<Int64, Int64>([1, -2, -3], 0, Int64.sub) // => 4\n  /// ```\n  public func sub(x : Int64, y : Int64) : Int64 { x - y };\n\n  /// Returns the product of `x` and `y`, `x * y`.\n  ///\n  /// Traps on overflow/underflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int64.mul(123, 10) // => +1_230\n  /// ```\n  ///\n\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// import Array \"mo:base/Array\";\n  /// Array.foldLeft<Int64, Int64>([1, -2, -3], 1, Int64.mul) // => 6\n  /// ```\n  public func mul(x : Int64, y : Int64) : Int64 { x * y };\n\n  /// Returns the signed integer division of `x` by `y`, `x / y`.\n  /// Rounds the quotient towards zero, which is the same as truncating the decimal places of the quotient.\n  ///\n  /// Traps when `y` is zero.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int64.div(123, 10) // => +12\n  /// ```\n  ///\n\n  public func div(x : Int64, y : Int64) : Int64 { x / y };\n\n  /// Returns the remainder of the signed integer division of `x` by `y`, `x % y`,\n  /// which is defined as `x - x / y * y`.\n  ///\n  /// Traps when `y` is zero.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int64.rem(123, 10) // => +3\n  /// ```\n  ///\n\n  public func rem(x : Int64, y : Int64) : Int64 { x % y };\n\n  /// Returns `x` to the power of `y`, `x ** y`.\n  ///\n  /// Traps on overflow/underflow and when `y < 0 or y >= 64`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int64.pow(2, 10) // => +1_024\n  /// ```\n  ///\n\n  public func pow(x : Int64, y : Int64) : Int64 { x ** y };\n\n  /// Returns the bitwise negation of `x`, `^x`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int64.bitnot(-256 /* 0xffff_ffff_ffff_ff00 */) // => +255 // 0xff\n  /// ```\n  ///\n\n  public func bitnot(x : Int64) : Int64 { ^x };\n\n  /// Returns the bitwise \"and\" of `x` and `y`, `x & y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int64.bitand(0xffff, 0x00f0) // => +240 // 0xf0\n  /// ```\n  ///\n\n  public func bitand(x : Int64, y : Int64) : Int64 { x & y };\n\n  /// Returns the bitwise \"or\" of `x` and `y`, `x | y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int64.bitor(0xffff, 0x00f0) // => +65_535 // 0xffff\n  /// ```\n  ///\n\n  public func bitor(x : Int64, y : Int64) : Int64 { x | y };\n\n  /// Returns the bitwise \"exclusive or\" of `x` and `y`, `x ^ y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int64.bitxor(0xffff, 0x00f0) // => +65_295 // 0xff0f\n  /// ```\n  ///\n\n  public func bitxor(x : Int64, y : Int64) : Int64 { x ^ y };\n\n  /// Returns the bitwise left shift of `x` by `y`, `x << y`.\n  /// The right bits of the shift filled with zeros.\n  /// Left-overflowing bits, including the sign bit, are discarded.\n  ///\n  /// For `y >= 64`, the semantics is the same as for `bitshiftLeft(x, y % 64)`.\n  /// For `y < 0`,  the semantics is the same as for `bitshiftLeft(x, y + y % 64)`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int64.bitshiftLeft(1, 8) // => +256 // 0x100 equivalent to `2 ** 8`.\n  /// ```\n  ///\n\n  public func bitshiftLeft(x : Int64, y : Int64) : Int64 { x << y };\n\n  /// Returns the signed bitwise right shift of `x` by `y`, `x >> y`.\n  /// The sign bit is retained and the left side is filled with the sign bit.\n  /// Right-underflowing bits are discarded, i.e. not rotated to the left side.\n  ///\n  /// For `y >= 64`, the semantics is the same as for `bitshiftRight(x, y % 64)`.\n  /// For `y < 0`,  the semantics is the same as for `bitshiftRight (x, y + y % 64)`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int64.bitshiftRight(1024, 8) // => +4 // equivalent to `1024 / (2 ** 8)`\n  /// ```\n  ///\n\n  public func bitshiftRight(x : Int64, y : Int64) : Int64 { x >> y };\n\n  /// Returns the bitwise left rotatation of `x` by `y`, `x <<> y`.\n  /// Each left-overflowing bit is inserted again on the right side.\n  /// The sign bit is rotated like other bits, i.e. the rotation interprets the number as unsigned.\n  ///\n  /// Changes the direction of rotation for negative `y`.\n  /// For `y >= 64`, the semantics is the same as for `bitrotLeft(x, y % 64)`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  ///\n  /// Int64.bitrotLeft(0x2000_0000_0000_0001, 4) // => +18 // 0x12.\n  /// ```\n  ///\n\n  public func bitrotLeft(x : Int64, y : Int64) : Int64 { x <<> y };\n\n  /// Returns the bitwise right rotation of `x` by `y`, `x <>> y`.\n  /// Each right-underflowing bit is inserted again on the right side.\n  /// The sign bit is rotated like other bits, i.e. the rotation interprets the number as unsigned.\n  ///\n  /// Changes the direction of rotation for negative `y`.\n  /// For `y >= 64`, the semantics is the same as for `bitrotRight(x, y % 64)`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int64.bitrotRight(0x0002_0000_0000_0001, 48) // => +65538 // 0x1_0002.\n  /// ```\n  ///\n\n  public func bitrotRight(x : Int64, y : Int64) : Int64 { x <>> y };\n\n  /// Returns the value of bit `p` in `x`, `x & 2**p == 2**p`.\n  /// If `p >= 64`, the semantics is the same as for `bittest(x, p % 64)`.\n  /// This is equivalent to checking if the `p`-th bit is set in `x`, using 0 indexing.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int64.bittest(128, 7) // => true\n  /// ```\n  public func bittest(x : Int64, p : Nat) : Bool {\n    Prim.btstInt64(x, Prim.intToInt64(p))\n  };\n\n  /// Returns the value of setting bit `p` in `x` to `1`.\n  /// If `p >= 64`, the semantics is the same as for `bitset(x, p % 64)`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int64.bitset(0, 7) // => +128\n  /// ```\n  public func bitset(x : Int64, p : Nat) : Int64 {\n    x | (1 << Prim.intToInt64(p))\n  };\n\n  /// Returns the value of clearing bit `p` in `x` to `0`.\n  /// If `p >= 64`, the semantics is the same as for `bitclear(x, p % 64)`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int64.bitclear(-1, 7) // => -129\n  /// ```\n  public func bitclear(x : Int64, p : Nat) : Int64 {\n    x & ^(1 << Prim.intToInt64(p))\n  };\n\n  /// Returns the value of flipping bit `p` in `x`.\n  /// If `p >= 64`, the semantics is the same as for `bitclear(x, p % 64)`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int64.bitflip(255, 7) // => +127\n  /// ```\n  public func bitflip(x : Int64, p : Nat) : Int64 {\n    x ^ (1 << Prim.intToInt64(p))\n  };\n\n  /// Returns the count of non-zero bits in `x`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int64.bitcountNonZero(0xffff) // => +16\n  /// ```\n  public let bitcountNonZero : (x : Int64) -> Int64 = Prim.popcntInt64;\n\n  /// Returns the count of leading zero bits in `x`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int64.bitcountLeadingZero(0x8000_0000) // => +32\n  /// ```\n  public let bitcountLeadingZero : (x : Int64) -> Int64 = Prim.clzInt64;\n\n  /// Returns the count of trailing zero bits in `x`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int64.bitcountTrailingZero(0x0201_0000) // => +16\n  /// ```\n  public let bitcountTrailingZero : (x : Int64) -> Int64 = Prim.ctzInt64;\n\n  /// Returns the upper (i.e. most significant), lower (least significant)\n  /// and in-between bytes of `x`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int64.explode 0x33772266aa885511 // => (51, 119, 34, 102, 170, 136, 85, 17)\n  /// ```\n  public let explode : (x : Int64) -> (msb : Nat8, Nat8, Nat8, Nat8, Nat8, Nat8, Nat8, lsb : Nat8) = Prim.explodeInt64;\n\n  /// Returns the sum of `x` and `y`, `x +% y`.\n  ///\n  /// Wraps on overflow/underflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int64.addWrap(2 ** 62, 2 ** 62) // => -9_223_372_036_854_775_808 // overflow\n  /// ```\n  ///\n  /// :::info\n  /// The reason why this function is defined in this library (in addition\n  /// to the existing `+%` operator) is so that you can use it as a function\n  /// value to pass to a higher order function. It is not possible to use `+%`\n  /// as a function value at the moment.\n  /// :::\n  public func addWrap(x : Int64, y : Int64) : Int64 { x +% y };\n\n  /// Returns the difference of `x` and `y`, `x -% y`.\n  ///\n  /// Wraps on overflow/underflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int64.subWrap(-2 ** 63, 1) // => +9_223_372_036_854_775_807 // underflow\n  /// ```\n  ///\n\n  public func subWrap(x : Int64, y : Int64) : Int64 { x -% y };\n\n  /// Returns the product of `x` and `y`, `x *% y`. Wraps on overflow.\n  ///\n  /// Wraps on overflow/underflow.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int64.mulWrap(2 ** 32, 2 ** 32) // => 0 // overflow\n  /// ```\n  ///\n\n  public func mulWrap(x : Int64, y : Int64) : Int64 { x *% y };\n\n  /// Returns `x` to the power of `y`, `x **% y`.\n  ///\n  /// Wraps on overflow/underflow.\n  /// Traps if `y < 0 or y >= 64`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int64.powWrap(2, 63) // => -9_223_372_036_854_775_808 // overflow\n  /// ```\n  ///\n\n  public func powWrap(x : Int64, y : Int64) : Int64 { x **% y }\n}\n"},"Hash.mo":{"content":"\nimport Prim \"mo:⛔\";\nimport Iter \"Iter\";\n\nmodule {\n\n  /// Hash values represent a string of _hash bits_, packed into a `Nat32`.\n  public type Hash = Nat32;\n\n  /// The hash length, always 31.\n  public let length : Nat = 31; // Why not 32?\n\n  /// Project a given bit from the bit vector.\n  public func bit(h : Hash, pos : Nat) : Bool {\n    assert (pos <= length);\n    (h & (Prim.natToNat32(1) << Prim.natToNat32(pos))) != Prim.natToNat32(0)\n  };\n\n  /// Test if two hashes are equal.\n  public func equal(ha : Hash, hb : Hash) : Bool {\n    ha == hb\n  };\n\n  /// Computes a hash from the least significant 32-bits of `n`, ignoring other bits.\n  ///\n  /// @deprecated For large `Nat` values consider using a bespoke hash function that considers all of the argument's bits.\n  public func hash(n : Nat) : Hash {\n    let j = Prim.intToNat32Wrap(n);\n    hashNat8([\n      j & (255 << 0),\n      j & (255 << 8),\n      j & (255 << 16),\n      j & (255 << 24)\n    ])\n  };\n\n  /// @deprecated This function will be removed in future.\n  public func debugPrintBits(bits : Hash) {\n    for (j in Iter.range(0, length - 1)) {\n      if (bit(bits, j)) {\n        Prim.debugPrint(\"1\")\n      } else {\n        Prim.debugPrint(\"0\")\n      }\n    }\n  };\n\n\n  /// @deprecated This function will be removed in future.\n  public func debugPrintBitsRev(bits : Hash) {\n    for (j in Iter.revRange(length - 1, 0)) {\n      if (bit(bits, Prim.abs(j))) {\n        Prim.debugPrint(\"1\")\n      } else {\n        Prim.debugPrint(\"0\")\n      }\n    }\n  };\n\n  /// [View Jenkin's one at a time](https://en.wikipedia.org/wiki/Jenkins_hash_function#one_at_a_time).\n  ///\n  /// :::note\n  /// The input type should actually be `[Nat8]`.\n  /// Be sure to explode each `Nat8` of a `Nat32` into its own `Nat32`, and shift into the lower 8 bits.\n  /// :::\n  ///\n  /// @deprecated This function may be removed or changed in future.\n  public func hashNat8(key : [Hash]) : Hash {\n    var hash : Nat32 = 0;\n    for (natOfKey in key.vals()) {\n      hash := hash +% natOfKey;\n      hash := hash +% hash << 10;\n      hash := hash ^ (hash >> 6)\n    };\n    hash := hash +% hash << 3;\n    hash := hash ^ (hash >> 11);\n    hash := hash +% hash << 15;\n    return hash\n  };\n\n}\n"},"TrieMap.mo":{"content":"/// Class `TrieMap<K, V>` provides a map from keys of type `K` to values of type `V`.\n/// The class wraps and manipulates an underlying hash trie, found in the `Trie` module.\n/// The trie is a binary tree where element positions are determined using the hash of the keys.\n///\n/// :::warning Limitations\n///\n/// This data structure allows at most `MAX_LEAF_SIZE = 8` hash collisions.\n/// Attempts to insert more than 8 keys (whether directly via `put` or indirectly via other operations) with the same hash value will trap.\n/// This limitation is inherited from the underlying `Trie` data structure.\n/// :::\n///\n/// :::note Interface compatibility\n///\n/// The `class` `TrieMap` exposes the same interface as `HashMap`.\n/// :::\n///\n/// :::note Assumptions\n///\n/// Runtime and space complexity assumes that `hash`, `equal`, and other function parameters execute in `O(1)` time and space.\n/// Where applicable, runtimes also assume the trie is reasonably balanced.\n/// :::\n///\n/// :::note Iterator performance\n///\n/// All iterator-related runtime and space costs refer to iterator construction.\n/// The iteration itself takes linear time and logarithmic space to execute.\n/// :::\n///\n/// Creating a map:\n/// The equality function is used to compare keys, and the hash function is used to hash keys. See the example below.\n///\n/// ```motoko name=initialize\n/// import TrieMap \"mo:base/TrieMap\";\n/// import Nat \"mo:base/Nat\";\n/// import Hash \"mo:base/Hash\";\n/// import Iter \"mo:base/Iter\";\n///\n/// let map = TrieMap.TrieMap<Nat, Nat>(Nat.equal, Hash.hash)\n/// ```\n\nimport T \"Trie\";\nimport P \"Prelude\";\nimport I \"Iter\";\nimport Hash \"Hash\";\nimport List \"List\";\n\nmodule {\n  public class TrieMap<K, V>(isEq : (K, K) -> Bool, hashOf : K -> Hash.Hash) {\n    var map = T.empty<K, V>();\n    var _size : Nat = 0;\n\n    /// Returns the number of entries in the map.\n    ///\n    /// Example:\n    /// ```motoko include=initialize\n    /// map.size()\n    /// ```\n    ///\n    /// | Runtime        | Space         |\n    /// |----------------|---------------|\n    /// | `O(1)`   | `O(log(1))`  |\n    public func size() : Nat { _size };\n\n    /// Maps `key` to `value`, and overwrites the old entry if the key\n    /// was already present.\n    ///\n    /// Example:\n    /// ```motoko include=initialize\n    /// map.put(0, 10);\n    /// map.put(2, 12);\n    /// Iter.toArray(map.entries())\n    /// ```\n    ///\n    /// | Runtime        | Space         |\n    /// |----------------|---------------|\n    /// | `O(log(size))`   | `O(log(size))`  |\n    public func put(key : K, value : V) = ignore replace(key, value);\n\n    /// Maps `key` to `value`. Overwrites _and_ returns the old entry as an\n    /// option if the key was already present, and `null` otherwise.\n    ///\n    /// Example:\n    /// ```motoko include=initialize\n    /// map.put(0, 10);\n    /// map.replace(0, 20)\n    /// ```\n    ///\n    /// | Runtime        | Space         |\n    /// |----------------|---------------|\n    /// | `O(log(size))`   | `O(log(size))`  |\n    public func replace(key : K, value : V) : ?V {\n      let keyObj = { key; hash = hashOf(key) };\n      let (map2, ov) = T.put<K, V>(map, keyObj, isEq, value);\n      map := map2;\n      switch (ov) {\n        case null { _size += 1 };\n        case _ {}\n      };\n      ov\n    };\n\n    /// Gets the value associated with the key `key` in an option, or `null` if it\n    /// doesn't exist.\n    ///\n    /// Example:\n    /// ```motoko include=initialize\n    /// map.put(0, 10);\n    /// map.get(0)\n    /// ```\n    ///\n    /// | Runtime        | Space         |\n    /// |----------------|---------------|\n    /// | `O(log(size))`   | `O(log(size))`  |\n    public func get(key : K) : ?V {\n      let keyObj = { key; hash = hashOf(key) };\n      T.find<K, V>(map, keyObj, isEq)\n    };\n\n    /// Delete the entry associated with key `key`, if it exists. If the key is\n    /// absent, there is no effect.\n    ///\n    /// :::note\n    /// The deletion of an existing key shrinks the trie map.\n    /// :::\n    ///\n    /// Example:\n    /// ```motoko include=initialize\n    /// map.put(0, 10);\n    /// map.delete(0);\n    /// map.get(0)\n    /// ```\n    ///\n    /// | Runtime        | Space         |\n    /// |----------------|---------------|\n    /// | `O(log(size))`   | `O(log(size))`  |\n    public func delete(key : K) = ignore remove(key);\n\n    /// Delete the entry associated with key `key`. Return the deleted value\n    /// as an option if it exists, and `null` otherwise.\n    ///\n    /// :::note\n    /// The deletion of an existing key shrinks the trie map.\n    /// :::\n    ///\n    /// Example:\n    /// ```motoko include=initialize\n    /// map.put(0, 10);\n    /// map.remove(0)\n    /// ```\n    ///\n    /// | Runtime        | Space         |\n    /// |----------------|---------------|\n    /// | `O(log(size))`   | `O(log(size))`  |\n    public func remove(key : K) : ?V {\n      let keyObj = { key; hash = hashOf(key) };\n      let (t, ov) = T.remove<K, V>(map, keyObj, isEq);\n      map := t;\n      switch (ov) {\n        case null {};\n        case (?_) { _size -= 1 }\n      };\n      ov\n    };\n\n    /// Returns an iterator over the keys of the map.\n    ///\n    /// Each iterator gets a _snapshot view_ of the mapping, and is unaffected\n    /// by concurrent updates to the iterated map.\n    ///\n    /// Example:\n    /// ```motoko include=initialize\n    /// map.put(0, 10);\n    /// map.put(1, 11);\n    /// map.put(2, 12);\n    ///\n    /// // find the sum of all the keys\n    /// var sum = 0;\n    /// for (key in map.keys()) {\n    ///   sum += key;\n    /// };\n    /// // 0 + 1 + 2\n    /// sum\n    /// ```\n    ///\n    /// | Runtime | Space |\n    /// |---------|--------|\n    /// | `O(1)`    | `O(1)`   |\n    public func keys() : I.Iter<K> {\n      I.map(entries(), func(kv : (K, V)) : K { kv.0 })\n    };\n\n    /// Returns an iterator over the values in the map.\n    ///\n    /// Each iterator gets a _snapshot view_ of the mapping, and is unaffected\n    /// by concurrent updates to the iterated map.\n    ///\n    /// Example:\n    /// ```motoko include=initialize\n    /// map.put(0, 10);\n    /// map.put(1, 11);\n    /// map.put(2, 12);\n    ///\n    /// // find the sum of all the values\n    /// var sum = 0;\n    /// for (key in map.vals()) {\n    ///   sum += key;\n    /// };\n    /// // 10 + 11 + 12\n    /// sum\n    /// ```\n    ///\n    /// | Runtime | Space |\n    /// |---------|--------|\n    /// | `O(1)`   | `O(1)`  |\n    public func vals() : I.Iter<V> {\n      I.map(entries(), func(kv : (K, V)) : V { kv.1 })\n    };\n\n    /// Returns an iterator over the entries (key-value pairs) in the map.\n    ///\n    /// Each iterator gets a _snapshot view_ of the mapping, and is unaffected\n    /// by concurrent updates to the iterated map.\n    ///\n    /// Example:\n    /// ```motoko include=initialize\n    /// map.put(0, 10);\n    /// map.put(1, 11);\n    /// map.put(2, 12);\n    ///\n    /// // find the sum of all the products of key-value pairs\n    /// var sum = 0;\n    /// for ((key, value) in map.entries()) {\n    ///   sum += key * value;\n    /// };\n    /// // (0 * 10) + (1 * 11) + (2 * 12)\n    /// sum\n    /// ```\n    ///\n    /// | Runtime | Space |\n    /// |---------|--------|\n    /// | `O(1)`    | `O(1)`   |\n    public func entries() : I.Iter<(K, V)> {\n      object {\n        var stack = ?(map, null) : List.List<T.Trie<K, V>>;\n        public func next() : ?(K, V) {\n          switch stack {\n            case null { null };\n            case (?(trie, stack2)) {\n              switch trie {\n                case (#empty) {\n                  stack := stack2;\n                  next()\n                };\n                case (#leaf({ keyvals = null })) {\n                  stack := stack2;\n                  next()\n                };\n                case (#leaf({ size = c; keyvals = ?((k, v), kvs) })) {\n                  stack := ?(#leaf({ size = c -1; keyvals = kvs }), stack2);\n                  ?(k.key, v)\n                };\n                case (#branch(br)) {\n                  stack := ?(br.left, ?(br.right, stack2));\n                  next()\n                }\n              }\n            }\n          }\n        }\n      }\n    }\n  };\n\n  /// Produce a copy of `map`, using `keyEq` to compare keys and `keyHash` to\n  /// hash keys.\n  ///\n  /// Example:\n  /// ```motoko include=initialize\n  /// map.put(0, 10);\n  /// map.put(1, 11);\n  /// map.put(2, 12);\n  /// // Clone using the same equality and hash functions used to initialize `map`\n  /// let mapCopy = TrieMap.clone(map, Nat.equal, Hash.hash);\n  /// Iter.toArray(mapCopy.entries())\n  /// ```\n  ///\n  /// | Runtime             | Space    |\n  /// |---------------------|----------|\n  /// | `O(size * log(size))` | `O(size)`  |\n  public func clone<K, V>(\n    map : TrieMap<K, V>,\n    keyEq : (K, K) -> Bool,\n    keyHash : K -> Hash.Hash\n  ) : TrieMap<K, V> {\n    let h2 = TrieMap<K, V>(keyEq, keyHash);\n    for ((k, v) in map.entries()) {\n      h2.put(k, v)\n    };\n    h2\n  };\n\n  /// Create a new map from the entries in `entries`, using `keyEq` to compare\n  /// keys and `keyHash` to hash keys.\n  ///\n  /// Example:\n  /// ```motoko include=initialize\n  /// let entries = [(0, 10), (1, 11), (2, 12)];\n  /// let newMap = TrieMap.fromEntries<Nat, Nat>(entries.vals(), Nat.equal, Hash.hash);\n  /// newMap.get(2)\n  /// ```\n  ///\n  /// | Runtime             | Space    |\n  /// |---------------------|----------|\n  /// | `O(size * log(size))` | `O(size)`  |\n  public func fromEntries<K, V>(\n    entries : I.Iter<(K, V)>,\n    keyEq : (K, K) -> Bool,\n    keyHash : K -> Hash.Hash\n  ) : TrieMap<K, V> {\n    let h = TrieMap<K, V>(keyEq, keyHash);\n    for ((k, v) in entries) {\n      h.put(k, v)\n    };\n    h\n  };\n\n  /// Transform (map) the values in `map` using function `f`, retaining the keys.\n  /// Uses `keyEq` to compare keys and `keyHash` to hash keys.\n  ///\n  /// Example:\n  /// ```motoko include=initialize\n  /// map.put(0, 10);\n  /// map.put(1, 11);\n  /// map.put(2, 12);\n  /// // double all the values in map\n  /// let newMap = TrieMap.map<Nat, Nat, Nat>(map, Nat.equal, Hash.hash, func(key, value) = value * 2);\n  /// Iter.toArray(newMap.entries())\n  /// ```\n  ///\n  /// | Runtime             | Space    |\n  /// |---------------------|----------|\n  /// | `O(size * log(size))` | `O(size)`  |\n  public func map<K, V1, V2>(\n    map : TrieMap<K, V1>,\n    keyEq : (K, K) -> Bool,\n    keyHash : K -> Hash.Hash,\n    f : (K, V1) -> V2\n  ) : TrieMap<K, V2> {\n    let h2 = TrieMap<K, V2>(keyEq, keyHash);\n    for ((k, v1) in map.entries()) {\n      let v2 = f(k, v1);\n      h2.put(k, v2)\n    };\n    h2\n  };\n\n  /// Transform (map) the values in `map` using function `f`, discarding entries\n  /// for which `f` evaluates to `null`. Uses `keyEq` to compare keys and\n  /// `keyHash` to hash keys.\n  ///\n  /// Example:\n  /// ```motoko include=initialize\n  /// map.put(0, 10);\n  /// map.put(1, 11);\n  /// map.put(2, 12);\n  /// // double all the values in map, only keeping entries that have an even key\n  /// let newMap =\n  ///   TrieMap.mapFilter<Nat, Nat, Nat>(\n  ///     map,\n  ///     Nat.equal,\n  ///     Hash.hash,\n  ///     func(key, value) = if (key % 2 == 0) { ?(value * 2) } else { null }\n  ///   );\n  /// Iter.toArray(newMap.entries())\n  /// ```\n  ///\n  /// | Runtime             | Space    |\n  /// |---------------------|----------|\n  /// | `O(size * log(size))` | `O(size)`\n  public func mapFilter<K, V1, V2>(\n    map : TrieMap<K, V1>,\n    keyEq : (K, K) -> Bool,\n    keyHash : K -> Hash.Hash,\n    f : (K, V1) -> ?V2\n  ) : TrieMap<K, V2> {\n    let h2 = TrieMap<K, V2>(keyEq, keyHash);\n    for ((k, v1) in map.entries()) {\n      switch (f(k, v1)) {\n        case null {};\n        case (?v2) {\n          h2.put(k, v2)\n        }\n      }\n    };\n    h2\n  }\n}\n"},"HashMap.mo":{"content":"/// Class `HashMap<K, V>` provides a hashmap from keys of type `K` to values of type `V`.\n/// The class is parameterized by the key's equality and hash functions, and an initial capacity.\n/// However, the underlying allocation occurs only upon the first insertion.\n///\n/// Internally, the map is backed by an array of `AssocList` (buckets).\n/// The array doubles in size when the expected bucket list size grows beyond a fixed threshold.\n///\n/// :::warning Performance considerations\n///\n/// Certain operations, such as `put`, are amortized `O(1)` but can run in worst-case `O(size)` time.\n/// These worst cases may exceed the cycle limit per message on large maps.\n/// This analysis assumes that the hash function distributes keys uniformly.\n/// Use caution when growing large maps and ensure good hash functions are used.\n///\n/// :::\n///\n/// :::note Non-amortized alternative\n///\n/// For maps without amortization, see `TrieMap`.\n/// :::\n///\n/// :::info Constructor note\n///\n/// The `initCapacity` argument sets the initial number of buckets.\n/// All runtime and space complexities assume that the equality and hash functions run in `O(1)` time and space.\n///\n/// :::\n///\n/// Example:\n///\n/// ```motoko name=initialize\n/// import HashMap \"mo:base/HashMap\";\n/// import Text \"mo:base/Text\";\n///\n/// let map = HashMap.HashMap<Text, Nat>(5, Text.equal, Text.hash);\n/// ```\n///\n/// | Runtime   | Space     |\n/// |-----------|-----------|\n/// | `O(1)` | `O(1)` |\n\nimport Prim \"mo:⛔\";\nimport P \"Prelude\";\nimport A \"Array\";\nimport Hash \"Hash\";\nimport Iter \"Iter\";\nimport AssocList \"AssocList\";\nimport Nat32 \"Nat32\";\n\nmodule {\n\n  // hash field avoids re-hashing the key when the array grows.\n  type Key<K> = (Hash.Hash, K);\n\n  // key-val list type\n  type KVs<K, V> = AssocList.AssocList<Key<K>, V>;\n\n  public class HashMap<K, V>(\n    initCapacity : Nat,\n    keyEq : (K, K) -> Bool,\n    keyHash : K -> Hash.Hash\n  ) {\n\n    var table : [var KVs<K, V>] = [var];\n    var _count : Nat = 0;\n\n    /// Returns the current number of key-value entries in the map.\n    ///\n    /// Example:\n    /// ```motoko include=initialize\n    /// map.size() // => 0\n    /// ```\n    ///\n    /// | Runtime   | Space     |\n    /// |-----------|-----------|\n    /// | `O(1)` | `O(1)` |\n    public func size() : Nat = _count;\n\n    /// Returns the value assocaited with key `key` if present and `null` otherwise.\n    ///\n    /// Example:\n    /// ```motoko include=initialize\n    /// map.put(\"key\", 3);\n    /// map.get(\"key\") // => ?3\n    /// ```\n    ///\n    /// | Runtime(worst) | Runtime(amortized) |  Space |\n    /// |----------------------------|--------------------|---------------------------|\n    /// | `O(size)`                     | `O(1)`          | `O(1)`                    |\n    ///\n    public func get(key : K) : (value : ?V) {\n      let h = Prim.nat32ToNat(keyHash(key));\n      let m = table.size();\n      if (m > 0) {\n        AssocList.find<Key<K>, V>(table[h % m], keyHash_(key), keyHashEq)\n      } else {\n        null\n      }\n    };\n\n    /// Insert the value `value` with key `key`. Overwrites any existing entry with key `key`.\n    ///\n    /// Example:\n    /// ```motoko include=initialize\n    /// map.put(\"key\", 3);\n    /// map.get(\"key\") // => ?3\n    /// ```\n    ///\n    /// | Runtime(amortized) | Runtime(worst) | Space (amortized) | Space(worst)\n    /// |----------------------------|--------------------|---------------------------|------------------|\n    /// | `O(1)`                     | `O(size)`          | `O(1)`                    | `O(size)`        |\n    /// :::note Initial allocation\n    ///\n    /// This operation triggers the allocation of the underlying array if it is the first entry in the map.\n    /// :::\n    public func put(key : K, value : V) = ignore replace(key, value);\n\n    /// Insert the value `value` with key `key`. Returns the previous value\n    /// associated with key `key` or `null` if no such value exists.\n    ///\n    /// Example:\n    /// ```motoko include=initialize\n    /// map.put(\"key\", 3);\n    /// ignore map.replace(\"key\", 2); // => ?3\n    /// map.get(\"key\") // => ?2\n    /// ```\n    ///\n    /// | Expected Amortized Runtime | Worst Case Runtime | Expected Amortized Space | Worst Case Space |\n    /// |----------------------------|--------------------|---------------------------|------------------|\n    /// | `O(1)`                     | `O(size)`          | `O(1)`                    | `O(size)`        |\n    ///\n    /// :::note Initial allocation\n    ///\n    /// This operation triggers the allocation of the underlying array if it is the first entry in the map.\n    /// :::\n    public func replace(key : K, value : V) : (oldValue : ?V) {\n      if (_count >= table.size()) {\n        let size = if (_count == 0) {\n          if (initCapacity > 0) {\n            initCapacity\n          } else {\n            1\n          }\n        } else {\n          table.size() * 2\n        };\n        let table2 = A.init<KVs<K, V>>(size, null);\n        for (i in table.keys()) {\n          var kvs = table[i];\n          label moveKeyVals : () loop {\n            switch kvs {\n              case null { break moveKeyVals };\n              case (?((k, v), kvsTail)) {\n                let pos2 = Nat32.toNat(k.0) % table2.size(); // critical: uses saved hash. no re-hash.\n                table2[pos2] := ?((k, v), table2[pos2]);\n                kvs := kvsTail\n              }\n            }\n          }\n        };\n        table := table2\n      };\n      let h = Prim.nat32ToNat(keyHash(key));\n      let pos = h % table.size();\n      let (kvs2, ov) = AssocList.replace<Key<K>, V>(table[pos], keyHash_(key), keyHashEq, ?value);\n      table[pos] := kvs2;\n      switch (ov) {\n        case null { _count += 1 };\n        case _ {}\n      };\n      ov\n    };\n\n    /// Deletes the entry with the key `key`. Has no effect if `key` is not\n    /// present in the map.\n    ///\n    /// Example:\n    /// ```motoko include=initialize\n    /// map.put(\"key\", 3);\n    /// map.delete(\"key\");\n    /// map.get(\"key\"); // => null\n    /// ```\n    ///\n    /// | Expected Runtime | Worst Case Runtime | Expected Space | Worst Case Space |\n    /// |------------------|--------------------|----------------|------------------|\n    /// | `O(1)`           | `O(size)`          | `O(1)`         | `O(size)`        |\n    ///\n    public func delete(key : K) = ignore remove(key);\n\n    func keyHash_(k : K) : Key<K> = (keyHash(k), k);\n\n    func keyHashEq(k1 : Key<K>, k2 : Key<K>) : Bool {\n      k1.0 == k2.0 and keyEq(k1.1, k2.1)\n    };\n\n    /// Deletes the entry with the key `key`. Returns the previous value\n    /// associated with key `key` or `null` if no such value exists.\n    ///\n    /// Example:\n    /// ```motoko include=initialize\n    /// map.put(\"key\", 3);\n    /// map.remove(\"key\"); // => ?3\n    /// ```\n    ///\n    /// | Expected Runtime | Worst Case Runtime | Expected Space | Worst Case Space |\n    /// |------------------|--------------------|----------------|------------------|\n    /// | `O(1)`           | `O(size)`          | `O(1)`         | `O(size)`        |\n    public func remove(key : K) : (oldValue : ?V) {\n      let m = table.size();\n      if (m > 0) {\n        let h = Prim.nat32ToNat(keyHash(key));\n        let pos = h % m;\n        let (kvs2, ov) = AssocList.replace<Key<K>, V>(table[pos], keyHash_(key), keyHashEq, null);\n        table[pos] := kvs2;\n        switch (ov) {\n          case null {};\n          case _ { _count -= 1 }\n        };\n        ov\n      } else {\n        null\n      }\n    };\n\n    /// Returns an Iterator (`Iter`) over the keys of the map.\n    /// Iterator provides a single method `next()`, which returns\n    /// keys in no specific order, or `null` when out of keys to iterate over.\n    ///\n    /// Example:\n    /// ```motoko include=initialize\n    ///\n    /// map.put(\"key1\", 1);\n    /// map.put(\"key2\", 2);\n    /// map.put(\"key3\", 3);\n    ///\n    /// var keys = \"\";\n    /// for (key in map.keys()) {\n    ///   keys := key # \" \" # keys\n    /// };\n    /// keys // => \"key3 key2 key1 \"\n    /// ```\n    ///\n    /// Cost of iteration over all keys:\n    ///\n    /// | Runtime   | Space     |\n    /// |-----------|-----------|\n    /// | `O(size)` | `O(1)` |\n    public func keys() : Iter.Iter<K> {\n      Iter.map(entries(), func(kv : (K, V)) : K { kv.0 })\n    };\n\n    /// Returns an Iterator (`Iter`) over the values of the map.\n    /// Iterator provides a single method `next()`, which returns\n    /// values in no specific order, or `null` when out of values to iterate over.\n    ///\n    /// Example:\n    /// ```motoko include=initialize\n    ///\n    /// map.put(\"key1\", 1);\n    /// map.put(\"key2\", 2);\n    /// map.put(\"key3\", 3);\n    ///\n    /// var sum = 0;\n    /// for (value in map.vals()) {\n    ///   sum += value;\n    /// };\n    /// sum // => 6\n    /// ```\n    ///\n    /// | Runtime   | Space     |\n    /// |-----------|-----------|\n    /// | `O(size)` | `O(1)` |\n    public func vals() : Iter.Iter<V> {\n      Iter.map(entries(), func(kv : (K, V)) : V { kv.1 })\n    };\n\n    /// Returns an Iterator (`Iter`) over the key-value pairs in the map.\n    /// Iterator provides a single method `next()`, which returns\n    /// pairs in no specific order, or `null` when out of pairs to iterate over.\n    ///\n    /// Example:\n    /// ```motoko include=initialize\n    /// import Nat \"mo:base/Nat\";\n    ///\n    /// map.put(\"key1\", 1);\n    /// map.put(\"key2\", 2);\n    /// map.put(\"key3\", 3);\n    ///\n    /// var pairs = \"\";\n    /// for ((key, value) in map.entries()) {\n    ///   pairs := \"(\" # key # \", \" # Nat.toText(value) # \") \" # pairs\n    /// };\n    /// pairs // => \"(key3, 3) (key2, 2) (key1, 1)\"\n    /// ```\n    ///\n    /// Cost of iteration over all pairs:\n    ///\n    /// | Runtime   | Space     |\n    /// |-----------|-----------|\n    /// | `O(size)` | `O(1)` |\n    public func entries() : Iter.Iter<(K, V)> {\n      if (table.size() == 0) {\n        object { public func next() : ?(K, V) { null } }\n      } else {\n        object {\n          var kvs = table[0];\n          var nextTablePos = 1;\n          public func next() : ?(K, V) {\n            switch kvs {\n              case (?(kv, kvs2)) {\n                kvs := kvs2;\n                ?(kv.0.1, kv.1)\n              };\n              case null {\n                if (nextTablePos < table.size()) {\n                  kvs := table[nextTablePos];\n                  nextTablePos += 1;\n                  next()\n                } else {\n                  null\n                }\n              }\n            }\n          }\n        }\n      }\n    };\n\n  };\n\n  /// Returns a copy of `map`, initializing the copy with the provided equality\n  /// and hash functions.\n  ///\n  /// Example:\n  /// ```motoko include=initialize\n  /// map.put(\"key1\", 1);\n  /// map.put(\"key2\", 2);\n  /// map.put(\"key3\", 3);\n  ///\n  /// let map2 = HashMap.clone(map, Text.equal, Text.hash);\n  /// map2.get(\"key1\") // => ?1\n  /// ```\n  ///\n  /// | Runtime(expected) | Runtime(worst) |  Space(expected) | Space(worst) |\n  /// |------------------|--------------------|----------------|------------------|\n  /// | `O(size)`        | `O(size * size)`   | `O(size)`      | `O(size)`        |\n  public func clone<K, V>(\n    map : HashMap<K, V>,\n    keyEq : (K, K) -> Bool,\n    keyHash : K -> Hash.Hash\n  ) : HashMap<K, V> {\n    let h2 = HashMap<K, V>(map.size(), keyEq, keyHash);\n    for ((k, v) in map.entries()) {\n      h2.put(k, v)\n    };\n    h2\n  };\n\n  /// Returns a new map, containing all entries given by the iterator `iter`.\n  /// The new map is initialized with the provided initial capacity, equality,\n  /// and hash functions.\n  ///\n  /// Example:\n  /// ```motoko include=initialize\n  /// let entries = [(\"key3\", 3), (\"key2\", 2), (\"key1\", 1)];\n  /// let iter = entries.vals();\n  ///\n  /// let map2 = HashMap.fromIter<Text, Nat>(iter, entries.size(), Text.equal, Text.hash);\n  /// map2.get(\"key1\") // => ?1\n  /// ```\n  ///\n  /// | Runtime(expected) | Runtime(worst) |  Space(expected) | Space(worst) |\n  /// |------------------|--------------------|----------------|------------------|\n  /// | `O(size)`        | `O(size * size)`   | `O(size)`      | `O(size)`        |\n  public func fromIter<K, V>(\n    iter : Iter.Iter<(K, V)>,\n    initCapacity : Nat,\n    keyEq : (K, K) -> Bool,\n    keyHash : K -> Hash.Hash\n  ) : HashMap<K, V> {\n    let h = HashMap<K, V>(initCapacity, keyEq, keyHash);\n    for ((k, v) in iter) {\n      h.put(k, v)\n    };\n    h\n  };\n\n  /// Creates a new map by applying `f` to each entry in `hashMap`. Each entry\n  /// `(k, v)` in the old map is transformed into a new entry `(k, v2)`, where\n  /// the new value `v2` is created by applying `f` to `(k, v)`.\n  ///\n  /// ```motoko include=initialize\n  /// map.put(\"key1\", 1);\n  /// map.put(\"key2\", 2);\n  /// map.put(\"key3\", 3);\n  ///\n  /// let map2 = HashMap.map<Text, Nat, Nat>(map, Text.equal, Text.hash, func (k, v) = v * 2);\n  /// map2.get(\"key2\") // => ?4\n  /// ```\n  ///\n  /// Expected Runtime: O(size), Worst Case Runtime: O(size * size)\n  ///\n  /// | Runtime(expected) | Runtime(worst) |  Space(expected) | Space(worst) |\n  /// |------------------|--------------------|----------------|------------------|\n  /// | `O(size)`        | `O(size * size)`   | `O(size)`      | `O(size)`        |\n  public func map<K, V1, V2>(\n    hashMap : HashMap<K, V1>,\n    keyEq : (K, K) -> Bool,\n    keyHash : K -> Hash.Hash,\n    f : (K, V1) -> V2\n  ) : HashMap<K, V2> {\n    let h2 = HashMap<K, V2>(hashMap.size(), keyEq, keyHash);\n    for ((k, v1) in hashMap.entries()) {\n      let v2 = f(k, v1);\n      h2.put(k, v2)\n    };\n    h2\n  };\n\n  /// Creates a new map by applying `f` to each entry in `hashMap`. For each entry\n  /// `(k, v)` in the old map, if `f` evaluates to `null`, the entry is discarded.\n  /// Otherwise, the entry is transformed into a new entry `(k, v2)`, where\n  /// the new value `v2` is the result of applying `f` to `(k, v)`.\n  ///\n  /// ```motoko include=initialize\n  /// map.put(\"key1\", 1);\n  /// map.put(\"key2\", 2);\n  /// map.put(\"key3\", 3);\n  ///\n  /// let map2 =\n  ///   HashMap.mapFilter<Text, Nat, Nat>(\n  ///     map,\n  ///     Text.equal,\n  ///     Text.hash,\n  ///     func (k, v) = if (v == 2) { null } else { ?(v * 2)}\n  /// );\n  /// map2.get(\"key3\") // => ?6\n  /// ```\n  ///\n  /// | Runtime(expected) | Runtime(worst) |  Space(expected) | Space(worst) |\n  /// |------------------|--------------------|----------------|------------------|\n  /// | `O(size)`        | `O(size * size)`   | `O(size)`      | `O(size)`        |\n  public func mapFilter<K, V1, V2>(\n    hashMap : HashMap<K, V1>,\n    keyEq : (K, K) -> Bool,\n    keyHash : K -> Hash.Hash,\n    f : (K, V1) -> ?V2\n  ) : HashMap<K, V2> {\n    let h2 = HashMap<K, V2>(hashMap.size(), keyEq, keyHash);\n    for ((k, v1) in hashMap.entries()) {\n      switch (f(k, v1)) {\n        case null {};\n        case (?v2) {\n          h2.put(k, v2)\n        }\n      }\n    };\n    h2\n  };\n\n}\n"},"TrieSet.mo":{"content":"///\n/// Sets are partial maps from element type to unit type,\n/// i.e., the partial map represents the set with its domain.\n///\n/// :::warning Limitations\n///\n/// This data structure allows at most `MAX_LEAF_SIZE = 8` hash collisions.\n/// Attempts to insert more than 8 elements with the same hash value—either directly via `put` or indirectly via other operations—will trap.\n/// This limitation is inherited from the underlying `Trie` data structure.\n/// :::\n///\n\n// TODO-Matthew:\n// ---------------\n//\n// - for now, we pass a hash value each time we pass an element value;\n//   in the future, we might avoid passing element hashes with each element in the API;\n//   related to: https://dfinity.atlassian.net/browse/AST-32\n//\n// - similarly, we pass an equality function when we do some operations.\n//   in the future, we might avoid this via https://dfinity.atlassian.net/browse/AST-32\nimport Trie \"Trie\";\nimport Hash \"Hash\";\nimport List \"List\";\nimport Iter \"Iter\";\n\nmodule {\n\n  public type Hash = Hash.Hash;\n  public type Set<T> = Trie.Trie<T, ()>;\n  type Key<K> = Trie.Key<K>;\n  type Trie<K, V> = Trie.Trie<K, V>;\n\n  // helper for defining equal and sub, avoiding Trie.diff.\n  // TODO: add to Trie.mo?\n  private func keys<K>(t : Trie<K, Any>) : Iter.Iter<Key<K>> {\n    object {\n      var stack = ?(t, null) : List.List<Trie<K, Any>>;\n      public func next() : ?Key<K> {\n        switch stack {\n          case null { null };\n          case (?(trie, stack2)) {\n            switch trie {\n              case (#empty) {\n                stack := stack2;\n                next()\n              };\n              case (#leaf({ keyvals = null })) {\n                stack := stack2;\n                next()\n              };\n              case (#leaf({ size = c; keyvals = ?((k, _v), kvs) })) {\n                stack := ?(#leaf({ size = c - 1; keyvals = kvs }), stack2);\n                ?k\n              };\n              case (#branch(br)) {\n                stack := ?(br.left, ?(br.right, stack2));\n                next()\n              }\n            }\n          }\n        }\n      }\n    }\n  };\n\n  /// Empty set.\n  public func empty<T>() : Set<T> { Trie.empty<T, ()>() };\n\n  /// Put an element into the set.\n  public func put<T>(s : Set<T>, x : T, xh : Hash, eq : (T, T) -> Bool) : Set<T> {\n    let (s2, _) = Trie.put<T, ()>(s, { key = x; hash = xh }, eq, ());\n    s2\n  };\n\n  /// Delete an element from the set.\n  public func delete<T>(s : Set<T>, x : T, xh : Hash, eq : (T, T) -> Bool) : Set<T> {\n    let (s2, _) = Trie.remove<T, ()>(s, { key = x; hash = xh }, eq);\n    s2\n  };\n\n  /// Test if two sets are equal.\n  public func equal<T>(s1 : Set<T>, s2 : Set<T>, eq : (T, T) -> Bool) : Bool {\n    if (Trie.size(s1) != Trie.size(s2)) return false;\n    for (k in keys(s1)) {\n      if (Trie.find<T, ()>(s2, k, eq) == null) {\n        return false\n      }\n    };\n    return true\n  };\n\n  /// The number of set elements, set's cardinality.\n  public func size<T>(s : Set<T>) : Nat {\n    Trie.size(s)\n  };\n\n  /// Test if `s` is the empty set.\n  public func isEmpty<T>(s : Set<T>) : Bool {\n    Trie.size(s) == 0\n  };\n\n  /// Test if `s1` is a subset of `s2`.\n  public func isSubset<T>(s1 : Set<T>, s2 : Set<T>, eq : (T, T) -> Bool) : Bool {\n    if (Trie.size(s1) > Trie.size(s2)) return false;\n    for (k in keys(s1)) {\n      if (Trie.find<T, ()>(s2, k, eq) == null) {\n        return false\n      }\n    };\n    return true\n  };\n\n  /// :::warning Deprecated function\n  /// Use `TrieSet.contains()` instead.\n  /// :::\n  ///\n  /// Test if a set contains a given element.\n  public func mem<T>(s : Set<T>, x : T, xh : Hash, eq : (T, T) -> Bool) : Bool {\n    contains(s, x, xh, eq)\n  };\n\n  /// Test if a set contains a given element.\n  public func contains<T>(s : Set<T>, x : T, xh : Hash, eq : (T, T) -> Bool) : Bool {\n    switch (Trie.find<T, ()>(s, { key = x; hash = xh }, eq)) {\n      case null { false };\n      case (?_) { true }\n    }\n  };\n\n  /// [Set union](https://en.wikipedia.org/wiki/Union_(set_theory)).\n  public func union<T>(s1 : Set<T>, s2 : Set<T>, eq : (T, T) -> Bool) : Set<T> {\n    let s3 = Trie.merge<T, ()>(s1, s2, eq);\n    s3\n  };\n\n  /// [Set difference](https://en.wikipedia.org/wiki/Difference_(set_theory)).\n  public func diff<T>(s1 : Set<T>, s2 : Set<T>, eq : (T, T) -> Bool) : Set<T> {\n    let s3 = Trie.diff<T, (), ()>(s1, s2, eq);\n    s3\n  };\n\n  /// [Set intersection](https://en.wikipedia.org/wiki/Intersection_(set_theory)).\n  public func intersect<T>(s1 : Set<T>, s2 : Set<T>, eq : (T, T) -> Bool) : Set<T> {\n    let noop : ((), ()) -> (()) = func(_ : (), _ : ()) : (()) = ();\n    let s3 = Trie.join<T, (), (), ()>(s1, s2, eq, noop);\n    s3\n  };\n\n  /// Construct a set from an array.\n  public func fromArray<T>(arr : [T], elemHash : T -> Hash, eq : (T, T) -> Bool) : Set<T> {\n    var s = empty<T>();\n    for (elem in arr.vals()) {\n      s := put<T>(s, elem, elemHash(elem), eq)\n    };\n    s\n  };\n\n  /// Returns the set as an array.\n  public func toArray<T>(s : Set<T>) : [T] {\n    Trie.toArray(s, func(t : T, _ : ()) : T { t })\n  }\n\n}\n"},"Time.mo":{"content":"/// System time\n\nimport Prim \"mo:⛔\";\nmodule {\n\n  /// System time is represent as nanoseconds since 1970-01-01.\n  public type Time = Int;\n\n  /// Current system time given as nanoseconds since 1970-01-01. The system guarantees that:\n  ///\n  /// * The time, as observed by the canister smart contract, is monotonically increasing, even across canister upgrades.\n  /// * Within an invocation of one entry point, the time is constant.\n  ///\n  /// The system times of different canisters are unrelated, and calls from one canister to another may appear to travel \"backwards in time\"\n  ///\n  /// :::note Accuracy guarantee\n  /// While an implementation will likely try to keep the system time close to the real time, this is not formally guaranteed.\n  /// :::\n  public let now : () -> Time = func() : Int = Prim.nat64ToNat(Prim.time());\n  ///\n  /// The following example illustrates using the system time:\n  ///\n  /// ```motoko\n  /// import Int = \"mo:base/Int\";\n  /// import Time = \"mo:base/Time\";\n  ///\n  /// actor {\n  ///   var lastTime = Time.now();\n  ///   public func greet(name : Text) : async Text {\n  ///     let now = Time.now();\n  ///     let elapsedSeconds = (now - lastTime) / 1000_000_000;\n  ///     lastTime := now;\n  ///     return \"Hello, \" # name # \"!\" #\n  ///       \" I was last called \" # Int.toText(elapsedSeconds) # \" seconds ago\";\n  ///    };\n  /// };\n  /// ```\n}\n"},"Iter.mo":{"content":"\nimport Array \"Array\";\nimport Buffer \"Buffer\";\nimport List \"List\";\nimport Order \"Order\";\n\nmodule {\n\n  /// An iterator that produces values of type `T`. Calling `next` returns\n  /// `null` when iteration is finished.\n  ///\n  /// Iterators are inherently stateful. Calling `next` \"consumes\" a value from\n  /// the Iterator that cannot be put back, so keep that in mind when sharing\n  /// iterators between consumers.\n  ///\n  /// An iterater `i` can be iterated over using\n  /// ```\n  /// for (x in i) {\n  ///   …do something with x…\n  /// }\n  /// ```\n  public type Iter<T> = { next : () -> ?T };\n\n  /// Creates an iterator that produces all `Nat`s from `x` to `y` including\n  /// both of the bounds.\n  /// ```motoko\n  /// import Iter \"mo:base/Iter\";\n  /// let iter = Iter.range(1, 3);\n  /// assert(?1 == iter.next());\n  /// assert(?2 == iter.next());\n  /// assert(?3 == iter.next());\n  /// assert(null == iter.next());\n  /// ```\n  public class range(x : Nat, y : Int) {\n    var i = x;\n    public func next() : ?Nat {\n      if (i > y) { null } else { let j = i; i += 1; ?j }\n    }\n  };\n\n  /// Like `range` but produces the values in the opposite\n  /// order.\n  public class revRange(x : Int, y : Int) {\n    var i = x;\n    public func next() : ?Int {\n      if (i < y) { null } else { let j = i; i -= 1; ?j }\n    }\n  };\n\n  /// Calls a function `f` on every value produced by an iterator and discards\n  /// the results. If you're looking to keep these results use `map` instead.\n  ///\n  /// ```motoko\n  /// import Iter \"mo:base/Iter\";\n  /// var sum = 0;\n  /// Iter.iterate<Nat>(Iter.range(1, 3), func(x, _index) {\n  ///   sum += x;\n  /// });\n  /// assert(6 == sum)\n  /// ```\n  public func iterate<A>(\n    xs : Iter<A>,\n    f : (A, Nat) -> ()\n  ) {\n    var i = 0;\n    label l loop {\n      switch (xs.next()) {\n        case (?next) {\n          f(next, i)\n        };\n        case (null) {\n          break l\n        }\n      };\n      i += 1;\n      continue l\n    }\n  };\n\n  /// Consumes an iterator and counts how many elements were produced\n  /// (discarding them in the process).\n  public func size<A>(xs : Iter<A>) : Nat {\n    var len = 0;\n    iterate<A>(xs, func(x, i) { len += 1 });\n    len\n  };\n\n  /// Takes a function and an iterator and returns a new iterator that lazily applies\n  /// the function to every element produced by the argument iterator.\n  /// ```motoko\n  /// import Iter \"mo:base/Iter\";\n  /// let iter = Iter.range(1, 3);\n  /// let mappedIter = Iter.map(iter, func (x : Nat) : Nat { x * 2 });\n  /// assert(?2 == mappedIter.next());\n  /// assert(?4 == mappedIter.next());\n  /// assert(?6 == mappedIter.next());\n  /// assert(null == mappedIter.next());\n  /// ```\n  public func map<A, B>(xs : Iter<A>, f : A -> B) : Iter<B> = object {\n    public func next() : ?B {\n      switch (xs.next()) {\n        case (?next) {\n          ?f(next)\n        };\n        case (null) {\n          null\n        }\n      }\n    }\n  };\n\n  /// Takes a function and an iterator and returns a new iterator that produces\n  /// elements from the original iterator if and only if the predicate is true.\n  /// ```motoko\n  /// import Iter \"mo:base/Iter\";\n  /// let iter = Iter.range(1, 3);\n  /// let mappedIter = Iter.filter(iter, func (x : Nat) : Bool { x % 2 == 1 });\n  /// assert(?1 == mappedIter.next());\n  /// assert(?3 == mappedIter.next());\n  /// assert(null == mappedIter.next());\n  /// ```\n  public func filter<A>(xs : Iter<A>, f : A -> Bool) : Iter<A> = object {\n    public func next() : ?A {\n      loop {\n        switch (xs.next()) {\n          case (null) {\n            return null\n          };\n          case (?x) {\n            if (f(x)) {\n              return ?x\n            }\n          }\n        }\n      };\n      null\n    }\n  };\n\n  /// Creates an iterator that produces an infinite sequence of `x`.\n  /// ```motoko\n  /// import Iter \"mo:base/Iter\";\n  /// let iter = Iter.make(10);\n  /// assert(?10 == iter.next());\n  /// assert(?10 == iter.next());\n  /// assert(?10 == iter.next());\n  /// // ...\n  /// ```\n  public func make<A>(x : A) : Iter<A> = object {\n    public func next() : ?A {\n      ?x\n    }\n  };\n\n  /// Takes two iterators and returns a new iterator that produces\n  /// elements from the original iterators sequentally.\n  /// ```motoko\n  /// import Iter \"mo:base/Iter\";\n  /// let iter1 = Iter.range(1, 2);\n  /// let iter2 = Iter.range(5, 6);\n  /// let concatenatedIter = Iter.concat(iter1, iter2);\n  /// assert(?1 == concatenatedIter.next());\n  /// assert(?2 == concatenatedIter.next());\n  /// assert(?5 == concatenatedIter.next());\n  /// assert(?6 == concatenatedIter.next());\n  /// assert(null == concatenatedIter.next());\n  /// ```\n  public func concat<A>(a : Iter<A>, b : Iter<A>) : Iter<A> {\n    var aEnded : Bool = false;\n    object {\n      public func next() : ?A {\n        if (aEnded) {\n          return b.next()\n        };\n        switch (a.next()) {\n          case (?x) ?x;\n          case (null) {\n            aEnded := true;\n            b.next()\n          }\n        }\n      }\n    }\n  };\n\n  /// Creates an iterator that produces the elements of an `Array` in ascending index order.\n  /// ```motoko\n  /// import Iter \"mo:base/Iter\";\n  /// let iter = Iter.fromArray([1, 2, 3]);\n  /// assert(?1 == iter.next());\n  /// assert(?2 == iter.next());\n  /// assert(?3 == iter.next());\n  /// assert(null == iter.next());\n  /// ```\n  public func fromArray<A>(xs : [A]) : Iter<A> {\n    var ix : Nat = 0;\n    let size = xs.size();\n    object {\n      public func next() : ?A {\n        if (ix >= size) {\n          return null\n        } else {\n          let res = ?(xs[ix]);\n          ix += 1;\n          return res\n        }\n      }\n    }\n  };\n\n  /// Like `fromArray` but for `Array`s with mutable elements. Captures\n  /// the elements of the `Array` at the time the iterator is created, so\n  /// further modifications won't be reflected in the iterator.\n  public func fromArrayMut<A>(xs : [var A]) : Iter<A> {\n    fromArray<A>(Array.freeze<A>(xs))\n  };\n\n  /// Like `fromArray` but for Lists.\n  public let fromList = List.toIter;\n\n  /// Consumes an iterator and collects its produced elements in an `Array`.\n  /// ```motoko\n  /// import Iter \"mo:base/Iter\";\n  /// let iter = Iter.range(1, 3);\n  /// assert([1, 2, 3] == Iter.toArray(iter));\n  /// ```\n  public func toArray<A>(xs : Iter<A>) : [A] {\n    let buffer = Buffer.Buffer<A>(8);\n    iterate(xs, func(x : A, _ : Nat) { buffer.add(x) });\n    return Buffer.toArray(buffer)\n  };\n\n  /// Like `toArray` but for `Array`s with mutable elements.\n  public func toArrayMut<A>(xs : Iter<A>) : [var A] {\n    Array.thaw<A>(toArray<A>(xs))\n  };\n\n  /// Like `toArray` but for Lists.\n  public func toList<A>(xs : Iter<A>) : List.List<A> {\n    var result = List.nil<A>();\n    iterate<A>(\n      xs,\n      func(x, _i) {\n        result := List.push<A>(x, result)\n      }\n    );\n    List.reverse<A>(result)\n  };\n\n  /// Sorted iterator.  Will iterate over *all* elements to sort them, necessarily.\n  public func sort<A>(xs : Iter<A>, compare : (A, A) -> Order.Order) : Iter<A> {\n    let a = toArrayMut<A>(xs);\n    Array.sortInPlace<A>(a, compare);\n    fromArrayMut<A>(a)\n  };\n\n}\n"},"Int.mo":{"content":"/// Signed integer numbers with infinite precision (also called big integers).\n///\n/// :::note\n/// Most operations on integer numbers (e.g. addition) are available as built-in operators (e.g. `-1 + 1`).\n/// This module provides equivalent functions and `Text` conversion.\n/// :::\n///\n/// :::info Function form for higher-order use\n///\n/// Several arithmetic and comparison functions (e.g. `add`, `sub`, `equal`, `less`, `pow`) are defined in this module to enable their use as first-class function values, which is not possible with operators like `+`, `-`, `==`, etc., in Motoko. This allows you to pass these operations to higher-order functions such as `map`, `foldLeft`, or `sort`.\n/// :::\n///\n/// Import from the base library to use this module.\n///\n/// ```motoko name=import\n/// import Int \"mo:base/Int\";\n/// ```\n///\n\nimport Prim \"mo:⛔\";\nimport Prelude \"Prelude\";\nimport Hash \"Hash\";\n\nmodule {\n\n  /// Infinite precision signed integers.\n  public type Int = Prim.Types.Int;\n\n  /// Returns the absolute value of `x`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int.abs(-12) // => 12\n  /// ```\n  public func abs(x : Int) : Nat {\n    Prim.abs(x)\n  };\n\n  /// Converts an integer number to its textual representation. Textual\n  /// representation _do not_ contain underscores to represent commas.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int.toText(-1234) // => \"-1234\"\n  /// ```\n  public func toText(x : Int) : Text {\n    if (x == 0) {\n      return \"0\"\n    };\n\n    let isNegative = x < 0;\n    var int = if isNegative { -x } else { x };\n\n    var text = \"\";\n    let base = 10;\n\n    while (int > 0) {\n      let rem = int % base;\n      text := (\n        switch (rem) {\n          case 0 { \"0\" };\n          case 1 { \"1\" };\n          case 2 { \"2\" };\n          case 3 { \"3\" };\n          case 4 { \"4\" };\n          case 5 { \"5\" };\n          case 6 { \"6\" };\n          case 7 { \"7\" };\n          case 8 { \"8\" };\n          case 9 { \"9\" };\n          case _ { Prelude.unreachable() }\n        }\n      ) # text;\n      int := int / base\n    };\n\n    return if isNegative { \"-\" # text } else { text }\n  };\n\n  /// Returns the minimum of `x` and `y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int.min(2, -3) // => -3\n  /// ```\n  public func min(x : Int, y : Int) : Int {\n    if (x < y) { x } else { y }\n  };\n\n  /// Returns the maximum of `x` and `y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int.max(2, -3) // => 2\n  /// ```\n  public func max(x : Int, y : Int) : Int {\n    if (x < y) { y } else { x }\n  };\n\n  // this is a local copy of deprecated Hash.hashNat8 (redefined to suppress the warning)\n  private func hashNat8(key : [Nat32]) : Hash.Hash {\n    var hash : Nat32 = 0;\n    for (natOfKey in key.vals()) {\n      hash := hash +% natOfKey;\n      hash := hash +% hash << 10;\n      hash := hash ^ (hash >> 6)\n    };\n    hash := hash +% hash << 3;\n    hash := hash ^ (hash >> 11);\n    hash := hash +% hash << 15;\n    return hash\n  };\n\n  /// Computes a hash from the least significant 32-bits of `i`, ignoring other bits.\n  /// @deprecated For large `Int` values consider using a bespoke hash function that considers all of the argument's bits.\n  public func hash(i : Int) : Hash.Hash {\n    // CAUTION: This removes the high bits!\n    let j = Prim.int32ToNat32(Prim.intToInt32Wrap(i));\n    hashNat8([\n      j & (255 << 0),\n      j & (255 << 8),\n      j & (255 << 16),\n      j & (255 << 24)\n    ])\n  };\n\n  /// Computes an accumulated hash from `h1` and the least significant 32-bits of `i`, ignoring other bits in `i`.\n  ///\n  /// @deprecated For large `Int` values consider using a bespoke hash function that considers all of the argument's bits.\n  public func hashAcc(h1 : Hash.Hash, i : Int) : Hash.Hash {\n    // CAUTION: This removes the high bits!\n    let j = Prim.int32ToNat32(Prim.intToInt32Wrap(i));\n    hashNat8([\n      h1,\n      j & (255 << 0),\n      j & (255 << 8),\n      j & (255 << 16),\n      j & (255 << 24)\n    ])\n  };\n\n  /// Equality function for Int types.\n  /// This is equivalent to `x == y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int.equal(-1, -1); // => true\n  /// ```\n  ///\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// import Buffer \"mo:base/Buffer\";\n  ///\n  /// let buffer1 = Buffer.Buffer<Int>(1);\n  /// buffer1.add(-3);\n  /// let buffer2 = Buffer.Buffer<Int>(1);\n  /// buffer2.add(-3);\n  /// Buffer.equal(buffer1, buffer2, Int.equal) // => true\n  /// ```\n  public func equal(x : Int, y : Int) : Bool { x == y };\n\n  /// Inequality function for Int types.\n  /// This is equivalent to `x != y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int.notEqual(-1, -2); // => true\n  /// ```\n  ///\n\n  public func notEqual(x : Int, y : Int) : Bool { x != y };\n\n  /// \"Less than\" function for Int types.\n  /// This is equivalent to `x < y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int.less(-2, 1); // => true\n  /// ```\n  ///\n\n  public func less(x : Int, y : Int) : Bool { x < y };\n\n  /// \"Less than or equal\" function for Int types.\n  /// This is equivalent to `x <= y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int.lessOrEqual(-2, 1); // => true\n  /// ```\n  ///\n\n  public func lessOrEqual(x : Int, y : Int) : Bool { x <= y };\n\n  /// \"Greater than\" function for Int types.\n  /// This is equivalent to `x > y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int.greater(1, -2); // => true\n  /// ```\n  ///\n\n  public func greater(x : Int, y : Int) : Bool { x > y };\n\n  /// \"Greater than or equal\" function for Int types.\n  /// This is equivalent to `x >= y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int.greaterOrEqual(1, -2); // => true\n  /// ```\n  ///\n\n  public func greaterOrEqual(x : Int, y : Int) : Bool { x >= y };\n\n  /// General-purpose comparison function for `Int`. Returns the `Order` (\n  /// either `#less`, `#equal`, or `#greater`) of comparing `x` with `y`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int.compare(-3, 2) // => #less\n  /// ```\n  ///\n  /// This function can be used as value for a high order function, such as a sort function.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// import Array \"mo:base/Array\";\n  /// Array.sort([1, -2, -3], Int.compare) // => [-3, -2, 1]\n  /// ```\n  public func compare(x : Int, y : Int) : { #less; #equal; #greater } {\n    if (x < y) { #less } else if (x == y) { #equal } else { #greater }\n  };\n\n  /// Returns the negation of `x`, `-x` .\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int.neg(123) // => -123\n  /// ```\n  ///\n\n  public func neg(x : Int) : Int { -x };\n\n  /// Returns the sum of `x` and `y`, `x + y`.\n  ///\n  /// No overflow since `Int` has infinite precision.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int.add(1, -2); // => -1\n  /// ```\n  ///\n\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// import Array \"mo:base/Array\";\n  /// Array.foldLeft([1, -2, -3], 0, Int.add) // => -4\n  /// ```\n  public func add(x : Int, y : Int) : Int { x + y };\n\n  /// Returns the difference of `x` and `y`, `x - y`.\n  ///\n  /// No overflow since `Int` has infinite precision.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int.sub(1, 2); // => -1\n  /// ```\n  ///\n\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// import Array \"mo:base/Array\";\n  /// Array.foldLeft([1, -2, -3], 0, Int.sub) // => 4\n  /// ```\n  public func sub(x : Int, y : Int) : Int { x - y };\n\n  /// Returns the product of `x` and `y`, `x * y`.\n  ///\n  /// No overflow since `Int` has infinite precision.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int.mul(-2, 3); // => -6\n  /// ```\n  ///\n\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// import Array \"mo:base/Array\";\n  /// Array.foldLeft([1, -2, -3], 1, Int.mul) // => 6\n  /// ```\n  public func mul(x : Int, y : Int) : Int { x * y };\n\n  /// Returns the signed integer division of `x` by `y`,  `x / y`.\n  /// Rounds the quotient towards zero, which is the same as truncating the decimal places of the quotient.\n  ///\n  /// Traps when `y` is zero.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int.div(6, -2); // => -3\n  /// ```\n  ///\n\n  public func div(x : Int, y : Int) : Int { x / y };\n\n  /// Returns the remainder of the signed integer division of `x` by `y`, `x % y`,\n  /// which is defined as `x - x / y * y`.\n  ///\n  /// Traps when `y` is zero.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int.rem(6, -4); // => 2\n  /// ```\n  ///\n\n  public func rem(x : Int, y : Int) : Int { x % y };\n\n  /// Returns `x` to the power of `y`, `x ** y`.\n  ///\n  /// Traps when `y` is negative or `y > 2 ** 32 - 1`.\n  /// No overflow since `Int` has infinite precision.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// Int.pow(-2, 3); // => -8\n  /// ```\n  ///\n  public func pow(x : Int, y : Int) : Int { x ** y };\n\n}\n"},"Text.mo":{"content":"/// Utility functions for `Text` values.\n///\n/// A `Text` value represents human-readable text as a sequence of characters of type `Char`.\n///\n/// ```motoko\n/// let text = \"Hello!\";\n/// let size = text.size(); // 6\n/// let iter = text.chars(); // iterator ('H', 'e', 'l', 'l', 'o', '!')\n/// let concat = text # \" 👋\"; // \"Hello! 👋\"\n/// ```\n///\n/// The `\"mo:base/Text\"` module defines additional operations on `Text` values.\n///\n/// Import the module from the base library:\n///\n/// ```motoko name=import\n/// import Text \"mo:base/Text\";\n/// ```\n///\n/// :::note\n/// `Text` values are represented as ropes of UTF-8 character sequences with O(1) concatenation.\n/// :::\n\nimport Char \"Char\";\nimport Iter \"Iter\";\nimport Hash \"Hash\";\nimport List \"List\";\nimport Stack \"Stack\";\nimport Prim \"mo:⛔\";\n\nmodule {\n\n  /// The type corresponding to primitive `Text` values.\n  ///\n  /// ```motoko\n  /// let hello = \"Hello!\";\n  /// let emoji = \"👋\";\n  /// let concat = hello # \" \" # emoji; // \"Hello! 👋\"\n  /// ```\n  public type Text = Prim.Types.Text;\n\n  /// Converts the given `Char` to a `Text` value.\n  ///\n  /// ```motoko include=import\n  /// let text = Text.fromChar('A'); // \"A\"\n  /// ```\n  public let fromChar : (c : Char) -> Text = Prim.charToText;\n\n  /// Converts the given `[Char]` to a `Text` value.\n  ///\n  /// ```motoko include=import\n  /// let text = Text.fromArray(['A', 'v', 'o', 'c', 'a', 'd', 'o']); // \"Avocado\"\n  /// ```\n  ///\n/// | Runtime   | Space     |\n/// |-----------|-----------|\n/// | O(a.size()) | O(a.size()) |\n  public func fromArray(a : [Char]) : Text = fromIter(a.vals());\n\n  /// Converts the given `[var Char]` to a `Text` value.\n  ///\n  /// ```motoko include=import\n  /// let text = Text.fromVarArray([var 'E', 'g', 'g', 'p', 'l', 'a', 'n', 't']); // \"Eggplant\"\n  /// ```\n  ///\n/// | Runtime   | Space     |\n/// |-----------|-----------|\n/// | O(a.size()) | O(a.size()) |\n  public func fromVarArray(a : [var Char]) : Text = fromIter(a.vals());\n\n  /// Iterates over each `Char` value in the given `Text`.\n  ///\n  /// Equivalent to calling the `t.chars()` method where `t` is a `Text` value.\n  ///\n  /// ```motoko include=import\n  /// import { print } \"mo:base/Debug\";\n  ///\n  /// for (c in Text.toIter(\"abc\")) {\n  ///   print(debug_show c);\n  /// }\n  /// ```\n  public func toIter(t : Text) : Iter.Iter<Char> = t.chars();\n\n  /// Creates a new `Array` containing characters of the given `Text`.\n  ///\n  /// Equivalent to `Iter.toArray(t.chars())`.\n  ///\n  /// ```motoko include=import\n  /// assert Text.toArray(\"Café\") == ['C', 'a', 'f', 'é'];\n  /// ```\n  ///\n/// | Runtime   | Space     |\n/// |-----------|-----------|\n/// | O(t.size()) | O(t.size()) |\n  public func toArray(t : Text) : [Char] {\n    let cs = t.chars();\n    // We rely on Array_tabulate's implementation details: it fills\n    // the array from left to right sequentially.\n    Prim.Array_tabulate<Char>(\n      t.size(),\n      func _ {\n        switch (cs.next()) {\n          case (?c) { c };\n          case null { Prim.trap(\"Text.toArray\") }\n        }\n      }\n    )\n  };\n\n  /// Creates a new mutable `Array` containing characters of the given `Text`.\n  ///\n  /// Equivalent to `Iter.toArrayMut(t.chars())`.\n  ///\n  /// ```motoko include=import\n  /// assert Text.toVarArray(\"Café\") == [var 'C', 'a', 'f', 'é'];\n  /// ```\n  ///\n/// | Runtime   | Space     |\n/// |-----------|-----------|\n/// | O(t.size()) | O(t.size()) |\n  public func toVarArray(t : Text) : [var Char] {\n    let n = t.size();\n    if (n == 0) {\n      return [var]\n    };\n    let array = Prim.Array_init<Char>(n, ' ');\n    var i = 0;\n    for (c in t.chars()) {\n      array[i] := c;\n      i += 1\n    };\n    array\n  };\n\n  /// Creates a `Text` value from a `Char` iterator.\n  ///\n  /// ```motoko include=import\n  /// let text = Text.fromIter(['a', 'b', 'c'].vals()); // \"abc\"\n  /// ```\n  public func fromIter(cs : Iter.Iter<Char>) : Text {\n    var r = \"\";\n    for (c in cs) {\n      r #= Prim.charToText(c)\n    };\n    return r\n  };\n\n  /// Create a text from a character list.\n  /// Example:\n  /// ```motoko include=initialize\n  /// fromList(?('H', ?('e', ?('l', ?('l', ?('o', null))))));\n  /// // => \"Hello\"\n  /// ```\n  ///\n/// | Runtime   | Space     |\n/// |-----------|-----------|\n/// | O(size cs) | O(size cs) |\n  public func fromList(cs : List.List<Char>) : Text = fromIter(List.toIter cs);\n\n  /// Create a character list from a text.\n  /// Example:\n  /// ```motoko include=initialize\n  /// toList(\"Hello\");\n  /// // => ?('H', ?('e', ?('l', ?('l', ?('o', null)))))\n  /// ```\n  ///\n/// | Runtime   | Space     |\n/// |-----------|-----------|\n/// | O(t.size()) | O(t.size()) |\n  public func toList(t : Text) : List.List<Char> {\n    var acc : List.List<Char> = null;\n    for (c in t.chars()) {\n      acc := ?(c, acc)\n    };\n    List.reverse acc\n  };\n\n  /// Returns the number of characters in the given `Text`.\n  ///\n  /// Equivalent to calling `t.size()` where `t` is a `Text` value.\n  ///\n  /// ```motoko include=import\n  /// let size = Text.size(\"abc\"); // 3\n  /// ```\n  public func size(t : Text) : Nat { t.size() };\n\n  /// Returns a hash obtained by using the `djb2` algorithm ([more details](http://www.cse.yorku.ca/~oz/hash.html)).\n  ///\n  /// ```motoko include=import\n  /// let hash = Text.hash(\"abc\");\n  /// ```\n  ///\n  /// :::info\n  /// This algorithm is intended for use in data structures rather than as a cryptographic hash function.\n  /// :::\n  public func hash(t : Text) : Hash.Hash {\n    var x : Nat32 = 5381;\n    for (char in t.chars()) {\n      let c : Nat32 = Prim.charToNat32(char);\n      x := ((x << 5) +% x) +% c\n    };\n    return x\n  };\n\n  /// Returns `t1 # t2`, where `#` is the `Text` concatenation operator.\n  ///\n  /// ```motoko include=import\n  /// let a = \"Hello\";\n  /// let b = \"There\";\n  /// let together = a # b; // \"HelloThere\"\n  /// let withSpace = a # \" \" # b; // \"Hello There\"\n  /// let togetherAgain = Text.concat(a, b); // \"HelloThere\"\n  /// ```\n  public func concat(t1 : Text, t2 : Text) : Text = t1 # t2;\n\n  /// Returns `t1 == t2`.\n  public func equal(t1 : Text, t2 : Text) : Bool { t1 == t2 };\n\n  /// Returns `t1 != t2`.\n  public func notEqual(t1 : Text, t2 : Text) : Bool { t1 != t2 };\n\n  /// Returns `t1 < t2`.\n  public func less(t1 : Text, t2 : Text) : Bool { t1 < t2 };\n\n  /// Returns `t1 <= t2`.\n  public func lessOrEqual(t1 : Text, t2 : Text) : Bool { t1 <= t2 };\n\n  /// Returns `t1 > t2`.\n  public func greater(t1 : Text, t2 : Text) : Bool { t1 > t2 };\n\n  /// Returns `t1 >= t2`.\n  public func greaterOrEqual(t1 : Text, t2 : Text) : Bool { t1 >= t2 };\n\n  /// Compares `t1` and `t2` lexicographically.\n  ///\n  /// ```motoko include=import\n  /// import { print } \"mo:base/Debug\";\n  ///\n  /// print(debug_show Text.compare(\"abc\", \"abc\")); // #equal\n  /// print(debug_show Text.compare(\"abc\", \"def\")); // #less\n  /// print(debug_show Text.compare(\"abc\", \"ABC\")); // #greater\n  /// ```\n  public func compare(t1 : Text, t2 : Text) : { #less; #equal; #greater } {\n    let c = Prim.textCompare(t1, t2);\n    if (c < 0) #less else if (c == 0) #equal else #greater\n  };\n\n  private func extract(t : Text, i : Nat, j : Nat) : Text {\n    let size = t.size();\n    if (i == 0 and j == size) return t;\n    assert (j <= size);\n    let cs = t.chars();\n    var r = \"\";\n    var n = i;\n    while (n > 0) {\n      ignore cs.next();\n      n -= 1\n    };\n    n := j;\n    while (n > 0) {\n      switch (cs.next()) {\n        case null { assert false };\n        case (?c) { r #= Prim.charToText(c) }\n      };\n      n -= 1\n    };\n    return r\n  };\n\n  /// Join an iterator of `Text` values with a given delimiter.\n  ///\n  /// ```motoko include=import\n  /// let joined = Text.join(\", \", [\"a\", \"b\", \"c\"].vals()); // \"a, b, c\"\n  /// ```\n  public func join(sep : Text, ts : Iter.Iter<Text>) : Text {\n    var r = \"\";\n    if (sep.size() == 0) {\n      for (t in ts) {\n        r #= t\n      };\n      return r\n    };\n    let next = ts.next;\n    switch (next()) {\n      case null { return r };\n      case (?t) {\n        r #= t\n      }\n    };\n    loop {\n      switch (next()) {\n        case null { return r };\n        case (?t) {\n          r #= sep;\n          r #= t\n        }\n      }\n    }\n  };\n\n  /// Applies a function to each character in a `Text` value, returning the concatenated `Char` results.\n  ///\n  /// ```motoko include=import\n  /// // Replace all occurrences of '?' with '!'\n  /// let result = Text.map(\"Motoko?\", func(c) {\n  ///   if (c == '?') '!'\n  ///   else c\n  /// });\n  /// ```\n  public func map(t : Text, f : Char -> Char) : Text {\n    var r = \"\";\n    for (c in t.chars()) {\n      r #= Prim.charToText(f(c))\n    };\n    return r\n  };\n\n  /// Returns the result of applying `f` to each character in `ts`, concatenating the intermediate text values.\n  ///\n  /// ```motoko include=import\n  /// // Replace all occurrences of '?' with \"!!\"\n  /// let result = Text.translate(\"Motoko?\", func(c) {\n  ///   if (c == '?') \"!!\"\n  ///   else Text.fromChar(c)\n  /// }); // \"Motoko!!\"\n  /// ```\n  public func translate(t : Text, f : Char -> Text) : Text {\n    var r = \"\";\n    for (c in t.chars()) {\n      r #= f(c)\n    };\n    return r\n  };\n\n  /// A pattern `p` describes a sequence of characters. A pattern has one of the following forms:\n  ///\n  /// * `#char c` matches the single character sequence, `c`.\n  /// * `#text t` matches multi-character text sequence `t`.\n  /// * `#predicate p` matches any single character sequence `c` satisfying predicate `p(c)`.\n  ///\n  /// A _match_ for `p` is any sequence of characters matching the pattern `p`.\n  ///\n  /// ```motoko include=import\n  /// let charPattern = #char 'A';\n  /// let textPattern = #text \"phrase\";\n  /// let predicatePattern : Text.Pattern = #predicate (func(c) { c == 'A' or c == 'B' }); // matches \"A\" or \"B\"\n  /// ```\n  public type Pattern = {\n    #char : Char;\n    #text : Text;\n    #predicate : (Char -> Bool)\n  };\n\n  private func take(n : Nat, cs : Iter.Iter<Char>) : Iter.Iter<Char> {\n    var i = n;\n    object {\n      public func next() : ?Char {\n        if (i == 0) return null;\n        i -= 1;\n        return cs.next()\n      }\n    }\n  };\n\n  private func empty() : Iter.Iter<Char> {\n    object {\n      public func next() : ?Char = null\n    }\n  };\n\n  private type Match = {\n    /// #success on complete match\n    #success;\n    /// #fail(cs,c) on partial match of cs, but failing match on c\n    #fail : (cs : Iter.Iter<Char>, c : Char);\n    /// #empty(cs) on partial match of cs and empty stream\n    #empty : (cs : Iter.Iter<Char>)\n  };\n\n  private func sizeOfPattern(pat : Pattern) : Nat {\n    switch pat {\n      case (#text(t)) { t.size() };\n      case (#predicate(_) or #char(_)) { 1 }\n    }\n  };\n\n  private func matchOfPattern(pat : Pattern) : (cs : Iter.Iter<Char>) -> Match {\n    switch pat {\n      case (#char(p)) {\n        func(cs : Iter.Iter<Char>) : Match {\n          switch (cs.next()) {\n            case (?c) {\n              if (p == c) {\n                #success\n              } else {\n                #fail(empty(), c)\n              }\n            };\n            case null { #empty(empty()) }\n          }\n        }\n      };\n      case (#predicate(p)) {\n        func(cs : Iter.Iter<Char>) : Match {\n          switch (cs.next()) {\n            case (?c) {\n              if (p(c)) {\n                #success\n              } else {\n                #fail(empty(), c)\n              }\n            };\n            case null { #empty(empty()) }\n          }\n        }\n      };\n      case (#text(p)) {\n        func(cs : Iter.Iter<Char>) : Match {\n          var i = 0;\n          let ds = p.chars();\n          loop {\n            switch (ds.next()) {\n              case (?d) {\n                switch (cs.next()) {\n                  case (?c) {\n                    if (c != d) {\n                      return #fail(take(i, p.chars()), c)\n                    };\n                    i += 1\n                  };\n                  case null {\n                    return #empty(take(i, p.chars()))\n                  }\n                }\n              };\n              case null { return #success }\n            }\n          }\n        }\n      }\n    }\n  };\n\n  private class CharBuffer(cs : Iter.Iter<Char>) : Iter.Iter<Char> = {\n\n    var stack : Stack.Stack<(Iter.Iter<Char>, Char)> = Stack.Stack();\n\n    public func pushBack(cs0 : Iter.Iter<Char>, c : Char) {\n      stack.push((cs0, c))\n    };\n\n    public func next() : ?Char {\n      switch (stack.peek()) {\n        case (?(buff, c)) {\n          switch (buff.next()) {\n            case null {\n              ignore stack.pop();\n              return ?c\n            };\n            case oc {\n              return oc\n            }\n          }\n        };\n        case null {\n          return cs.next()\n        }\n      }\n    }\n  };\n\n  /// Splits the input `Text` with the specified `Pattern`.\n  ///\n  /// Two fields are separated by exactly one match.\n  ///\n  /// ```motoko include=import\n  /// let words = Text.split(\"This is a sentence.\", #char ' ');\n  /// Text.join(\"|\", words) // \"This|is|a|sentence.\"\n  /// ```\n  public func split(t : Text, p : Pattern) : Iter.Iter<Text> {\n    let match = matchOfPattern(p);\n    let cs = CharBuffer(t.chars());\n    var state = 0;\n    var field = \"\";\n    object {\n      public func next() : ?Text {\n        switch state {\n          case (0 or 1) {\n            loop {\n              switch (match(cs)) {\n                case (#success) {\n                  let r = field;\n                  field := \"\";\n                  state := 1;\n                  return ?r\n                };\n                case (#empty(cs1)) {\n                  for (c in cs1) {\n                    field #= fromChar(c)\n                  };\n                  let r = if (state == 0 and field == \"\") {\n                    null\n                  } else {\n                    ?field\n                  };\n                  state := 2;\n                  return r\n                };\n                case (#fail(cs1, c)) {\n                  cs.pushBack(cs1, c);\n                  switch (cs.next()) {\n                    case (?ci) {\n                      field #= fromChar(ci)\n                    };\n                    case null {\n                      let r = if (state == 0 and field == \"\") {\n                        null\n                      } else {\n                        ?field\n                      };\n                      state := 2;\n                      return r\n                    }\n                  }\n                }\n              }\n            }\n          };\n          case _ { return null }\n        }\n      }\n    }\n  };\n\n  /// Returns a sequence of tokens from the input `Text` delimited by the specified `Pattern`, derived from start to end.\n  /// A \"token\" is a non-empty maximal subsequence of `t` not containing a match for pattern `p`.\n  /// Two tokens may be separated by one or more matches of `p`.\n  ///\n  /// ```motoko include=import\n  /// let tokens = Text.tokens(\"this needs\\n an   example\", #predicate (func(c) { c == ' ' or c == '\\n' }));\n  /// Text.join(\"|\", tokens) // \"this|needs|an|example\"\n  /// ```\n  public func tokens(t : Text, p : Pattern) : Iter.Iter<Text> {\n    let fs = split(t, p);\n    object {\n      public func next() : ?Text {\n        switch (fs.next()) {\n          case (?\"\") { next() };\n          case ot { ot }\n        }\n      }\n    }\n  };\n\n  /// Returns `true` if the input `Text` contains a match for the specified `Pattern`.\n  ///\n  /// ```motoko include=import\n  /// Text.contains(\"Motoko\", #text \"oto\") // true\n  /// ```\n  public func contains(t : Text, p : Pattern) : Bool {\n    let match = matchOfPattern(p);\n    let cs = CharBuffer(t.chars());\n    loop {\n      switch (match(cs)) {\n        case (#success) {\n          return true\n        };\n        case (#empty(_cs1)) {\n          return false\n        };\n        case (#fail(cs1, c)) {\n          cs.pushBack(cs1, c);\n          switch (cs.next()) {\n            case null {\n              return false\n            };\n            case _ {}; // continue\n          }\n        }\n      }\n    }\n  };\n\n  /// Returns `true` if the input `Text` starts with a prefix matching the specified `Pattern`.\n  ///\n  /// ```motoko include=import\n  /// Text.startsWith(\"Motoko\", #text \"Mo\") // true\n  /// ```\n  public func startsWith(t : Text, p : Pattern) : Bool {\n    var cs = t.chars();\n    let match = matchOfPattern(p);\n    switch (match(cs)) {\n      case (#success) { true };\n      case _ { false }\n    }\n  };\n\n  /// Returns `true` if the input `Text` ends with a suffix matching the specified `Pattern`.\n  ///\n  /// ```motoko include=import\n  /// Text.endsWith(\"Motoko\", #char 'o') // true\n  /// ```\n  public func endsWith(t : Text, p : Pattern) : Bool {\n    let s2 = sizeOfPattern(p);\n    if (s2 == 0) return true;\n    let s1 = t.size();\n    if (s2 > s1) return false;\n    let match = matchOfPattern(p);\n    var cs1 = t.chars();\n    var diff : Nat = s1 - s2;\n    while (diff > 0) {\n      ignore cs1.next();\n      diff -= 1\n    };\n    switch (match(cs1)) {\n      case (#success) { true };\n      case _ { false }\n    }\n  };\n\n  /// Returns the input text `t` with all matches of pattern `p` replaced by text `r`.\n  ///\n  /// ```motoko include=import\n  /// let result = Text.replace(\"abcabc\", #char 'a', \"A\"); // \"AbcAbc\"\n  /// ```\n  public func replace(t : Text, p : Pattern, r : Text) : Text {\n    let match = matchOfPattern(p);\n    let size = sizeOfPattern(p);\n    let cs = CharBuffer(t.chars());\n    var res = \"\";\n    label l loop {\n      switch (match(cs)) {\n        case (#success) {\n          res #= r;\n          if (size > 0) {\n            continue l\n          }\n        };\n        case (#empty(cs1)) {\n          for (c1 in cs1) {\n            res #= fromChar(c1)\n          };\n          break l\n        };\n        case (#fail(cs1, c)) {\n          cs.pushBack(cs1, c)\n        }\n      };\n      switch (cs.next()) {\n        case null {\n          break l\n        };\n        case (?c1) {\n          res #= fromChar(c1)\n        }; // continue\n      }\n    };\n    return res\n  };\n\n  /// Strips one occurrence of the given `Pattern` from the beginning of the input `Text`.\n  /// If you want to remove multiple instances of the pattern, use `Text.trimStart()` instead.\n  ///\n  /// ```motoko include=import\n  /// // Try to strip a nonexistent character\n  /// let none = Text.stripStart(\"abc\", #char '-'); // null\n  /// // Strip just one '-'\n  /// let one = Text.stripStart(\"--abc\", #char '-'); // ?\"-abc\"\n  /// ```\n  public func stripStart(t : Text, p : Pattern) : ?Text {\n    let s = sizeOfPattern(p);\n    if (s == 0) return ?t;\n    var cs = t.chars();\n    let match = matchOfPattern(p);\n    switch (match(cs)) {\n      case (#success) return ?fromIter(cs);\n      case _ return null\n    }\n  };\n\n  /// Strips one occurrence of the given `Pattern` from the end of the input `Text`.\n  /// If you want to remove multiple instances of the pattern, use `Text.trimEnd()` instead.\n  ///\n  /// ```motoko include=import\n  /// // Try to strip a nonexistent character\n  /// let none = Text.stripEnd(\"xyz\", #char '-'); // null\n  /// // Strip just one '-'\n  /// let one = Text.stripEnd(\"xyz--\", #char '-'); // ?\"xyz-\"\n  /// ```\n  public func stripEnd(t : Text, p : Pattern) : ?Text {\n    let s2 = sizeOfPattern(p);\n    if (s2 == 0) return ?t;\n    let s1 = t.size();\n    if (s2 > s1) return null;\n    let match = matchOfPattern(p);\n    var cs1 = t.chars();\n    var diff : Nat = s1 - s2;\n    while (diff > 0) {\n      ignore cs1.next();\n      diff -= 1\n    };\n    switch (match(cs1)) {\n      case (#success) return ?extract(t, 0, s1 - s2);\n      case _ return null\n    }\n  };\n\n  /// Trims the given `Pattern` from the start of the input `Text`.\n  /// If you only want to remove a single instance of the pattern, use `Text.stripStart()` instead.\n  ///\n  /// ```motoko include=import\n  /// let trimmed = Text.trimStart(\"---abc\", #char '-'); // \"abc\"\n  /// ```\n  public func trimStart(t : Text, p : Pattern) : Text {\n    let cs = t.chars();\n    let size = sizeOfPattern(p);\n    if (size == 0) return t;\n    var matchSize = 0;\n    let match = matchOfPattern(p);\n    loop {\n      switch (match(cs)) {\n        case (#success) {\n          matchSize += size\n        }; // continue\n        case (#empty(cs1)) {\n          return if (matchSize == 0) {\n            t\n          } else {\n            fromIter(cs1)\n          }\n        };\n        case (#fail(cs1, c)) {\n          return if (matchSize == 0) {\n            t\n          } else {\n            fromIter(cs1) # fromChar(c) # fromIter(cs)\n          }\n        }\n      }\n    }\n  };\n\n  /// Trims the given `Pattern` from the end of the input `Text`.\n  /// If you only want to remove a single instance of the pattern, use `Text.stripEnd()` instead.\n  ///\n  /// ```motoko include=import\n  /// let trimmed = Text.trimEnd(\"xyz---\", #char '-'); // \"xyz\"\n  /// ```\n  public func trimEnd(t : Text, p : Pattern) : Text {\n    let cs = CharBuffer(t.chars());\n    let size = sizeOfPattern(p);\n    if (size == 0) return t;\n    let match = matchOfPattern(p);\n    var matchSize = 0;\n    label l loop {\n      switch (match(cs)) {\n        case (#success) {\n          matchSize += size\n        }; // continue\n        case (#empty(cs1)) {\n          switch (cs1.next()) {\n            case null break l;\n            case (?_) return t\n          }\n        };\n        case (#fail(cs1, c)) {\n          matchSize := 0;\n          cs.pushBack(cs1, c);\n          ignore cs.next()\n        }\n      }\n    };\n    extract(t, 0, t.size() - matchSize)\n  };\n\n  /// Trims the given `Pattern` from both the start and end of the input `Text`.\n  ///\n  /// ```motoko include=import\n  /// let trimmed = Text.trim(\"---abcxyz---\", #char '-'); // \"abcxyz\"\n  /// ```\n  public func trim(t : Text, p : Pattern) : Text {\n    let cs = t.chars();\n    let size = sizeOfPattern(p);\n    if (size == 0) return t;\n    var matchSize = 0;\n    let match = matchOfPattern(p);\n    loop {\n      switch (match(cs)) {\n        case (#success) {\n          matchSize += size\n        }; // continue\n        case (#empty(cs1)) {\n          return if (matchSize == 0) { t } else { fromIter(cs1) }\n        };\n        case (#fail(cs1, c)) {\n          let start = matchSize;\n          let cs2 = CharBuffer(cs);\n          cs2.pushBack(cs1, c);\n          ignore cs2.next();\n          matchSize := 0;\n          label l loop {\n            switch (match(cs2)) {\n              case (#success) {\n                matchSize += size\n              }; // continue\n              case (#empty(_cs3)) {\n                switch (cs1.next()) {\n                  case null break l;\n                  case (?_) return t\n                }\n              };\n              case (#fail(cs3, c1)) {\n                matchSize := 0;\n                cs2.pushBack(cs3, c1);\n                ignore cs2.next()\n              }\n            }\n          };\n          return extract(t, start, t.size() - matchSize - start)\n        }\n      }\n    }\n  };\n\n  /// Compares `t1` and `t2` using the provided character-wise comparison function.\n  ///\n  /// ```motoko include=import\n  /// import Char \"mo:base/Char\";\n  ///\n  /// Text.compareWith(\"abc\", \"ABC\", func(c1, c2) { Char.compare(c1, c2) }) // #greater\n  /// ```\n  public func compareWith(\n    t1 : Text,\n    t2 : Text,\n    cmp : (Char, Char) -> { #less; #equal; #greater }\n  ) : { #less; #equal; #greater } {\n    let cs1 = t1.chars();\n    let cs2 = t2.chars();\n    loop {\n      switch (cs1.next(), cs2.next()) {\n        case (null, null) { return #equal };\n        case (null, ?_) { return #less };\n        case (?_, null) { return #greater };\n        case (?c1, ?c2) {\n          switch (cmp(c1, c2)) {\n            case (#equal) {}; // continue\n            case other { return other }\n          }\n        }\n      }\n    }\n  };\n\n  /// Returns a UTF-8 encoded `Blob` from the given `Text`.\n  ///\n  /// ```motoko include=import\n  /// let blob = Text.encodeUtf8(\"Hello\");\n  /// ```\n  public let encodeUtf8 : Text -> Blob = Prim.encodeUtf8;\n\n  /// Tries to decode the given `Blob` as UTF-8.\n  /// Returns `null` if the blob is not valid UTF-8.\n  ///\n  /// ```motoko include=import\n  /// let text = Text.decodeUtf8(\"\\48\\65\\6C\\6C\\6F\"); // ?\"Hello\"\n  /// ```\n  public let decodeUtf8 : Blob -> ?Text = Prim.decodeUtf8;\n\n  /// Returns the text argument in lowercase.\n  ///\n  /// :::warning Compliance\n  /// Unicode compliant only when compiled, not interpreted.\n  /// :::\n  ///\n  /// ```motoko include=import\n  /// let text = Text.toLowercase(\"Good Day\"); // ?\"good day\"\n  /// ```\n  public let toLowercase : Text -> Text = Prim.textLowercase;\n\n  /// Returns the text argument in uppercase. Unicode compliant.\n  /// :::warning Compliance\n  /// Unicode compliant only when compiled, not interpreted.\n  /// :::\n  ///\n  /// ```motoko include=import\n  /// let text = Text.toUppercase(\"Good Day\"); // ?\"GOOD DAY\"\n  /// ```\n  public let toUppercase : Text -> Text = Prim.textUppercase\n}\n"},"CertifiedData.mo":{"content":"/// The Internet Computer allows canister smart contracts to store a small amount of data during\n/// update method processing so that during query call processing, the canister can obtain\n/// a certificate about that data.\n///\n/// :::info Intended audience\n///\n/// This module provides a _low-level_ interface to this API, aimed at advanced\n/// users and library implementors. See the Internet Computer interface\n/// specification and corresponding documentation for how to use this to make query\n/// calls to your canister tamperproof.\n/// :::\n///\n\nimport Prim \"mo:⛔\";\n\nmodule {\n\n  /// Set the certified data.\n  ///\n  /// :::note Usage constraints\n  ///\n  /// Must be called from an update method, else traps.\n  /// Must be passed a blob of at most 32 bytes, else traps.\n  /// :::\n  ///\n  /// Example:\n  ///\n  /// ```motoko no-repl\n  /// import CertifiedData \"mo:base/CertifiedData\";\n  /// import Blob \"mo:base/Blob\";\n  ///\n  /// // Must be in an update call\n  ///\n  /// let array : [Nat8] = [1, 2, 3];\n  /// let blob = Blob.fromArray(array);\n  /// CertifiedData.set(blob);\n  /// ```\n  ///\n  /// :::info\n  /// [See a full example on how to use certified variables](https://github.com/dfinity/examples/tree/master/motoko/cert-var).\n  /// :::\n  ///\n  public let set : (data : Blob) -> () = Prim.setCertifiedData;\n\n  /// Gets a certificate.\n  ///\n  /// :::note When available\n  ///\n  /// Returns `null` if no certificate is available, e.g. when processing an\n  /// update call or inter-canister call. This returns a non-`null` value only\n  /// when processing a query call.\n  /// :::\n  ///\n  /// Example:\n  ///\n  /// ```motoko no-repl\n  /// import CertifiedData \"mo:base/CertifiedData\";\n  /// // Must be in a query call\n  ///\n  /// CertifiedData.getCertificate();\n  /// ```\n  ///\n  /// :::info\n  /// [See a full example on how to use certified variables](https://github.com/dfinity/examples/tree/master/motoko/cert-var).\n  /// :::\n  public let getCertificate : () -> ?Blob = Prim.getCertificate\n}\n"},"Result.mo":{"content":"/// Error handling with the `Result` type.\n\nimport Prim \"mo:⛔\";\nimport P \"Prelude\";\nimport Order \"Order\";\n\nmodule {\n\n  /// `Result<Ok, Err>` is the type used for returning and propagating errors. It\n  /// is a type with the variants, `#ok(Ok)`, representing success and containing\n  /// a value, and `#err(Err)`, representing error and containing an error value.\n  ///\n  /// The simplest way of working with `Result`s is to pattern match on them:\n  ///\n  /// For example, given a function `createUser(user : User) : Result<Id, String>`\n  /// where `String` is an error message we could use it like so:\n  /// ```motoko no-repl\n  /// switch(createUser(myUser)) {\n  ///   case (#ok(id)) { Debug.print(\"Created new user with id: \" # id) };\n  ///   case (#err(msg)) { Debug.print(\"Failed to create user with the error: \" # msg) };\n  /// }\n  /// ```\n  public type Result<Ok, Err> = {\n    #ok : Ok;\n    #err : Err\n  };\n\n  // Compares two Result's for equality.\n  public func equal<Ok, Err>(\n    eqOk : (Ok, Ok) -> Bool,\n    eqErr : (Err, Err) -> Bool,\n    r1 : Result<Ok, Err>,\n    r2 : Result<Ok, Err>\n  ) : Bool {\n    switch (r1, r2) {\n      case (#ok(ok1), #ok(ok2)) {\n        eqOk(ok1, ok2)\n      };\n      case (#err(err1), #err(err2)) {\n        eqErr(err1, err2)\n      };\n      case _ { false }\n    }\n  };\n\n  // Compares two Results. `#ok` is larger than `#err`. This ordering is\n  // arbitrary, but it lets you for example use Results as keys in ordered maps.\n  public func compare<Ok, Err>(\n    compareOk : (Ok, Ok) -> Order.Order,\n    compareErr : (Err, Err) -> Order.Order,\n    r1 : Result<Ok, Err>,\n    r2 : Result<Ok, Err>\n  ) : Order.Order {\n    switch (r1, r2) {\n      case (#ok(ok1), #ok(ok2)) {\n        compareOk(ok1, ok2)\n      };\n      case (#err(err1), #err(err2)) {\n        compareErr(err1, err2)\n      };\n      case (#ok(_), _) { #greater };\n      case (#err(_), _) { #less }\n    }\n  };\n\n  /// Allows sequencing of `Result` values and functions that return\n  /// `Result`'s themselves.\n  /// ```motoko\n  /// import Result \"mo:base/Result\";\n  /// type Result<T,E> = Result.Result<T, E>;\n  /// func largerThan10(x : Nat) : Result<Nat, Text> =\n  ///   if (x > 10) { #ok(x) } else { #err(\"Not larger than 10.\") };\n  ///\n  /// func smallerThan20(x : Nat) : Result<Nat, Text> =\n  ///   if (x < 20) { #ok(x) } else { #err(\"Not smaller than 20.\") };\n  ///\n  /// func between10And20(x : Nat) : Result<Nat, Text> =\n  ///   Result.chain(largerThan10(x), smallerThan20);\n  ///\n  /// assert(between10And20(15) == #ok(15));\n  /// assert(between10And20(9) == #err(\"Not larger than 10.\"));\n  /// assert(between10And20(21) == #err(\"Not smaller than 20.\"));\n  /// ```\n  public func chain<R1, R2, Error>(\n    x : Result<R1, Error>,\n    y : R1 -> Result<R2, Error>\n  ) : Result<R2, Error> {\n    switch x {\n      case (#err(e)) { #err(e) };\n      case (#ok(r)) { y(r) }\n    }\n  };\n\n  /// Flattens a nested `Result`.\n  ///\n  /// ```motoko\n  /// import Result \"mo:base/Result\";\n  /// assert(Result.flatten<Nat, Text>(#ok(#ok(10))) == #ok(10));\n  /// assert(Result.flatten<Nat, Text>(#err(\"Wrong\")) == #err(\"Wrong\"));\n  /// assert(Result.flatten<Nat, Text>(#ok(#err(\"Wrong\"))) == #err(\"Wrong\"));\n  /// ```\n  public func flatten<Ok, Error>(\n    result : Result<Result<Ok, Error>, Error>\n  ) : Result<Ok, Error> {\n    switch result {\n      case (#ok(ok)) { ok };\n      case (#err(err)) { #err(err) }\n    }\n  };\n\n  /// Maps the `Ok` type/value, leaving any `Error` type/value unchanged.\n  public func mapOk<Ok1, Ok2, Error>(\n    x : Result<Ok1, Error>,\n    f : Ok1 -> Ok2\n  ) : Result<Ok2, Error> {\n    switch x {\n      case (#err(e)) { #err(e) };\n      case (#ok(r)) { #ok(f(r)) }\n    }\n  };\n\n  /// Maps the `Err` type/value, leaving any `Ok` type/value unchanged.\n  public func mapErr<Ok, Error1, Error2>(\n    x : Result<Ok, Error1>,\n    f : Error1 -> Error2\n  ) : Result<Ok, Error2> {\n    switch x {\n      case (#err(e)) { #err(f(e)) };\n      case (#ok(r)) { #ok(r) }\n    }\n  };\n\n  /// Create a `Result` from an option, including an error value to handle the `null` case.\n  /// ```motoko\n  /// import Result \"mo:base/Result\";\n  /// assert(Result.fromOption(?42, \"err\") == #ok(42));\n  /// assert(Result.fromOption(null, \"err\") == #err(\"err\"));\n  /// ```\n  public func fromOption<R, E>(x : ?R, err : E) : Result<R, E> {\n    switch x {\n      case (?x) { #ok(x) };\n      case null { #err(err) }\n    }\n  };\n\n  /// Create an option from a `Result`, turning all #err into `null`.\n  /// ```motoko\n  /// import Result \"mo:base/Result\";\n  /// assert(Result.toOption(#ok(42)) == ?42);\n  /// assert(Result.toOption(#err(\"err\")) == null);\n  /// ```\n  public func toOption<R, E>(r : Result<R, E>) : ?R {\n    switch r {\n      case (#ok(x)) { ?x };\n      case (#err(_)) { null }\n    }\n  };\n\n  /// Applies a function to a successful value, but discards the result. Use\n  /// `iterate` if you're only interested in the side effect `f` produces.\n  ///\n  /// ```motoko\n  /// import Result \"mo:base/Result\";\n  /// var counter : Nat = 0;\n  /// Result.iterate<Nat, Text>(#ok(5), func (x : Nat) { counter += x });\n  /// assert(counter == 5);\n  /// Result.iterate<Nat, Text>(#err(\"Wrong\"), func (x : Nat) { counter += x });\n  /// assert(counter == 5);\n  /// ```\n  public func iterate<Ok, Err>(res : Result<Ok, Err>, f : Ok -> ()) {\n    switch res {\n      case (#ok(ok)) { f(ok) };\n      case _ {}\n    }\n  };\n\n  // Whether this Result is an `#ok`\n  public func isOk(r : Result<Any, Any>) : Bool {\n    switch r {\n      case (#ok(_)) { true };\n      case (#err(_)) { false }\n    }\n  };\n\n  // Whether this Result is an `#err`\n  public func isErr(r : Result<Any, Any>) : Bool {\n    switch r {\n      case (#ok(_)) { false };\n      case (#err(_)) { true }\n    }\n  };\n\n  /// Asserts that its argument is an `#ok` result, traps otherwise.\n  public func assertOk(r : Result<Any, Any>) {\n    switch (r) {\n      case (#err(_)) { assert false };\n      case (#ok(_)) {}\n    }\n  };\n\n  /// Asserts that its argument is an `#err` result, traps otherwise.\n  public func assertErr(r : Result<Any, Any>) {\n    switch (r) {\n      case (#err(_)) {};\n      case (#ok(_)) assert false\n    }\n  };\n\n  /// Converts an upper cased `#Ok`, `#Err` result type into a lowercased `#ok`, `#err` result type.\n  /// On the IC, a common convention is to use `#Ok` and `#Err` as the variants of a result type,\n  /// but in Motoko, we use `#ok` and `#err` instead.\n  public func fromUpper<Ok, Err>(\n    result : { #Ok : Ok; #Err : Err }\n  ) : Result<Ok, Err> {\n    switch result {\n      case (#Ok(ok)) { #ok(ok) };\n      case (#Err(err)) { #err(err) }\n    }\n  };\n\n  /// Converts a lower cased `#ok`, `#err` result type into an upper cased `#Ok`, `#Err` result type.\n  /// On the IC, a common convention is to use `#Ok` and `#Err` as the variants of a result type,\n  /// but in Motoko, we use `#ok` and `#err` instead.\n  public func toUpper<Ok, Err>(\n    result : Result<Ok, Err>\n  ) : { #Ok : Ok; #Err : Err } {\n    switch result {\n      case (#ok(ok)) { #Ok(ok) };\n      case (#err(err)) { #Err(err) }\n    }\n  };\n\n}\n"},"Error.mo":{"content":"/// Error values and inspection.\n///\n/// The `Error` type is the argument to `throw`, parameter of `catch`.\n/// The `Error` type is opaque.\n\nimport Prim \"mo:⛔\";\n\nmodule {\n\n  /// Error value resulting from  `async` computations\n  public type Error = Prim.Types.Error;\n\n  /// Error code to classify different kinds of user and system errors:\n  /// ```motoko\n  /// type ErrorCode = {\n  ///   // Fatal error.\n  ///   #system_fatal;\n  ///   // Transient error.\n  ///   #system_transient;\n  ///   // Response unknown due to missed deadline.\n  ///   #system_unknown;\n  ///   // Destination invalid.\n  ///   #destination_invalid;\n  ///   // Explicit reject by canister code.\n  ///   #canister_reject;\n  ///   // Canister trapped.\n  ///   #canister_error;\n  ///   // Future error code (with unrecognized numeric code).\n  ///   #future : Nat32;\n  ///   // Error issuing inter-canister call\n  ///   // (indicating destination queue full or freezing threshold crossed).\n  ///   #call_error : { err_code :  Nat32 }\n  /// };\n  /// ```\n  public type ErrorCode = Prim.ErrorCode;\n\n  /// Create an error from the message with the code `#canister_reject`.\n  ///\n  /// Example:\n  /// ```motoko\n  /// import Error \"mo:base/Error\";\n  ///\n  /// Error.reject(\"Example error\") // can be used as throw argument\n  /// ```\n  public let reject : (message : Text) -> Error = Prim.error;\n\n  /// Returns the code of an error.\n  ///\n  /// Example:\n  /// ```motoko\n  /// import Error \"mo:base/Error\";\n  ///\n  /// let error = Error.reject(\"Example error\");\n  /// Error.code(error) // #canister_reject\n  /// ```\n  public let code : (error : Error) -> ErrorCode = Prim.errorCode;\n\n  /// Returns the message of an error.\n  ///\n  /// Example:\n  /// ```motoko\n  /// import Error \"mo:base/Error\";\n  ///\n  /// let error = Error.reject(\"Example error\");\n  /// Error.message(error) // \"Example error\"\n  /// ```\n  public let message : (error : Error) -> Text = Prim.errorMessage;\n\n  /// Returns whether retrying to send a message may result in success.\n  ///\n  /// Example:\n  /// ```motoko\n  /// import { message; isRetryPossible } \"mo:base/Error\";\n  /// import { print } \"mo:base/Debug\";\n  ///\n  /// try await (with timeout = 3) Actor.call(arg)\n  /// catch e { if (isRetryPossible e) print(message e) }\n  /// ```\n  public func isRetryPossible(error : Error) : Bool = switch (code error) {\n    case (#system_unknown or #system_transient) true;\n    case _ false\n  };\n\n}\n"},"Principal.mo":{"content":"/// Module for interacting with Principals (users, canisters, or other entities).\n///\n/// Principals are used to identify entities that can interact with the Internet\n/// Computer including users or canisters.\n///\n/// Example textual representation of Principals:\n///\n/// `un4fu-tqaaa-aaaab-qadjq-cai`\n///\n/// In Motoko, there is a primitive Principal type called `Principal`. As an example\n/// of where you might see Principals, you can access the Principal of the\n/// caller of your shared function.\n///\n/// ```motoko no-repl\n/// shared(msg) func foo() {\n///  let caller : Principal = msg.caller;\n/// };\n/// ```\n///\n/// Then, you can use this module to work with the `Principal`.\n///\n/// :::note Comparison usage\n///\n/// These functions are defined in this library in addition to the existing comparison operators so that they can be passed as function values to higher-order functions. It is currently not possible to use operators such as `==`, `!=`, `<`, `<=`, `>`, or `>=` as function values directly.\n/// :::\n///\n/// Import from the base library to use this module.\n///\n/// ```motoko name=import\n/// import Principal \"mo:base/Principal\";\n/// ```\n///\n\nimport Prim \"mo:⛔\";\nimport Blob \"Blob\";\nimport Hash \"Hash\";\nimport Array \"Array\";\nimport Nat8 \"Nat8\";\nimport Nat32 \"Nat32\";\nimport Nat64 \"Nat64\";\nimport Text \"Text\";\n\nmodule {\n\n  public type Principal = Prim.Types.Principal;\n\n  /// Get the `Principal` identifier of an actor.\n  ///\n  /// Example:\n  /// ```motoko include=import no-repl\n  /// actor MyCanister {\n  ///   func getPrincipal() : Principal {\n  ///     let principal = Principal.fromActor(MyCanister);\n  ///   }\n  /// }\n  /// ```\n  public func fromActor(a : actor {}) : Principal = Prim.principalOfActor a;\n\n  /// Compute the Ledger account identifier of a principal. Optionally specify a sub-account.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// let principal = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n  /// let subAccount : Blob = \"\\4A\\8D\\3F\\2B\\6E\\01\\C8\\7D\\9E\\03\\B4\\56\\7C\\F8\\9A\\01\\D2\\34\\56\\78\\9A\\BC\\DE\\F0\\12\\34\\56\\78\\9A\\BC\\DE\\F0\";\n  /// let account = Principal.toLedgerAccount(principal, ?subAccount); // => \\8C\\5C\\20\\C6\\15\\3F\\7F\\51\\E2\\0D\\0F\\0F\\B5\\08\\51\\5B\\47\\65\\63\\A9\\62\\B4\\A9\\91\\5F\\4F\\02\\70\\8A\\ED\\4F\\82\n  /// ```\n  public func toLedgerAccount(principal : Principal, subAccount : ?Blob) : Blob {\n    let sha224 = SHA224();\n    let accountSeparator : Blob = \"\\0Aaccount-id\";\n    sha224.writeBlob(accountSeparator);\n    sha224.writeBlob(toBlob(principal));\n    switch subAccount {\n      case (?subAccount) {\n        sha224.writeBlob(subAccount)\n      };\n      case (null) {\n        let defaultSubAccount = Array.tabulate<Nat8>(32, func _ = 0);\n        sha224.writeArray(defaultSubAccount)\n      }\n    };\n\n    let hashSum = sha224.sum();\n\n    // hashBlob is a CRC32 implementation\n    let crc32Bytes = nat32ToByteArray(Prim.hashBlob hashSum);\n\n    Blob.fromArray(Array.append(crc32Bytes, Blob.toArray(hashSum)))\n  };\n\n  /// Convert a `Principal` to its `Blob` (bytes) representation.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// let principal = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n  /// let blob = Principal.toBlob(principal); // => \\00\\00\\00\\00\\00\\30\\00\\D3\\01\\01\n  /// ```\n  public func toBlob(p : Principal) : Blob = Prim.blobOfPrincipal p;\n\n  /// Converts a `Blob` (bytes) representation of a `Principal` to a `Principal` value.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// let blob = \"\\00\\00\\00\\00\\00\\30\\00\\D3\\01\\01\" : Blob;\n  /// let principal = Principal.fromBlob(blob);\n  /// Principal.toText(principal) // => \"un4fu-tqaaa-aaaab-qadjq-cai\"\n  /// ```\n  public func fromBlob(b : Blob) : Principal = Prim.principalOfBlob b;\n\n  /// Converts a `Principal` to its `Text` representation.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// let principal = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n  /// Principal.toText(principal) // => \"un4fu-tqaaa-aaaab-qadjq-cai\"\n  /// ```\n  public func toText(p : Principal) : Text = debug_show (p);\n\n  /// Converts a `Text` representation of a `Principal` to a `Principal` value.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// let principal = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n  /// Principal.toText(principal) // => \"un4fu-tqaaa-aaaab-qadjq-cai\"\n  /// ```\n  public func fromText(t : Text) : Principal = fromActor(actor (t));\n\n  private let anonymousPrincipal : Blob = \"\\04\";\n\n  /// Checks if the given principal represents an anonymous user.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// let principal = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n  /// Principal.isAnonymous(principal) // => false\n  /// ```\n  public func isAnonymous(p : Principal) : Bool = Prim.blobOfPrincipal p == anonymousPrincipal;\n\n  /// Checks if the given principal can control this canister.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// let principal = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n  /// Principal.isController(principal) // => false\n  /// ```\n  public func isController(p : Principal) : Bool = Prim.isController p;\n\n  /// Hashes the given principal by hashing its `Blob` representation.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// let principal = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n  /// Principal.hash(principal) // => 2_742_573_646\n  /// ```\n  public func hash(principal : Principal) : Hash.Hash = Blob.hash(Prim.blobOfPrincipal(principal));\n\n  /// General purpose comparison function for `Principal`. Returns the `Order` (\n  /// either `#less`, `#equal`, or `#greater`) of comparing `principal1` with\n  /// `principal2`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// let principal1 = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n  /// let principal2 = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n  /// Principal.compare(principal1, principal2) // => #equal\n  /// ```\n  public func compare(principal1 : Principal, principal2 : Principal) : {\n    #less;\n    #equal;\n    #greater\n  } {\n    if (principal1 < principal2) {\n      #less\n    } else if (principal1 == principal2) {\n      #equal\n    } else {\n      #greater\n    }\n  };\n\n  /// Equality function for Principal types.\n  /// This is equivalent to `principal1 == principal2`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// let principal1 = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n  /// let principal2 = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n  /// ignore Principal.equal(principal1, principal2);\n  /// principal1 == principal2 // => true\n  /// ```\n  ///\n\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// import Buffer \"mo:base/Buffer\";\n  ///\n  /// let buffer1 = Buffer.Buffer<Principal>(3);\n  /// let buffer2 = Buffer.Buffer<Principal>(3);\n  /// Buffer.equal(buffer1, buffer2, Principal.equal) // => true\n  /// ```\n  public func equal(principal1 : Principal, principal2 : Principal) : Bool {\n    principal1 == principal2\n  };\n\n  /// Inequality function for Principal types.\n  /// This is equivalent to `principal1 != principal2`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// let principal1 = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n  /// let principal2 = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n  /// ignore Principal.notEqual(principal1, principal2);\n  /// principal1 != principal2 // => false\n  /// ```\n  ///\n\n  public func notEqual(principal1 : Principal, principal2 : Principal) : Bool {\n    principal1 != principal2\n  };\n\n  /// \"Less than\" function for Principal types.\n  /// This is equivalent to `principal1 < principal2`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// let principal1 = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n  /// let principal2 = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n  /// ignore Principal.less(principal1, principal2);\n  /// principal1 < principal2 // => false\n  /// ```\n  ///\n\n  public func less(principal1 : Principal, principal2 : Principal) : Bool {\n    principal1 < principal2\n  };\n\n  /// \"Less than or equal to\" function for Principal types.\n  /// This is equivalent to `principal1 <= principal2`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// let principal1 = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n  /// let principal2 = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n  /// ignore Principal.lessOrEqual(principal1, principal2);\n  /// principal1 <= principal2 // => true\n  /// ```\n  ///\n\n  public func lessOrEqual(principal1 : Principal, principal2 : Principal) : Bool {\n    principal1 <= principal2\n  };\n\n  /// \"Greater than\" function for Principal types.\n  /// This is equivalent to `principal1 > principal2`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// let principal1 = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n  /// let principal2 = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n  /// ignore Principal.greater(principal1, principal2);\n  /// principal1 > principal2 // => false\n  /// ```\n  ///\n\n  public func greater(principal1 : Principal, principal2 : Principal) : Bool {\n    principal1 > principal2\n  };\n\n  /// \"Greater than or equal to\" function for Principal types.\n  /// This is equivalent to `principal1 >= principal2`.\n  ///\n  /// Example:\n  /// ```motoko include=import\n  /// let principal1 = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n  /// let principal2 = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n  /// ignore Principal.greaterOrEqual(principal1, principal2);\n  /// principal1 >= principal2 // => true\n  /// ```\n  ///\n\n  public func greaterOrEqual(principal1 : Principal, principal2 : Principal) : Bool {\n    principal1 >= principal2\n  };\n\n  /**\n  * SHA224 Utilities used in toAccount().\n  * Utilities are not exposed as public functions.\n  * Taken with permission from https://github.com/research-ag/sha2\n  **/\n  let K00 : Nat32 = 0x428a2f98;\n  let K01 : Nat32 = 0x71374491;\n  let K02 : Nat32 = 0xb5c0fbcf;\n  let K03 : Nat32 = 0xe9b5dba5;\n  let K04 : Nat32 = 0x3956c25b;\n  let K05 : Nat32 = 0x59f111f1;\n  let K06 : Nat32 = 0x923f82a4;\n  let K07 : Nat32 = 0xab1c5ed5;\n  let K08 : Nat32 = 0xd807aa98;\n  let K09 : Nat32 = 0x12835b01;\n  let K10 : Nat32 = 0x243185be;\n  let K11 : Nat32 = 0x550c7dc3;\n  let K12 : Nat32 = 0x72be5d74;\n  let K13 : Nat32 = 0x80deb1fe;\n  let K14 : Nat32 = 0x9bdc06a7;\n  let K15 : Nat32 = 0xc19bf174;\n  let K16 : Nat32 = 0xe49b69c1;\n  let K17 : Nat32 = 0xefbe4786;\n  let K18 : Nat32 = 0x0fc19dc6;\n  let K19 : Nat32 = 0x240ca1cc;\n  let K20 : Nat32 = 0x2de92c6f;\n  let K21 : Nat32 = 0x4a7484aa;\n  let K22 : Nat32 = 0x5cb0a9dc;\n  let K23 : Nat32 = 0x76f988da;\n  let K24 : Nat32 = 0x983e5152;\n  let K25 : Nat32 = 0xa831c66d;\n  let K26 : Nat32 = 0xb00327c8;\n  let K27 : Nat32 = 0xbf597fc7;\n  let K28 : Nat32 = 0xc6e00bf3;\n  let K29 : Nat32 = 0xd5a79147;\n  let K30 : Nat32 = 0x06ca6351;\n  let K31 : Nat32 = 0x14292967;\n  let K32 : Nat32 = 0x27b70a85;\n  let K33 : Nat32 = 0x2e1b2138;\n  let K34 : Nat32 = 0x4d2c6dfc;\n  let K35 : Nat32 = 0x53380d13;\n  let K36 : Nat32 = 0x650a7354;\n  let K37 : Nat32 = 0x766a0abb;\n  let K38 : Nat32 = 0x81c2c92e;\n  let K39 : Nat32 = 0x92722c85;\n  let K40 : Nat32 = 0xa2bfe8a1;\n  let K41 : Nat32 = 0xa81a664b;\n  let K42 : Nat32 = 0xc24b8b70;\n  let K43 : Nat32 = 0xc76c51a3;\n  let K44 : Nat32 = 0xd192e819;\n  let K45 : Nat32 = 0xd6990624;\n  let K46 : Nat32 = 0xf40e3585;\n  let K47 : Nat32 = 0x106aa070;\n  let K48 : Nat32 = 0x19a4c116;\n  let K49 : Nat32 = 0x1e376c08;\n  let K50 : Nat32 = 0x2748774c;\n  let K51 : Nat32 = 0x34b0bcb5;\n  let K52 : Nat32 = 0x391c0cb3;\n  let K53 : Nat32 = 0x4ed8aa4a;\n  let K54 : Nat32 = 0x5b9cca4f;\n  let K55 : Nat32 = 0x682e6ff3;\n  let K56 : Nat32 = 0x748f82ee;\n  let K57 : Nat32 = 0x78a5636f;\n  let K58 : Nat32 = 0x84c87814;\n  let K59 : Nat32 = 0x8cc70208;\n  let K60 : Nat32 = 0x90befffa;\n  let K61 : Nat32 = 0xa4506ceb;\n  let K62 : Nat32 = 0xbef9a3f7;\n  let K63 : Nat32 = 0xc67178f2;\n\n  let ivs : [[Nat32]] = [\n    [\n      // 224\n      0xc1059ed8,\n      0x367cd507,\n      0x3070dd17,\n      0xf70e5939,\n      0xffc00b31,\n      0x68581511,\n      0x64f98fa7,\n      0xbefa4fa4\n    ],\n    [\n      // 256\n      0x6a09e667,\n      0xbb67ae85,\n      0x3c6ef372,\n      0xa54ff53a,\n      0x510e527f,\n      0x9b05688c,\n      0x1f83d9ab,\n      0x5be0cd19\n    ]\n  ];\n\n  let rot = Nat32.bitrotRight;\n\n  class SHA224() {\n    let (sum_bytes, iv) = (28, 0);\n\n    var s0 : Nat32 = 0;\n    var s1 : Nat32 = 0;\n    var s2 : Nat32 = 0;\n    var s3 : Nat32 = 0;\n    var s4 : Nat32 = 0;\n    var s5 : Nat32 = 0;\n    var s6 : Nat32 = 0;\n    var s7 : Nat32 = 0;\n\n    let msg : [var Nat32] = Array.init<Nat32>(16, 0);\n    let digest = Array.init<Nat8>(sum_bytes, 0);\n    var word : Nat32 = 0;\n\n    var i_msg : Nat8 = 0;\n    var i_byte : Nat8 = 4;\n    var i_block : Nat64 = 0;\n\n    public func reset() {\n      i_msg := 0;\n      i_byte := 4;\n      i_block := 0;\n      s0 := ivs[iv][0];\n      s1 := ivs[iv][1];\n      s2 := ivs[iv][2];\n      s3 := ivs[iv][3];\n      s4 := ivs[iv][4];\n      s5 := ivs[iv][5];\n      s6 := ivs[iv][6];\n      s7 := ivs[iv][7]\n    };\n\n    reset();\n\n    private func writeByte(val : Nat8) : () {\n      word := (word << 8) ^ Nat32.fromIntWrap(Nat8.toNat(val));\n      i_byte -%= 1;\n      if (i_byte == 0) {\n        msg[Nat8.toNat(i_msg)] := word;\n        word := 0;\n        i_byte := 4;\n        i_msg +%= 1;\n        if (i_msg == 16) {\n          process_block();\n          i_msg := 0;\n          i_block +%= 1\n        }\n      }\n    };\n\n    private func process_block() : () {\n      let w00 = msg[0];\n      let w01 = msg[1];\n      let w02 = msg[2];\n      let w03 = msg[3];\n      let w04 = msg[4];\n      let w05 = msg[5];\n      let w06 = msg[6];\n      let w07 = msg[7];\n      let w08 = msg[8];\n      let w09 = msg[9];\n      let w10 = msg[10];\n      let w11 = msg[11];\n      let w12 = msg[12];\n      let w13 = msg[13];\n      let w14 = msg[14];\n      let w15 = msg[15];\n      let w16 = w00 +% rot(w01, 07) ^ rot(w01, 18) ^ (w01 >> 03) +% w09 +% rot(w14, 17) ^ rot(w14, 19) ^ (w14 >> 10);\n      let w17 = w01 +% rot(w02, 07) ^ rot(w02, 18) ^ (w02 >> 03) +% w10 +% rot(w15, 17) ^ rot(w15, 19) ^ (w15 >> 10);\n      let w18 = w02 +% rot(w03, 07) ^ rot(w03, 18) ^ (w03 >> 03) +% w11 +% rot(w16, 17) ^ rot(w16, 19) ^ (w16 >> 10);\n      let w19 = w03 +% rot(w04, 07) ^ rot(w04, 18) ^ (w04 >> 03) +% w12 +% rot(w17, 17) ^ rot(w17, 19) ^ (w17 >> 10);\n      let w20 = w04 +% rot(w05, 07) ^ rot(w05, 18) ^ (w05 >> 03) +% w13 +% rot(w18, 17) ^ rot(w18, 19) ^ (w18 >> 10);\n      let w21 = w05 +% rot(w06, 07) ^ rot(w06, 18) ^ (w06 >> 03) +% w14 +% rot(w19, 17) ^ rot(w19, 19) ^ (w19 >> 10);\n      let w22 = w06 +% rot(w07, 07) ^ rot(w07, 18) ^ (w07 >> 03) +% w15 +% rot(w20, 17) ^ rot(w20, 19) ^ (w20 >> 10);\n      let w23 = w07 +% rot(w08, 07) ^ rot(w08, 18) ^ (w08 >> 03) +% w16 +% rot(w21, 17) ^ rot(w21, 19) ^ (w21 >> 10);\n      let w24 = w08 +% rot(w09, 07) ^ rot(w09, 18) ^ (w09 >> 03) +% w17 +% rot(w22, 17) ^ rot(w22, 19) ^ (w22 >> 10);\n      let w25 = w09 +% rot(w10, 07) ^ rot(w10, 18) ^ (w10 >> 03) +% w18 +% rot(w23, 17) ^ rot(w23, 19) ^ (w23 >> 10);\n      let w26 = w10 +% rot(w11, 07) ^ rot(w11, 18) ^ (w11 >> 03) +% w19 +% rot(w24, 17) ^ rot(w24, 19) ^ (w24 >> 10);\n      let w27 = w11 +% rot(w12, 07) ^ rot(w12, 18) ^ (w12 >> 03) +% w20 +% rot(w25, 17) ^ rot(w25, 19) ^ (w25 >> 10);\n      let w28 = w12 +% rot(w13, 07) ^ rot(w13, 18) ^ (w13 >> 03) +% w21 +% rot(w26, 17) ^ rot(w26, 19) ^ (w26 >> 10);\n      let w29 = w13 +% rot(w14, 07) ^ rot(w14, 18) ^ (w14 >> 03) +% w22 +% rot(w27, 17) ^ rot(w27, 19) ^ (w27 >> 10);\n      let w30 = w14 +% rot(w15, 07) ^ rot(w15, 18) ^ (w15 >> 03) +% w23 +% rot(w28, 17) ^ rot(w28, 19) ^ (w28 >> 10);\n      let w31 = w15 +% rot(w16, 07) ^ rot(w16, 18) ^ (w16 >> 03) +% w24 +% rot(w29, 17) ^ rot(w29, 19) ^ (w29 >> 10);\n      let w32 = w16 +% rot(w17, 07) ^ rot(w17, 18) ^ (w17 >> 03) +% w25 +% rot(w30, 17) ^ rot(w30, 19) ^ (w30 >> 10);\n      let w33 = w17 +% rot(w18, 07) ^ rot(w18, 18) ^ (w18 >> 03) +% w26 +% rot(w31, 17) ^ rot(w31, 19) ^ (w31 >> 10);\n      let w34 = w18 +% rot(w19, 07) ^ rot(w19, 18) ^ (w19 >> 03) +% w27 +% rot(w32, 17) ^ rot(w32, 19) ^ (w32 >> 10);\n      let w35 = w19 +% rot(w20, 07) ^ rot(w20, 18) ^ (w20 >> 03) +% w28 +% rot(w33, 17) ^ rot(w33, 19) ^ (w33 >> 10);\n      let w36 = w20 +% rot(w21, 07) ^ rot(w21, 18) ^ (w21 >> 03) +% w29 +% rot(w34, 17) ^ rot(w34, 19) ^ (w34 >> 10);\n      let w37 = w21 +% rot(w22, 07) ^ rot(w22, 18) ^ (w22 >> 03) +% w30 +% rot(w35, 17) ^ rot(w35, 19) ^ (w35 >> 10);\n      let w38 = w22 +% rot(w23, 07) ^ rot(w23, 18) ^ (w23 >> 03) +% w31 +% rot(w36, 17) ^ rot(w36, 19) ^ (w36 >> 10);\n      let w39 = w23 +% rot(w24, 07) ^ rot(w24, 18) ^ (w24 >> 03) +% w32 +% rot(w37, 17) ^ rot(w37, 19) ^ (w37 >> 10);\n      let w40 = w24 +% rot(w25, 07) ^ rot(w25, 18) ^ (w25 >> 03) +% w33 +% rot(w38, 17) ^ rot(w38, 19) ^ (w38 >> 10);\n      let w41 = w25 +% rot(w26, 07) ^ rot(w26, 18) ^ (w26 >> 03) +% w34 +% rot(w39, 17) ^ rot(w39, 19) ^ (w39 >> 10);\n      let w42 = w26 +% rot(w27, 07) ^ rot(w27, 18) ^ (w27 >> 03) +% w35 +% rot(w40, 17) ^ rot(w40, 19) ^ (w40 >> 10);\n      let w43 = w27 +% rot(w28, 07) ^ rot(w28, 18) ^ (w28 >> 03) +% w36 +% rot(w41, 17) ^ rot(w41, 19) ^ (w41 >> 10);\n      let w44 = w28 +% rot(w29, 07) ^ rot(w29, 18) ^ (w29 >> 03) +% w37 +% rot(w42, 17) ^ rot(w42, 19) ^ (w42 >> 10);\n      let w45 = w29 +% rot(w30, 07) ^ rot(w30, 18) ^ (w30 >> 03) +% w38 +% rot(w43, 17) ^ rot(w43, 19) ^ (w43 >> 10);\n      let w46 = w30 +% rot(w31, 07) ^ rot(w31, 18) ^ (w31 >> 03) +% w39 +% rot(w44, 17) ^ rot(w44, 19) ^ (w44 >> 10);\n      let w47 = w31 +% rot(w32, 07) ^ rot(w32, 18) ^ (w32 >> 03) +% w40 +% rot(w45, 17) ^ rot(w45, 19) ^ (w45 >> 10);\n      let w48 = w32 +% rot(w33, 07) ^ rot(w33, 18) ^ (w33 >> 03) +% w41 +% rot(w46, 17) ^ rot(w46, 19) ^ (w46 >> 10);\n      let w49 = w33 +% rot(w34, 07) ^ rot(w34, 18) ^ (w34 >> 03) +% w42 +% rot(w47, 17) ^ rot(w47, 19) ^ (w47 >> 10);\n      let w50 = w34 +% rot(w35, 07) ^ rot(w35, 18) ^ (w35 >> 03) +% w43 +% rot(w48, 17) ^ rot(w48, 19) ^ (w48 >> 10);\n      let w51 = w35 +% rot(w36, 07) ^ rot(w36, 18) ^ (w36 >> 03) +% w44 +% rot(w49, 17) ^ rot(w49, 19) ^ (w49 >> 10);\n      let w52 = w36 +% rot(w37, 07) ^ rot(w37, 18) ^ (w37 >> 03) +% w45 +% rot(w50, 17) ^ rot(w50, 19) ^ (w50 >> 10);\n      let w53 = w37 +% rot(w38, 07) ^ rot(w38, 18) ^ (w38 >> 03) +% w46 +% rot(w51, 17) ^ rot(w51, 19) ^ (w51 >> 10);\n      let w54 = w38 +% rot(w39, 07) ^ rot(w39, 18) ^ (w39 >> 03) +% w47 +% rot(w52, 17) ^ rot(w52, 19) ^ (w52 >> 10);\n      let w55 = w39 +% rot(w40, 07) ^ rot(w40, 18) ^ (w40 >> 03) +% w48 +% rot(w53, 17) ^ rot(w53, 19) ^ (w53 >> 10);\n      let w56 = w40 +% rot(w41, 07) ^ rot(w41, 18) ^ (w41 >> 03) +% w49 +% rot(w54, 17) ^ rot(w54, 19) ^ (w54 >> 10);\n      let w57 = w41 +% rot(w42, 07) ^ rot(w42, 18) ^ (w42 >> 03) +% w50 +% rot(w55, 17) ^ rot(w55, 19) ^ (w55 >> 10);\n      let w58 = w42 +% rot(w43, 07) ^ rot(w43, 18) ^ (w43 >> 03) +% w51 +% rot(w56, 17) ^ rot(w56, 19) ^ (w56 >> 10);\n      let w59 = w43 +% rot(w44, 07) ^ rot(w44, 18) ^ (w44 >> 03) +% w52 +% rot(w57, 17) ^ rot(w57, 19) ^ (w57 >> 10);\n      let w60 = w44 +% rot(w45, 07) ^ rot(w45, 18) ^ (w45 >> 03) +% w53 +% rot(w58, 17) ^ rot(w58, 19) ^ (w58 >> 10);\n      let w61 = w45 +% rot(w46, 07) ^ rot(w46, 18) ^ (w46 >> 03) +% w54 +% rot(w59, 17) ^ rot(w59, 19) ^ (w59 >> 10);\n      let w62 = w46 +% rot(w47, 07) ^ rot(w47, 18) ^ (w47 >> 03) +% w55 +% rot(w60, 17) ^ rot(w60, 19) ^ (w60 >> 10);\n      let w63 = w47 +% rot(w48, 07) ^ rot(w48, 18) ^ (w48 >> 03) +% w56 +% rot(w61, 17) ^ rot(w61, 19) ^ (w61 >> 10);\n\n      /*\n      for ((i, j, k, l, m) in expansion_rounds.vals()) {\n        // (j,k,l,m) = (i+1,i+9,i+14,i+16)\n        let (v0, v1) = (msg[j], msg[l]);\n        let s0 = rot(v0, 07) ^ rot(v0, 18) ^ (v0 >> 03);\n        let s1 = rot(v1, 17) ^ rot(v1, 19) ^ (v1 >> 10);\n        msg[m] := msg[i] +% s0 +% msg[k] +% s1;\n      };\n      */\n      // compress\n      var a = s0;\n      var b = s1;\n      var c = s2;\n      var d = s3;\n      var e = s4;\n      var f = s5;\n      var g = s6;\n      var h = s7;\n      var t = 0 : Nat32;\n\n      t := h +% K00 +% w00 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n      h := g;\n      g := f;\n      f := e;\n      e := d +% t;\n      d := c;\n      c := b;\n      b := a;\n      a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n      t := h +% K01 +% w01 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n      h := g;\n      g := f;\n      f := e;\n      e := d +% t;\n      d := c;\n      c := b;\n      b := a;\n      a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n      t := h +% K02 +% w02 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n      h := g;\n      g := f;\n      f := e;\n      e := d +% t;\n      d := c;\n      c := b;\n      b := a;\n      a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n      t := h +% K03 +% w03 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n      h := g;\n      g := f;\n      f := e;\n      e := d +% t;\n      d := c;\n      c := b;\n      b := a;\n      a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n      t := h +% K04 +% w04 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n      h := g;\n      g := f;\n      f := e;\n      e := d +% t;\n      d := c;\n      c := b;\n      b := a;\n      a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n      t := h +% K05 +% w05 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n      h := g;\n      g := f;\n      f := e;\n      e := d +% t;\n      d := c;\n      c := b;\n      b := a;\n      a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n      t := h +% K06 +% w06 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n      h := g;\n      g := f;\n      f := e;\n      e := d +% t;\n      d := c;\n      c := b;\n      b := a;\n      a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n      t := h +% K07 +% w07 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n      h := g;\n      g := f;\n      f := e;\n      e := d +% t;\n      d := c;\n      c := b;\n      b := a;\n      a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n      t := h +% K08 +% w08 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n      h := g;\n      g := f;\n      f := e;\n      e := d +% t;\n      d := c;\n      c := b;\n      b := a;\n      a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n      t := h +% K09 +% w09 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n      h := g;\n      g := f;\n      f := e;\n      e := d +% t;\n      d := c;\n      c := b;\n      b := a;\n      a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n      t := h +% K10 +% w10 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n      h := g;\n      g := f;\n      f := e;\n      e := d +% t;\n      d := c;\n      c := b;\n      b := a;\n      a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n      t := h +% K11 +% w11 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n      h := g;\n      g := f;\n      f := e;\n      e := d +% t;\n      d := c;\n      c := b;\n      b := a;\n      a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n      t := h +% K12 +% w12 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n      h := g;\n      g := f;\n      f := e;\n      e := d +% t;\n      d := c;\n      c := b;\n      b := a;\n      a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n      t := h +% K13 +% w13 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n      h := g;\n      g := f;\n      f := e;\n      e := d +% t;\n      d := c;\n      c := b;\n      b := a;\n      a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n      t := h +% K14 +% w14 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n      h := g;\n      g := f;\n      f := e;\n      e := d +% t;\n      d := c;\n      c := b;\n      b := a;\n      a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n      t := h +% K15 +% w15 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n      h := g;\n      g := f;\n      f := e;\n      e := d +% t;\n      d := c;\n      c := b;\n      b := a;\n      a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n      t := h +% K16 +% w16 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n      h := g;\n      g := f;\n      f := e;\n      e := d +% t;\n      d := c;\n      c := b;\n      b := a;\n      a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n      t := h +% K17 +% w17 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n      h := g;\n      g := f;\n      f := e;\n      e := d +% t;\n      d := c;\n      c := b;\n      b := a;\n      a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n      t := h +% K18 +% w18 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n      h := g;\n      g := f;\n      f := e;\n      e := d +% t;\n      d := c;\n      c := b;\n      b := a;\n      a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n      t := h +% K19 +% w19 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n      h := g;\n      g := f;\n      f := e;\n      e := d +% t;\n      d := c;\n      c := b;\n      b := a;\n      a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n      t := h +% K20 +% w20 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n      h := g;\n      g := f;\n      f := e;\n      e := d +% t;\n      d := c;\n      c := b;\n      b := a;\n      a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n      t := h +% K21 +% w21 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n      h := g;\n      g := f;\n      f := e;\n      e := d +% t;\n      d := c;\n      c := b;\n      b := a;\n      a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n      t := h +% K22 +% w22 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n      h := g;\n      g := f;\n      f := e;\n      e := d +% t;\n      d := c;\n      c := b;\n      b := a;\n      a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n      t := h +% K23 +% w23 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n      h := g;\n      g := f;\n      f := e;\n      e := d +% t;\n      d := c;\n      c := b;\n      b := a;\n      a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n      t := h +% K24 +% w24 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n      h := g;\n      g := f;\n      f := e;\n      e := d +% t;\n      d := c;\n      c := b;\n      b := a;\n      a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n      t := h +% K25 +% w25 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n      h := g;\n      g := f;\n      f := e;\n      e := d +% t;\n      d := c;\n      c := b;\n      b := a;\n      a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n      t := h +% K26 +% w26 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n      h := g;\n      g := f;\n      f := e;\n      e := d +% t;\n      d := c;\n      c := b;\n      b := a;\n      a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n      t := h +% K27 +% w27 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n      h := g;\n      g := f;\n      f := e;\n      e := d +% t;\n      d := c;\n      c := b;\n      b := a;\n      a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n      t := h +% K28 +% w28 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n      h := g;\n      g := f;\n      f := e;\n      e := d +% t;\n      d := c;\n      c := b;\n      b := a;\n      a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n      t := h +% K29 +% w29 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n      h := g;\n      g := f;\n      f := e;\n      e := d +% t;\n      d := c;\n      c := b;\n      b := a;\n      a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n      t := h +% K30 +% w30 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n      h := g;\n      g := f;\n      f := e;\n      e := d +% t;\n      d := c;\n      c := b;\n      b := a;\n      a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n      t := h +% K31 +% w31 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n      h := g;\n      g := f;\n      f := e;\n      e := d +% t;\n      d := c;\n      c := b;\n      b := a;\n      a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n      t := h +% K32 +% w32 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n      h := g;\n      g := f;\n      f := e;\n      e := d +% t;\n      d := c;\n      c := b;\n      b := a;\n      a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n      t := h +% K33 +% w33 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n      h := g;\n      g := f;\n      f := e;\n      e := d +% t;\n      d := c;\n      c := b;\n      b := a;\n      a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n      t := h +% K34 +% w34 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n      h := g;\n      g := f;\n      f := e;\n      e := d +% t;\n      d := c;\n      c := b;\n      b := a;\n      a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n      t := h +% K35 +% w35 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n      h := g;\n      g := f;\n      f := e;\n      e := d +% t;\n      d := c;\n      c := b;\n      b := a;\n      a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n      t := h +% K36 +% w36 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n      h := g;\n      g := f;\n      f := e;\n      e := d +% t;\n      d := c;\n      c := b;\n      b := a;\n      a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n      t := h +% K37 +% w37 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n      h := g;\n      g := f;\n      f := e;\n      e := d +% t;\n      d := c;\n      c := b;\n      b := a;\n      a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n      t := h +% K38 +% w38 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n      h := g;\n      g := f;\n      f := e;\n      e := d +% t;\n      d := c;\n      c := b;\n      b := a;\n      a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n      t := h +% K39 +% w39 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n      h := g;\n      g := f;\n      f := e;\n      e := d +% t;\n      d := c;\n      c := b;\n      b := a;\n      a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n      t := h +% K40 +% w40 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n      h := g;\n      g := f;\n      f := e;\n      e := d +% t;\n      d := c;\n      c := b;\n      b := a;\n      a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n      t := h +% K41 +% w41 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n      h := g;\n      g := f;\n      f := e;\n      e := d +% t;\n      d := c;\n      c := b;\n      b := a;\n      a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n      t := h +% K42 +% w42 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n      h := g;\n      g := f;\n      f := e;\n      e := d +% t;\n      d := c;\n      c := b;\n      b := a;\n      a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n      t := h +% K43 +% w43 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n      h := g;\n      g := f;\n      f := e;\n      e := d +% t;\n      d := c;\n      c := b;\n      b := a;\n      a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n      t := h +% K44 +% w44 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n      h := g;\n      g := f;\n      f := e;\n      e := d +% t;\n      d := c;\n      c := b;\n      b := a;\n      a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n      t := h +% K45 +% w45 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n      h := g;\n      g := f;\n      f := e;\n      e := d +% t;\n      d := c;\n      c := b;\n      b := a;\n      a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n      t := h +% K46 +% w46 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n      h := g;\n      g := f;\n      f := e;\n      e := d +% t;\n      d := c;\n      c := b;\n      b := a;\n      a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n      t := h +% K47 +% w47 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n      h := g;\n      g := f;\n      f := e;\n      e := d +% t;\n      d := c;\n      c := b;\n      b := a;\n      a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n      t := h +% K48 +% w48 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n      h := g;\n      g := f;\n      f := e;\n      e := d +% t;\n      d := c;\n      c := b;\n      b := a;\n      a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n      t := h +% K49 +% w49 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n      h := g;\n      g := f;\n      f := e;\n      e := d +% t;\n      d := c;\n      c := b;\n      b := a;\n      a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n      t := h +% K50 +% w50 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n      h := g;\n      g := f;\n      f := e;\n      e := d +% t;\n      d := c;\n      c := b;\n      b := a;\n      a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n      t := h +% K51 +% w51 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n      h := g;\n      g := f;\n      f := e;\n      e := d +% t;\n      d := c;\n      c := b;\n      b := a;\n      a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n      t := h +% K52 +% w52 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n      h := g;\n      g := f;\n      f := e;\n      e := d +% t;\n      d := c;\n      c := b;\n      b := a;\n      a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n      t := h +% K53 +% w53 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n      h := g;\n      g := f;\n      f := e;\n      e := d +% t;\n      d := c;\n      c := b;\n      b := a;\n      a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n      t := h +% K54 +% w54 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n      h := g;\n      g := f;\n      f := e;\n      e := d +% t;\n      d := c;\n      c := b;\n      b := a;\n      a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n      t := h +% K55 +% w55 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n      h := g;\n      g := f;\n      f := e;\n      e := d +% t;\n      d := c;\n      c := b;\n      b := a;\n      a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n      t := h +% K56 +% w56 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n      h := g;\n      g := f;\n      f := e;\n      e := d +% t;\n      d := c;\n      c := b;\n      b := a;\n      a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n      t := h +% K57 +% w57 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n      h := g;\n      g := f;\n      f := e;\n      e := d +% t;\n      d := c;\n      c := b;\n      b := a;\n      a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n      t := h +% K58 +% w58 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n      h := g;\n      g := f;\n      f := e;\n      e := d +% t;\n      d := c;\n      c := b;\n      b := a;\n      a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n      t := h +% K59 +% w59 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n      h := g;\n      g := f;\n      f := e;\n      e := d +% t;\n      d := c;\n      c := b;\n      b := a;\n      a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n      t := h +% K60 +% w60 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n      h := g;\n      g := f;\n      f := e;\n      e := d +% t;\n      d := c;\n      c := b;\n      b := a;\n      a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n      t := h +% K61 +% w61 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n      h := g;\n      g := f;\n      f := e;\n      e := d +% t;\n      d := c;\n      c := b;\n      b := a;\n      a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n      t := h +% K62 +% w62 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n      h := g;\n      g := f;\n      f := e;\n      e := d +% t;\n      d := c;\n      c := b;\n      b := a;\n      a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n      t := h +% K63 +% w63 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n      h := g;\n      g := f;\n      f := e;\n      e := d +% t;\n      d := c;\n      c := b;\n      b := a;\n      a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n\n      /*\n      for (i in compression_rounds.keys()) {\n        let ch = (e & f) ^ (^ e & g);\n        let maj = (a & b) ^ (a & c) ^ (b & c);\n        let sigma0 = rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n        let sigma1 = rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n        let t = h +% K[i] +% msg[i] +% ch +% sigma1;\n        h := g;\n        g := f;\n        f := e;\n        e := d +% t;\n        d := c;\n        c := b;\n        b := a;\n        a := t +% maj +% sigma0;\n      };\n      */\n      // final addition\n      s0 +%= a;\n      s1 +%= b;\n      s2 +%= c;\n      s3 +%= d;\n      s4 +%= e;\n      s5 +%= f;\n      s6 +%= g;\n      s7 +%= h\n    };\n\n    public func writeIter(iter : { next() : ?Nat8 }) : () {\n      label reading loop {\n        switch (iter.next()) {\n          case (?val) {\n            writeByte(val);\n            continue reading\n          };\n          case (null) {\n            break reading\n          }\n        }\n      }\n    };\n\n    public func writeArray(arr : [Nat8]) : () = writeIter(arr.vals());\n    public func writeBlob(blob : Blob) : () = writeIter(blob.vals());\n\n    public func sum() : Blob {\n      // calculate padding\n      // t = bytes in the last incomplete block (0-63)\n      let t : Nat8 = (i_msg << 2) +% 4 -% i_byte;\n      // p = length of padding (1-64)\n      var p : Nat8 = if (t < 56) (56 -% t) else (120 -% t);\n      // n_bits = length of message in bits\n      let n_bits : Nat64 = ((i_block << 6) +% Nat64.fromIntWrap(Nat8.toNat(t))) << 3;\n\n      // write padding\n      writeByte(0x80);\n      p -%= 1;\n      while (p != 0) {\n        writeByte(0x00);\n        p -%= 1\n      };\n\n      // write length (8 bytes)\n      // Note: this exactly fills the block buffer, hence process_block will get\n      // triggered by the last writeByte\n      writeByte(Nat8.fromIntWrap(Nat64.toNat((n_bits >> 56) & 0xff)));\n      writeByte(Nat8.fromIntWrap(Nat64.toNat((n_bits >> 48) & 0xff)));\n      writeByte(Nat8.fromIntWrap(Nat64.toNat((n_bits >> 40) & 0xff)));\n      writeByte(Nat8.fromIntWrap(Nat64.toNat((n_bits >> 32) & 0xff)));\n      writeByte(Nat8.fromIntWrap(Nat64.toNat((n_bits >> 24) & 0xff)));\n      writeByte(Nat8.fromIntWrap(Nat64.toNat((n_bits >> 16) & 0xff)));\n      writeByte(Nat8.fromIntWrap(Nat64.toNat((n_bits >> 8) & 0xff)));\n      writeByte(Nat8.fromIntWrap(Nat64.toNat(n_bits & 0xff)));\n\n      // retrieve sum\n      digest[0] := Nat8.fromIntWrap(Nat32.toNat((s0 >> 24) & 0xff));\n      digest[1] := Nat8.fromIntWrap(Nat32.toNat((s0 >> 16) & 0xff));\n      digest[2] := Nat8.fromIntWrap(Nat32.toNat((s0 >> 8) & 0xff));\n      digest[3] := Nat8.fromIntWrap(Nat32.toNat(s0 & 0xff));\n      digest[4] := Nat8.fromIntWrap(Nat32.toNat((s1 >> 24) & 0xff));\n      digest[5] := Nat8.fromIntWrap(Nat32.toNat((s1 >> 16) & 0xff));\n      digest[6] := Nat8.fromIntWrap(Nat32.toNat((s1 >> 8) & 0xff));\n      digest[7] := Nat8.fromIntWrap(Nat32.toNat(s1 & 0xff));\n      digest[8] := Nat8.fromIntWrap(Nat32.toNat((s2 >> 24) & 0xff));\n      digest[9] := Nat8.fromIntWrap(Nat32.toNat((s2 >> 16) & 0xff));\n      digest[10] := Nat8.fromIntWrap(Nat32.toNat((s2 >> 8) & 0xff));\n      digest[11] := Nat8.fromIntWrap(Nat32.toNat(s2 & 0xff));\n      digest[12] := Nat8.fromIntWrap(Nat32.toNat((s3 >> 24) & 0xff));\n      digest[13] := Nat8.fromIntWrap(Nat32.toNat((s3 >> 16) & 0xff));\n      digest[14] := Nat8.fromIntWrap(Nat32.toNat((s3 >> 8) & 0xff));\n      digest[15] := Nat8.fromIntWrap(Nat32.toNat(s3 & 0xff));\n      digest[16] := Nat8.fromIntWrap(Nat32.toNat((s4 >> 24) & 0xff));\n      digest[17] := Nat8.fromIntWrap(Nat32.toNat((s4 >> 16) & 0xff));\n      digest[18] := Nat8.fromIntWrap(Nat32.toNat((s4 >> 8) & 0xff));\n      digest[19] := Nat8.fromIntWrap(Nat32.toNat(s4 & 0xff));\n      digest[20] := Nat8.fromIntWrap(Nat32.toNat((s5 >> 24) & 0xff));\n      digest[21] := Nat8.fromIntWrap(Nat32.toNat((s5 >> 16) & 0xff));\n      digest[22] := Nat8.fromIntWrap(Nat32.toNat((s5 >> 8) & 0xff));\n      digest[23] := Nat8.fromIntWrap(Nat32.toNat(s5 & 0xff));\n      digest[24] := Nat8.fromIntWrap(Nat32.toNat((s6 >> 24) & 0xff));\n      digest[25] := Nat8.fromIntWrap(Nat32.toNat((s6 >> 16) & 0xff));\n      digest[26] := Nat8.fromIntWrap(Nat32.toNat((s6 >> 8) & 0xff));\n      digest[27] := Nat8.fromIntWrap(Nat32.toNat(s6 & 0xff));\n\n      return Blob.fromArrayMut(digest)\n    }\n  }; // class SHA224\n\n  func nat32ToByteArray(n : Nat32) : [Nat8] {\n    func byte(n : Nat32) : Nat8 {\n      Nat8.fromNat(Nat32.toNat(n & 0xff))\n    };\n    [byte(n >> 24), byte(n >> 16), byte(n >> 8), byte(n)]\n  }\n}\n"},"Stack.mo":{"content":"/// Class `Stack<X>` provides a minimal LIFO stack of elements of type `X`.\n///\n/// See library `Deque` for mixed LIFO/FIFO behavior.\n///\n/// Example:\n/// ```motoko name=initialize\n/// import Stack \"mo:base/Stack\";\n///\n/// let stack = Stack.Stack<Nat>(); // create a stack\n/// ```\n/// | Runtime   | Space     |\n/// |-----------|-----------|\n/// | `O(1)` | `O(1)` |\n\nimport List \"List\";\n\nmodule {\n\n  public class Stack<T>() {\n\n    var stack : List.List<T> = List.nil<T>();\n\n    /// Push an element on the top of the stack.\n    ///\n    /// Example:\n    /// ```motoko include=initialize\n    /// stack.push(1);\n    /// stack.push(2);\n    /// stack.push(3);\n    /// stack.peek(); // examine the top most element\n    /// ```\n    /// | Runtime   | Space     |\n    /// |-----------|-----------|\n    /// | `O(1)` | `O(1)` |\n    public func push(x : T) {\n      stack := ?(x, stack)\n    };\n\n    /// True when the stack is empty and false otherwise.\n    ///\n    /// Example:\n    /// ```motoko include=initialize\n    /// stack.isEmpty();\n    /// ```\n    ///\n    /// | Runtime   | Space     |\n    /// |-----------|-----------|\n    /// | `O(1)` | `O(1)` |\n    public func isEmpty() : Bool {\n      List.isNil<T>(stack)\n    };\n\n    /// Return (without removing) the top element, or return null if the stack is empty.\n    ///\n    /// Example:\n    /// ```motoko include=initialize\n    /// stack.push(1);\n    /// stack.push(2);\n    /// stack.push(3);\n    /// stack.peek();\n    /// ```\n    ///\n    /// | Runtime   | Space     |\n    /// |-----------|-----------|\n    /// | `O(1)` | `O(1)` |\n    public func peek() : ?T {\n      switch stack {\n        case null { null };\n        case (?(h, _)) { ?h }\n      }\n    };\n\n    /// Remove and return the top element, or return null if the stack is empty.\n    ///\n    /// Example:\n    /// ```motoko include=initialize\n    /// stack.push(1);\n    /// ignore stack.pop();\n    /// stack.isEmpty();\n    /// ```\n    ///\n    /// | Runtime   | Space     |\n    /// |-----------|-----------|\n    /// | `O(1)` | `O(1)` |\n    public func pop() : ?T {\n      switch stack {\n        case null { null };\n        case (?(h, t)) { stack := t; ?h }\n      }\n    }\n  }\n}\n"},"Array.mo":{"content":"/// Provides extended utility functions on Arrays.\n///\n/// :::warning\n///\n/// If you are looking for a list that can grow and shrink in size,\n/// it is recommended you use either the `Buffer` or `List` data structure for\n/// those purposes.\n///\n/// :::\n///\n/// :::note Assumptions\n///\n/// Runtime and space complexity assumes that `generator`, `equal`, and other functions execute in `O(1)` time and space.\n/// :::\n///\n/// Import from the base library to use this module.\n///\n/// ```motoko name=import\n/// import Array \"mo:base/Array\";\n/// ```\n///\n\nimport I \"IterType\";\nimport Option \"Option\";\nimport Order \"Order\";\nimport Prim \"mo:⛔\";\nimport Result \"Result\";\n\nmodule {\n  /// Create a mutable array with `size` copies of the initial value.\n  ///\n  /// ```motoko include=import\n  /// let array = Array.init<Nat>(4, 2);\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size)` | `O(size)` |\n  public func init<X>(size : Nat, initValue : X) : [var X] = Prim.Array_init<X>(size, initValue);\n\n  /// Create an immutable array of size `size`. Each element at index i\n  /// is created by applying `generator` to i.\n  ///\n  /// ```motoko include=import\n  /// let array : [Nat] = Array.tabulate<Nat>(4, func i = i * 2);\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size)` | `O(size)` |\n  public func tabulate<X>(size : Nat, generator : Nat -> X) : [X] = Prim.Array_tabulate<X>(size, generator);\n\n  /// Create a mutable array of size `size`. Each element at index i\n  /// is created by applying `generator` to i.\n  ///\n  /// ```motoko include=import\n  /// let array : [var Nat] = Array.tabulateVar<Nat>(4, func i = i * 2);\n  /// array[2] := 0;\n  /// array\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size)` | `O(size)` |\n  public func tabulateVar<X>(size : Nat, generator : Nat -> X) : [var X] {\n    // FIXME add this as a primitive in the RTS\n    if (size == 0) { return [var] };\n    let array = Prim.Array_init<X>(size, generator 0);\n    var i = 1;\n    while (i < size) {\n      array[i] := generator i;\n      i += 1\n    };\n    array\n  };\n\n  /// Transforms a mutable array into an immutable array.\n  ///\n  /// ```motoko include=import\n  ///\n  /// let varArray = [var 0, 1, 2];\n  /// varArray[2] := 3;\n  /// let array = Array.freeze<Nat>(varArray);\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size)` | `O(1)` |\n  public func freeze<X>(varArray : [var X]) : [X] = Prim.Array_tabulate<X>(varArray.size(), func i = varArray[i]);\n\n  /// Transforms an immutable array into a mutable array.\n  ///\n  /// ```motoko include=import\n  ///\n  /// let array = [0, 1, 2];\n  /// let varArray = Array.thaw<Nat>(array);\n  /// varArray[2] := 3;\n  /// varArray\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size)` | `O(1)` |\n  public func thaw<A>(array : [A]) : [var A] {\n    let size = array.size();\n    if (size == 0) {\n      return [var]\n    };\n    let newArray = Prim.Array_init<A>(size, array[0]);\n    var i = 0;\n    while (i < size) {\n      newArray[i] := array[i];\n      i += 1\n    };\n    newArray\n  };\n\n  /// Tests if two arrays contain equal values (i.e. they represent the same\n  /// list of elements). Uses `equal` to compare elements in the arrays.\n  ///\n  /// ```motoko include=import\n  /// // Use the equal function from the Nat module to compare Nats\n  /// import {equal} \"mo:base/Nat\";\n  ///\n  /// let array1 = [0, 1, 2, 3];\n  /// let array2 = [0, 1, 2, 3];\n  /// Array.equal(array1, array2, equal)\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size1 + size2)` | `O(size1 + size2)` |\n  public func equal<X>(array1 : [X], array2 : [X], equal : (X, X) -> Bool) : Bool {\n    let size1 = array1.size();\n    let size2 = array2.size();\n    if (size1 != size2) {\n      return false\n    };\n    var i = 0;\n    while (i < size1) {\n      if (not equal(array1[i], array2[i])) {\n        return false\n      };\n      i += 1\n    };\n    return true\n  };\n\n  /// Returns the first value in `array` for which `predicate` returns true.\n  /// If no element satisfies the predicate, returns null.\n  ///\n  /// ```motoko include=import\n  /// let array = [1, 9, 4, 8];\n  /// Array.find<Nat>(array, func x = x > 8)\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size)` | `O(1)` |\n  ///\n  public func find<X>(array : [X], predicate : X -> Bool) : ?X {\n    for (element in array.vals()) {\n      if (predicate element) {\n        return ?element\n      }\n    };\n    return null\n  };\n\n  /// Create a new array by appending the values of `array1` and `array2`.\n  ///\n  /// :::note Efficient appending\n  ///\n  /// `Array.append` copies its arguments and runs in linear time.\n  /// For better performance in loops, consider using `Buffer` and `Buffer.append` instead.\n  ///\n  /// :::\n  ///\n  /// ```motoko include=import\n  /// let array1 = [1, 2, 3];\n  /// let array2 = [4, 5, 6];\n  /// Array.append<Nat>(array1, array2)\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size1 + size2)` | `O(size1 + size2)` |\n  public func append<X>(array1 : [X], array2 : [X]) : [X] {\n    let size1 = array1.size();\n    let size2 = array2.size();\n    Prim.Array_tabulate<X>(\n      size1 + size2,\n      func i {\n        if (i < size1) {\n          array1[i]\n        } else {\n          array2[i - size1]\n        }\n      }\n    )\n  };\n\n  /// Sorts the elements in the array according to `compare`.\n  /// Sort is deterministic and stable.\n  ///\n  /// ```motoko include=import\n  /// import Nat \"mo:base/Nat\";\n  ///\n  /// let array = [4, 2, 6];\n  /// Array.sort(array, Nat.compare).\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size * log(size))` | `O(size)` |\n  public func sort<X>(array : [X], compare : (X, X) -> Order.Order) : [X] {\n    let temp : [var X] = thaw(array);\n    sortInPlace(temp, compare);\n    freeze(temp)\n  };\n\n  /// Sorts the elements in the array, __in place__, according to `compare`.\n  /// Sort is deterministic, stable, and in-place.\n  ///\n  /// ```motoko include=import\n  /// import {compare} \"mo:base/Nat\";\n  /// let array = [var 4, 2, 6];\n  /// Array.sortInPlace(array, compare);\n  /// array\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size * log(size))` | `O(size)` |\n  ///\n  public func sortInPlace<X>(array : [var X], compare : (X, X) -> Order.Order) {\n    // Stable merge sort in a bottom-up iterative style. Same algorithm as the sort in Buffer.\n    let size = array.size();\n    if (size == 0) {\n      return\n    };\n    let scratchSpace = Prim.Array_init<X>(size, array[0]);\n\n    let sizeDec = size - 1 : Nat;\n    var currSize = 1; // current size of the subarrays being merged\n    // when the current size == size, the array has been merged into a single sorted array\n    while (currSize < size) {\n      var leftStart = 0; // selects the current left subarray being merged\n      while (leftStart < sizeDec) {\n        let mid : Nat = if (leftStart + currSize - 1 : Nat < sizeDec) {\n          leftStart + currSize - 1\n        } else { sizeDec };\n        let rightEnd : Nat = if (leftStart + (2 * currSize) - 1 : Nat < sizeDec) {\n          leftStart + (2 * currSize) - 1\n        } else { sizeDec };\n\n        // Merge subarrays elements[leftStart...mid] and elements[mid+1...rightEnd]\n        var left = leftStart;\n        var right = mid + 1;\n        var nextSorted = leftStart;\n        while (left < mid + 1 and right < rightEnd + 1) {\n          let leftElement = array[left];\n          let rightElement = array[right];\n          switch (compare(leftElement, rightElement)) {\n            case (#less or #equal) {\n              scratchSpace[nextSorted] := leftElement;\n              left += 1\n            };\n            case (#greater) {\n              scratchSpace[nextSorted] := rightElement;\n              right += 1\n            }\n          };\n          nextSorted += 1\n        };\n        while (left < mid + 1) {\n          scratchSpace[nextSorted] := array[left];\n          nextSorted += 1;\n          left += 1\n        };\n        while (right < rightEnd + 1) {\n          scratchSpace[nextSorted] := array[right];\n          nextSorted += 1;\n          right += 1\n        };\n\n        // Copy over merged elements\n        var i = leftStart;\n        while (i < rightEnd + 1) {\n          array[i] := scratchSpace[i];\n          i += 1\n        };\n\n        leftStart += 2 * currSize\n      };\n      currSize *= 2\n    }\n  };\n\n  /// Creates a new array by reversing the order of elements in `array`.\n  ///\n  /// ```motoko include=import\n  /// let array = [10, 11, 12];\n  /// Array.reverse(array)\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size)` | `O(1)` |\n  public func reverse<X>(array : [X]) : [X] {\n    let size = array.size();\n    Prim.Array_tabulate<X>(size, func i = array[size - i - 1])\n  };\n\n  /// Creates a new array by applying `f` to each element in `array`. `f` \"maps\"\n  /// each element it is applied to of type `X` to an element of type `Y`.\n  /// Retains original ordering of elements.\n  ///\n  /// ```motoko include=import\n  /// let array = [0, 1, 2, 3];\n  /// Array.map<Nat, Nat>(array, func x = x * 3)\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size)` | `O(size)` |\n  ///\n  public func map<X, Y>(array : [X], f : X -> Y) : [Y] = Prim.Array_tabulate<Y>(array.size(), func i = f(array[i]));\n\n  /// Creates a new array by applying `predicate` to every element\n  /// in `array`, retaining the elements for which `predicate` returns true.\n  ///\n  /// ```motoko include=import\n  /// let array = [4, 2, 6, 1, 5];\n  /// let evenElements = Array.filter<Nat>(array, func x = x % 2 == 0);\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size)` | `O(size)` |\n  public func filter<X>(array : [X], predicate : X -> Bool) : [X] {\n    var count = 0;\n    let keep = Prim.Array_tabulate<Bool>(\n      array.size(),\n      func i {\n        if (predicate(array[i])) {\n          count += 1;\n          true\n        } else {\n          false\n        }\n      }\n    );\n    var nextKeep = 0;\n    Prim.Array_tabulate<X>(\n      count,\n      func _ {\n        while (not keep[nextKeep]) {\n          nextKeep += 1\n        };\n        nextKeep += 1;\n        array[nextKeep - 1]\n      }\n    )\n  };\n\n  /// Creates a new array by applying `f` to each element in `array` and its index.\n  /// Retains original ordering of elements.\n  ///\n  /// ```motoko include=import\n  /// let array = [10, 10, 10, 10];\n  /// Array.mapEntries<Nat, Nat>(array, func (x, i) = i * x)\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size)` | `O(size)` |\n  public func mapEntries<X, Y>(array : [X], f : (X, Nat) -> Y) : [Y] = Prim.Array_tabulate<Y>(array.size(), func i = f(array[i], i));\n\n  /// Creates a new array by applying `f` to each element in `array`,\n  /// and keeping all non-null elements. The ordering is retained.\n  ///\n  /// ```motoko include=import\n  /// import {toText} \"mo:base/Nat\";\n  ///\n  /// let array = [4, 2, 0, 1];\n  /// let newArray =\n  ///  Array.mapFilter<Nat, Text>( // mapping from Nat to Text values\n  ///    array,\n  ///    func x = if (x == 0) { null } else { ?toText(100 / x) } // can't divide by 0, so return null\n  ///  );\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size)` | `O(size)` |\n  ///\n  public func mapFilter<X, Y>(array : [X], f : X -> ?Y) : [Y] {\n    var count = 0;\n    let options = Prim.Array_tabulate<?Y>(\n      array.size(),\n      func i {\n        let result = f(array[i]);\n        switch (result) {\n          case (?element) {\n            count += 1;\n            result\n          };\n          case null {\n            null\n          }\n        }\n      }\n    );\n\n    var nextSome = 0;\n    Prim.Array_tabulate<Y>(\n      count,\n      func _ {\n        while (Option.isNull(options[nextSome])) {\n          nextSome += 1\n        };\n        nextSome += 1;\n        switch (options[nextSome - 1]) {\n          case (?element) element;\n          case null {\n            Prim.trap \"Malformed array in mapFilter\"\n          }\n        }\n      }\n    )\n  };\n\n  /// Creates a new array by applying `f` to each element in `array`.\n  /// If any invocation of `f` produces an `#err`, returns an `#err`. Otherwise\n  /// returns an `#ok` containing the new array.\n  ///\n  /// ```motoko include=import\n  /// let array = [4, 3, 2, 1, 0];\n  /// // divide 100 by every element in the array\n  /// Array.mapResult<Nat, Nat, Text>(array, func x {\n  ///   if (x > 0) {\n  ///     #ok(100 / x)\n  ///   } else {\n  ///     #err \"Cannot divide by zero\"\n  ///   }\n  /// })\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size)` | `O(size)` |\n  public func mapResult<X, Y, E>(array : [X], f : X -> Result.Result<Y, E>) : Result.Result<[Y], E> {\n    let size = array.size();\n\n    var error : ?Result.Result<[Y], E> = null;\n    let results = Prim.Array_tabulate<?Y>(\n      size,\n      func i {\n        switch (f(array[i])) {\n          case (#ok element) {\n            ?element\n          };\n          case (#err e) {\n            switch (error) {\n              case null {\n                // only take the first error\n                error := ?(#err e)\n              };\n              case _ {}\n            };\n            null\n          }\n        }\n      }\n    );\n\n    switch error {\n      case null {\n        // unpack the option\n        #ok(\n          map<?Y, Y>(\n            results,\n            func element {\n              switch element {\n                case (?element) {\n                  element\n                };\n                case null {\n                  Prim.trap \"Malformed array in mapResults\"\n                }\n              }\n            }\n          )\n        )\n      };\n      case (?error) {\n        error\n      }\n    }\n  };\n\n  /// Creates a new array by applying `k` to each element in `array`,\n  /// and concatenating the resulting arrays in order. This operation\n  /// is similar to what in other functional languages is known as monadic bind.\n  ///\n  /// ```motoko include=import\n  /// import Nat \"mo:base/Nat\";\n  ///\n  /// let array = [1, 2, 3, 4];\n  /// Array.chain<Nat, Int>(array, func x = [x, -x])\n  ///\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size)` | `O(size)` |\n  public func chain<X, Y>(array : [X], k : X -> [Y]) : [Y] {\n    var flatSize = 0;\n    let arrays = Prim.Array_tabulate<[Y]>(\n      array.size(),\n      func i {\n        let subArray = k(array[i]);\n        flatSize += subArray.size();\n        subArray\n      }\n    );\n\n    // could replace with a call to flatten,\n    // but it would require an extra pass (to compute `flatSize`)\n    var outer = 0;\n    var inner = 0;\n    Prim.Array_tabulate<Y>(\n      flatSize,\n      func _ {\n        while (inner == arrays[outer].size()) {\n          inner := 0;\n          outer += 1\n        };\n        let element = arrays[outer][inner];\n        inner += 1;\n        element\n      }\n    )\n  };\n\n  /// Collapses the elements in `array` into a single value by starting with `base`\n  /// and progessively combining elements into `base` with `combine`. Iteration runs\n  /// left to right.\n  ///\n  /// ```motoko include=import\n  /// import {add} \"mo:base/Nat\";\n  ///\n  /// let array = [4, 2, 0, 1];\n  /// let sum =\n  ///  Array.foldLeft<Nat, Nat>(\n  ///    array,\n  ///    0, // start the sum at 0\n  ///    func(sumSoFar, x) = sumSoFar + x // this entire function can be replaced with `add`!\n  ///  );\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size)` | `O(1)` |\n  public func foldLeft<X, A>(array : [X], base : A, combine : (A, X) -> A) : A {\n    var accumulation = base;\n\n    for (element in array.vals()) {\n      accumulation := combine(accumulation, element)\n    };\n\n    accumulation\n  };\n\n  /// Collapses the elements in `array` into a single value by starting with `base`\n  /// and progessively combining elements into `base` with `combine`. Iteration runs\n  /// right to left.\n  ///\n  /// ```motoko include=import\n  /// import {toText} \"mo:base/Nat\";\n  ///\n  /// let array = [1, 9, 4, 8];\n  /// let bookTitle = Array.foldRight<Nat, Text>(array, \"\", func(x, acc) = toText(x) # acc);\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size)` | `O(1)` |\n  public func foldRight<X, A>(array : [X], base : A, combine : (X, A) -> A) : A {\n    var accumulation = base;\n    let size = array.size();\n\n    var i = size;\n    while (i > 0) {\n      i -= 1;\n      accumulation := combine(array[i], accumulation)\n    };\n\n    accumulation\n  };\n\n  /// Flattens the array of arrays into a single array. Retains the original\n  /// ordering of the elements.\n  ///\n  /// ```motoko include=import\n  /// let arrays = [[0, 1, 2], [2, 3], [], [4]];\n  /// Array.flatten<Nat>(arrays)\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(n)` | `O(n)` |\n  public func flatten<X>(arrays : [[X]]) : [X] {\n    var flatSize = 0;\n    for (subArray in arrays.vals()) {\n      flatSize += subArray.size()\n    };\n\n    var outer = 0;\n    var inner = 0;\n    Prim.Array_tabulate<X>(\n      flatSize,\n      func _ {\n        while (inner == arrays[outer].size()) {\n          inner := 0;\n          outer += 1\n        };\n        let element = arrays[outer][inner];\n        inner += 1;\n        element\n      }\n    )\n  };\n\n  /// Create an array containing a single value.\n  ///\n  /// ```motoko include=import\n  /// Array.make(2)\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(1)` | `O(1)` |\n  public func make<X>(element : X) : [X] = [element];\n\n  /// Returns an Iterator (`Iter`) over the elements of `array`.\n  /// Iterator provides a single method `next()`, which returns\n  /// elements in order, or `null` when out of elements to iterate over.\n  ///\n  /// :::note Alternative approach\n  ///\n  /// Alternatively, you can use `array.size()` to achieve the same result. See the example below.\n  /// :::\n  ///\n  /// ```motoko include=import\n  /// let array = [10, 11, 12];\n  /// var sum = 0;\n  /// for (element in array.vals()) {\n  ///  sum += element;\n  /// };\n  /// sum\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(1)` | `O(1)` |\n  public func vals<X>(array : [X]) : I.Iter<X> = array.vals();\n\n  /// Returns an Iterator (`Iter`) over the indices of `array`.\n  /// Iterator provides a single method `next()`, which returns\n  /// indices in order, or `null` when out of index to iterate over.\n  ///\n  /// :::note Alternative approach\n  /// You can also use `array.keys()` instead of this function. See example\n  /// below.\n  ///\n  /// :::\n  ///\n  /// ```motoko include=import\n  /// let array = [10, 11, 12];\n  /// var sum = 0;\n  /// for (element in array.keys()) {\n  ///  sum += element;\n  /// };\n  /// sum\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(1)` | `O(1)` |\n  public func keys<X>(array : [X]) : I.Iter<Nat> = array.keys();\n\n  /// Returns the size of `array`.\n  ///\n  /// :::note Alternative approach\n  ///\n  /// Alternatively, you can use `array.size()` to achieve the same result. See the example below.\n  /// :::\n  ///\n  /// ```motoko include=import\n  /// let array = [10, 11, 12];\n  /// let size = Array.size(array);\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(1)` | `O(1)` |\n  public func size<X>(array : [X]) : Nat = array.size();\n\n  /// Returns a new subarray from the given array provided the start index and length of elements in the subarray.\n  ///\n  /// :::note Limitations\n  /// Traps if the start index + length is greater than the size of the array.\n  /// :::\n  ///\n  /// ```motoko include=import\n  /// let array = [1,2,3,4,5];\n  /// let subArray = Array.subArray<Nat>(array, 2, 3);\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(length)` | `O(length)` |\n  public func subArray<X>(array : [X], start : Nat, length : Nat) : [X] {\n    if (start + length > array.size()) { Prim.trap(\"Array.subArray\") };\n    tabulate<X>(\n      length,\n      func(i) {\n        array[start + i]\n      }\n    )\n  };\n\n  /// Returns the index of the first `element` in the `array`.\n  ///\n  /// ```motoko include=import\n  /// import Char \"mo:base/Char\";\n  /// let array = ['c', 'o', 'f', 'f', 'e', 'e'];\n  /// assert Array.indexOf<Char>('c', array, Char.equal) == ?0;\n  /// assert Array.indexOf<Char>('f', array, Char.equal) == ?2;\n  /// assert Array.indexOf<Char>('g', array, Char.equal) == null;\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(array.size())` | `O(1)` |\n  public func indexOf<X>(element : X, array : [X], equal : (X, X) -> Bool) : ?Nat = nextIndexOf<X>(element, array, 0, equal);\n\n  /// Returns the index of the next occurrence of `element` in the `array` starting from the `from` index (inclusive).\n  ///\n  /// ```motoko include=import\n  /// import Char \"mo:base/Char\";\n  /// let array = ['c', 'o', 'f', 'f', 'e', 'e'];\n  /// assert Array.nextIndexOf<Char>('c', array, 0, Char.equal) == ?0;\n  /// assert Array.nextIndexOf<Char>('f', array, 0, Char.equal) == ?2;\n  /// assert Array.nextIndexOf<Char>('f', array, 2, Char.equal) == ?2;\n  /// assert Array.nextIndexOf<Char>('f', array, 3, Char.equal) == ?3;\n  /// assert Array.nextIndexOf<Char>('f', array, 4, Char.equal) == null;\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(array.size())` | `O(1)` |\n  public func nextIndexOf<X>(element : X, array : [X], fromInclusive : Nat, equal : (X, X) -> Bool) : ?Nat {\n    var i = fromInclusive;\n    let n = array.size();\n    while (i < n) {\n      if (equal(array[i], element)) {\n        return ?i\n      } else {\n        i += 1\n      }\n    };\n    null\n  };\n\n  /// Returns the index of the last `element` in the `array`.\n  ///\n  /// ```motoko include=import\n  /// import Char \"mo:base/Char\";\n  /// let array = ['c', 'o', 'f', 'f', 'e', 'e'];\n  /// assert Array.lastIndexOf<Char>('c', array, Char.equal) == ?0;\n  /// assert Array.lastIndexOf<Char>('f', array, Char.equal) == ?3;\n  /// assert Array.lastIndexOf<Char>('e', array, Char.equal) == ?5;\n  /// assert Array.lastIndexOf<Char>('g', array, Char.equal) == null;\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(array.size())` | `O(1)` |\n  public func lastIndexOf<X>(element : X, array : [X], equal : (X, X) -> Bool) : ?Nat = prevIndexOf<X>(element, array, array.size(), equal);\n\n  /// Returns the index of the previous occurrence of `element` in the `array` starting from the `from` index (exclusive).\n  ///\n  /// ```motoko include=import\n  /// import Char \"mo:base/Char\";\n  /// let array = ['c', 'o', 'f', 'f', 'e', 'e'];\n  /// assert Array.prevIndexOf<Char>('c', array, array.size(), Char.equal) == ?0;\n  /// assert Array.prevIndexOf<Char>('e', array, array.size(), Char.equal) == ?5;\n  /// assert Array.prevIndexOf<Char>('e', array, 5, Char.equal) == ?4;\n  /// assert Array.prevIndexOf<Char>('e', array, 4, Char.equal) == null;\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(array.size())` | `O(1)` |\n  public func prevIndexOf<T>(element : T, array : [T], fromExclusive : Nat, equal : (T, T) -> Bool) : ?Nat {\n    var i = fromExclusive;\n    while (i > 0) {\n      i -= 1;\n      if (equal(array[i], element)) {\n        return ?i\n      }\n    };\n    null\n  };\n\n  /// Returns an iterator over a slice of the given array.\n  ///\n  /// ```motoko include=import\n  /// let array = [1, 2, 3, 4, 5];\n  /// let s = Array.slice<Nat>(array, 3, array.size());\n  /// assert s.next() == ?4;\n  /// assert s.next() == ?5;\n  /// assert s.next() == null;\n  ///\n  /// let s = Array.slice<Nat>(array, 0, 0);\n  /// assert s.next() == null;\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(1)` | `O(1)` |\n  public func slice<X>(array : [X], fromInclusive : Nat, toExclusive : Nat) : I.Iter<X> = object {\n    var i = fromInclusive;\n\n    public func next() : ?X {\n      if (i >= toExclusive) {\n        return null\n      };\n      let result = array[i];\n      i += 1;\n      return ?result\n    }\n  };\n\n  /// Returns a new subarray of given length from the beginning or end of the given array.\n  ///\n  /// Returns the entire array if the length is greater than the size of the array.\n  ///\n  /// ```motoko include=import\n  /// let array = [1, 2, 3, 4, 5];\n  /// assert Array.take(array, 2) == [1, 2];\n  /// assert Array.take(array, -2) == [4, 5];\n  /// assert Array.take(array, 10) == [1, 2, 3, 4, 5];\n  /// assert Array.take(array, -99) == [1, 2, 3, 4, 5];\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(length)` | `O(length)` |\n  public func take<T>(array : [T], length : Int) : [T] {\n    let len = Prim.abs(length);\n    let size = array.size();\n    let resSize = if (len < size) { len } else { size };\n    let start : Nat = if (length > 0) 0 else size - resSize;\n    subArray(array, start, resSize)\n  }\n}\n"},"Debug.mo":{"content":"/// Utility functions for debugging.\n///\n/// Import from the base library to use this module.\n/// ```motoko name=import\n/// import Debug \"mo:base/Debug\";\n/// ```\n\nimport Prim \"mo:⛔\";\nmodule {\n  /// Prints `text` to output stream.\n  ///\n  /// :::note\n  /// When running on ICP, all output is written to the [canister log](https://internetcomputer.org/docs/current/developer-docs/smart-contracts/maintain/logs) with the exclusion of any output\n  /// produced during the execution of non-replicated queries and composite queries.\n  /// In other environments, like the interpreter and stand-alone Wasm engines, the output is written to standard out.\n  /// :::\n  ///\n  /// ```motoko include=import\n  /// Debug.print \"Hello New World!\";\n  /// Debug.print(debug_show(4)) // Often used with `debug_show` to convert values to Text\n  /// ```\n  public func print(text : Text) {\n    Prim.debugPrint text\n  };\n\n  /// `trap(t)` traps execution with a user-provided diagnostic message.\n  ///\n  /// The caller of a future whose execution called `trap(t)` will\n  /// observe the trap as an `Error` value, thrown at `await`, with code\n  /// `#canister_error` and message `m`. Here `m` is a more descriptive `Text`\n  /// message derived from the provided `t`. See example for more details.\n  ///\n  /// :::note\n\n  /// Other execution environments that cannot handle traps may only\n  /// propagate the trap and terminate execution, with or without some\n  /// descriptive message.\n  /// :::\n  ///\n  /// ```motoko\n  /// import Debug \"mo:base/Debug\";\n  /// import Error \"mo:base/Error\";\n  ///\n  /// actor {\n  ///   func fail() : async () {\n  ///     Debug.trap(\"user provided error message\");\n  ///   };\n  ///\n  ///   public func foo() : async () {\n  ///     try {\n  ///       await fail();\n  ///     } catch e {\n  ///       let code = Error.code(e); // evaluates to #canister_error\n  ///       let message = Error.message(e); // contains user provided error message\n  ///     }\n  ///   };\n  /// }\n  /// ```\n  public func trap(errorMessage : Text) : None {\n    Prim.trap errorMessage\n  }\n}\n"},"Trie.mo":{"content":"/// Functional key-value hash map.\n///\n/// Provides an applicative (purely functional) hash map, called a *trie*, where each operation returns a new version of the structure without mutating the original.\n///\n/// Operations use `Key` records that group the key value with its precomputed hash.\n///\n/// For imperative or object-oriented alternatives, see [`TrieMap`](../TrieMap) or [`HashMap`](../HashMap).\n///\n/// :::warning Hash collision limit\n/// Each trie node supports at most 8 distinct keys with the same hash (`MAX_LEAF_SIZE = 8`). Exceeding this will cause a trap.\n/// :::\n///\n/// :::info Credits\n/// Based on Section 6 of [\"Incremental computation via function caching\", Pugh & Teitelbaum](https://dl.acm.org/citation.cfm?id=75305).\n/// :::\n///\n/// Example:\n///\n/// ```motoko\n/// import Trie \"mo:base/Trie\";\n/// import Text \"mo:base/Text\";\n///\n/// // we do this to have shorter type names and thus\n/// // better readability\n/// type Trie<K, V> = Trie.Trie<K, V>;\n/// type Key<K> = Trie.Key<K>;\n///\n/// // we have to provide `put`, `get` and `remove` with\n/// // a record of type `Key<K> = { hash : Hash.Hash; key : K }`;\n/// // thus we define the following function that takes a value of type `K`\n/// // (in this case `Text`) and returns a `Key<K>` record.\n/// func key(t: Text) : Key<Text> { { hash = Text.hash t; key = t } };\n///\n/// // we start off by creating an empty `Trie`\n/// let t0 : Trie<Text, Nat> = Trie.empty();\n///\n/// // `put` requires 4 arguments:\n/// // - the trie we want to insert the value into,\n/// // - the key of the value we want to insert (note that we use the `key` function defined above),\n/// // - a function that checks for equality of keys, and\n/// // - the value we want to insert.\n/// //\n/// // When inserting a value, `put` returns a tuple of type `(Trie<K, V>, ?V)`.\n/// // to get the new trie that contains the value,  we use the `0` projection\n/// // and assign it to `t1` and `t2` respectively.\n/// let t1 : Trie<Text, Nat> = Trie.put(t0, key \"hello\", Text.equal, 42).0;\n/// let t2 : Trie<Text, Nat> = Trie.put(t1, key \"world\", Text.equal, 24).0;\n///\n/// // If for a given key there already was a value in the trie, `put` returns\n/// // that previous value as the second element of the tuple.\n/// // in our case we have already inserted the value 42 for the key \"hello\", so\n/// // `put` returns 42 as the second element of the tuple.\n/// let (t3, n) : (Trie<Text, Nat>, ?Nat) = Trie.put(\n///  t2,\n///  key \"hello\",\n///  Text.equal,\n///  0,\n/// );\n/// assert (n == ?42);\n///\n/// // `get` requires 3 arguments:\n/// // - the trie we want to get the value from\n/// // - the key of the value we want to get (note that we use the `key` function defined above)\n/// // - a function that checks for equality of keys\n/// //\n/// // If the given key is nonexistent in the trie, `get` returns `null`.\n/// var value = Trie.get(t3, key \"hello\", Text.equal); // Returns `?42`\n/// assert(value == ?0);\n/// value := Trie.get(t3, key \"universe\", Text.equal); // Returns `null`\n/// assert(value == null);\n///\n/// // `remove` requires 3 arguments:\n/// // - the trie we want to remove the value from,\n/// // - the key of the value we want to remove (note that we use the `key` function defined above), and\n/// // - a function that checks for equality of keys.\n/// //\n/// // In the case of keys of type `Text`, we can use `Text.equal`\n/// // to check for equality of keys. Function `remove` returns a tuple of type `(Trie<K, V>, ?V)`.\n/// // where the second element of the tuple is the value that was removed, or `null` if\n/// // there was no value for the given key.\n/// let removedValue : ?Nat = Trie.remove(\n///  t3,\n///  key \"hello\",\n///  Text.equal,\n/// ).1;\n/// assert (removedValue == ?0);\n///\n/// // To iterate over the Trie, we use the `iter` function that takes a trie\n/// // of type `Trie<K,V>` and returns an iterator of type `Iter<(K,V)>`:\n/// var sum : Nat = 0;\n/// for (kv in Trie.iter(t3)) {\n///  sum += kv.1;\n/// };\n/// assert(sum == 24);\n/// ```\n\nimport Debug \"Debug\";\n\nimport Prim \"mo:⛔\";\nimport P \"Prelude\";\nimport Option \"Option\";\nimport Hash \"Hash\";\nimport A \"Array\";\n\nimport List \"List\";\nimport AssocList \"AssocList\";\nimport I \"Iter\";\n\nmodule {\n\n  let MAX_LEAF_SIZE = 8; // to do -- further profiling and tuning\n\n  /// Binary hash tries: either empty, a leaf node, or a branch node.\n  public type Trie<K, V> = {\n    #empty;\n    #leaf : Leaf<K, V>;\n    #branch : Branch<K, V>\n  };\n\n  /// Leaf nodes of trie consist of key-value pairs as a list.\n  public type Leaf<K, V> = {\n    size : Nat;\n    keyvals : AssocList<Key<K>, V>\n  };\n\n  /// Branch nodes of the trie discriminate on a bit position of the keys' hashes.\n  /// This bit position is not stored in the branch but determined from\n  /// the context of the branch.\n  public type Branch<K, V> = {\n    size : Nat;\n    left : Trie<K, V>;\n    right : Trie<K, V>\n  };\n\n  public type AssocList<K, V> = AssocList.AssocList<K, V>;\n\n  /// A `Key` for the trie has an associated hash value:\n  /// - `hash` permits fast inequality checks, and permits collisions.\n  /// - `key` permits precise equality checks, but is only used on values with equal hashes.\n  public type Key<K> = {\n    hash : Hash.Hash;\n    key : K\n  };\n\n  type List<T> = List.List<T>;\n\n  /// Equality function for two `Key<K>`s, in terms of equality of `K`'s.\n  public func equalKey<K>(keq : (K, K) -> Bool) : ((Key<K>, Key<K>) -> Bool) = func(key1 : Key<K>, key2 : Key<K>) : Bool = Hash.equal(key1.hash, key2.hash) and keq(key1.key, key2.key);\n\n  /// :::warning Deprecated function\n  /// `isValid` is an internal predicate and will be removed in future.\n  /// :::\n  public func isValid<K, V>(t : Trie<K, V>, _enforceNormal : Bool) : Bool {\n    func rec(t : Trie<K, V>, bitpos : ?Hash.Hash, bits : Hash.Hash, mask : Hash.Hash) : Bool = switch t {\n      case (#empty) {\n        true\n      };\n      case (#leaf l) {\n        let len = List.size(l.keyvals);\n        len <= MAX_LEAF_SIZE and len == l.size and List.all(\n          l.keyvals,\n          func((k : Key<K>, _v : V)) : Bool { ((k.hash & mask) == bits) }\n        )\n      };\n      case (#branch b) {\n        let bitpos1 = switch bitpos {\n          case null { Prim.natToNat32(0) };\n          case (?bp) { Prim.natToNat32(Prim.nat32ToNat(bp) + 1) }\n        };\n        let mask1 = mask | (Prim.natToNat32(1) << bitpos1);\n        let bits1 = bits | (Prim.natToNat32(1) << bitpos1);\n        let sum = size(b.left) + size(b.right);\n        (b.size == sum) and rec(b.left, ?bitpos1, bits, mask1) and rec(b.right, ?bitpos1, bits1, mask1)\n      }\n    };\n    rec(t, null, 0, 0)\n  };\n\n  /// A 2D trie maps dimension-1 keys to another\n  /// layer of tries, each keyed on the dimension-2 keys.\n  public type Trie2D<K1, K2, V> = Trie<K1, Trie<K2, V>>;\n\n  /// A 3D trie maps dimension-1 keys to another\n  /// Composition of 2D tries, each keyed on the dimension-2 and dimension-3 keys.\n  public type Trie3D<K1, K2, K3, V> = Trie<K1, Trie2D<K2, K3, V>>;\n\n  /// An empty trie. This is usually the starting point for building a trie.\n  ///\n  /// Example:\n  /// ```motoko name=initialize\n  /// import { print } \"mo:base/Debug\";\n  /// import Trie \"mo:base/Trie\";\n  /// import Text \"mo:base/Text\";\n  ///\n  /// // we do this to have shorter type names and thus\n  /// // better readibility\n  /// type Trie<K, V> = Trie.Trie<K, V>;\n  /// type Key<K> = Trie.Key<K>;\n  ///\n  /// // We have to provide `put`, `get` and `remove` with\n  /// // a function of return type `Key<K> = { hash : Hash.Hash; key : K }`\n  /// func key(t: Text) : Key<Text> { { hash = Text.hash t; key = t } };\n  /// // We start off by creating an empty `Trie`\n  /// var trie : Trie<Text, Nat> = Trie.empty();\n  /// ```\n  public func empty<K, V>() : Trie<K, V> = #empty;\n\n  /// Get the size in O(1) time.\n  ///\n  ///\n  /// Example:\n  /// ```motoko include=initialize\n  /// var size = Trie.size(trie); // Returns 0, as `trie` is empty\n  /// assert(size == 0);\n  /// trie := Trie.put(trie, key \"hello\", Text.equal, 42).0;\n  /// size := Trie.size(trie); // Returns 1, as we just added a new entry\n  /// assert(size == 1);\n  /// ```\n\n  public func size<K, V>(t : Trie<K, V>) : Nat = switch t {\n    case (#empty) { 0 };\n    case (#leaf l) { l.size };\n    case (#branch b) { b.size }\n  };\n\n  /// Construct a branch node, computing the size stored there.\n  public func branch<K, V>(l : Trie<K, V>, r : Trie<K, V>) : Trie<K, V> =\n  #branch {\n    size = size l + size r;\n    left = l;\n    right = r\n  };\n\n  /// Construct a leaf node, computing the size stored there.\n  ///\n  /// This helper function automatically enforces the MAX_LEAF_SIZE\n  /// by constructing branches as necessary; to do so, it also needs the bitpos\n  /// of the leaf.\n  public func leaf<K, V>(kvs : AssocList<Key<K>, V>, bitpos : Nat) : Trie<K, V> = fromList(null, kvs, bitpos);\n\n  module ListUtil {\n    /* Deprecated: List.lenClamp */\n    /// Return the list length unless the number of items in the list exceeds\n    /// a maximum value. If the list length exceed the maximum, the function\n    /// returns `null`.\n    public func lenClamp<T>(l : List<T>, max : Nat) : ?Nat {\n      func rec(l : List<T>, max : Nat, i : Nat) : ?Nat = switch l {\n        case null { ?i };\n        case (?(_, t)) {\n          if (i >= max) { null } else { rec(t, max, i + 1) }\n        }\n      };\n      rec(l, max, 0)\n    }\n  };\n\n  /// Transform a list into a trie, splitting input list into small (leaf) lists, if necessary.\n  public func fromList<K, V>(kvc : ?Nat, kvs : AssocList<Key<K>, V>, bitpos : Nat) : Trie<K, V> {\n    func rec(kvc : ?Nat, kvs : AssocList<Key<K>, V>, bitpos : Nat) : Trie<K, V> {\n      switch kvc {\n        case null {\n          switch (ListUtil.lenClamp(kvs, MAX_LEAF_SIZE)) {\n            case null {} /* fall through to branch case. */;\n            case (?len) {\n              return #leaf { size = len; keyvals = kvs }\n            }\n          }\n        };\n        case (?c) {\n          if (c == 0) {\n            return #empty\n          } else if (c <= MAX_LEAF_SIZE) {\n            return #leaf { size = c; keyvals = kvs }\n          } else {\n\n            //fall through to branch case\n          }\n        }\n      };\n      let (ls, l, rs, r) = splitList(kvs, bitpos);\n      if (ls == 0 and rs == 0) {\n        #empty\n      } else if (rs == 0 and ls <= MAX_LEAF_SIZE) {\n        #leaf { size = ls; keyvals = l }\n      } else if (ls == 0 and rs <= MAX_LEAF_SIZE) {\n        #leaf { size = rs; keyvals = r }\n      } else {\n        branch(rec(?ls, l, bitpos + 1), rec(?rs, r, bitpos + 1))\n      }\n    };\n    rec(kvc, kvs, bitpos)\n  };\n\n  /// Clone the trie efficiently, via sharing.\n  ///\n  /// Purely-functional representation permits _O(1)_ copy, via persistent sharing.\n  public func clone<K, V>(t : Trie<K, V>) : Trie<K, V> = t;\n\n  /// Combine two nodes that may have a reduced size after an entry deletion.\n  func combineReducedNodes<K, V>(left : Trie<K, V>, right : Trie<K, V>) : Trie<K, V> = switch (left, right) {\n    case (#empty, #empty) {\n      #empty\n    };\n    case (#leaf _, #empty) {\n      left\n    };\n    case (#empty, #leaf _) {\n      right\n    };\n    case (#leaf leftLeaf, #leaf rightLeaf) {\n      let size = leftLeaf.size + rightLeaf.size;\n      if (size <= MAX_LEAF_SIZE) {\n        let union = List.append(leftLeaf.keyvals, rightLeaf.keyvals);\n        #leaf { size; keyvals = union }\n      } else {\n        branch(left, right)\n      }\n    };\n    case (left, right) {\n      branch(left, right)\n    }\n  };\n\n  /// Replace the given key's value option with the given value, returning the modified trie.\n  /// Also returns the replaced value if the key existed and `null` otherwise.\n  /// Compares keys using the provided function `k_eq`.\n  ///\n  /// :::note\n  /// Replacing a key's value by `null` removes the key and also shrinks the trie.\n  /// :::\n  ///\n  /// Example:\n  /// ```motoko include=initialize\n  /// trie := Trie.put(trie, key \"test\", Text.equal, 1).0;\n  /// trie := Trie.replace(trie, key \"test\", Text.equal, 42).0;\n  /// assert (Trie.get(trie, key \"hello\", Text.equal) == ?42);\n  /// ```\n  public func replace<K, V>(t : Trie<K, V>, k : Key<K>, k_eq : (K, K) -> Bool, v : ?V) : (Trie<K, V>, ?V) {\n    let key_eq = equalKey(k_eq);\n    var replacedValue : ?V = null;\n\n    func recursiveReplace(t : Trie<K, V>, bitpos : Nat) : Trie<K, V> = switch t {\n      case (#empty) {\n        let (kvs, _) = AssocList.replace(null, k, key_eq, v);\n        leaf(kvs, bitpos)\n      };\n      case (#branch b) {\n        let bit = Hash.bit(k.hash, bitpos);\n        // rebuild either the left or right path with the (k, v) pair\n        if (not bit) {\n          let l = recursiveReplace(b.left, bitpos + 1);\n          combineReducedNodes(l, b.right)\n        } else {\n          let r = recursiveReplace(b.right, bitpos + 1);\n          combineReducedNodes(b.left, r)\n        }\n      };\n      case (#leaf l) {\n        let (kvs2, oldValue) = AssocList.replace(l.keyvals, k, key_eq, v);\n        replacedValue := oldValue;\n        leaf(kvs2, bitpos)\n      }\n    };\n    let newTrie = recursiveReplace(t, 0);\n    //assert(isValid<K, V>(newTrie, false));\n    (newTrie, replacedValue)\n  };\n\n  /// Put the given key's value in the trie; return the new trie, and the previous value associated with the key, if any.\n  ///\n  ///\n  /// Example:\n  /// ```motoko include=initialize\n  /// trie := Trie.put(trie, key \"hello\", Text.equal, 42).0;\n  /// let previousValue = Trie.put(trie, key \"hello\", Text.equal, 33).1; // Returns ?42\n  /// assert(previousValue == ?42);\n  /// ```\n  public func put<K, V>(t : Trie<K, V>, k : Key<K>, k_eq : (K, K) -> Bool, v : V) : (Trie<K, V>, ?V) = replace(t, k, k_eq, ?v);\n\n  /// Get the value of the given key in the trie, or return null if nonexistent.\n  ///\n  ///\n  /// Example:\n  /// ```motoko include=initialize\n  /// trie := Trie.put(trie, key \"hello\", Text.equal, 42).0;\n  /// var value = Trie.get(trie, key \"hello\", Text.equal); // Returns `?42`\n  /// assert(value == ?42);\n  /// value := Trie.get(trie, key \"world\", Text.equal); // Returns `null`\n  /// assert(value == null);\n  /// ```\n  public func get<K, V>(t : Trie<K, V>, k : Key<K>, k_eq : (K, K) -> Bool) : ?V = find(t, k, k_eq);\n\n  /// Find the given key's value in the trie, or return `null` if nonexistent\n  ///\n  ///\n  /// Example:\n  /// ```motoko include=initialize\n  /// trie := Trie.put(trie, key \"hello\", Text.equal, 42).0;\n  /// var value = Trie.find(trie, key \"hello\", Text.equal); // Returns `?42`\n  /// assert(value == ?42);\n  /// value := Trie.find(trie, key \"world\", Text.equal); // Returns `null`\n  /// assert(value == null);\n  /// ```\n  public func find<K, V>(t : Trie<K, V>, k : Key<K>, k_eq : (K, K) -> Bool) : ?V {\n    let key_eq = equalKey(k_eq);\n    func rec(t : Trie<K, V>, bitpos : Nat) : ?V = switch t {\n      case (#empty) { null };\n      case (#leaf l) {\n        AssocList.find(l.keyvals, k, key_eq)\n      };\n      case (#branch b) {\n        let bit = Hash.bit(k.hash, bitpos);\n        if (not bit) {\n          rec(b.left, bitpos + 1)\n        } else {\n          rec(b.right, bitpos + 1)\n        }\n      }\n    };\n    rec(t, 0)\n  };\n\n  func splitAssocList<K, V>(al : AssocList<Key<K>, V>, bitpos : Nat) : (AssocList<Key<K>, V>, AssocList<Key<K>, V>) = List.partition(\n    al,\n    func((k : Key<K>, _v : V)) : Bool = not Hash.bit(k.hash, bitpos)\n  );\n\n  func splitList<K, V>(l : AssocList<Key<K>, V>, bitpos : Nat) : (Nat, AssocList<Key<K>, V>, Nat, AssocList<Key<K>, V>) {\n    func rec(l : AssocList<Key<K>, V>) : (Nat, AssocList<Key<K>, V>, Nat, AssocList<Key<K>, V>) = switch l {\n      case null { (0, null, 0, null) };\n      case (?((k, v), t)) {\n        let (cl, l, cr, r) = rec(t);\n        if (not Hash.bit(k.hash, bitpos)) { (cl + 1, ?((k, v), l), cr, r) } else {\n          (cl, l, cr + 1, ?((k, v), r))\n        }\n      }\n    };\n    rec(l)\n  };\n\n  /// Merge tries, preferring the left trie where there are collisions\n  /// in common keys.\n  ///\n  /// :::note\n  /// The `disj` operation generalizes this `merge`\n  /// operation in various ways, and does not (in general) lose\n  /// information; this operation is a simpler, special case.\n  /// :::\n  ///\n  /// Example:\n  /// ```motoko include=initialize\n  /// trie := Trie.put(trie, key \"hello\", Text.equal, 42).0;\n  /// trie := Trie.put(trie, key \"bye\", Text.equal, 42).0;\n  /// // trie2 is a copy of trie\n  /// var trie2 = Trie.clone(trie);\n  /// // trie2 has a different value for \"hello\"\n  /// trie2 := Trie.put(trie2, key \"hello\", Text.equal, 33).0;\n  /// // mergedTrie has the value 42 for \"hello\", as the left trie is preferred\n  /// // in the case of a collision\n  /// var mergedTrie = Trie.merge(trie, trie2, Text.equal);\n  /// var value = Trie.get(mergedTrie, key \"hello\", Text.equal);\n  /// assert(value == ?42);\n  /// ```\n  public func merge<K, V>(tl : Trie<K, V>, tr : Trie<K, V>, k_eq : (K, K) -> Bool) : Trie<K, V> {\n    let key_eq = equalKey(k_eq);\n    func rec(bitpos : Nat, tl : Trie<K, V>, tr : Trie<K, V>) : Trie<K, V> = switch (tl, tr) {\n      case (#empty, _) { return tr };\n      case (_, #empty) { return tl };\n      case (#leaf l1, #leaf l2) {\n        leaf(\n          AssocList.disj(\n            l1.keyvals,\n            l2.keyvals,\n            key_eq,\n            func(x : ?V, y : ?V) : V = switch (x, y) {\n              case (null, null) { P.unreachable() };\n              case (null, ?v) { v };\n              case (?v, _) { v }\n            }\n          ),\n          bitpos\n        )\n      };\n      case (#leaf l, _) {\n        let (ll, lr) = splitAssocList(l.keyvals, bitpos);\n        rec(bitpos, branch(leaf(ll, bitpos), leaf(lr, bitpos)), tr)\n      };\n      case (_, #leaf l) {\n        let (ll, lr) = splitAssocList(l.keyvals, bitpos);\n        rec(bitpos, tl, branch(leaf(ll, bitpos), leaf(lr, bitpos)))\n      };\n      case (#branch b1, #branch b2) {\n        branch(\n          rec(bitpos + 1, b1.left, b2.left),\n          rec(bitpos + 1, b1.right, b2.right)\n        )\n      }\n    };\n    rec(0, tl, tr)\n  };\n\n  /// <a name=\"mergedisjoint\"></a>\n  ///\n  /// Merge tries like `merge`, but traps if there are collisions in common keys between the\n  /// left and right inputs.\n  ///\n  ///\n  /// Example:\n  /// ```motoko include=initialize\n  /// trie := Trie.put(trie, key \"hello\", Text.equal, 42).0;\n  /// trie := Trie.put(trie, key \"bye\", Text.equal, 42).0;\n  /// // trie2 is a copy of trie\n  /// var trie2 = Trie.clone(trie);\n  /// // trie2 has a different value for \"hello\"\n  /// trie2 := Trie.put(trie2, key \"hello\", Text.equal, 33).0;\n  /// // `mergeDisjoint` signals a dynamic errror\n  /// // in the case of a collision\n  /// var mergedTrie = Trie.mergeDisjoint(trie, trie2, Text.equal);\n  /// ```\n  public func mergeDisjoint<K, V>(tl : Trie<K, V>, tr : Trie<K, V>, k_eq : (K, K) -> Bool) : Trie<K, V> {\n    func rec(bitpos : Nat, tl : Trie<K, V>, tr : Trie<K, V>) : Trie<K, V> = switch (tl, tr) {\n      case (#empty, _) { return tr };\n      case (_, #empty) { return tl };\n      case (#leaf l1, #leaf l2) {\n        leaf(\n          AssocList.disj(\n            l1.keyvals,\n            l2.keyvals,\n            equalKey(k_eq),\n            func(x : ?V, y : ?V) : V = switch (x, y) {\n              case (null, ?v) { v };\n              case (?v, null) { v };\n              case (_, _) { Debug.trap \"Trie.mergeDisjoint\" }\n            }\n          ),\n          bitpos\n        )\n      };\n      case (#leaf l, _) {\n        let (ll, lr) = splitAssocList(l.keyvals, bitpos);\n        rec(bitpos, branch(leaf(ll, bitpos), leaf(lr, bitpos)), tr)\n      };\n      case (_, #leaf l) {\n        let (ll, lr) = splitAssocList(l.keyvals, bitpos);\n        rec(bitpos, tl, branch(leaf(ll, bitpos), leaf(lr, bitpos)))\n      };\n      case (#branch b1, #branch b2) {\n        branch(\n          rec(bitpos + 1, b1.left, b2.left),\n          rec(bitpos + 1, b1.right, b2.right)\n        )\n      }\n    };\n    rec(0, tl, tr)\n  };\n\n  /// Difference of tries. The output consists of pairs of\n  /// the left trie whose keys are not present in the right trie; the\n  /// values of the right trie are irrelevant.\n  ///\n  ///\n  /// Example:\n  /// ```motoko include=initialize\n  /// trie := Trie.put(trie, key \"hello\", Text.equal, 42).0;\n  /// trie := Trie.put(trie, key \"bye\", Text.equal, 42).0;\n  /// // trie2 is a copy of trie\n  /// var trie2 = Trie.clone(trie);\n  /// // trie2 now has an additional key\n  /// trie2 := Trie.put(trie2, key \"ciao\", Text.equal, 33).0;\n  /// // `diff` returns a trie with the key \"ciao\",\n  /// // as this key is not present in `trie`\n  /// // (note that we pass `trie2` as the left trie)\n  /// Trie.diff(trie2, trie, Text.equal);\n  /// ```\n  public func diff<K, V, W>(tl : Trie<K, V>, tr : Trie<K, W>, k_eq : (K, K) -> Bool) : Trie<K, V> {\n    let key_eq = equalKey(k_eq);\n\n    func rec(bitpos : Nat, tl : Trie<K, V>, tr : Trie<K, W>) : Trie<K, V> = switch (tl, tr) {\n      case (#empty, _) { return #empty };\n      case (_, #empty) { return tl };\n      case (#leaf l1, #leaf l2) {\n        leaf(\n          AssocList.diff(\n            l1.keyvals,\n            l2.keyvals,\n            key_eq\n          ),\n          bitpos\n        )\n      };\n      case (#leaf l, _) {\n        let (ll, lr) = splitAssocList(l.keyvals, bitpos);\n        rec(bitpos, branch(leaf(ll, bitpos), leaf(lr, bitpos)), tr)\n      };\n      case (_, #leaf l) {\n        let (ll, lr) = splitAssocList(l.keyvals, bitpos);\n        rec(bitpos, tl, branch(leaf(ll, bitpos), leaf(lr, bitpos)))\n      };\n      case (#branch b1, #branch b2) {\n        branch(\n          rec(bitpos + 1, b1.left, b2.left),\n          rec(bitpos + 1, b1.right, b2.right)\n        )\n      }\n    };\n    rec(0, tl, tr)\n  };\n\n  /// Map disjunction.\n  ///\n  /// This operation generalizes the notion of \"set union\" to finite maps.\n  ///\n  /// Produces a \"disjunctive image\" of the two tries, where the values of\n  /// matching keys are combined with the given binary operator.\n  ///\n  /// For unmatched key-value pairs, the operator is still applied to\n  /// create the value in the image.  To accomodate these various\n  /// situations, the operator accepts optional values, but is never\n  /// applied to (null, null).\n  ///\n  /// Implements the database idea of an [\"outer join\"](https://stackoverflow.com/questions/38549/what-is-the-difference-between-inner-join-and-outer-join).\n  ///\n  public func disj<K, V, W, X>(\n    tl : Trie<K, V>,\n    tr : Trie<K, W>,\n    k_eq : (K, K) -> Bool,\n    vbin : (?V, ?W) -> X\n  ) : Trie<K, X> {\n    let key_eq = equalKey(k_eq);\n\n    /* empty right case; build from left only: */\n    func recL(t : Trie<K, V>, bitpos : Nat) : Trie<K, X> = switch t {\n      case (#empty) { #empty };\n      case (#leaf l) {\n        leaf(AssocList.disj(l.keyvals, null, key_eq, vbin), bitpos)\n      };\n      case (#branch b) {\n        branch(\n          recL(b.left, bitpos + 1),\n          recL(b.right, bitpos + 1)\n        )\n      }\n    };\n\n    /* empty left case; build from right only: */\n    func recR(t : Trie<K, W>, bitpos : Nat) : Trie<K, X> = switch t {\n      case (#empty) { #empty };\n      case (#leaf l) {\n        leaf(AssocList.disj(null, l.keyvals, key_eq, vbin), bitpos)\n      };\n      case (#branch b) {\n        branch(\n          recR(b.left, bitpos + 1),\n          recR(b.right, bitpos + 1)\n        )\n      }\n    };\n\n    /* main recursion */\n    func rec(bitpos : Nat, tl : Trie<K, V>, tr : Trie<K, W>) : Trie<K, X> = switch (tl, tr) {\n      case (#empty, #empty) { #empty };\n      case (#empty, _) { recR(tr, bitpos) };\n      case (_, #empty) { recL(tl, bitpos) };\n      case (#leaf l1, #leaf l2) {\n        leaf(AssocList.disj(l1.keyvals, l2.keyvals, key_eq, vbin), bitpos)\n      };\n      case (#leaf l, _) {\n        let (ll, lr) = splitAssocList(l.keyvals, bitpos);\n        rec(bitpos, branch(leaf(ll, bitpos), leaf(lr, bitpos)), tr)\n      };\n      case (_, #leaf l) {\n        let (ll, lr) = splitAssocList(l.keyvals, bitpos);\n        rec(bitpos, tl, branch(leaf(ll, bitpos), leaf(lr, bitpos)))\n      };\n      case (#branch b1, #branch b2) {\n        branch(\n          rec(bitpos + 1, b1.left, b2.left),\n          rec(bitpos + 1, b1.right, b2.right)\n        )\n      }\n    };\n\n    rec(0, tl, tr)\n  };\n\n  /// Map join.\n  ///\n  /// Implements the database idea of an [\"inner join\"](https://stackoverflow.com/questions/38549/what-is-the-difference-between-inner-join-and-outer-join).\n  ///\n  /// This operation generalizes the notion of \"set intersection\" to\n  /// finite maps.  The values of matching keys are combined with the given binary\n  /// operator, and unmatched key-value pairs are not present in the output.\n  ///\n  public func join<K, V, W, X>(\n    tl : Trie<K, V>,\n    tr : Trie<K, W>,\n    k_eq : (K, K) -> Bool,\n    vbin : (V, W) -> X\n  ) : Trie<K, X> {\n    let key_eq = equalKey(k_eq);\n\n    func rec(bitpos : Nat, tl : Trie<K, V>, tr : Trie<K, W>) : Trie<K, X> = switch (tl, tr) {\n      case (#empty, _) { #empty };\n      case (_, #empty) { #empty };\n      case (#leaf l1, #leaf l2) {\n        leaf(AssocList.join(l1.keyvals, l2.keyvals, key_eq, vbin), bitpos)\n      };\n      case (#leaf l, _) {\n        let (ll, lr) = splitAssocList(l.keyvals, bitpos);\n        rec(bitpos, branch(leaf(ll, bitpos), leaf(lr, bitpos)), tr)\n      };\n      case (_, #leaf l) {\n        let (ll, lr) = splitAssocList(l.keyvals, bitpos);\n        rec(bitpos, tl, branch(leaf(ll, bitpos), leaf(lr, bitpos)))\n      };\n      case (#branch b1, #branch b2) {\n        branch(\n          rec(bitpos + 1, b1.left, b2.left),\n          rec(bitpos + 1, b1.right, b2.right)\n        )\n      }\n    };\n\n    rec(0, tl, tr)\n  };\n\n  /// This operation gives a recursor for the internal structure of\n  /// tries.  Many common operations are instantiations of this function,\n  /// either as clients, or as hand-specialized versions (e.g., see , map,\n  /// mapFilter, some and all below).\n  public func foldUp<K, V, X>(t : Trie<K, V>, bin : (X, X) -> X, leaf : (K, V) -> X, empty : X) : X {\n    func rec(t : Trie<K, V>) : X = switch t {\n      case (#empty) { empty };\n      case (#leaf l) {\n        AssocList.fold(\n          l.keyvals,\n          empty,\n          func(k : Key<K>, v : V, x : X) : X = bin(leaf(k.key, v), x)\n        )\n      };\n      case (#branch b) { bin(rec(b.left), rec(b.right)) }\n    };\n    rec(t)\n  };\n\n  /// Map product.\n  ///\n  /// Conditional _catesian product_, where the given\n  /// operation `op` _conditionally_ creates output elements in the\n  /// resulting trie.\n  ///\n  /// The keyed structure of the input tries are not relevant for this\n  /// operation: all pairs are considered, regardless of keys matching or\n  /// not.  Moreover, the resulting trie may use keys that are unrelated to\n  /// these input keys.\n  ///\n  public func prod<K1, V1, K2, V2, K3, V3>(\n    tl : Trie<K1, V1>,\n    tr : Trie<K2, V2>,\n    op : (K1, V1, K2, V2) -> ?(Key<K3>, V3),\n    k3_eq : (K3, K3) -> Bool\n  ) : Trie<K3, V3> {\n\n    /*- binary case: merge disjoint results: */\n    func merge(a : Trie<K3, V3>, b : Trie<K3, V3>) : Trie<K3, V3> = mergeDisjoint(a, b, k3_eq);\n\n    /*- \"`foldUp` squared\" (imagine two nested loops): */\n    foldUp(\n      tl,\n      merge,\n      func(k1 : K1, v1 : V1) : Trie<K3, V3> = foldUp(\n        tr,\n        merge,\n        func(k2 : K2, v2 : V2) : Trie<K3, V3> = switch (op(k1, v1, k2, v2)) {\n          case null { #empty };\n          case (?(k3, v3)) { put(#empty, k3, k3_eq, v3).0 }\n        },\n        #empty\n      ),\n      #empty\n    )\n  };\n\n  /// Returns an iterator of type `Iter` over the key-value entries of the trie.\n  ///\n  /// Each iterator gets a _persistent view_ of the mapping, independent of concurrent updates to the iterated map.\n  ///\n  ///\n  /// Example:\n  /// ```motoko include=initialize\n  /// trie := Trie.put(trie, key \"hello\", Text.equal, 42).0;\n  /// trie := Trie.put(trie, key \"bye\", Text.equal, 32).0;\n  /// // create an Iterator over key-value pairs of trie\n  /// let iter = Trie.iter(trie);\n  /// // add another key-value pair to `trie`.\n  /// // because we created our iterator before\n  /// // this update, it will not contain this new key-value pair\n  /// trie := Trie.put(trie, key \"ciao\", Text.equal, 3).0;\n  /// var sum : Nat = 0;\n  /// for ((k,v) in iter) {\n  ///   sum += v;\n  /// };\n  /// assert(sum == 74);\n  /// ```\n  public func iter<K, V>(t : Trie<K, V>) : I.Iter<(K, V)> = object {\n    var stack = ?(t, null) : List.List<Trie<K, V>>;\n    public func next() : ?(K, V) = switch stack {\n      case null { null };\n      case (?(trie, stack2)) {\n        switch trie {\n          case (#empty) {\n            stack := stack2;\n            next()\n          };\n          case (#leaf { keyvals = null }) {\n            stack := stack2;\n            next()\n          };\n          case (#leaf { size = c; keyvals = ?((k, v), kvs) }) {\n            stack := ?(#leaf { size = c - 1; keyvals = kvs }, stack2);\n            ?(k.key, v)\n          };\n          case (#branch br) {\n            stack := ?(br.left, ?(br.right, stack2));\n            next()\n          }\n        }\n      }\n    }\n  };\n\n  /// Represent the construction of tries as data.\n  ///\n  /// This module provides optimized variants of normal tries, for\n  /// more efficient join queries.\n  ///\n  /// The central insight is that for (unmaterialized) join query results, we\n  /// do not need to actually build any resulting trie of the resulting\n  /// data, but rather, just need a collection of what would be in that\n  /// trie.  Since query results can be large (quadratic in the DB size),\n  /// avoiding the construction of this trie provides a considerable savings.\n  ///\n  /// To get this savings, we use an ADT for the operations that _would_ build this trie,\n  /// if evaluated. This structure specializes a rope: a balanced tree representing a\n  /// sequence.  It is only as balanced as the tries from which we generate\n  /// these build ASTs.  They have no intrinsic balance properties of their\n  /// own.\n  ///\n  public module Build {\n    /// The build of a trie, as an AST for a simple DSL.\n    public type Build<K, V> = {\n      #skip;\n      #put : (K, ?Hash.Hash, V);\n      #seq : {\n        size : Nat;\n        left : Build<K, V>;\n        right : Build<K, V>\n      }\n    };\n\n    /// Size of the build, measured in `#put` operations\n    public func size<K, V>(tb : Build<K, V>) : Nat = switch tb {\n      case (#skip) { 0 };\n      case (#put(_, _, _)) { 1 };\n      case (#seq(seq)) { seq.size }\n    };\n\n    /// Build sequence of two sub-builds\n    public func seq<K, V>(l : Build<K, V>, r : Build<K, V>) : Build<K, V> {\n      let sum = size(l) + size(r);\n      #seq { size = sum; left = l; right = r }\n    };\n\n    /// Like [`prod`](#prod), except do not actually do the put calls, just\n    /// record them, as a (binary tree) data structure, isomorphic to the\n    /// recursion of this function (which is balanced, in expectation).\n    public func prod<K1, V1, K2, V2, K3, V3>(\n      tl : Trie<K1, V1>,\n      tr : Trie<K2, V2>,\n      op : (K1, V1, K2, V2) -> ?(K3, V3),\n      _k3_eq : (K3, K3) -> Bool\n    ) : Build<K3, V3> {\n\n      func bin(a : Build<K3, V3>, b : Build<K3, V3>) : Build<K3, V3> = seq(a, b);\n\n      /// double-nested folds\n      foldUp(\n        tl,\n        bin,\n        func(k1 : K1, v1 : V1) : Build<K3, V3> = foldUp(\n          tr,\n          bin,\n          func(k2 : K2, v2 : V2) : Build<K3, V3> = switch (op(k1, v1, k2, v2)) {\n            case null { #skip };\n            case (?(k3, v3)) { #put(k3, null, v3) }\n          },\n          #skip\n        ),\n        #skip\n      )\n    };\n\n    /// Project the nth key-value pair from the trie build.\n    ///\n    /// This position is meaningful only when the build contains multiple uses of one or more keys, otherwise it is not.\n    public func nth<K, V>(tb : Build<K, V>, i : Nat) : ?(K, ?Hash.Hash, V) {\n      func rec(tb : Build<K, V>, i : Nat) : ?(K, ?Hash.Hash, V) = switch tb {\n        case (#skip) { P.unreachable() };\n        case (#put(k, h, v)) {\n          assert (i == 0);\n          ?(k, h, v)\n        };\n        case (#seq(s)) {\n          let size_left = size(s.left);\n          if (i < size_left) { rec(s.left, i) } else {\n            rec(s.right, i - size_left)\n          }\n        }\n      };\n\n      if (i >= size(tb)) {\n        return null\n      };\n      rec(tb, i)\n    };\n\n    /// Like [`mergeDisjoint`](#mergedisjoint), except that it avoids the\n    /// work of actually merging any tries; rather, just record the work for\n    /// latter (if ever).\n    public func projectInner<K1, K2, V>(t : Trie<K1, Build<K2, V>>) : Build<K2, V> = foldUp(\n      t,\n      func(t1 : Build<K2, V>, t2 : Build<K2, V>) : Build<K2, V> = seq(t1, t2),\n      func(_ : K1, t : Build<K2, V>) : Build<K2, V> = t,\n      #skip\n    );\n\n    /// Gather the collection of key-value pairs into an array of a (possibly-distinct) type.\n    public func toArray<K, V, W>(tb : Build<K, V>, f : (K, V) -> W) : [W] {\n      let c = size(tb);\n      let a = A.init<?W>(c, null);\n      var i = 0;\n      func rec(tb : Build<K, V>) = switch tb {\n        case (#skip) {};\n        case (#put(k, _, v)) { a[i] := ?f(k, v); i := i + 1 };\n        case (#seq(s)) { rec(s.left); rec(s.right) }\n      };\n      rec(tb);\n      A.tabulate(\n        c,\n        func(i : Nat) : W = switch (a[i]) {\n          case null { P.unreachable() };\n          case (?x) { x }\n        }\n      )\n    };\n\n  };\n\n  /// Fold over the key-value pairs of the trie, using an accumulator.\n  /// The key-value pairs have no reliable or meaningful ordering.\n  ///\n  ///\n  /// Example:\n  /// ```motoko include=initialize\n  /// trie := Trie.put(trie, key \"hello\", Text.equal, 42).0;\n  /// trie := Trie.put(trie, key \"bye\", Text.equal, 32).0;\n  /// trie := Trie.put(trie, key \"ciao\", Text.equal, 3).0;\n  /// // create an accumulator, in our case the sum of all values\n  /// func calculateSum(k : Text, v : Nat, acc : Nat) : Nat = acc + v;\n  /// // Fold over the trie using the accumulator.\n  /// // Note that 0 is the initial value of the accumulator.\n  /// let sum = Trie.fold(trie, calculateSum, 0);\n  /// assert(sum == 77);\n  /// ```\n  public func fold<K, V, X>(t : Trie<K, V>, f : (K, V, X) -> X, x : X) : X {\n    func rec(t : Trie<K, V>, x : X) : X = switch t {\n      case (#empty) { x };\n      case (#leaf l) {\n        AssocList.fold(\n          l.keyvals,\n          x,\n          func(k : Key<K>, v : V, x : X) : X = f(k.key, v, x)\n        )\n      };\n      case (#branch b) { rec(b.left, rec(b.right, x)) }\n    };\n    rec(t, x)\n  };\n\n  /// Test whether a given key-value pair is present, or not.\n  ///\n  ///\n  /// Example:\n  /// ```motoko include=initialize\n  /// trie := Trie.put(trie, key \"hello\", Text.equal, 42).0;\n  /// trie := Trie.put(trie, key \"bye\", Text.equal, 32).0;\n  /// trie := Trie.put(trie, key \"ciao\", Text.equal, 3).0;\n  /// // `some` takes a function that returns a Boolean indicating whether\n  /// // the key-value pair is present or not\n  /// var isPresent = Trie.some(\n  ///   trie,\n  ///   func(k : Text, v : Nat) : Bool = k == \"bye\" and v == 32,\n  /// );\n  /// assert(isPresent == true);\n  /// isPresent := Trie.some(\n  ///   trie,\n  ///   func(k : Text, v : Nat) : Bool = k == \"hello\" and v == 32,\n  /// );\n  /// assert(isPresent == false);\n  /// ```\n  public func some<K, V>(t : Trie<K, V>, f : (K, V) -> Bool) : Bool {\n    func rec(t : Trie<K, V>) : Bool = switch t {\n      case (#empty) { false };\n      case (#leaf l) {\n        List.some(\n          l.keyvals,\n          func((k : Key<K>, v : V)) : Bool = f(k.key, v)\n        )\n      };\n      case (#branch b) { rec(b.left) or rec(b.right) }\n    };\n    rec(t)\n  };\n\n  /// Test whether all key-value pairs have a given property.\n  ///\n  ///\n  /// Example:\n  /// ```motoko include=initialize\n  /// trie := Trie.put(trie, key \"hello\", Text.equal, 42).0;\n  /// trie := Trie.put(trie, key \"bye\", Text.equal, 32).0;\n  /// trie := Trie.put(trie, key \"ciao\", Text.equal, 10).0;\n  /// // `all` takes a function that returns a boolean indicating whether\n  /// // the key-value pairs all have a given property, in our case that\n  /// // all values are greater than 9\n  /// var hasProperty = Trie.all(\n  ///   trie,\n  ///   func(k : Text, v : Nat) : Bool = v > 9,\n  /// );\n  /// assert(hasProperty == true);\n  /// // now we check if all values are greater than 100\n  /// hasProperty := Trie.all(\n  ///   trie,\n  ///   func(k : Text, v : Nat) : Bool = v > 100,\n  /// );\n  /// assert(hasProperty == false);\n  /// ```\n  public func all<K, V>(t : Trie<K, V>, f : (K, V) -> Bool) : Bool {\n    func rec(t : Trie<K, V>) : Bool = switch t {\n      case (#empty) { true };\n      case (#leaf l) {\n        List.all(\n          l.keyvals,\n          func((k : Key<K>, v : V)) : Bool = f(k.key, v)\n        )\n      };\n      case (#branch b) { rec(b.left) and rec(b.right) }\n    };\n    rec(t)\n  };\n\n  /// Project the nth key-value pair from the trie.\n  ///\n  /// :::note\n  /// This position is not meaningful; it's only here so that we\n  /// can inject tries into arrays using functions like `Array.tabulate`.\n  /// :::\n  ///\n  /// Example:\n  /// ```motoko include=initialize\n  /// import Array \"mo:base/Array\";\n  /// trie := Trie.put(trie, key \"hello\", Text.equal, 42).0;\n  /// trie := Trie.put(trie, key \"bye\", Text.equal, 32).0;\n  /// trie := Trie.put(trie, key \"ciao\", Text.equal, 10).0;\n  /// // `tabulate` takes a size parameter, so we check the size of\n  /// // the trie first\n  /// let size = Trie.size(trie);\n  /// // Now we can create an array of the same size passing `nth` as\n  /// // the generator used to fill the array.\n  /// // Note that `toArray` is a convenience function that does the\n  /// // same thing without you having to check whether the tuple is\n  /// // `null` or not, which we're not doing in this example\n  /// let array = Array.tabulate<?(Key<Text>, Nat)>(\n  ///   size,\n  ///   func n = Trie.nth(trie, n)\n  /// );\n  /// ```\n  public func nth<K, V>(t : Trie<K, V>, i : Nat) : ?(Key<K>, V) {\n    func rec(t : Trie<K, V>, i : Nat) : ?(Key<K>, V) = switch t {\n      case (#empty) { P.unreachable() };\n      case (#leaf l) { List.get(l.keyvals, i) };\n      case (#branch b) {\n        let size_left = size(b.left);\n        if (i < size_left) { rec(b.left, i) } else {\n          rec(b.right, i - size_left)\n        }\n      }\n    };\n    if (i >= size(t)) {\n      return null\n    };\n    rec(t, i)\n  };\n\n  /// Gather the collection of key-value pairs into an array of a (possibly-distinct) type.\n  ///\n  ///\n  /// Example:\n  /// ```motoko include=initialize\n  /// trie := Trie.put(trie, key \"hello\", Text.equal, 42).0;\n  /// trie := Trie.put(trie, key \"bye\", Text.equal, 32).0;\n  /// trie := Trie.put(trie, key \"ciao\", Text.equal, 10).0;\n  /// // `toArray` takes a function that takes a key-value tuple\n  /// // and returns a value of the type you want to use to fill\n  /// // the array.\n  /// // In our case we just return the value\n  /// let array = Trie.toArray<Text, Nat, Nat>(\n  ///   trie,\n  ///   func (k, v) = v\n  /// );\n  /// ```\n  public func toArray<K, V, W>(t : Trie<K, V>, f : (K, V) -> W) : [W] = A.tabulate<W>(\n    size(t),\n    func(i : Nat) : W {\n      let (k, v) = switch (nth(t, i)) {\n        case null { P.unreachable() };\n        case (?x) { x }\n      };\n      f(k.key, v)\n    }\n  );\n\n  /// Test for \"deep emptiness\": subtrees that have branching structure,\n  /// but no leaves.  These can result from naive filtering operations;\n  /// filter uses this function to avoid creating such subtrees.\n  public func isEmpty<K, V>(t : Trie<K, V>) : Bool = size(t) == 0;\n\n  /// Filter the key-value pairs by a given predicate.\n  ///\n  ///\n  /// Example:\n  /// ```motoko include=initialize\n  /// trie := Trie.put(trie, key \"hello\", Text.equal, 42).0;\n  /// trie := Trie.put(trie, key \"bye\", Text.equal, 32).0;\n  /// trie := Trie.put(trie, key \"ciao\", Text.equal, 10).0;\n  /// // `filter` takes a function that takes a key-value tuple\n  /// // and returns true if the key-value pair should be included.\n  /// // In our case those are pairs with a value greater than 20\n  /// let filteredTrie = Trie.filter<Text, Nat>(\n  ///   trie,\n  ///   func (k, v) = v > 20\n  /// );\n  /// assert (Trie.all<Text, Nat>(filteredTrie, func(k, v) = v > 20) == true);\n  /// ```\n  public func filter<K, V>(t : Trie<K, V>, f : (K, V) -> Bool) : Trie<K, V> {\n    func rec(t : Trie<K, V>, bitpos : Nat) : Trie<K, V> = switch t {\n      case (#empty) { #empty };\n      case (#leaf l) {\n        leaf(\n          List.filter(\n            l.keyvals,\n            func((k : Key<K>, v : V)) : Bool = f(k.key, v)\n          ),\n          bitpos\n        )\n      };\n      case (#branch b) {\n        let fl = rec(b.left, bitpos + 1);\n        let fr = rec(b.right, bitpos + 1);\n        combineReducedNodes(fl, fr)\n      }\n    };\n    rec(t, 0)\n  };\n\n  /// Map and filter the key-value pairs by a given predicate.\n  ///\n  ///\n  /// Example:\n  /// ```motoko include=initialize\n  /// trie := Trie.put(trie, key \"hello\", Text.equal, 42).0;\n  /// trie := Trie.put(trie, key \"bye\", Text.equal, 32).0;\n  /// trie := Trie.put(trie, key \"ciao\", Text.equal, 10).0;\n  /// // `mapFilter` takes a function that takes a key-value tuple\n  /// // and returns a possibly-distinct value if the key-value pair should be included.\n  /// // In our case, we filter for values greater than 20 and map them to their square.\n  /// let filteredTrie = Trie.mapFilter<Text, Nat, Nat>(\n  ///   trie,\n  ///   func (k, v) = if (v > 20) return ?(v**2) else return null\n  /// );\n  /// assert (Trie.all<Text, Nat>(filteredTrie, func(k, v) = v > 60) == true);\n  /// ```\n  public func mapFilter<K, V, W>(t : Trie<K, V>, f : (K, V) -> ?W) : Trie<K, W> {\n    func rec(t : Trie<K, V>, bitpos : Nat) : Trie<K, W> = switch t {\n      case (#empty) { #empty };\n      case (#leaf l) {\n        leaf(\n          List.mapFilter(\n            l.keyvals,\n            // retain key and hash, but update key's value using f:\n            func((k : Key<K>, v : V)) : ?(Key<K>, W) = switch (f(k.key, v)) {\n              case null { null };\n              case (?w) { ?({ key = k.key; hash = k.hash }, w) }\n            }\n          ),\n          bitpos\n        )\n      };\n      case (#branch b) {\n        let fl = rec(b.left, bitpos + 1);\n        let fr = rec(b.right, bitpos + 1);\n        combineReducedNodes(fl, fr)\n      }\n    };\n\n    rec(t, 0)\n  };\n\n  /// Test for equality, but naively, based on structure.\n  /// Does not attempt to remove \"junk\" in the tree;\n  /// For instance, a \"smarter\" approach would equate\n  ///   `#bin {left = #empty; right = #empty}`\n  /// with\n  ///   `#empty`.\n  /// We do not observe that equality here.\n  public func equalStructure<K, V>(\n    tl : Trie<K, V>,\n    tr : Trie<K, V>,\n    keq : (K, K) -> Bool,\n    veq : (V, V) -> Bool\n  ) : Bool {\n    func rec(tl : Trie<K, V>, tr : Trie<K, V>) : Bool = switch (tl, tr) {\n      case (#empty, #empty) { true };\n      case (#leaf l1, #leaf l2) {\n        List.equal(\n          l1.keyvals,\n          l2.keyvals,\n          func((k1 : Key<K>, v1 : V), (k2 : Key<K>, v2 : V)) : Bool = keq(k1.key, k2.key) and veq(v1, v2)\n        )\n      };\n      case (#branch b1, #branch b2) {\n        rec(b1.left, b2.left) and rec(b2.right, b2.right)\n      };\n      case _ { false }\n    };\n    rec(tl, tr)\n  };\n\n  /// Replace the given key's value in the trie,\n  /// and only if successful, do the success continuation,\n  /// otherwise, return the failure value\n  ///\n  ///\n  /// Example:\n  /// ```motoko include=initialize\n  /// trie := Trie.put(trie, key \"hello\", Text.equal, 42).0;\n  /// trie := Trie.put(trie, key \"bye\", Text.equal, 32).0;\n  /// trie := Trie.put(trie, key \"ciao\", Text.equal, 10).0;\n  /// // `replaceThen` takes the same arguments as `replace` but also a success continuation\n  /// // and a failure connection that are called in the respective scenarios.\n  /// // if the replace fails, that is the key is not present in the trie, the failure continuation is called.\n  /// // if the replace succeeds, that is the key is present in the trie, the success continuation is called.\n  /// // in this example we are simply returning the Text values `success` and `fail` respectively.\n  /// var continuation = Trie.replaceThen<Text, Nat, Text>(\n  ///   trie,\n  ///   key \"hello\",\n  ///   Text.equal,\n  ///   12,\n  ///   func (t, v) = \"success\",\n  ///   func () = \"fail\"\n  /// );\n  /// assert (continuation == \"success\");\n  /// continuation := Trie.replaceThen<Text, Nat, Text>(\n  ///   trie,\n  ///   key \"shalom\",\n  ///   Text.equal,\n  ///   12,\n  ///   func (t, v) = \"success\",\n  ///   func () = \"fail\"\n  /// );\n  /// assert (continuation == \"fail\");\n  /// ```\n  public func replaceThen<K, V, X>(\n    t : Trie<K, V>,\n    k : Key<K>,\n    k_eq : (K, K) -> Bool,\n    v2 : V,\n    success : (Trie<K, V>, V) -> X,\n    fail : () -> X\n  ) : X {\n    let (t2, ov) = replace(t, k, k_eq, ?v2);\n    switch ov {\n      case null { /* no prior value; failure to remove */ fail() };\n      case (?v1) { success(t2, v1) }\n    }\n  };\n\n  /// Put the given key's value in the trie; return the new trie; assert that no prior value is associated with the key.\n  ///\n  /// Example:\n  /// ```motoko include=initialize\n  /// // note that compared to `put`, `putFresh` does not return a tuple\n  /// trie := Trie.putFresh(trie, key \"hello\", Text.equal, 42);\n  /// trie := Trie.putFresh(trie, key \"bye\", Text.equal, 32);\n  /// // this will fail as \"hello\" is already present in the trie\n  /// trie := Trie.putFresh(trie, key \"hello\", Text.equal, 10);\n  /// ```\n  public func putFresh<K, V>(t : Trie<K, V>, k : Key<K>, k_eq : (K, K) -> Bool, v : V) : Trie<K, V> {\n    let (t2, none) = replace(t, k, k_eq, ?v);\n    switch none {\n      case null {};\n      case (?_) assert false\n    };\n    t2\n  };\n\n  /// Put the given key's value in the 2D trie; return the new 2D trie.\n  public func put2D<K1, K2, V>(\n    t : Trie2D<K1, K2, V>,\n    k1 : Key<K1>,\n    k1_eq : (K1, K1) -> Bool,\n    k2 : Key<K2>,\n    k2_eq : (K2, K2) -> Bool,\n    v : V\n  ) : Trie2D<K1, K2, V> {\n    let inner = find(t, k1, k1_eq);\n    let (updated_inner, _) = switch inner {\n      case null { put(#empty, k2, k2_eq, v) };\n      case (?inner) { put(inner, k2, k2_eq, v) }\n    };\n    let (updated_outer, _) = put(t, k1, k1_eq, updated_inner);\n    updated_outer\n  };\n\n  /// Put the given key's value in the trie; return the new trie;\n  public func put3D<K1, K2, K3, V>(\n    t : Trie3D<K1, K2, K3, V>,\n    k1 : Key<K1>,\n    k1_eq : (K1, K1) -> Bool,\n    k2 : Key<K2>,\n    k2_eq : (K2, K2) -> Bool,\n    k3 : Key<K3>,\n    k3_eq : (K3, K3) -> Bool,\n    v : V\n  ) : Trie3D<K1, K2, K3, V> {\n    let inner1 = find(t, k1, k1_eq);\n    let (updated_inner1, _) = switch inner1 {\n      case null {\n        put(\n          #empty,\n          k2,\n          k2_eq,\n          (put(#empty, k3, k3_eq, v)).0\n        )\n      };\n      case (?inner1) {\n        let inner2 = find(inner1, k2, k2_eq);\n        let (updated_inner2, _) = switch inner2 {\n          case null { put(#empty, k3, k3_eq, v) };\n          case (?inner2) { put(inner2, k3, k3_eq, v) }\n        };\n        put(inner1, k2, k2_eq, updated_inner2)\n      }\n    };\n    let (updated_outer, _) = put(t, k1, k1_eq, updated_inner1);\n    updated_outer\n  };\n\n  /// Remove the entry for the given key from the trie, by returning the reduced trie.\n  /// Also returns the removed value if the key existed and `null` otherwise.\n  /// Compares keys using the provided function `k_eq`.\n  ///\n  /// :::note\n  /// The removal of an existing key shrinks the trie.\n  /// :::\n  ///\n  /// Example:\n  /// ```motoko include=initialize\n  /// trie := Trie.put(trie, key \"hello\", Text.equal, 42).0;\n  /// trie := Trie.put(trie, key \"bye\", Text.equal, 32).0;\n  /// // remove the entry associated with \"hello\"\n  /// trie := Trie.remove(trie, key \"hello\", Text.equal).0;\n  /// assert (Trie.get(trie, key \"hello\", Text.equal) == null);\n  /// ```\n  public func remove<K, V>(t : Trie<K, V>, k : Key<K>, k_eq : (K, K) -> Bool) : (Trie<K, V>, ?V) = replace(t, k, k_eq, null);\n\n  /// Remove the given key's value in the trie,\n  /// and only if successful, do the success continuation,\n  /// otherwise, return the failure value.\n  public func removeThen<K, V, X>(\n    t : Trie<K, V>,\n    k : Key<K>,\n    k_eq : (K, K) -> Bool,\n    success : (Trie<K, V>, V) -> X,\n    fail : () -> X\n  ) : X {\n    let (t2, ov) = replace(t, k, k_eq, null);\n    switch ov {\n      case null { /* no prior value; failure to remove */ fail() };\n      case (?v) { success(t2, v) }\n    }\n  };\n\n  /// remove the given key-key pair's value in the 2D trie; return the\n  /// new trie, and the prior value, if any.\n  public func remove2D<K1, K2, V>(\n    t : Trie2D<K1, K2, V>,\n    k1 : Key<K1>,\n    k1_eq : (K1, K1) -> Bool,\n    k2 : Key<K2>,\n    k2_eq : (K2, K2) -> Bool\n  ) : (Trie2D<K1, K2, V>, ?V) = switch (find(t, k1, k1_eq)) {\n    case null { (t, null) };\n    case (?inner) {\n      let (updated_inner, ov) = remove(inner, k2, k2_eq);\n      let (updated_outer, _) = put(t, k1, k1_eq, updated_inner);\n      (updated_outer, ov)\n    }\n  };\n\n  /// Remove the given key-key pair's value in the 3D trie; return the\n  /// new trie, and the prior value, if any.\n  public func remove3D<K1, K2, K3, V>(\n    t : Trie3D<K1, K2, K3, V>,\n    k1 : Key<K1>,\n    k1_eq : (K1, K1) -> Bool,\n    k2 : Key<K2>,\n    k2_eq : (K2, K2) -> Bool,\n    k3 : Key<K3>,\n    k3_eq : (K3, K3) -> Bool\n  ) : (Trie3D<K1, K2, K3, V>, ?V) = switch (find(t, k1, k1_eq)) {\n    case null { (t, null) };\n    case (?inner) {\n      let (updated_inner, ov) = remove2D(inner, k2, k2_eq, k3, k3_eq);\n      let (updated_outer, _) = put(t, k1, k1_eq, updated_inner);\n      (updated_outer, ov)\n    }\n  };\n\n  /// Like [`mergeDisjoint`](#mergedisjoint), except instead of merging a\n  /// pair, it merges the collection of dimension-2 sub-trees of a 2D\n  /// trie.\n  public func mergeDisjoint2D<K1, K2, V>(\n    t : Trie2D<K1, K2, V>,\n    _k1_eq : (K1, K1) -> Bool,\n    k2_eq : (K2, K2) -> Bool\n  ) : Trie<K2, V> = foldUp(\n    t,\n    func(t1 : Trie<K2, V>, t2 : Trie<K2, V>) : Trie<K2, V> = mergeDisjoint(t1, t2, k2_eq),\n    func(_ : K1, t : Trie<K2, V>) : Trie<K2, V> = t,\n    #empty\n  );\n\n}\n"},"Buffer.mo":{"content":"/// Class `Buffer<X>` provides a mutable list of elements of type `X`.\n/// It wraps a resizable underlying array and is comparable to `ArrayList` or `Vector` in other languages.\n///\n/// You can convert a buffer to a fixed-size array using `Buffer.toArray`, which is recommended for storing data in stable variables.\n///\n/// Like arrays, buffer elements are indexed from `0` to `size - 1`.\n///\n/// :::note Assumptions\n///\n/// Runtime and space complexity assumes that `combine`, `equal`, and other functions execute in `O(1)` time and space.\n///\n/// :::\n///\n/// :::note Size vs capacity\n///\n/// - `size`: Number of elements in the buffer.\n/// - `capacity`: Length of the underlying array.\n///\n/// The invariant `capacity >= size` always holds.\n/// :::\n///\n/// :::warning Performance caveat\n///\n/// Operations like `add` are amortized `O(1)` but can take `O(n)` in the worst case.\n/// For large buffers, these worst cases may exceed the cycle limit per message.\n/// Use with care when growing buffers dynamically.\n/// :::\n///\n/// :::info Constructor behavior\n///\n/// The `initCapacity` argument sets the initial capacity of the underlying array.\n///\n/// - When the capacity is exceeded, the array grows by a factor of 1.5.\n/// - When the buffer size drops below 1/4 of the capacity, it shrinks by a factor of 2.\n/// :::\n///\n/// Example:\n///\n/// ```motoko name=initialize\n/// import Buffer \"mo:base/Buffer\";\n///\n/// let buffer = Buffer.Buffer<Nat>(3); // Creates a new Buffer\n/// ```\n///\n/// | Runtime   | Space     |\n/// |-----------|-----------|\n/// | `O(initCapacity)` | `O(initCapacity)` |\n\nimport Prim \"mo:⛔\";\nimport Result \"Result\";\nimport Order \"Order\";\nimport Array \"Array\";\n\nmodule {\n  type Order = Order.Order;\n\n  // The following constants are used to manage the capacity.\n  // The length of `elements` is increased by `INCREASE_FACTOR` when capacity is reached.\n  // The length of `elements` is decreased by `DECREASE_FACTOR` when capacity is strictly less than\n  // `DECREASE_THRESHOLD`.\n\n  // INCREASE_FACTOR = INCREASE_FACTOR_NUME / INCREASE_FACTOR_DENOM (with floating point division)\n  // Keep INCREASE_FACTOR low to minimize cycle limit problem\n  private let INCREASE_FACTOR_NUME = 3;\n  private let INCREASE_FACTOR_DENOM = 2;\n  private let DECREASE_THRESHOLD = 4; // Don't decrease capacity too early to avoid thrashing\n  private let DECREASE_FACTOR = 2;\n  private let DEFAULT_CAPACITY = 8;\n\n  private func newCapacity(oldCapacity : Nat) : Nat {\n    if (oldCapacity == 0) {\n      1\n    } else {\n      // calculates ceil(oldCapacity * INCREASE_FACTOR) without floats\n      ((oldCapacity * INCREASE_FACTOR_NUME) + INCREASE_FACTOR_DENOM - 1) / INCREASE_FACTOR_DENOM\n    }\n  };\n\n  public class Buffer<X>(initCapacity : Nat) = this {\n    var _size : Nat = 0; // avoid name clash with `size()` method\n    var elements : [var ?X] = Prim.Array_init(initCapacity, null);\n\n    /// Returns the current number of elements in the buffer.\n    ///\n    /// Example:\n    ///\n    /// ```motoko include=initialize\n    /// buffer.size() // => 0\n    /// ```\n    ///\n    /// | Runtime   | Space     |\n    /// |-----------|-----------|\n    /// | `O(1)` | `O(1)` |\n    public func size() : Nat = _size;\n\n    /// Adds a single element to the end of the buffer, doubling\n    /// the size of the array if capacity is exceeded.\n    ///\n    /// Example:\n    ///\n    /// ```motoko include=initialize\n    /// buffer.add(0); // add 0 to buffer\n    /// buffer.add(1);\n    /// buffer.add(2);\n    /// buffer.add(3); // causes underlying array to increase in capacity\n    /// Buffer.toArray(buffer) // => [0, 1, 2, 3]\n    /// ```\n    ///\n    /// | Runtime (worst) | Runtime (amortized) | Space (worst) | Space (amortized) |\n    /// |------------------|----------------------|----------------|---------------------|\n    /// | `O(size)`           | `O(1)`               | `O(size)`         | `O(1)`              |\n    public func add(element : X) {\n      if (_size == elements.size()) {\n        reserve(newCapacity(elements.size()))\n      };\n      elements[_size] := ?element;\n      _size += 1\n    };\n\n    /// Returns the element at index `index`. Traps if  `index >= size`. Indexing is zero-based.\n    ///\n    /// Example:\n    ///\n    /// ```motoko include=initialize\n    /// buffer.add(10);\n    /// buffer.add(11);\n    /// buffer.get(0); // => 10\n    /// ```\n    ///\n    /// | Runtime   | Space     |\n    /// |-----------|-----------|\n    /// | `O(1)` | `O(1)` |\n    public func get(index : Nat) : X {\n      switch (elements[index]) {\n        case (?element) element;\n        case null Prim.trap(\"Buffer index out of bounds in get\")\n      }\n    };\n\n    /// Returns the element at index `index` as an option.\n    /// Returns `null` when `index >= size`. Indexing is zero-based.\n    ///\n    /// Example:\n    ///\n    /// ```motoko include=initialize\n    /// buffer.add(10);\n    /// buffer.add(11);\n    /// let x = buffer.getOpt(0); // => ?10\n    /// let y = buffer.getOpt(2); // => null\n    /// ```\n    ///\n    /// | Runtime   | Space     |\n    /// |-----------|-----------|\n    /// | `O(1)` | `O(1)` |\n\n\n    public func getOpt(index : Nat) : ?X {\n      if (index < _size) {\n        elements[index]\n      } else {\n        null\n      }\n    };\n    /// ```motoko include=initialize\n    /// buffer.add(10);\n    /// buffer.put(0, 20); // overwrites 10 at index 0 with 20\n    /// Buffer.toArray(buffer) // => [20]\n    /// ```\n    ///\n    /// | Runtime   | Space     |\n    /// |-----------|-----------|\n    /// | `O(1)` | `O(1)` |\n    ///\n    public func put(index : Nat, element : X) {\n      if (index >= _size) {\n        Prim.trap \"Buffer index out of bounds in put\"\n      };\n      elements[index] := ?element\n    };\n\n    /// Removes and returns the last item in the buffer or `null` if\n    /// the buffer is empty.\n    ///\n    /// Example:\n    ///\n    /// ```motoko include=initialize\n    /// buffer.add(10);\n    /// buffer.add(11);\n    /// buffer.removeLast(); // => ?11\n    /// ```\n    ///\n    /// | Runtime (worst) | Runtime (amortized) | Space (worst) | Space (amortized) |\n    /// |------------------|----------------------|----------------|---------------------|\n    /// | `O(size)`           | `O(1)`               | `O(size)`         | `O(1)`              |\n    ///\n    public func removeLast() : ?X {\n      if (_size == 0) {\n        return null\n      };\n\n      _size -= 1;\n      let lastElement = elements[_size];\n      elements[_size] := null;\n\n      if (_size < elements.size() / DECREASE_THRESHOLD) {\n        // FIXME should this new capacity be a function of _size\n        // instead of the current capacity? E.g. _size * INCREASE_FACTOR\n        reserve(elements.size() / DECREASE_FACTOR)\n      };\n\n      lastElement\n    };\n\n    /// Removes and returns the element at `index` from the buffer.\n    /// All elements with index > `index` are shifted one position to the left.\n    /// This may cause a downsizing of the array.\n    ///\n    /// Traps if index >= size.\n    ///\n    /// :::warning Inefficient pattern\n    ///\n    /// Repeated removal of elements using this method is inefficient and may indicate that a different data structure would better suit your use case.\n    /// :::\n    ///\n    /// Example:\n    ///\n    /// ```motoko include=initialize\n    /// buffer.add(10);\n    /// buffer.add(11);\n    /// buffer.add(12);\n    /// let x = buffer.remove(1); // evaluates to 11. 11 no longer in list.\n    /// Buffer.toArray(buffer) // => [10, 12]\n    /// ```\n    ///\n    /// | Runtime (worst) | Runtime (amortized) | Space (worst) | Space (amortized) |\n    /// |------------------|----------------------|----------------|---------------------|\n    /// | `O(size)`           |-               | `O(size)`         | `O(1)`              |\n    public func remove(index : Nat) : X {\n      if (index >= _size) {\n        Prim.trap \"Buffer index out of bounds in remove\"\n      };\n\n      let element = elements[index];\n\n      // copy elements to new array and shift over in one pass\n      if ((_size - 1) : Nat < elements.size() / DECREASE_THRESHOLD) {\n        let elements2 = Prim.Array_init<?X>(elements.size() / DECREASE_FACTOR, null);\n\n        var i = 0;\n        var j = 0;\n        label l while (i < _size) {\n          if (i == index) {\n            i += 1;\n            continue l\n          };\n\n          elements2[j] := elements[i];\n          i += 1;\n          j += 1\n        };\n        elements := elements2\n      } else {\n        // just shift over elements\n        var i = index;\n        while (i < (_size - 1 : Nat)) {\n          elements[i] := elements[i + 1];\n          i += 1\n        };\n        elements[_size - 1] := null\n      };\n\n      _size -= 1;\n\n      switch (element) {\n        case (?element) {\n          element\n        };\n        case null {\n          Prim.trap \"Malformed buffer in remove\"\n        }\n      }\n    };\n\n    /// Resets the buffer. Capacity is set to 8.\n    ///\n    /// Example:\n    ///\n    /// ```motoko include=initialize\n    /// buffer.add(10);\n    /// buffer.add(11);\n    /// buffer.add(12);\n    /// buffer.clear(); // buffer is now empty\n    /// Buffer.toArray(buffer) // => []\n    /// ```\n    ///\n    /// | Runtime   | Space     |\n    /// |-----------|-----------|\n    /// | `O(1)` | `O(1)` |\n    public func clear() {\n      _size := 0;\n      reserve(DEFAULT_CAPACITY)\n    };\n\n    /// Removes all elements from the buffer for which the predicate returns false.\n    /// The predicate is given both the index of the element and the element itself.\n    /// This may cause a downsizing of the array.\n    ///\n    /// Example:\n    ///\n    /// ```motoko include=initialize\n    /// buffer.add(10);\n    /// buffer.add(11);\n    /// buffer.add(12);\n    /// buffer.filterEntries(func(_, x) = x % 2 == 0); // only keep even elements\n    /// Buffer.toArray(buffer) // => [10, 12]\n    /// ```\n    ///\n    /// | Runtime (worst) | Runtime (amortized) | Space (worst) | Space (amortized) |\n    /// |------------------|----------------------|----------------|---------------------|\n    /// | `O(size)`           | -               | `O(size)`         | `O(1)`              |\n    ///\n    public func filterEntries(predicate : (Nat, X) -> Bool) {\n      var numRemoved = 0;\n      let keep = Prim.Array_tabulate<Bool>(\n        _size,\n        func i {\n          switch (elements[i]) {\n            case (?element) {\n              if (predicate(i, element)) {\n                true\n              } else {\n                numRemoved += 1;\n                false\n              }\n            };\n            case null {\n              Prim.trap \"Malformed buffer in filter()\"\n            }\n          }\n        }\n      );\n\n      let capacity = elements.size();\n\n      if ((_size - numRemoved : Nat) < capacity / DECREASE_THRESHOLD) {\n        let elements2 = Prim.Array_init<?X>(capacity / DECREASE_FACTOR, null);\n\n        var i = 0;\n        var j = 0;\n        while (i < _size) {\n          if (keep[i]) {\n            elements2[j] := elements[i];\n            i += 1;\n            j += 1\n          } else {\n            i += 1\n          }\n        };\n\n        elements := elements2\n      } else {\n        var i = 0;\n        var j = 0;\n        while (i < _size) {\n          if (keep[i]) {\n            elements[j] := elements[i];\n            i += 1;\n            j += 1\n          } else {\n            i += 1\n          }\n        };\n\n        while (j < _size) {\n          elements[j] := null;\n          j += 1\n        }\n      };\n\n      _size -= numRemoved\n    };\n\n    /// Returns the capacity of the buffer (the length of the underlying array).\n    ///\n    /// Example:\n    ///\n    /// ```motoko include=initialize\n    /// let buffer = Buffer.Buffer<Nat>(2); // underlying array has capacity 2\n    /// buffer.add(10);\n    /// let c1 = buffer.capacity(); // => 2\n    /// buffer.add(11);\n    /// buffer.add(12); // causes capacity to increase by factor of 1.5\n    /// let c2 = buffer.capacity(); // => 3\n    /// ```\n    ///\n    /// | Runtime   | Space     |\n    /// |-----------|-----------|\n    /// | `O(1)` | `O(1)` |\n    public func capacity() : Nat = elements.size();\n\n    /// Changes the capacity to `capacity`. Traps if `capacity` < `size`.\n    ///\n    /// ```motoko include=initialize\n    /// buffer.reserve(4);\n    /// buffer.add(10);\n    /// buffer.add(11);\n    /// buffer.capacity(); // => 4\n    /// ```\n    ///\n    /// | Runtime   | Space     |\n    /// |-----------|-----------|\n    /// | `O(capacity)` | `O(capacity)` |\n    public func reserve(capacity : Nat) {\n      if (capacity < _size) {\n        Prim.trap \"capacity must be >= size in reserve\"\n      };\n\n      let elements2 = Prim.Array_init<?X>(capacity, null);\n\n      var i = 0;\n      while (i < _size) {\n        elements2[i] := elements[i];\n        i += 1\n      };\n      elements := elements2\n    };\n\n    /// Adds all elements in buffer `b` to this buffer.\n    ///\n    /// ```motoko include=initialize\n    /// let buffer1 = Buffer.Buffer<Nat>(2);\n    /// let buffer2 = Buffer.Buffer<Nat>(2);\n    /// buffer1.add(10);\n    /// buffer1.add(11);\n    /// buffer2.add(12);\n    /// buffer2.add(13);\n    /// buffer1.append(buffer2); // adds elements from buffer2 to buffer1\n    /// Buffer.toArray(buffer1) // => [10, 11, 12, 13]\n    /// ```\n    ///\n    /// | Runtime (worst) | Runtime (amortized) | Space (worst) | Space (amortized) |\n    /// |------------------|----------------------|----------------|---------------------|\n    /// | `O(size1 + size2)`           | `O(size2)`              | `O(size1 +size2)`         | `O(1)`              |\n\n    public func append(buffer2 : Buffer<X>) {\n      let size2 = buffer2.size();\n      // Make sure you only allocate a new array at most once\n      if (_size + size2 > elements.size()) {\n        // FIXME would be nice to have a tabulate for var arrays here\n        reserve(newCapacity(_size + size2))\n      };\n      var i = 0;\n      while (i < size2) {\n        elements[_size + i] := buffer2.getOpt i;\n        i += 1\n      };\n\n      _size += size2\n    };\n\n    /// Inserts `element` at `index`, shifts all elements to the right of\n    /// `index` over by one index. Traps if `index` is greater than size.\n    ///\n    /// ```motoko include=initialize\n    /// let buffer1 = Buffer.Buffer<Nat>(2);\n    /// let buffer2 = Buffer.Buffer<Nat>(2);\n    /// buffer.add(10);\n    /// buffer.add(11);\n    /// buffer.insert(1, 9);\n    /// Buffer.toArray(buffer) // => [10, 9, 11]\n    /// ```\n    ///\n    /// | Runtime (worst) | Runtime (amortized) | Space (worst) | Space (amortized) |\n    /// |------------------|----------------------|----------------|---------------------|\n    /// | `O(size)`           | -               | `O(size)`         | `O(1)`              |\n    public func insert(index : Nat, element : X) {\n      if (index > _size) {\n        Prim.trap \"Buffer index out of bounds in insert\"\n      };\n      let capacity = elements.size();\n\n      if (_size + 1 > capacity) {\n        let capacity = elements.size();\n        let elements2 = Prim.Array_init<?X>(newCapacity capacity, null);\n        var i = 0;\n        while (i < _size + 1) {\n          if (i < index) {\n            elements2[i] := elements[i]\n          } else if (i == index) {\n            elements2[i] := ?element\n          } else {\n            elements2[i] := elements[i - 1]\n          };\n\n          i += 1\n        };\n        elements := elements2\n      } else {\n        var i : Nat = _size;\n        while (i > index) {\n          elements[i] := elements[i - 1];\n          i -= 1\n        };\n        elements[index] := ?element\n      };\n\n      _size += 1\n    };\n\n    /// Inserts `buffer2` at `index`, and shifts all elements to the right of\n    /// `index` over by size2. Traps if `index` is greater than size.\n    ///\n    /// ```motoko include=initialize\n    /// let buffer1 = Buffer.Buffer<Nat>(2);\n    /// let buffer2 = Buffer.Buffer<Nat>(2);\n    /// buffer1.add(10);\n    /// buffer1.add(11);\n    /// buffer2.add(12);\n    /// buffer2.add(13);\n    /// buffer1.insertBuffer(1, buffer2);\n    /// Buffer.toArray(buffer1) // => [10, 12, 13, 11]\n    /// ```\n    ///\n    /// | Runtime (worst) | Runtime (amortized) | Space (worst) | Space (amortized) |\n    /// |------------------|----------------------|----------------|---------------------|\n    /// | `O(size)`           | -             | `O(size1 +size2)`         | `O(1)`              |\n    public func insertBuffer(index : Nat, buffer2 : Buffer<X>) {\n      if (index > _size) {\n        Prim.trap \"Buffer index out of bounds in insertBuffer\"\n      };\n\n      let size2 = buffer2.size();\n      let capacity = elements.size();\n\n      // copy elements to new array and shift over in one pass\n      if (_size + size2 > capacity) {\n        let elements2 = Prim.Array_init<?X>(newCapacity(_size + size2), null);\n        var i = 0;\n        for (element in elements.vals()) {\n          if (i == index) {\n            i += size2\n          };\n          elements2[i] := element;\n          i += 1\n        };\n\n        i := 0;\n        while (i < size2) {\n          elements2[i + index] := buffer2.getOpt(i);\n          i += 1\n        };\n        elements := elements2\n      } // just insert\n      else {\n        var i = index;\n        while (i < index + size2) {\n          if (i < _size) {\n            elements[i + size2] := elements[i]\n          };\n          elements[i] := buffer2.getOpt(i - index);\n\n          i += 1\n        }\n      };\n\n      _size += size2\n    };\n\n    /// Sorts the elements in the buffer according to `compare`.\n    /// Sort is deterministic, stable, and in-place.\n    ///\n    /// ```motoko include=initialize\n    /// import Nat \"mo:base/Nat\";\n    ///\n    /// buffer.add(11);\n    /// buffer.add(12);\n    /// buffer.add(10);\n    /// buffer.sort(Nat.compare);\n    /// Buffer.toArray(buffer) // => [10, 11, 12]\n    /// ```\n    ///\n    /// | Runtime   | Space     |\n    /// |-----------|-----------|\n    /// | `O(size * log(size))` | `O(size)` |\n    public func sort(compare : (X, X) -> Order.Order) {\n      // Stable merge sort in a bottom-up iterative style\n      if (_size == 0) {\n        return\n      };\n      let scratchSpace = Prim.Array_init<?X>(_size, null);\n\n      let sizeDec = _size - 1 : Nat;\n      var currSize = 1; // current size of the subarrays being merged\n      // when the current size == size, the array has been merged into a single sorted array\n      while (currSize < _size) {\n        var leftStart = 0; // selects the current left subarray being merged\n        while (leftStart < sizeDec) {\n          let mid : Nat = if (leftStart + currSize - 1 : Nat < sizeDec) {\n            leftStart + currSize - 1\n          } else { sizeDec };\n          let rightEnd : Nat = if (leftStart + (2 * currSize) - 1 : Nat < sizeDec) {\n            leftStart + (2 * currSize) - 1\n          } else { sizeDec };\n\n          // Merge subarrays elements[leftStart...mid] and elements[mid+1...rightEnd]\n          var left = leftStart;\n          var right = mid + 1;\n          var nextSorted = leftStart;\n          while (left < mid + 1 and right < rightEnd + 1) {\n            let leftOpt = elements[left];\n            let rightOpt = elements[right];\n            switch (leftOpt, rightOpt) {\n              case (?leftElement, ?rightElement) {\n                switch (compare(leftElement, rightElement)) {\n                  case (#less or #equal) {\n                    scratchSpace[nextSorted] := leftOpt;\n                    left += 1\n                  };\n                  case (#greater) {\n                    scratchSpace[nextSorted] := rightOpt;\n                    right += 1\n                  }\n                }\n              };\n              case (_, _) {\n                // only sorting non-null items\n                Prim.trap \"Malformed buffer in sort\"\n              }\n            };\n            nextSorted += 1\n          };\n          while (left < mid + 1) {\n            scratchSpace[nextSorted] := elements[left];\n            nextSorted += 1;\n            left += 1\n          };\n          while (right < rightEnd + 1) {\n            scratchSpace[nextSorted] := elements[right];\n            nextSorted += 1;\n            right += 1\n          };\n\n          // Copy over merged elements\n          var i = leftStart;\n          while (i < rightEnd + 1) {\n            elements[i] := scratchSpace[i];\n            i += 1\n          };\n\n          leftStart += 2 * currSize\n        };\n        currSize *= 2\n      }\n    };\n\n    /// Returns an Iterator (`Iter`) over the elements of this buffer.\n    /// Iterator provides a single method `next()`, which returns\n    /// elements in order, or `null` when out of elements to iterate over.\n    ///\n    /// ```motoko include=initialize\n    /// buffer.add(10);\n    /// buffer.add(11);\n    /// buffer.add(12);\n    ///\n    /// var sum = 0;\n    /// for (element in buffer.vals()) {\n    ///  sum += element;\n    /// };\n    /// sum // => 33\n    /// ```\n    ///\n    /// | Runtime   | Space     |\n    /// |-----------|-----------|\n    /// | `O(1)` | `O(1)` |\n    public func vals() : { next : () -> ?X } = object {\n      // FIXME either handle modification to underlying list\n      // or explicitly warn users in documentation\n      var nextIndex = 0;\n      public func next() : ?X {\n        if (nextIndex >= _size) {\n          return null\n        };\n        let nextElement = elements[nextIndex];\n        nextIndex += 1;\n        nextElement\n      }\n    };\n\n    // FOLLOWING METHODS ARE DEPRECATED\n\n    /// @deprecated Use the static library function instead of this instance method.\n    public func clone() : Buffer<X> {\n      let newBuffer = Buffer<X>(elements.size());\n      for (element in vals()) {\n        newBuffer.add(element)\n      };\n      newBuffer\n    };\n\n    /// @deprecated Use the static library function instead of this instance method.\n    public func toArray() : [X] =\n    // immutable clone of array\n    Prim.Array_tabulate<X>(\n      _size,\n      func(i : Nat) : X { get i }\n    );\n\n    /// @deprecated Use the static library function instead of this instance method.\n    public func toVarArray() : [var X] {\n      if (_size == 0) { [var] } else {\n        let newArray = Prim.Array_init<X>(_size, get 0);\n        var i = 0;\n        for (element in vals()) {\n          newArray[i] := element;\n          i += 1\n        };\n        newArray\n      }\n    }\n  };\n\n  /// Returns true if and only if the buffer is empty.\n  ///\n  /// Example:\n  ///\n  /// ```motoko include=initialize\n  /// buffer.add(2);\n  /// buffer.add(0);\n  /// buffer.add(3);\n  /// Buffer.isEmpty(buffer); // => false\n  /// ```\n  ///\n  /// ```motoko include=initialize\n  /// Buffer.isEmpty(buffer); // => true\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(1)` | `O(1)` |\n  public func isEmpty<X>(buffer : Buffer<X>) : Bool = buffer.size() == 0;\n\n  /// Returns true if `buffer` contains `element` with respect to equality\n  /// defined by `equal`.\n  ///\n  /// Example:\n  ///\n  /// ```motoko include=initialize\n  /// import Nat \"mo:base/Nat\";\n  ///\n  /// buffer.add(2);\n  /// buffer.add(0);\n  /// buffer.add(3);\n  /// Buffer.contains<Nat>(buffer, 2, Nat.equal); // => true\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size)` | `O(1)` |\n  public func contains<X>(buffer : Buffer<X>, element : X, equal : (X, X) -> Bool) : Bool {\n    for (current in buffer.vals()) {\n      if (equal(current, element)) {\n        return true\n      }\n    };\n\n    false\n  };\n\n  /// Returns a copy of `buffer`, with the same capacity.\n  ///\n  /// Example:\n  ///\n  /// ```motoko include=initialize\n  /// buffer.add(1);\n  ///\n  /// let clone = Buffer.clone(buffer);\n  /// Buffer.toArray(clone); // => [1]\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size)` | `O(size)` |\n  public func clone<X>(buffer : Buffer<X>) : Buffer<X> {\n    let newBuffer = Buffer<X>(buffer.capacity());\n    for (element in buffer.vals()) {\n      newBuffer.add(element)\n    };\n    newBuffer\n  };\n\n  /// Finds the greatest element in `buffer` defined by `compare`.\n  /// Returns `null` if `buffer` is empty.\n  ///\n  /// Example:\n  ///\n  /// ```motoko include=initialize\n  /// import Nat \"mo:base/Nat\";\n  ///\n  /// buffer.add(1);\n  /// buffer.add(2);\n  ///\n  /// Buffer.max(buffer, Nat.compare); // => ?2\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size)` | `O(1)` |\n  public func max<X>(buffer : Buffer<X>, compare : (X, X) -> Order) : ?X {\n    if (buffer.size() == 0) {\n      return null\n    };\n\n    var maxSoFar = buffer.get(0);\n    for (current in buffer.vals()) {\n      switch (compare(current, maxSoFar)) {\n        case (#greater) {\n          maxSoFar := current\n        };\n        case _ {}\n      }\n    };\n\n    ?maxSoFar\n  };\n\n  /// Finds the least element in `buffer` defined by `compare`.\n  /// Returns `null` if `buffer` is empty.\n  ///\n  /// Example:\n  ///\n  /// ```motoko include=initialize\n  /// import Nat \"mo:base/Nat\";\n  ///\n  /// buffer.add(1);\n  /// buffer.add(2);\n  ///\n  /// Buffer.min(buffer, Nat.compare); // => ?1\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size)` | `O(1)` |\n  public func min<X>(buffer : Buffer<X>, compare : (X, X) -> Order) : ?X {\n    if (buffer.size() == 0) {\n      return null\n    };\n\n    var minSoFar = buffer.get(0);\n    for (current in buffer.vals()) {\n      switch (compare(current, minSoFar)) {\n        case (#less) {\n          minSoFar := current\n        };\n        case _ {}\n      }\n    };\n\n    ?minSoFar\n  };\n\n  /// Defines equality for two buffers, using `equal` to recursively compare elements in the\n  /// buffers. Returns true if the two buffers are of the same size, and `equal`\n  /// evaluates to true for every pair of elements in the two buffers of the same\n  /// index.\n  ///\n  /// Example:\n  ///\n  /// ```motoko include=initialize\n  /// import Nat \"mo:base/Nat\";\n  ///\n  /// let buffer1 = Buffer.Buffer<Nat>(2);\n  /// buffer1.add(1);\n  /// buffer1.add(2);\n  ///\n  /// let buffer2 = Buffer.Buffer<Nat>(5);\n  /// buffer2.add(1);\n  /// buffer2.add(2);\n  ///\n  /// Buffer.equal(buffer1, buffer2, Nat.equal); // => true\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size)` | `O(1)` |\n  public func equal<X>(buffer1 : Buffer<X>, buffer2 : Buffer<X>, equal : (X, X) -> Bool) : Bool {\n    let size1 = buffer1.size();\n\n    if (size1 != buffer2.size()) {\n      return false\n    };\n\n    var i = 0;\n    while (i < size1) {\n      if (not equal(buffer1.get(i), buffer2.get(i))) {\n        return false\n      };\n      i += 1\n    };\n\n    true\n  };\n\n  /// Defines comparison for two buffers, using `compare` to recursively compare elements in the\n  /// buffers. Comparison is defined lexicographically.\n  ///\n  /// Example:\n  ///\n  /// ```motoko include=initialize\n  /// import Nat \"mo:base/Nat\";\n  ///\n  /// let buffer1 = Buffer.Buffer<Nat>(2);\n  /// buffer1.add(1);\n  /// buffer1.add(2);\n  ///\n  /// let buffer2 = Buffer.Buffer<Nat>(3);\n  /// buffer2.add(3);\n  /// buffer2.add(4);\n  ///\n  /// Buffer.compare<Nat>(buffer1, buffer2, Nat.compare); // => #less\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size)` | `O(1)` |\n  public func compare<X>(buffer1 : Buffer<X>, buffer2 : Buffer<X>, compare : (X, X) -> Order.Order) : Order.Order {\n    let size1 = buffer1.size();\n    let size2 = buffer2.size();\n    let minSize = if (size1 < size2) { size1 } else { size2 };\n\n    var i = 0;\n    while (i < minSize) {\n      switch (compare(buffer1.get(i), buffer2.get(i))) {\n        case (#less) {\n          return #less\n        };\n        case (#greater) {\n          return #greater\n        };\n        case _ {}\n      };\n      i += 1\n    };\n\n    if (size1 < size2) {\n      #less\n    } else if (size1 == size2) {\n      #equal\n    } else {\n      #greater\n    }\n  };\n\n  /// Creates a textual representation of `buffer`, using `toText` to recursively\n  /// convert the elements into Text.\n  ///\n  /// Example:\n  ///\n  /// ```motoko include=initialize\n  /// import Nat \"mo:base/Nat\";\n  ///\n  /// buffer.add(1);\n  /// buffer.add(2);\n  /// buffer.add(3);\n  /// buffer.add(4);\n  ///\n  /// Buffer.toText(buffer, Nat.toText); // => \"[1, 2, 3, 4]\"\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size)` | `O(size)` |\n\n  public func toText<X>(buffer : Buffer<X>, toText : X -> Text) : Text {\n    let size : Int = buffer.size();\n    var i = 0;\n    var text = \"\";\n    while (i < size - 1) {\n      text := text # toText(buffer.get(i)) # \", \"; // Text implemented as rope\n      i += 1\n    };\n    if (size > 0) {\n      // avoid the trailing comma\n      text := text # toText(buffer.get(i))\n    };\n\n    \"[\" # text # \"]\"\n  };\n\n  /// Hashes `buffer` using `hash` to hash the underlying elements.\n  /// The deterministic hash function is a function of the elements in the `buffer`, as well\n  /// as their ordering.\n  ///\n  /// Example:\n  ///\n  /// ```motoko include=initialize\n  /// import Hash \"mo:base/Hash\";\n  ///\n  /// buffer.add(1);\n  /// buffer.add(2);\n  /// buffer.add(3);\n  /// buffer.add(1000);\n  ///\n  /// Buffer.hash<Nat>(buffer, Hash.hash); // => 2_872_640_342\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size)` | `O(1)` |\n  public func hash<X>(buffer : Buffer<X>, hash : X -> Nat32) : Nat32 {\n    let size = buffer.size();\n    var i = 0;\n    var accHash : Nat32 = 0;\n\n    while (i < size) {\n      accHash := Prim.intToNat32Wrap(i) ^ accHash ^ hash(buffer.get(i));\n      i += 1\n    };\n\n    accHash\n  };\n\n  /// Finds the first index of `element` in `buffer` using equality of elements defined\n  /// by `equal`. Returns `null` if `element` is not found.\n  ///\n  /// Example:\n  ///\n  /// ```motoko include=initialize\n  /// import Nat \"mo:base/Nat\";\n  ///\n  /// buffer.add(1);\n  /// buffer.add(2);\n  /// buffer.add(3);\n  /// buffer.add(4);\n  ///\n  /// Buffer.indexOf<Nat>(3, buffer, Nat.equal); // => ?2\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size)` | `O(size)` |\n  public func indexOf<X>(element : X, buffer : Buffer<X>, equal : (X, X) -> Bool) : ?Nat {\n    let size = buffer.size();\n    var i = 0;\n    while (i < size) {\n      if (equal(buffer.get(i), element)) {\n        return ?i\n      };\n      i += 1\n    };\n\n    null\n  };\n\n  /// Finds the last index of `element` in `buffer` using equality of elements defined\n  /// by `equal`. Returns `null` if `element` is not found.\n  ///\n  /// Example:\n  ///\n  /// ```motoko include=initialize\n  /// import Nat \"mo:base/Nat\";\n  ///\n  /// buffer.add(1);\n  /// buffer.add(2);\n  /// buffer.add(3);\n  /// buffer.add(4);\n  /// buffer.add(2);\n  /// buffer.add(2);\n  ///\n  /// Buffer.lastIndexOf<Nat>(2, buffer, Nat.equal); // => ?5\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size)` | `O(size)` |\n  public func lastIndexOf<X>(element : X, buffer : Buffer<X>, equal : (X, X) -> Bool) : ?Nat {\n    let size = buffer.size();\n    if (size == 0) {\n      return null\n    };\n    var i = size;\n    while (i >= 1) {\n      i -= 1;\n      if (equal(buffer.get(i), element)) {\n        return ?i\n      }\n    };\n\n    null\n  };\n\n  /// Searches for `subBuffer` in `buffer`, and returns the starting index if it is found.\n  ///\n  /// Example:\n  ///\n  /// ```motoko include=initialize\n  /// import Nat \"mo:base/Nat\";\n  ///\n  /// buffer.add(1);\n  /// buffer.add(2);\n  /// buffer.add(3);\n  /// buffer.add(4);\n  /// buffer.add(5);\n  /// buffer.add(6);\n  ///\n  /// let sub = Buffer.Buffer<Nat>(2);\n  /// sub.add(4);\n  /// sub.add(5);\n  /// sub.add(6);\n  ///\n  /// Buffer.indexOfBuffer<Nat>(sub, buffer, Nat.equal); // => ?3\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size of buffer + size of subBuffer)` | `O(size of subBuffer)` |\n  public func indexOfBuffer<X>(subBuffer : Buffer<X>, buffer : Buffer<X>, equal : (X, X) -> Bool) : ?Nat {\n    // Uses the KMP substring search algorithm\n    // Implementation from: https://www.educative.io/answers/what-is-the-knuth-morris-pratt-algorithm\n    let size = buffer.size();\n    let subSize = subBuffer.size();\n    if (subSize > size or subSize == 0) {\n      return null\n    };\n\n    // precompute lps\n    let lps = Prim.Array_init<Nat>(subSize, 0);\n    var i = 0;\n    var j = 1;\n\n    while (j < subSize) {\n      if (equal(subBuffer.get(i), subBuffer.get(j))) {\n        i += 1;\n        lps[j] := i;\n        j += 1\n      } else if (i == 0) {\n        lps[j] := 0;\n        j += 1\n      } else {\n        i := lps[i - 1]\n      }\n    };\n\n    // start search\n    i := 0;\n    j := 0;\n    let subSizeDec = subSize - 1 : Nat; // hoisting loop invariant\n    while (i < subSize and j < size) {\n      if (equal(subBuffer.get(i), buffer.get(j)) and i == subSizeDec) {\n        return ?(j - i)\n      } else if (equal(subBuffer.get(i), buffer.get(j))) {\n        i += 1;\n        j += 1\n      } else {\n        if (i != 0) {\n          i := lps[i - 1]\n        } else {\n          j += 1\n        }\n      }\n    };\n\n    null\n  };\n\n  /// Similar to `indexOf`, but runs in logarithmic time. Assumes that `buffer` is sorted.\n  /// Behavior is undefined if `buffer` is not sorted. Uses `compare` to\n  /// perform the search. Returns an index of `element` if it is found.\n  ///\n  /// Example:\n  ///\n  /// ```motoko include=initialize\n  /// import Nat \"mo:base/Nat\";\n  ///\n  /// buffer.add(1);\n  /// buffer.add(4);\n  /// buffer.add(5);\n  /// buffer.add(6);\n  ///\n  /// Buffer.binarySearch<Nat>(5, buffer, Nat.compare); // => ?2\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(log(size))` | `O(1)` |\n  public func binarySearch<X>(element : X, buffer : Buffer<X>, compare : (X, X) -> Order.Order) : ?Nat {\n    var low = 0;\n    var high = buffer.size();\n\n    while (low < high) {\n      let mid = (low + high) / 2;\n      let current = buffer.get(mid);\n      switch (compare(element, current)) {\n        case (#equal) {\n          return ?mid\n        };\n        case (#less) {\n          high := mid\n        };\n        case (#greater) {\n          low := mid + 1\n        }\n      }\n    };\n\n    null\n  };\n\n  /// Returns the sub-buffer of `buffer` starting at index `start`\n  /// of length `length`. Traps if `start` is out of bounds, or `start + length`\n  /// is greater than the size of `buffer`.\n  ///\n  /// Example:\n  ///\n  /// ```motoko include=initialize\n  /// import Nat \"mo:base/Nat\";\n  ///\n  /// buffer.add(1);\n  /// buffer.add(2);\n  /// buffer.add(3);\n  /// buffer.add(4);\n  /// buffer.add(5);\n  /// buffer.add(6);\n  ///\n  /// let sub = Buffer.subBuffer(buffer, 3, 2);\n  /// Buffer.toText(sub, Nat.toText); // => [4, 5]\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(length)` | `O(length)` |\n  public func subBuffer<X>(buffer : Buffer<X>, start : Nat, length : Nat) : Buffer<X> {\n    let size = buffer.size();\n    let end = start + length; // exclusive\n    if (start >= size or end > size) {\n      Prim.trap \"Buffer index out of bounds in subBuffer\"\n    };\n\n    let newBuffer = Buffer<X>(newCapacity length);\n\n    var i = start;\n    while (i < end) {\n      newBuffer.add(buffer.get(i));\n\n      i += 1\n    };\n\n    newBuffer\n  };\n\n  /// Checks if `subBuffer` is a sub-Buffer of `buffer`. Uses `equal` to\n  /// compare elements.\n  ///\n  /// Example:\n  ///\n  /// ```motoko include=initialize\n  /// import Nat \"mo:base/Nat\";\n  ///\n  /// buffer.add(1);\n  /// buffer.add(2);\n  /// buffer.add(3);\n  /// buffer.add(4);\n  /// buffer.add(5);\n  /// buffer.add(6);\n  ///\n  /// let sub = Buffer.Buffer<Nat>(2);\n  /// sub.add(2);\n  /// sub.add(3);\n  /// Buffer.isSubBufferOf(sub, buffer, Nat.equal); // => true\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size of subBuffer + size of buffer)` | `O(size of subBuffer)` |\n  public func isSubBufferOf<X>(subBuffer : Buffer<X>, buffer : Buffer<X>, equal : (X, X) -> Bool) : Bool {\n    switch (indexOfBuffer(subBuffer, buffer, equal)) {\n      case null subBuffer.size() == 0;\n      case _ true\n    }\n  };\n\n  /// Checks if `subBuffer` is a strict subBuffer of `buffer`, i.e. `subBuffer` must be\n  /// strictly contained inside both the first and last indices of `buffer`.\n  /// Uses `equal` to compare elements.\n  ///\n  /// Example:\n  ///\n  /// ```motoko include=initialize\n  /// import Nat \"mo:base/Nat\";\n  ///\n  /// buffer.add(1);\n  /// buffer.add(2);\n  /// buffer.add(3);\n  /// buffer.add(4);\n  ///\n  /// let sub = Buffer.Buffer<Nat>(2);\n  /// sub.add(2);\n  /// sub.add(3);\n  /// Buffer.isStrictSubBufferOf(sub, buffer, Nat.equal); // => true\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size of subBuffer + size of buffer)` | `O(size of subBuffer)` |\n  public func isStrictSubBufferOf<X>(subBuffer : Buffer<X>, buffer : Buffer<X>, equal : (X, X) -> Bool) : Bool {\n    let subBufferSize = subBuffer.size();\n\n    switch (indexOfBuffer(subBuffer, buffer, equal)) {\n      case (?index) {\n        index != 0 and index != (buffer.size() - subBufferSize : Nat) // enforce strictness\n      };\n      case null {\n        subBufferSize == 0 and subBufferSize != buffer.size()\n      }\n    }\n  };\n\n  /// Returns the prefix of `buffer` of length `length`. Traps if `length`\n  /// is greater than the size of `buffer`.\n  ///\n  /// Example:\n  ///\n  /// ```motoko include=initialize\n  /// import Nat \"mo:base/Nat\";\n  ///\n  /// buffer.add(1);\n  /// buffer.add(2);\n  /// buffer.add(3);\n  /// buffer.add(4);\n  ///\n  /// let pre = Buffer.prefix(buffer, 3); // => [1, 2, 3]\n  /// Buffer.toText(pre, Nat.toText);\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(length)` | `O(length)` |\n  ///\n  public func prefix<X>(buffer : Buffer<X>, length : Nat) : Buffer<X> {\n    let size = buffer.size();\n    if (length > size) {\n      Prim.trap \"Buffer index out of bounds in prefix\"\n    };\n\n    let newBuffer = Buffer<X>(newCapacity length);\n\n    var i = 0;\n    while (i < length) {\n      newBuffer.add(buffer.get(i));\n      i += 1\n    };\n\n    newBuffer\n  };\n\n  /// Checks if `prefix` is a prefix of `buffer`. Uses `equal` to\n  /// compare elements.\n  ///\n  /// Example:\n  ///\n  /// ```motoko include=initialize\n  /// import Nat \"mo:base/Nat\";\n  ///\n  /// buffer.add(1);\n  /// buffer.add(2);\n  /// buffer.add(3);\n  /// buffer.add(4);\n  ///\n  /// let pre = Buffer.Buffer<Nat>(2);\n  /// pre.add(1);\n  /// pre.add(2);\n  /// Buffer.isPrefixOf(pre, buffer, Nat.equal); // => true\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size of prefix)` | `O(size of prefix)` |\n  public func isPrefixOf<X>(prefix : Buffer<X>, buffer : Buffer<X>, equal : (X, X) -> Bool) : Bool {\n    let sizePrefix = prefix.size();\n    if (buffer.size() < sizePrefix) {\n      return false\n    };\n\n    var i = 0;\n    while (i < sizePrefix) {\n      if (not equal(buffer.get(i), prefix.get(i))) {\n        return false\n      };\n\n      i += 1\n    };\n\n    return true\n  };\n\n  /// Checks if `prefix` is a strict prefix of `buffer`. Uses `equal` to\n  /// compare elements.\n  ///\n  /// Example:\n  ///\n  /// ```motoko include=initialize\n  /// import Nat \"mo:base/Nat\";\n  ///\n  /// buffer.add(1);\n  /// buffer.add(2);\n  /// buffer.add(3);\n  /// buffer.add(4);\n  ///\n  /// let pre = Buffer.Buffer<Nat>(3);\n  /// pre.add(1);\n  /// pre.add(2);\n  /// pre.add(3);\n  /// Buffer.isStrictPrefixOf(pre, buffer, Nat.equal); // => true\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size of prefix)` | `O(size of prefix)` |\n  public func isStrictPrefixOf<X>(prefix : Buffer<X>, buffer : Buffer<X>, equal : (X, X) -> Bool) : Bool {\n    if (buffer.size() <= prefix.size()) {\n      return false\n    };\n    isPrefixOf(prefix, buffer, equal)\n  };\n\n  /// Returns the suffix of `buffer` of length `length`.\n  /// Traps if `length`is greater than the size of `buffer`.\n  ///\n  /// Example:\n  ///\n  /// ```motoko include=initialize\n  /// import Nat \"mo:base/Nat\";\n  ///\n  /// buffer.add(1);\n  /// buffer.add(2);\n  /// buffer.add(3);\n  /// buffer.add(4);\n  ///\n  /// let suf = Buffer.suffix(buffer, 3); // => [2, 3, 4]\n  /// Buffer.toText(suf, Nat.toText);\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(length)` | `O(length)` |\n  public func suffix<X>(buffer : Buffer<X>, length : Nat) : Buffer<X> {\n    let size = buffer.size();\n\n    if (length > size) {\n      Prim.trap \"Buffer index out of bounds in suffix\"\n    };\n\n    let newBuffer = Buffer<X>(newCapacity length);\n\n    var i = size - length : Nat;\n    while (i < size) {\n      newBuffer.add(buffer.get(i));\n\n      i += 1\n    };\n\n    newBuffer\n  };\n\n  /// Checks if `suffix` is a suffix of `buffer`. Uses `equal` to compare\n  /// elements.\n  ///\n  /// Example:\n  ///\n  /// ```motoko include=initialize\n  /// import Nat \"mo:base/Nat\";\n  ///\n  /// buffer.add(1);\n  /// buffer.add(2);\n  /// buffer.add(3);\n  /// buffer.add(4);\n  ///\n  /// let suf = Buffer.Buffer<Nat>(3);\n  /// suf.add(2);\n  /// suf.add(3);\n  /// suf.add(4);\n  /// Buffer.isSuffixOf(suf, buffer, Nat.equal); // => true\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(length of suffix)` | `O(length of suffix)` |\n  public func isSuffixOf<X>(suffix : Buffer<X>, buffer : Buffer<X>, equal : (X, X) -> Bool) : Bool {\n    let suffixSize = suffix.size();\n    let bufferSize = buffer.size();\n    if (bufferSize < suffixSize) {\n      return false\n    };\n\n    var i = bufferSize;\n    var j = suffixSize;\n    while (i >= 1 and j >= 1) {\n      i -= 1;\n      j -= 1;\n      if (not equal(buffer.get(i), suffix.get(j))) {\n        return false\n      }\n    };\n\n    return true\n  };\n\n  /// Checks if `suffix` is a strict suffix of `buffer`. Uses `equal` to compare\n  /// elements.\n  ///\n  /// Example:\n  /// ```motoko include=initialize\n  /// import Nat \"mo:base/Nat\";\n  ///\n  /// buffer.add(1);\n  /// buffer.add(2);\n  /// buffer.add(3);\n  /// buffer.add(4);\n  ///\n  /// let suf = Buffer.Buffer<Nat>(3);\n  /// suf.add(2);\n  /// suf.add(3);\n  /// suf.add(4);\n  /// Buffer.isStrictSuffixOf(suf, buffer, Nat.equal); // => true\n  /// ```\n  ///\n/// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(length)` | `O(length)` |\n  public func isStrictSuffixOf<X>(suffix : Buffer<X>, buffer : Buffer<X>, equal : (X, X) -> Bool) : Bool {\n    if (buffer.size() <= suffix.size()) {\n      return false\n    };\n    isSuffixOf(suffix, buffer, equal)\n  };\n\n  /// Returns true if every element in `buffer` satisfies `predicate`.\n  ///\n  /// Example:\n  ///\n  /// ```motoko include=initialize\n  /// buffer.add(2);\n  /// buffer.add(3);\n  /// buffer.add(4);\n  ///\n  /// Buffer.forAll<Nat>(buffer, func x { x > 1 }); // => true\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size)` | `O(1)` |\n  public func forAll<X>(buffer : Buffer<X>, predicate : X -> Bool) : Bool {\n    for (element in buffer.vals()) {\n      if (not predicate element) {\n        return false\n      }\n    };\n\n    true\n  };\n\n  /// Returns true if some element in `buffer` satisfies `predicate`.\n  ///\n  /// Example:\n  ///\n  /// ```motoko include=initialize\n  /// buffer.add(2);\n  /// buffer.add(3);\n  /// buffer.add(4);\n  ///\n  /// Buffer.forSome<Nat>(buffer, func x { x > 3 }); // => true\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size)` | `O(1)` |\n  public func forSome<X>(buffer : Buffer<X>, predicate : X -> Bool) : Bool {\n    for (element in buffer.vals()) {\n      if (predicate element) {\n        return true\n      }\n    };\n\n    false\n  };\n\n  /// Returns true if no element in `buffer` satisfies `predicate`.\n  ///\n  /// Example:\n  ///\n  /// ```motoko include=initialize\n  /// buffer.add(2);\n  /// buffer.add(3);\n  /// buffer.add(4);\n  ///\n  /// Buffer.forNone<Nat>(buffer, func x { x == 0 }); // => true\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size)` | `O(1)` |\n  public func forNone<X>(buffer : Buffer<X>, predicate : X -> Bool) : Bool {\n    for (element in buffer.vals()) {\n      if (predicate element) {\n        return false\n      }\n    };\n\n    true\n  };\n\n  /// Creates an `array` containing elements from `buffer`.\n  ///\n  /// Example:\n  ///\n  /// ```motoko include=initialize\n  /// buffer.add(1);\n  /// buffer.add(2);\n  /// buffer.add(3);\n  ///\n  /// Buffer.toArray<Nat>(buffer); // => [1, 2, 3]\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size)` | `O(size)` |\n  public func toArray<X>(buffer : Buffer<X>) : [X] =\n  // immutable clone of array\n  Prim.Array_tabulate<X>(\n    buffer.size(),\n    func(i : Nat) : X { buffer.get(i) }\n  );\n\n  /// Creates a mutable array containing elements from `buffer`.\n  ///\n  /// Example:\n  ///\n  /// ```motoko include=initialize\n  /// buffer.add(1);\n  /// buffer.add(2);\n  /// buffer.add(3);\n  ///\n  /// Buffer.toVarArray<Nat>(buffer); // => [1, 2, 3]\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size)` | `O(size)` |\n  public func toVarArray<X>(buffer : Buffer<X>) : [var X] {\n    let size = buffer.size();\n    if (size == 0) { [var] } else {\n      let newArray = Prim.Array_init<X>(size, buffer.get(0));\n      var i = 1;\n      while (i < size) {\n        newArray[i] := buffer.get(i);\n        i += 1\n      };\n      newArray\n    }\n  };\n\n  /// Creates a `buffer` containing elements from `array`.\n  ///\n  /// Example:\n  ///\n  /// ```motoko include=initialize\n  /// import Nat \"mo:base/Nat\";\n  ///\n  /// let array = [2, 3];\n  ///\n  /// let buf = Buffer.fromArray<Nat>(array); // => [2, 3]\n  /// Buffer.toText(buf, Nat.toText);\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size)` | `O(size)` |\n  public func fromArray<X>(array : [X]) : Buffer<X> {\n    // When returning new buffer, if possible, set the capacity\n    // to the capacity of the old buffer. Otherwise, return them\n    // at 2/3 capacity (like in this case). Alternative is to\n    // calculate what the size would be if the elements were\n    // sequentially added using `add`. This current strategy (2/3)\n    // is the upper bound of that calculation (if the last element\n    // added caused a capacity increase).\n    let newBuffer = Buffer<X>(newCapacity(array.size()));\n\n    for (element in array.vals()) {\n      newBuffer.add(element)\n    };\n\n    newBuffer\n  };\n\n  /// Creates a `buffer` containing elements from `array`.\n  ///\n  /// Example:\n  ///\n  /// ```motoko include=initialize\n  /// import Nat \"mo:base/Nat\";\n  ///\n  /// let array = [var 1, 2, 3];\n  ///\n  /// let buf = Buffer.fromVarArray<Nat>(array); // => [1, 2, 3]\n  /// Buffer.toText(buf, Nat.toText);\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size)` | `O(size)` |\n  public func fromVarArray<X>(array : [var X]) : Buffer<X> {\n    let newBuffer = Buffer<X>(newCapacity(array.size()));\n\n    for (element in array.vals()) {\n      newBuffer.add(element)\n    };\n\n    newBuffer\n  };\n\n  /// Creates a `buffer` containing elements from `iter`.\n  ///\n  /// Example:\n  ///\n  /// ```motoko include=initialize\n  /// import Nat \"mo:base/Nat\";\n  ///\n  /// let array = [1, 1, 1];\n  /// let iter = array.vals();\n  ///\n  /// let buf = Buffer.fromIter<Nat>(iter); // => [1, 1, 1]\n  /// Buffer.toText(buf, Nat.toText);\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size)` | `O(size)` |\n  public func fromIter<X>(iter : { next : () -> ?X }) : Buffer<X> {\n    let newBuffer = Buffer<X>(DEFAULT_CAPACITY); // can't get size from `iter`\n\n    for (element in iter) {\n      newBuffer.add(element)\n    };\n\n    newBuffer\n  };\n\n  /// Reallocates the array underlying `buffer` such that capacity == size.\n  ///\n  /// Example:\n  ///\n  /// ```motoko include=initialize\n  /// let buffer = Buffer.Buffer<Nat>(10);\n  /// buffer.add(1);\n  /// buffer.add(2);\n  /// buffer.add(3);\n  ///\n  /// Buffer.trimToSize<Nat>(buffer);\n  /// buffer.capacity(); // => 3\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size)` | `O(size)` |\n  public func trimToSize<X>(buffer : Buffer<X>) {\n    let size = buffer.size();\n    if (size < buffer.capacity()) {\n      buffer.reserve(size)\n    }\n  };\n\n  /// Creates a new `buffer` by applying `f` to each element in `buffer`.\n  ///\n  /// Example:\n  ///\n  /// ```motoko include=initialize\n  /// import Nat \"mo:base/Nat\";\n  ///\n  /// buffer.add(1);\n  /// buffer.add(2);\n  /// buffer.add(3);\n  ///\n  /// let newBuf = Buffer.map<Nat, Nat>(buffer, func (x) { x + 1 });\n  /// Buffer.toText(newBuf, Nat.toText); // => [2, 3, 4]\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size)` | `O(size)` |\n  public func map<X, Y>(buffer : Buffer<X>, f : X -> Y) : Buffer<Y> {\n    let newBuffer = Buffer<Y>(buffer.capacity());\n\n    for (element in buffer.vals()) {\n      newBuffer.add(f element)\n    };\n\n    newBuffer\n  };\n\n  /// Applies `f` to each element in `buffer`.\n  ///\n  /// Example:\n  ///\n  /// ```motoko include=initialize\n  /// import Nat \"mo:base/Nat\";\n  /// import Debug \"mo:base/Debug\";\n  ///\n  /// buffer.add(1);\n  /// buffer.add(2);\n  /// buffer.add(3);\n  ///\n  /// Buffer.iterate<Nat>(buffer, func (x) {\n  ///   Debug.print(Nat.toText(x)); // prints each element in buffer\n  /// });\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size)` | `O(size)` |\n  ///\n  public func iterate<X>(buffer : Buffer<X>, f : X -> ()) {\n    for (element in buffer.vals()) {\n      f element\n    }\n  };\n\n  /// Applies `f` to each element in `buffer` and its index.\n  ///\n  /// Example:\n  ///\n  /// ```motoko include=initialize\n  /// import Nat \"mo:base/Nat\";\n  /// buffer.add(1);\n  /// buffer.add(2);\n  /// buffer.add(3);\n  ///\n  /// let newBuf = Buffer.mapEntries<Nat, Nat>(buffer, func (x, i) { x + i + 1 });\n  /// Buffer.toText(newBuf, Nat.toText); // => [2, 4, 6]\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size)` | `O(size)` |\n  public func mapEntries<X, Y>(buffer : Buffer<X>, f : (Nat, X) -> Y) : Buffer<Y> {\n    let newBuffer = Buffer<Y>(buffer.capacity());\n\n    var i = 0;\n    let size = buffer.size();\n    while (i < size) {\n      newBuffer.add(f(i, buffer.get(i)));\n      i += 1\n    };\n\n    newBuffer\n  };\n\n  /// Creates a new buffer by applying `f` to each element in `buffer`,\n  /// and keeping all non-null elements.\n  ///\n  /// Example:\n  ///\n  /// ```motoko include=initialize\n  /// import Nat \"mo:base/Nat\";\n  /// buffer.add(1);\n  /// buffer.add(2);\n  /// buffer.add(3);\n  ///\n  /// let newBuf = Buffer.mapFilter<Nat, Nat>(buffer, func (x) {\n  ///  if (x > 1) {\n  ///    ?(x * 2);\n  ///  } else {\n  ///    null;\n  ///  }\n  /// });\n  /// Buffer.toText(newBuf, Nat.toText); // => [4, 6]\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size)` | `O(size)` |\n  public func mapFilter<X, Y>(buffer : Buffer<X>, f : X -> ?Y) : Buffer<Y> {\n    let newBuffer = Buffer<Y>(buffer.capacity());\n\n    for (element in buffer.vals()) {\n      switch (f element) {\n        case (?element) {\n          newBuffer.add(element)\n        };\n        case _ {}\n      }\n    };\n\n    newBuffer\n  };\n\n  /// Creates a new buffer by applying `f` to each element in `buffer`.\n  /// If any invocation of `f` produces an `#err`, returns an `#err`. Otherwise\n  /// Returns an `#ok` containing the new buffer.\n  ///\n  /// Example:\n  ///\n  /// ```motoko include=initialize\n  /// import Result \"mo:base/Result\";\n  /// buffer.add(1);\n  /// buffer.add(2);\n  /// buffer.add(3);\n  ///\n  /// let result = Buffer.mapResult<Nat, Nat, Text>(buffer, func (k) {\n  ///  if (k > 0) {\n  ///    #ok(k);\n  ///  } else {\n  ///    #err(\"One or more elements are zero.\");\n  ///  }\n  /// });\n  ///\n  /// Result.mapOk<Buffer.Buffer<Nat>, [Nat], Text>(result, func buffer = Buffer.toArray(buffer)) // => #ok([1, 2, 3])\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size)` | `O(size)` |\n  public func mapResult<X, Y, E>(buffer : Buffer<X>, f : X -> Result.Result<Y, E>) : Result.Result<Buffer<Y>, E> {\n    let newBuffer = Buffer<Y>(buffer.capacity());\n\n    for (element in buffer.vals()) {\n      switch (f element) {\n        case (#ok result) {\n          newBuffer.add(result)\n        };\n        case (#err e) {\n          return #err e\n        }\n      }\n    };\n\n    #ok newBuffer\n  };\n\n  /// Creates a new `buffer` by applying `k` to each element in `buffer`,\n  /// and concatenating the resulting buffers in order. This operation\n  /// is similar to what in other functional languages is known as monadic bind.\n  ///\n  /// Example:\n  ///\n  /// ```motoko include=initialize\n  /// import Nat \"mo:base/Nat\";\n  /// buffer.add(1);\n  /// buffer.add(2);\n  /// buffer.add(3);\n  ///\n  /// let chain = Buffer.chain<Nat, Nat>(buffer, func (x) {\n  /// let b = Buffer.Buffer<Nat>(2);\n  /// b.add(x);\n  /// b.add(x * 2);\n  /// return b;\n  /// });\n  /// Buffer.toText(chain, Nat.toText); // => [1, 2, 2, 4, 3, 6]\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size)` | `O(size)` |\n  public func chain<X, Y>(buffer : Buffer<X>, k : X -> Buffer<Y>) : Buffer<Y> {\n    let newBuffer = Buffer<Y>(buffer.size() * 4);\n\n    for (element in buffer.vals()) {\n      newBuffer.append(k element)\n    };\n\n    newBuffer\n  };\n\n  /// Collapses the elements in `buffer` into a single value by starting with `base`\n  /// and progessively combining elements into `base` with `combine`. Iteration runs\n  /// left to right.\n  ///\n  /// Example:\n  ///\n  /// ```motoko include=initialize\n  /// import Nat \"mo:base/Nat\";\n  /// buffer.add(1);\n  /// buffer.add(2);\n  /// buffer.add(3);\n  ///\n  /// Buffer.foldLeft<Text, Nat>(buffer, \"\", func (acc, x) { acc # Nat.toText(x)}); // => \"123\"\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size)` | `O(1)` |\n  public func foldLeft<A, X>(buffer : Buffer<X>, base : A, combine : (A, X) -> A) : A {\n    var accumulation = base;\n\n    for (element in buffer.vals()) {\n      accumulation := combine(accumulation, element)\n    };\n\n    accumulation\n  };\n\n  /// Collapses the elements in `buffer` into a single value by starting with `base`\n  /// and progessively combining elements into `base` with `combine`. Iteration runs\n  /// right to left.\n  ///\n  /// Example:\n  ///\n  /// ```motoko include=initialize\n  /// import Nat \"mo:base/Nat\";\n  /// buffer.add(1);\n  /// buffer.add(2);\n  /// buffer.add(3);\n  ///\n  /// Buffer.foldRight<Nat, Text>(buffer, \"\", func (x, acc) { Nat.toText(x) # acc }); // => \"123\"\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size)` | `O(1)` |\n  public func foldRight<X, A>(buffer : Buffer<X>, base : A, combine : (X, A) -> A) : A {\n    let size = buffer.size();\n    if (size == 0) {\n      return base\n    };\n    var accumulation = base;\n\n    var i = size;\n    while (i >= 1) {\n      i -= 1; // to avoid Nat underflow, subtract first and stop iteration at 1\n      accumulation := combine(buffer.get(i), accumulation)\n    };\n\n    accumulation\n  };\n\n  /// Returns the first element of `buffer`. Traps if `buffer` is empty.\n  ///\n  /// Example:\n  ///\n  /// ```motoko include=initialize\n  /// buffer.add(1);\n  /// buffer.add(2);\n  /// buffer.add(3);\n  ///\n  /// Buffer.first(buffer); // => 1\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(1)` | `O(1)` |\n  public func first<X>(buffer : Buffer<X>) : X = buffer.get(0);\n\n  /// Returns the last element of `buffer`. Traps if `buffer` is empty.\n  ///\n  /// Example:\n  /// ```motoko include=initialize\n  /// buffer.add(1);\n  /// buffer.add(2);\n  /// buffer.add(3);\n  ///\n  /// Buffer.last(buffer); // => 3\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(1)` | `O(1)` |\n  public func last<X>(buffer : Buffer<X>) : X = buffer.get(buffer.size() - 1);\n\n  /// Returns a new `buffer` with capacity and size 1, containing `element`.\n  ///\n  /// Example:\n  ///\n  /// ```motoko include=initialize\n  /// import Nat \"mo:base/Nat\";\n  ///\n  /// let buffer = Buffer.make<Nat>(1);\n  /// Buffer.toText(buffer, Nat.toText); // => [1]\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(1)` | `O(1)` |\n  public func make<X>(element : X) : Buffer<X> {\n    let newBuffer = Buffer<X>(1);\n    newBuffer.add(element);\n    newBuffer\n  };\n\n  /// Reverses the order of elements in `buffer`.\n  ///\n  /// Example:\n  /// ```motoko include=initialize\n  /// import Nat \"mo:base/Nat\";\n  ///\n  /// buffer.add(1);\n  /// buffer.add(2);\n  /// buffer.add(3);\n  ///\n  /// Buffer.reverse(buffer);\n  /// Buffer.toText(buffer, Nat.toText); // => [3, 2, 1]\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size)` | `O(1)` |\n  public func reverse<X>(buffer : Buffer<X>) {\n    let size = buffer.size();\n    if (size == 0) {\n      return\n    };\n\n    var i = 0;\n    var j = size - 1 : Nat;\n    var temp = buffer.get(0);\n    while (i < size / 2) {\n      temp := buffer.get(j);\n      buffer.put(j, buffer.get(i));\n      buffer.put(i, temp);\n      i += 1;\n      j -= 1\n    }\n  };\n\n  /// Merges two sorted buffers into a single sorted `buffer`, using `compare` to define\n  /// the ordering. The final ordering is stable. Behavior is undefined if either\n  /// `buffer1` or `buffer2` is not sorted.\n  ///\n  /// Example:\n  ///\n  /// ```motoko include=initialize\n  /// import Nat \"mo:base/Nat\";\n  ///\n  /// let buffer1 = Buffer.Buffer<Nat>(2);\n  /// buffer1.add(1);\n  /// buffer1.add(2);\n  /// buffer1.add(4);\n  ///\n  /// let buffer2 = Buffer.Buffer<Nat>(2);\n  /// buffer2.add(2);\n  /// buffer2.add(4);\n  /// buffer2.add(6);\n  ///\n  /// let merged = Buffer.merge<Nat>(buffer1, buffer2, Nat.compare);\n  /// Buffer.toText(merged, Nat.toText); // => [1, 2, 2, 4, 4, 6]\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size1 + size2)` | `O(size1 + size2)` |\n  public func merge<X>(buffer1 : Buffer<X>, buffer2 : Buffer<X>, compare : (X, X) -> Order) : Buffer<X> {\n    let size1 = buffer1.size();\n    let size2 = buffer2.size();\n\n    let newBuffer = Buffer<X>(newCapacity(size1 + size2));\n\n    var pointer1 = 0;\n    var pointer2 = 0;\n\n    while (pointer1 < size1 and pointer2 < size2) {\n      let current1 = buffer1.get(pointer1);\n      let current2 = buffer2.get(pointer2);\n\n      switch (compare(current1, current2)) {\n        case (#less) {\n          newBuffer.add(current1);\n          pointer1 += 1\n        };\n        case _ {\n          newBuffer.add(current2);\n          pointer2 += 1\n        }\n      }\n    };\n\n    while (pointer1 < size1) {\n      newBuffer.add(buffer1.get(pointer1));\n      pointer1 += 1\n    };\n\n    while (pointer2 < size2) {\n      newBuffer.add(buffer2.get(pointer2));\n      pointer2 += 1\n    };\n\n    newBuffer\n  };\n\n  /// Eliminates all duplicate elements in `buffer` as defined by `compare`.\n  /// Elimination is stable with respect to the original ordering of the elements.\n  ///\n  /// Example:\n  ///\n  /// ```motoko include=initialize\n  /// import Nat \"mo:base/Nat\";\n  ///\n  /// buffer.add(1);\n  /// buffer.add(2);\n  /// buffer.add(3);\n  /// buffer.add(1);\n  /// buffer.add(2);\n  /// buffer.add(3);\n  ///\n  /// Buffer.removeDuplicates<Nat>(buffer, Nat.compare);\n  /// Buffer.toText(buffer, Nat.toText); // => [1, 2, 3]\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size * log(size))` | `O(size)` |\n  public func removeDuplicates<X>(buffer : Buffer<X>, compare : (X, X) -> Order) {\n    let size = buffer.size();\n    let indices = Prim.Array_tabulate<(Nat, X)>(size, func i = (i, buffer.get(i)));\n    // Sort based on element, while carrying original index information\n    // This groups together the duplicate elements\n    let sorted = Array.sort<(Nat, X)>(indices, func(pair1, pair2) = compare(pair1.1, pair2.1));\n    let uniques = Buffer<(Nat, X)>(size);\n\n    // Iterate over elements\n    var i = 0;\n    while (i < size) {\n      var j = i;\n      // Iterate over duplicate elements, and find the smallest index among them (for stability)\n      var minIndex = sorted[j];\n      label duplicates while (j < (size - 1 : Nat)) {\n        let pair1 = sorted[j];\n        let pair2 = sorted[j + 1];\n        switch (compare(pair1.1, pair2.1)) {\n          case (#equal) {\n            if (pair2.0 < pair1.0) {\n              minIndex := pair2\n            };\n            j += 1\n          };\n          case _ {\n            break duplicates\n          }\n        }\n      };\n\n      uniques.add(minIndex);\n      i := j + 1\n    };\n\n    // resort based on original ordering and place back in buffer\n    uniques.sort(\n      func(pair1, pair2) {\n        if (pair1.0 < pair2.0) {\n          #less\n        } else if (pair1.0 == pair2.0) {\n          #equal\n        } else {\n          #greater\n        }\n      }\n    );\n\n    buffer.clear();\n    buffer.reserve(uniques.size());\n    for (element in uniques.vals()) {\n      buffer.add(element.1)\n    }\n  };\n\n  /// Splits `buffer` into a pair of buffers where all elements in the left\n  /// `buffer` satisfy `predicate` and all elements in the right `buffer` do not.\n  ///\n  /// Example:\n  ///\n  /// ```motoko include=initialize\n  /// import Nat \"mo:base/Nat\";\n  ///\n  /// buffer.add(1);\n  /// buffer.add(2);\n  /// buffer.add(3);\n  /// buffer.add(4);\n  /// buffer.add(5);\n  /// buffer.add(6);\n  ///\n  /// let partitions = Buffer.partition<Nat>(buffer, func (x) { x % 2 == 0 });\n  /// (Buffer.toArray(partitions.0), Buffer.toArray(partitions.1)) // => ([2, 4, 6], [1, 3, 5])\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size)` | `O(size)` |\n  public func partition<X>(buffer : Buffer<X>, predicate : X -> Bool) : (Buffer<X>, Buffer<X>) {\n    let size = buffer.size();\n    let trueBuffer = Buffer<X>(size);\n    let falseBuffer = Buffer<X>(size);\n\n    for (element in buffer.vals()) {\n      if (predicate element) {\n        trueBuffer.add(element)\n      } else {\n        falseBuffer.add(element)\n      }\n    };\n\n    (trueBuffer, falseBuffer)\n  };\n\n  /// Splits the buffer into two buffers at `index`, where the left buffer contains\n  /// all elements with indices less than `index`, and the right buffer contains all\n  /// elements with indices greater than or equal to `index`. Traps if `index` is out\n  /// of bounds.\n  ///\n  /// Example:\n  ///\n  /// ```motoko include=initialize\n  /// import Nat \"mo:base/Nat\";\n  ///\n  /// buffer.add(1);\n  /// buffer.add(2);\n  /// buffer.add(3);\n  /// buffer.add(4);\n  /// buffer.add(5);\n  /// buffer.add(6);\n  ///\n  /// let split = Buffer.split<Nat>(buffer, 3);\n  /// (Buffer.toArray(split.0), Buffer.toArray(split.1)) // => ([1, 2, 3], [4, 5, 6])\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size)` | `O(size)` |\n\n  public func split<X>(buffer : Buffer<X>, index : Nat) : (Buffer<X>, Buffer<X>) {\n    let size = buffer.size();\n\n    if (index < 0 or index > size) {\n      Prim.trap \"Index out of bounds in split\"\n    };\n\n    let buffer1 = Buffer<X>(newCapacity index);\n    let buffer2 = Buffer<X>(newCapacity(size - index));\n\n    var i = 0;\n    while (i < index) {\n      buffer1.add(buffer.get(i));\n      i += 1\n    };\n    while (i < size) {\n      buffer2.add(buffer.get(i));\n      i += 1\n    };\n\n    (buffer1, buffer2)\n  };\n\n  /// Breaks up `buffer` into buffers of size `size`. The last chunk may\n  /// have less than `size` elements if the number of elements is not divisible\n  /// by the chunk size.\n  ///\n  /// Example:\n  ///\n  /// ```motoko include=initialize\n  /// import Nat \"mo:base/Nat\";\n  ///\n  /// buffer.add(1);\n  /// buffer.add(2);\n  /// buffer.add(3);\n  /// buffer.add(4);\n  /// buffer.add(5);\n  /// buffer.add(6);\n  ///\n  /// let chunks = Buffer.chunk<Nat>(buffer, 3);\n  /// Buffer.toText<Buffer.Buffer<Nat>>(chunks, func buf = Buffer.toText(buf, Nat.toText)); // => [[1, 2, 3], [4, 5, 6]]\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(number of elements in buffer)` | `O(number of elements in buffer)` |\n  ///\n  public func chunk<X>(buffer : Buffer<X>, size : Nat) : Buffer<Buffer<X>> {\n    if (size == 0) {\n      Prim.trap \"Chunk size must be non-zero in chunk\"\n    };\n\n    // ceil(buffer.size() / size)\n    let newBuffer = Buffer<Buffer<X>>((buffer.size() + size - 1) / size);\n\n    var newInnerBuffer = Buffer<X>(newCapacity size);\n    var innerSize = 0;\n    for (element in buffer.vals()) {\n      if (innerSize == size) {\n        newBuffer.add(newInnerBuffer);\n        newInnerBuffer := Buffer<X>(newCapacity size);\n        innerSize := 0\n      };\n      newInnerBuffer.add(element);\n      innerSize += 1\n    };\n    if (innerSize > 0) {\n      newBuffer.add(newInnerBuffer)\n    };\n\n    newBuffer\n  };\n\n  /// Groups equal and adjacent elements in the list into sub lists.\n  ///\n  /// Example:\n  ///\n  /// ```motoko include=initialize\n  /// import Nat \"mo:base/Nat\";\n  ///\n  /// buffer.add(1);\n  /// buffer.add(2);\n  /// buffer.add(2);\n  /// buffer.add(4);\n  /// buffer.add(5);\n  /// buffer.add(5);\n  ///\n  /// let grouped = Buffer.groupBy<Nat>(buffer, func (x, y) { x == y });\n  /// Buffer.toText<Buffer.Buffer<Nat>>(grouped, func buf = Buffer.toText(buf, Nat.toText)); // => [[1], [2, 2], [4], [5, 5]]\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size)` | `O(size)` |\n  public func groupBy<X>(buffer : Buffer<X>, equal : (X, X) -> Bool) : Buffer<Buffer<X>> {\n    let size = buffer.size();\n    let newBuffer = Buffer<Buffer<X>>(size);\n    if (size == 0) {\n      return newBuffer\n    };\n\n    var i = 0;\n    var baseElement = buffer.get(0);\n    var newInnerBuffer = Buffer<X>(size);\n    while (i < size) {\n      let element = buffer.get(i);\n\n      if (equal(baseElement, element)) {\n        newInnerBuffer.add(element)\n      } else {\n        newBuffer.add(newInnerBuffer);\n        baseElement := element;\n        newInnerBuffer := Buffer<X>(size - i);\n        newInnerBuffer.add(element)\n      };\n      i += 1\n    };\n    if (newInnerBuffer.size() > 0) {\n      newBuffer.add(newInnerBuffer)\n    };\n\n    newBuffer\n  };\n\n  /// Flattens the `buffer` of buffers into a single `buffer`.\n  ///\n  /// Example:\n  ///\n  /// ```motoko include=initialize\n  /// import Nat \"mo:base/Nat\";\n  ///\n  /// let buffer = Buffer.Buffer<Buffer.Buffer<Nat>>(1);\n  ///\n  /// let inner1 = Buffer.Buffer<Nat>(2);\n  /// inner1.add(1);\n  /// inner1.add(2);\n  ///\n  /// let inner2 = Buffer.Buffer<Nat>(2);\n  /// inner2.add(3);\n  /// inner2.add(4);\n  ///\n  /// buffer.add(inner1);\n  /// buffer.add(inner2);\n  /// // buffer = [[1, 2], [3, 4]]\n  ///\n  /// let flat = Buffer.flatten<Nat>(buffer);\n  /// Buffer.toText<Nat>(flat, Nat.toText); // => [1, 2, 3, 4]\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(number of elements in buffer)` | `O(number of elements in buffer)` |\n  public func flatten<X>(buffer : Buffer<Buffer<X>>) : Buffer<X> {\n    let size = buffer.size();\n    if (size == 0) {\n      return Buffer<X>(0)\n    };\n\n    let newBuffer = Buffer<X>(\n      if (buffer.get(0).size() != 0) {\n        newCapacity(buffer.get(0).size() * size)\n      } else {\n        newCapacity(size)\n      }\n    );\n\n    for (innerBuffer in buffer.vals()) {\n      for (innerElement in innerBuffer.vals()) {\n        newBuffer.add(innerElement)\n      }\n    };\n\n    newBuffer\n  };\n\n  /// Combines the two buffers into a single buffer of pairs, pairing together\n  /// elements with the same index. If one buffer is longer than the other, the\n  /// remaining elements from the longer buffer are not included.\n  ///\n  /// Example:\n  ///\n  /// ```motoko include=initialize\n  ///\n  /// let buffer1 = Buffer.Buffer<Nat>(2);\n  /// buffer1.add(1);\n  /// buffer1.add(2);\n  /// buffer1.add(3);\n  ///\n  /// let buffer2 = Buffer.Buffer<Nat>(2);\n  /// buffer2.add(4);\n  /// buffer2.add(5);\n  ///\n  /// let zipped = Buffer.zip(buffer1, buffer2);\n  /// Buffer.toArray(zipped); // => [(1, 4), (2, 5)]\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(min(size1, size2))` | `O(min(size1, size2))` |\n  public func zip<X, Y>(buffer1 : Buffer<X>, buffer2 : Buffer<Y>) : Buffer<(X, Y)> {\n    // compiler should pull lamda out as a static function since it is fully closed\n    zipWith<X, Y, (X, Y)>(buffer1, buffer2, func(x, y) = (x, y))\n  };\n\n  /// Combines the two buffers into a single buffer, pairing together\n  /// elements with the same index and combining them using `zip`. If\n  /// one buffer is longer than the other, the remaining elements from\n  /// the longer buffer are not included.\n  ///\n  /// Example:\n  ///\n  /// ```motoko include=initialize\n  ///\n  /// let buffer1 = Buffer.Buffer<Nat>(2);\n  /// buffer1.add(1);\n  /// buffer1.add(2);\n  /// buffer1.add(3);\n  ///\n  /// let buffer2 = Buffer.Buffer<Nat>(2);\n  /// buffer2.add(4);\n  /// buffer2.add(5);\n  /// buffer2.add(6);\n  ///\n  /// let zipped = Buffer.zipWith<Nat, Nat, Nat>(buffer1, buffer2, func (x, y) { x + y });\n  /// Buffer.toArray(zipped) // => [5, 7, 9]\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(min(size1, size2))` | `O(min(size1, size2))` |\n  ///\n  public func zipWith<X, Y, Z>(buffer1 : Buffer<X>, buffer2 : Buffer<Y>, zip : (X, Y) -> Z) : Buffer<Z> {\n    let size1 = buffer1.size();\n    let size2 = buffer2.size();\n    let minSize = if (size1 < size2) { size1 } else { size2 };\n\n    var i = 0;\n    let newBuffer = Buffer<Z>(newCapacity minSize);\n    while (i < minSize) {\n      newBuffer.add(zip(buffer1.get(i), buffer2.get(i)));\n      i += 1\n    };\n    newBuffer\n  };\n\n  /// Creates a new buffer taking elements in order from `buffer` until predicate\n  /// returns false.\n  ///\n  /// Example:\n  ///\n  /// ```motoko include=initialize\n  /// import Nat \"mo:base/Nat\";\n  ///\n  /// buffer.add(1);\n  /// buffer.add(2);\n  /// buffer.add(3);\n  ///\n  /// let newBuf = Buffer.takeWhile<Nat>(buffer, func (x) { x < 3 });\n  /// Buffer.toText(newBuf, Nat.toText); // => [1, 2]\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size)` | `O(size)` |\n  public func takeWhile<X>(buffer : Buffer<X>, predicate : X -> Bool) : Buffer<X> {\n    let newBuffer = Buffer<X>(buffer.size());\n\n    for (element in buffer.vals()) {\n      if (not predicate element) {\n        return newBuffer\n      };\n      newBuffer.add(element)\n    };\n\n    newBuffer\n  };\n\n  /// Creates a new buffer excluding elements in order from `buffer` until predicate\n  /// returns false.\n  ///\n  /// Example:\n  ///\n  /// ```motoko include=initialize\n  /// import Nat \"mo:base/Nat\";\n  ///\n  /// buffer.add(1);\n  /// buffer.add(2);\n  /// buffer.add(3);\n  ///\n  /// let newBuf = Buffer.dropWhile<Nat>(buffer, func x { x < 3 }); // => [3]\n  /// Buffer.toText(newBuf, Nat.toText);\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size)` | `O(size)` |\n  public func dropWhile<X>(buffer : Buffer<X>, predicate : X -> Bool) : Buffer<X> {\n    let size = buffer.size();\n    let newBuffer = Buffer<X>(size);\n\n    var i = 0;\n    var take = false;\n    label iter for (element in buffer.vals()) {\n      if (not (take or predicate element)) {\n        take := true\n      };\n      if (take) {\n        newBuffer.add(element)\n      }\n    };\n    newBuffer\n  }\n}\n"},"Deque.mo":{"content":"/// Double-ended queue (deque) of a generic element type `T`.\n///\n/// The interface of deques is purely functional, not imperative, and deques are immutable values.\n/// In particular, deque operations such as push and pop do not update their input deque but instead return the value of the modified deque, alongside any other data.\n/// The input deque is left unchanged.\n///\n/// Examples of use-cases:\n/// Queue (FIFO) by using `pushBack()` and `popFront()`.\n/// Stack (LIFO) by using `pushFront()` and `popFront()`.\n///\n/// A deque is internally implemented as two lists, a head access list and a (reversed) tail access list, that are dynamically size-balanced by splitting.\n///\n/// Construction: Create a new deque with the `empty<T>()` function.\n///\n/// :::note Performance characteristics\n///\n/// Push and pop operations have `O(1)` amortized cost and `O(n)` worst-case cost per call.\n/// Space usage follows the same pattern.\n/// `n` denotes the number of elements stored in the deque.\n/// :::\n\nimport List \"List\";\nimport P \"Prelude\";\n\nmodule {\n  type List<T> = List.List<T>;\n\n  /// Double-ended queue (deque) data type.\n  public type Deque<T> = (List<T>, List<T>);\n\n  /// Create a new empty deque.\n  ///\n  /// Example:\n  /// ```motoko\n  /// import Deque \"mo:base/Deque\";\n  ///\n  /// Deque.empty<Nat>()\n  /// ```\n  ///\n  /// | Runtime | Space |\n  /// |---------|--------|\n  /// | `O(1)`  | `O(1)` |\n\n  public func empty<T>() : Deque<T> { (List.nil(), List.nil()) };\n\n  /// Determine whether a deque is empty.\n  /// Returns true if `deque` is empty, otherwise `false`.\n  ///\n  /// Example:\n  /// ```motoko\n  /// import Deque \"mo:base/Deque\";\n  ///\n  /// let deque = Deque.empty<Nat>();\n  /// Deque.isEmpty(deque) // => true\n  /// ```\n  ///\n  /// | Runtime | Space |\n  /// |---------|--------|\n  /// | `O(1)`  | `O(1)` |\n  public func isEmpty<T>(deque : Deque<T>) : Bool {\n    switch deque {\n      case (f, r) { List.isNil(f) and List.isNil(r) }\n    }\n  };\n\n  func check<T>(q : Deque<T>) : Deque<T> {\n    switch q {\n      case (null, r) {\n        let (a, b) = List.split(List.size(r) / 2, r);\n        (List.reverse(b), a)\n      };\n      case (f, null) {\n        let (a, b) = List.split(List.size(f) / 2, f);\n        (a, List.reverse(b))\n      };\n      case q { q }\n    }\n  };\n\n  /// Insert a new element on the front end of a deque.\n  /// Returns the new deque with `element` in the front followed by the elements of `deque`.\n  ///\n  /// This may involve dynamic rebalancing of the two, internally used lists.\n  ///\n  /// Example:\n  /// ```motoko\n  /// import Deque \"mo:base/Deque\";\n  ///\n  /// Deque.pushFront(Deque.pushFront(Deque.empty<Nat>(), 2), 1) // deque with elements [1, 2]\n  /// ```\n  ///\n  /// | Runtime (worst) | Runtime (amortized) | Space (worst) | Space (amortized) |\n  /// |------------------|----------------------|----------------|---------------------|\n  /// | `O(n)`           | `O(1)`               | `O(n)`         | `O(1)`              |\n  ///\n  /// `n` denotes the number of elements stored in the deque.\n  public func pushFront<T>(deque : Deque<T>, element : T) : Deque<T> {\n    check(List.push(element, deque.0), deque.1)\n  };\n\n  /// Inspect the optional element on the front end of a deque.\n  /// Returns `null` if `deque` is empty. Otherwise, the front element of `deque`.\n  ///\n  /// Example:\n  /// ```motoko\n  /// import Deque \"mo:base/Deque\";\n  ///\n  /// let deque = Deque.pushFront(Deque.pushFront(Deque.empty<Nat>(), 2), 1);\n  /// Deque.peekFront(deque) // => ?1\n  /// ```\n  ///\n  /// | Runtime | Space |\n  /// |---------|--------|\n  /// | `O(1)`  | `O(1)` |\n  ///\n  public func peekFront<T>(deque : Deque<T>) : ?T {\n    switch deque {\n      case (?(x, _f), _r) { ?x };\n      case (null, ?(x, _r)) { ?x };\n      case _ { null }\n    }\n  };\n\n  /// Remove the element on the front end of a deque.\n  /// Returns `null` if `deque` is empty. Otherwise, it returns a pair of\n  /// the first element and a new deque that contains all the remaining elements of `deque`.\n  ///\n  /// This may involve dynamic rebalancing of the two, internally used lists.\n  ///\n  /// Example:\n  /// ```motoko\n  /// import Deque \"mo:base/Deque\";\n  /// import Debug \"mo:base/Debug\";\n  /// let initial = Deque.pushFront(Deque.pushFront(Deque.empty<Nat>(), 2), 1);\n  /// // initial deque with elements [1, 2]\n  /// let reduced = Deque.popFront(initial);\n  /// switch reduced {\n  ///   case null {\n  ///     Debug.trap \"Empty queue impossible\"\n  ///   };\n  ///   case (?result) {\n  ///     let removedElement = result.0; // 1\n  ///     let reducedDeque = result.1; // deque with element [2].\n  ///   }\n  /// }\n  /// ```\n  ///\n  /// | Runtime (worst) | Runtime (amortized) | Space (worst) | Space (amortized) |\n  /// |------------------|----------------------|----------------|---------------------|\n  /// | `O(n)`           | `O(1)`               | `O(n)`         | `O(1)`              |\n  public func popFront<T>(deque : Deque<T>) : ?(T, Deque<T>) {\n    switch deque {\n      case (?(x, f), r) { ?(x, check(f, r)) };\n      case (null, ?(x, r)) { ?(x, check(null, r)) };\n      case _ { null }\n    }\n  };\n\n  /// Insert a new element on the back end of a deque.\n  /// Returns the new deque with all the elements of `deque`, followed by `element` on the back.\n  ///\n  /// This may involve dynamic rebalancing of the two, internally used lists.\n  ///\n  /// Example:\n  /// ```motoko\n  /// import Deque \"mo:base/Deque\";\n  ///\n  /// Deque.pushBack(Deque.pushBack(Deque.empty<Nat>(), 1), 2) // deque with elements [1, 2]\n  /// ```\n  ///\n  /// | Runtime (worst) | Runtime (amortized) | Space (worst) | Space (amortized) |\n  /// |------------------|----------------------|----------------|---------------------|\n  /// | `O(n)`           | `O(1)`               | `O(n)`         | `O(1)`              |\n  ///\n  /// `n` denotes the number of elements stored in the deque.\n  public func pushBack<T>(deque : Deque<T>, element : T) : Deque<T> {\n    check(deque.0, List.push(element, deque.1))\n  };\n\n  /// Inspect the optional element on the back end of a deque.\n  /// Returns `null` if `deque` is empty. Otherwise, the back element of `deque`.\n  ///\n  /// Example:\n  /// ```motoko\n  /// import Deque \"mo:base/Deque\";\n  ///\n  /// let deque = Deque.pushBack(Deque.pushBack(Deque.empty<Nat>(), 1), 2);\n  /// Deque.peekBack(deque) // => ?2\n  /// ```\n  ///\n  /// | Runtime | Space |\n  /// |---------|--------|\n  /// | `O(1)`  | `O(1)` |\n  ///\n  ///\n  public func peekBack<T>(deque : Deque<T>) : ?T {\n    switch deque {\n      case (_f, ?(x, _r)) { ?x };\n      case (?(x, _r), null) { ?x };\n      case _ { null }\n    }\n  };\n\n  /// Remove the element on the back end of a deque.\n  /// Returns `null` if `deque` is empty. Otherwise, it returns a pair of\n  /// a new deque that contains the remaining elements of `deque`\n  /// and, as the second pair item, the removed back element.\n  ///\n  /// This may involve dynamic rebalancing of the two, internally used lists.\n  ///\n  /// Example:\n  /// ```motoko\n  /// import Deque \"mo:base/Deque\";\n  /// import Debug \"mo:base/Debug\";\n  ///\n  /// let initial = Deque.pushBack(Deque.pushBack(Deque.empty<Nat>(), 1), 2);\n  /// // initial deque with elements [1, 2]\n  /// let reduced = Deque.popBack(initial);\n  /// switch reduced {\n  ///   case null {\n  ///     Debug.trap \"Empty queue impossible\"\n  ///   };\n  ///   case (?result) {\n  ///     let reducedDeque = result.0; // deque with element [1].\n  ///     let removedElement = result.1; // 2\n  ///   }\n  /// }\n  /// ```\n  ///\n  /// | Runtime (worst) | Runtime (amortized) | Space (worst) | Space (amortized) |\n  /// |------------------|----------------------|----------------|---------------------|\n  /// | `O(n)`           | `O(1)`               | `O(n)`         | `O(1)`              |\n  public func popBack<T>(deque : Deque<T>) : ?(Deque<T>, T) {\n    switch deque {\n      case (f, ?(x, r)) { ?(check(f, r), x) };\n      case (?(x, f), null) { ?(check(f, null), x) };\n      case _ { null }\n    }\n  }\n}\n"},"ExperimentalStableMemory.mo":{"content":"/// Byte-level access to (virtual) _stable memory_.\n///\n/// :::warning Experimental module\n///\n/// As the name suggests, this library is experimental, subject to change, and may be replaced by safer alternatives in later versions of Motoko.\n/// Use at your own risk and discretion.\n/// :::\n///\n/// :::warning Deprecation notice\n///\n/// Use of `ExperimentalStableMemory` may be deprecated in the future.\n/// Consider using `Region.mo` for isolated memory regions.\n/// Isolated regions ensure that writing to one region does not affect unrelated state elsewhere.\n/// :::\n///\n/// This is a lightweight abstraction over IC _stable memory_ and supports persisting raw binary data across Motoko upgrades.\n/// It is fully compatible with Motoko's _stable variables_, which also use IC stable memory internally, but do not interfere with this API.\n///\n/// Memory is allocated using `grow(pages)`, sequentially and on demand, in units of 64KiB pages, starting with 0 allocated pages.\n/// New pages are zero-initialized.\n/// Growth is capped by a soft page limit set with the compile-time flag `--max-stable-pages <n>` (default: 65536, or 4GiB).\n///\n/// Each `load` reads from byte address `offset` in little-endian format using the natural bit-width of the type.\n/// Traps if reading beyond the allocated size.\n///\n/// Each `store` writes to byte address `offset` in little-endian format using the natural bit-width of the type.\n/// Traps if writing beyond the allocated size.\n///\n/// Text can be handled using `Text.decodeUtf8` and `Text.encodeUtf8` in combination with `loadBlob` and `storeBlob`.\n///\n/// The current page allocation and contents are preserved across upgrades.\n///\n/// :::note IC stable memory discrepancy\n///\n/// The IC’s reported stable memory size (`ic0.stable_size`) may exceed what Motoko’s `size()` returns.\n/// This and the growth cap exist to protect Motoko’s internal use of stable variables.\n/// If you're not using stable variables (or using them sparingly), you may increase `--max-stable-pages` toward the IC maximum (currently 64GiB).\n/// Even if not using stable variables, always reserve at least one page.\n/// :::\n///\n/// Usage:\n///\n/// ```motoko no-repl\n/// import StableMemory \"mo:base/ExperimentalStableMemory\";\n/// ```\n\nimport Prim \"mo:⛔\";\n\nmodule {\n\n  /// Current size of the stable memory, in pages.\n  /// Each page is 64KiB (65536 bytes).\n  /// Initially `0`.\n  /// Preserved across upgrades, together with contents of allocated\n  /// stable memory.\n  ///\n  /// Example:\n  /// ```motoko no-repl\n  /// let beforeSize = StableMemory.size();\n  /// ignore StableMemory.grow(10);\n  /// let afterSize = StableMemory.size();\n  /// afterSize - beforeSize // => 10\n  /// ```\n  public let size : () -> (pages : Nat64) = Prim.stableMemorySize;\n\n  /// Grow current `size` of stable memory by the given number of pages.\n  /// Each page is 64KiB (65536 bytes).\n  /// Returns the previous `size` when able to grow.\n  /// Returns `0xFFFF_FFFF_FFFF_FFFF` if remaining pages insufficient.\n  /// Every new page is zero-initialized, containing byte 0x00 at every offset.\n  /// Function `grow` is capped by a soft limit on `size` controlled by compile-time flag\n  ///  `--max-stable-pages <n>` (the default is 65536, or 4GiB).\n  ///\n  /// Example:\n  /// ```motoko no-repl\n  /// import Error \"mo:base/Error\";\n  ///\n  /// let beforeSize = StableMemory.grow(10);\n  /// if (beforeSize == 0xFFFF_FFFF_FFFF_FFFF) {\n  ///   throw Error.reject(\"Out of memory\");\n  /// };\n  /// let afterSize = StableMemory.size();\n  /// afterSize - beforeSize // => 10\n  /// ```\n  public let grow : (newPages : Nat64) -> (oldPages : Nat64) = Prim.stableMemoryGrow;\n\n  /// Returns a query that, when called, returns the number of bytes of (real) IC stable memory that would be\n  /// occupied by persisting its current stable variables before an upgrade.\n  /// This function may be used to monitor or limit real stable memory usage.\n  /// The query computes the estimate by running the first half of an upgrade, including any `preupgrade` system method.\n  /// Like any other query, its state changes are discarded so no actual upgrade (or other state change) takes place.\n  /// The query can only be called by the enclosing actor and will trap for other callers.\n  ///\n  /// Example:\n  /// ```motoko no-repl\n  /// actor {\n  ///   stable var state = \"\";\n  ///   public func example() : async Text {\n  ///     let memoryUsage = StableMemory.stableVarQuery();\n  ///     let beforeSize = (await memoryUsage()).size;\n  ///     state #= \"abcdefghijklmnopqrstuvwxyz\";\n  ///     let afterSize = (await memoryUsage()).size;\n  ///     debug_show (afterSize - beforeSize)\n  ///   };\n  /// };\n  /// ```\n  public let stableVarQuery : () -> (shared query () -> async { size : Nat64 }) = Prim.stableVarQuery;\n\n  /// Loads a `Nat32` value from stable memory at the given `offset`.\n  /// Traps on an out-of-bounds access.\n  ///\n  /// Example:\n  /// ```motoko no-repl\n  /// let offset = 0;\n  /// let value = 123;\n  /// StableMemory.storeNat32(offset, value);\n  /// StableMemory.loadNat32(offset) // => 123\n  /// ```\n  public let loadNat32 : (offset : Nat64) -> Nat32 = Prim.stableMemoryLoadNat32;\n\n  /// Stores a `Nat32` value in stable memory at the given `offset`.\n  /// Traps on an out-of-bounds access.\n  ///\n  /// Example:\n  /// ```motoko no-repl\n  /// let offset = 0;\n  /// let value = 123;\n  /// StableMemory.storeNat32(offset, value);\n  /// StableMemory.loadNat32(offset) // => 123\n  /// ```\n  public let storeNat32 : (offset : Nat64, value : Nat32) -> () = Prim.stableMemoryStoreNat32;\n\n  /// Loads a `Nat8` value from stable memory at the given `offset`.\n  /// Traps on an out-of-bounds access.\n  ///\n  /// Example:\n  /// ```motoko no-repl\n  /// let offset = 0;\n  /// let value = 123;\n  /// StableMemory.storeNat8(offset, value);\n  /// StableMemory.loadNat8(offset) // => 123\n  /// ```\n  public let loadNat8 : (offset : Nat64) -> Nat8 = Prim.stableMemoryLoadNat8;\n\n  /// Stores a `Nat8` value in stable memory at the given `offset`.\n  /// Traps on an out-of-bounds access.\n  ///\n  /// Example:\n  /// ```motoko no-repl\n  /// let offset = 0;\n  /// let value = 123;\n  /// StableMemory.storeNat8(offset, value);\n  /// StableMemory.loadNat8(offset) // => 123\n  /// ```\n  public let storeNat8 : (offset : Nat64, value : Nat8) -> () = Prim.stableMemoryStoreNat8;\n\n  /// Loads a `Nat16` value from stable memory at the given `offset`.\n  /// Traps on an out-of-bounds access.\n  ///\n  /// Example:\n  /// ```motoko no-repl\n  /// let offset = 0;\n  /// let value = 123;\n  /// StableMemory.storeNat16(offset, value);\n  /// StableMemory.loadNat16(offset) // => 123\n  /// ```\n  public let loadNat16 : (offset : Nat64) -> Nat16 = Prim.stableMemoryLoadNat16;\n\n  /// Stores a `Nat16` value in stable memory at the given `offset`.\n  /// Traps on an out-of-bounds access.\n  ///\n  /// Example:\n  /// ```motoko no-repl\n  /// let offset = 0;\n  /// let value = 123;\n  /// StableMemory.storeNat16(offset, value);\n  /// StableMemory.loadNat16(offset) // => 123\n  /// ```\n  public let storeNat16 : (offset : Nat64, value : Nat16) -> () = Prim.stableMemoryStoreNat16;\n\n  /// Loads a `Nat64` value from stable memory at the given `offset`.\n  /// Traps on an out-of-bounds access.\n  ///\n  /// Example:\n  /// ```motoko no-repl\n  /// let offset = 0;\n  /// let value = 123;\n  /// StableMemory.storeNat64(offset, value);\n  /// StableMemory.loadNat64(offset) // => 123\n  /// ```\n  public let loadNat64 : (offset : Nat64) -> Nat64 = Prim.stableMemoryLoadNat64;\n\n  /// Stores a `Nat64` value in stable memory at the given `offset`.\n  /// Traps on an out-of-bounds access.\n  ///\n  /// Example:\n  /// ```motoko no-repl\n  /// let offset = 0;\n  /// let value = 123;\n  /// StableMemory.storeNat64(offset, value);\n  /// StableMemory.loadNat64(offset) // => 123\n  /// ```\n  public let storeNat64 : (offset : Nat64, value : Nat64) -> () = Prim.stableMemoryStoreNat64;\n\n  /// Loads an `Int32` value from stable memory at the given `offset`.\n  /// Traps on an out-of-bounds access.\n  ///\n  /// Example:\n  /// ```motoko no-repl\n  /// let offset = 0;\n  /// let value = 123;\n  /// StableMemory.storeInt32(offset, value);\n  /// StableMemory.loadInt32(offset) // => 123\n  /// ```\n  public let loadInt32 : (offset : Nat64) -> Int32 = Prim.stableMemoryLoadInt32;\n\n  /// Stores an `Int32` value in stable memory at the given `offset`.\n  /// Traps on an out-of-bounds access.\n  ///\n  /// Example:\n  /// ```motoko no-repl\n  /// let offset = 0;\n  /// let value = 123;\n  /// StableMemory.storeInt32(offset, value);\n  /// StableMemory.loadInt32(offset) // => 123\n  /// ```\n  public let storeInt32 : (offset : Nat64, value : Int32) -> () = Prim.stableMemoryStoreInt32;\n\n  /// Loads an `Int8` value from stable memory at the given `offset`.\n  /// Traps on an out-of-bounds access.\n  ///\n  /// Example:\n  /// ```motoko no-repl\n  /// let offset = 0;\n  /// let value = 123;\n  /// StableMemory.storeInt8(offset, value);\n  /// StableMemory.loadInt8(offset) // => 123\n  /// ```\n  public let loadInt8 : (offset : Nat64) -> Int8 = Prim.stableMemoryLoadInt8;\n\n  /// Stores an `Int8` value in stable memory at the given `offset`.\n  /// Traps on an out-of-bounds access.\n  ///\n  /// Example:\n  /// ```motoko no-repl\n  /// let offset = 0;\n  /// let value = 123;\n  /// StableMemory.storeInt8(offset, value);\n  /// StableMemory.loadInt8(offset) // => 123\n  /// ```\n  public let storeInt8 : (offset : Nat64, value : Int8) -> () = Prim.stableMemoryStoreInt8;\n\n  /// Loads an `Int16` value from stable memory at the given `offset`.\n  /// Traps on an out-of-bounds access.\n  ///\n  /// Example:\n  /// ```motoko no-repl\n  /// let offset = 0;\n  /// let value = 123;\n  /// StableMemory.storeInt16(offset, value);\n  /// StableMemory.loadInt16(offset) // => 123\n  /// ```\n  public let loadInt16 : (offset : Nat64) -> Int16 = Prim.stableMemoryLoadInt16;\n\n  /// Stores an `Int16` value in stable memory at the given `offset`.\n  /// Traps on an out-of-bounds access.\n  ///\n  /// Example:\n  /// ```motoko no-repl\n  /// let offset = 0;\n  /// let value = 123;\n  /// StableMemory.storeInt16(offset, value);\n  /// StableMemory.loadInt16(offset) // => 123\n  /// ```\n  public let storeInt16 : (offset : Nat64, value : Int16) -> () = Prim.stableMemoryStoreInt16;\n\n  /// Loads an `Int64` value from stable memory at the given `offset`.\n  /// Traps on an out-of-bounds access.\n  ///\n  /// Example:\n  /// ```motoko no-repl\n  /// let offset = 0;\n  /// let value = 123;\n  /// StableMemory.storeInt64(offset, value);\n  /// StableMemory.loadInt64(offset) // => 123\n  /// ```\n  public let loadInt64 : (offset : Nat64) -> Int64 = Prim.stableMemoryLoadInt64;\n\n  /// Stores an `Int64` value in stable memory at the given `offset`.\n  /// Traps on an out-of-bounds access.\n  ///\n  /// Example:\n  /// ```motoko no-repl\n  /// let offset = 0;\n  /// let value = 123;\n  /// StableMemory.storeInt64(offset, value);\n  /// StableMemory.loadInt64(offset) // => 123\n  /// ```\n  public let storeInt64 : (offset : Nat64, value : Int64) -> () = Prim.stableMemoryStoreInt64;\n\n  /// Loads a `Float` value from stable memory at the given `offset`.\n  /// Traps on an out-of-bounds access.\n  ///\n  /// Example:\n  /// ```motoko no-repl\n  /// let offset = 0;\n  /// let value = 1.25;\n  /// StableMemory.storeFloat(offset, value);\n  /// StableMemory.loadFloat(offset) // => 1.25\n  /// ```\n  public let loadFloat : (offset : Nat64) -> Float = Prim.stableMemoryLoadFloat;\n\n  /// Stores a `Float` value in stable memory at the given `offset`.\n  /// Traps on an out-of-bounds access.\n  ///\n  /// Example:\n  /// ```motoko no-repl\n  /// let offset = 0;\n  /// let value = 1.25;\n  /// StableMemory.storeFloat(offset, value);\n  /// StableMemory.loadFloat(offset) // => 1.25\n  /// ```\n  public let storeFloat : (offset : Nat64, value : Float) -> () = Prim.stableMemoryStoreFloat;\n\n  /// Load `size` bytes starting from `offset` as a `Blob`.\n  /// Traps on an out-of-bounds access.\n  ///\n  /// Example:\n  /// ```motoko no-repl\n  /// import Blob \"mo:base/Blob\";\n  ///\n  /// let offset = 0;\n  /// let value = Blob.fromArray([1, 2, 3]);\n  /// let size = value.size();\n  /// StableMemory.storeBlob(offset, value);\n  /// Blob.toArray(StableMemory.loadBlob(offset, size)) // => [1, 2, 3]\n  /// ```\n  public let loadBlob : (offset : Nat64, size : Nat) -> Blob = Prim.stableMemoryLoadBlob;\n\n  /// Write bytes of `blob` beginning at `offset`.\n  /// Traps on an out-of-bounds access.\n  ///\n  /// Example:\n  /// ```motoko no-repl\n  /// import Blob \"mo:base/Blob\";\n  ///\n  /// let offset = 0;\n  /// let value = Blob.fromArray([1, 2, 3]);\n  /// let size = value.size();\n  /// StableMemory.storeBlob(offset, value);\n  /// Blob.toArray(StableMemory.loadBlob(offset, size)) // => [1, 2, 3]\n  /// ```\n  public let storeBlob : (offset : Nat64, value : Blob) -> () = Prim.stableMemoryStoreBlob;\n\n}\n"},"AssocList.mo":{"content":"/// Map implemented as a linked-list of key-value pairs (\"Associations\").\n///\n/// :::note Usage context\n///\n/// This map implementation primarily serves as the underlying bucket structure for other map types. In most cases, those higher-level map implementations are easier to use.\n/// :::\n///\n/// :::note Assumptions\n///\n/// Runtime and space complexity assumes that `combine`, `equal`, and other functions execute in `O(1)` time and space.\n/// :::\n\nimport List \"List\";\n\nmodule {\n  /// Import from the base library to use this module.\n  ///\n  /// ```motoko name=import\n  /// import AssocList \"mo:base/AssocList\";\n  /// import List \"mo:base/List\";\n  /// import Nat \"mo:base/Nat\";\n  ///\n  /// type AssocList<K, V> = AssocList.AssocList<K, V>;\n  /// ```\n  ///\n  /// Initialize an empty map using an empty list.\n  /// ```motoko name=initialize include=import\n  /// var map : AssocList<Nat, Nat> = List.nil(); // Empty list as an empty map\n  /// map := null; // Alternative: null as empty list.\n  /// map\n  /// ```\n  public type AssocList<K, V> = List.List<(K, V)>;\n\n  /// Find the value associated with key `key`, or `null` if no such key exists.\n  /// Compares keys using the provided function `equal`.\n  ///\n  /// Example:\n  ///\n  /// ```motoko include=import,initialize\n  /// // Create map = [(0, 10), (1, 11), (2, 12)]\n  /// map := AssocList.replace(map, 0, Nat.equal, ?10).0;\n  /// map := AssocList.replace(map, 1, Nat.equal, ?11).0;\n  /// map := AssocList.replace(map, 2, Nat.equal, ?12).0;\n  ///\n  /// // Find value associated with key 1\n  /// AssocList.find(map, 1, Nat.equal)\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size)` | `O(1)` |\n  public func find<K, V>(\n    map : AssocList<K, V>,\n    key : K,\n    equal : (K, K) -> Bool\n  ) : ?V {\n    switch (map) {\n      case (?((hd_k, hd_v), tl)) {\n        if (equal(key, hd_k)) {\n          ?hd_v\n        } else {\n          find(tl, key, equal)\n        }\n      };\n      case (null) { null }\n    }\n  };\n\n  /// Maps `key` to `value` in `map`, and overwrites the old entry if the key\n  /// was already present. Returns the old value in an option if it existed and\n  /// `null` otherwise, as well as the new map. Compares keys using the provided\n  /// function `equal`.\n  ///\n  /// Example:\n  ///\n  /// ```motoko include=import,initialize\n  /// // Add three entries to the map\n  /// // map = [(0, 10), (1, 11), (2, 12)]\n  /// map := AssocList.replace(map, 0, Nat.equal, ?10).0;\n  /// map := AssocList.replace(map, 1, Nat.equal, ?11).0;\n  /// map := AssocList.replace(map, 2, Nat.equal, ?12).0;\n  /// // Override second entry\n  /// map := AssocList.replace(map, 1, Nat.equal, ?21).0;\n  ///\n  /// List.toArray(map)\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size)` | `O(size)` |\n  public func replace<K, V>(\n    map : AssocList<K, V>,\n    key : K,\n    equal : (K, K) -> Bool,\n    value : ?V\n  ) : (AssocList<K, V>, ?V) {\n    var prev : ?V = null;\n    func del(al : AssocList<K, V>) : AssocList<K, V> {\n      switch (al) {\n        case (?(kv, tl)) {\n          if (equal(key, kv.0)) {\n            prev := ?kv.1;\n            tl\n          } else {\n            let tl1 = del(tl);\n            switch (prev) {\n              case null { al };\n              case (?_) { ?(kv, tl1) }\n            }\n          }\n        };\n        case null {\n          null\n        }\n      }\n    };\n    let map1 = del(map);\n    switch value {\n      case (?value) { (?((key, value), map1), prev) };\n      case null { (map1, prev) }\n    }\n  };\n\n  /// Produces a new map containing all entries from `map1` whose keys are not\n  /// contained in `map2`. The \"extra\" entries in `map2` are ignored. Compares\n  /// keys using the provided function `equal`.\n  ///\n  /// Example:\n  ///\n  /// ```motoko include=import,initialize\n  /// // Create map1 = [(0, 10), (1, 11), (2, 12)]\n  /// var map1 : AssocList<Nat, Nat> = null;\n  /// map1 := AssocList.replace(map1, 0, Nat.equal, ?10).0;\n  /// map1 := AssocList.replace(map1, 1, Nat.equal, ?11).0;\n  /// map1 := AssocList.replace(map1, 2, Nat.equal, ?12).0;\n  ///\n  /// // Create map2 = [(2, 12), (3, 13)]\n  /// var map2 : AssocList<Nat, Nat> = null;\n  /// map2 := AssocList.replace(map2, 2, Nat.equal, ?12).0;\n  /// map2 := AssocList.replace(map2, 3, Nat.equal, ?13).0;\n  ///\n  /// // Take the difference\n  /// let newMap = AssocList.diff(map1, map2, Nat.equal);\n  /// List.toArray(newMap)\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size1 * size2)` | `O(1)` |\n  public func diff<K, V, W>(\n    map1 : AssocList<K, V>,\n    map2 : AssocList<K, W>,\n    equal : (K, K) -> Bool\n  ) : AssocList<K, V> {\n    func rec(al1 : AssocList<K, V>) : AssocList<K, V> {\n      switch al1 {\n        case (null) { null };\n        case (?((k, v1), tl)) {\n          switch (find<K, W>(map2, k, equal)) {\n            case (null) { ?((k, v1), rec(tl)) };\n            case (?_v2) { rec(tl) }\n          }\n        }\n      }\n    };\n    rec(map1)\n  };\n\n  /// @deprecated `mapAppend` is deprecated and may be removed in future versions. Consider using an alternative approach.\n  public func mapAppend<K, V, W, X>(\n    map1 : AssocList<K, V>,\n    map2 : AssocList<K, W>,\n    f : (?V, ?W) -> X\n  ) : AssocList<K, X> {\n    func rec(al1 : AssocList<K, V>, al2 : AssocList<K, W>) : AssocList<K, X> {\n      switch (al1, al2) {\n        case (null, null) { null };\n        case (?((k, v), al1_), _) { ?((k, f(?v, null)), rec(al1_, al2)) };\n        case (null, ?((k, v), al2_)) { ?((k, f(null, ?v)), rec(null, al2_)) }\n      }\n    };\n    rec(map1, map2)\n  };\n\n  /// Produces a new map by mapping entries in `map1` and `map2` using `f` and\n  /// concatenating the results. Assumes that there are no collisions between\n  /// keys in `map1` and `map2`.\n  ///\n  /// Example:\n  ///\n  /// ```motoko include=import,initialize\n  /// import { trap } \"mo:base/Debug\";\n  ///\n  /// // Create map1 = [(0, 10), (1, 11), (2, 12)]\n  /// var map1 : AssocList<Nat, Nat> = null;\n  /// map1 := AssocList.replace(map1, 0, Nat.equal, ?10).0;\n  /// map1 := AssocList.replace(map1, 1, Nat.equal, ?11).0;\n  /// map1 := AssocList.replace(map1, 2, Nat.equal, ?12).0;\n  ///\n  /// // Create map2 = [(4, \"14\"), (3, \"13\")]\n  /// var map2 : AssocList<Nat, Text> = null;\n  /// map2 := AssocList.replace(map2, 4, Nat.equal, ?\"14\").0;\n  /// map2 := AssocList.replace(map2, 3, Nat.equal, ?\"13\").0;\n  ///\n  /// // Map and append the two AssocLists\n  /// let newMap =\n  ///  AssocList.disjDisjoint<Nat, Nat, Text, Text>(\n  ///    map1,\n  ///    map2,\n  ///    func((v1, v2) : (?Nat, ?Text)) {\n  ///      switch(v1, v2) {\n  ///        case(?v1, null) {\n  ///          debug_show(v1) // convert values from map1 to Text\n  ///        };\n  ///        case(null, ?v2) {\n  ///          v2 // keep values from map2 as Text\n  ///        };\n  ///        case _ {\n  ///          trap \"These cases will never happen in mapAppend\"\n  ///        }\n  ///      }\n  ///    }\n  ///  );\n  ///\n  /// List.toArray(newMap)\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size1 + size2)` | `O(size1 + size2)` |\n\n  public func disjDisjoint<K, V, W, X>(\n    map1 : AssocList<K, V>,\n    map2 : AssocList<K, W>,\n    f : (?V, ?W) -> X\n  ) : AssocList<K, X> {\n    mapAppend<K, V, W, X>(map1, map2, f)\n  };\n\n  /// Creates a new map by merging entries from `map1` and `map2`, and mapping\n  /// them using `combine`. `combine` is also used to combine the values of colliding keys.\n  /// Keys are compared using the given `equal` function.\n  ///\n  /// :::note Behavior guarantee\n  ///\n  /// `combine` will never be applied to `(null, null)`.\n  ///\n  /// :::\n  ///\n  /// Example:\n  ///\n  /// ```motoko include=import,initialize\n  /// import { trap } \"mo:base/Debug\";\n  ///\n  /// // Create map1 = [(0, 10), (1, 11), (2, 12)]\n  /// var map1 : AssocList<Nat, Nat> = null;\n  /// map1 := AssocList.replace(map1, 0, Nat.equal, ?10).0;\n  /// map1 := AssocList.replace(map1, 1, Nat.equal, ?11).0;\n  /// map1 := AssocList.replace(map1, 2, Nat.equal, ?12).0;\n  ///\n  /// // Create map2 = [(2, 12), (3, 13)]\n  /// var map2 : AssocList<Nat, Nat> = null;\n  /// map2 := AssocList.replace(map2, 2, Nat.equal, ?12).0;\n  /// map2 := AssocList.replace(map2, 3, Nat.equal, ?13).0;\n  ///\n  /// // Merge the two maps using `combine`\n  /// let newMap =\n  ///  AssocList.disj<Nat, Nat, Nat, Nat>(\n  ///    map1,\n  ///    map2,\n  ///    Nat.equal,\n  ///    func((v1, v2) : (?Nat, ?Nat)) : Nat {\n  ///      switch(v1, v2) {\n  ///        case(?v1, ?v2) {\n  ///          v1 + v2 // combine values of colliding keys by adding them\n  ///        };\n  ///        case(?v1, null) {\n  ///          v1 // when a key doesn't collide, keep the original value\n  ///        };\n  ///        case(null, ?v2) {\n  ///          v2\n  ///        };\n  ///        case _ {\n  ///          trap \"This case will never happen in disj\"\n  ///        }\n  ///      }\n  ///    }\n  ///  );\n  ///\n  /// List.toArray(newMap)\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size1 * size2)` | `O(size1 + size2)` |\n  public func disj<K, V, W, X>(\n    map1 : AssocList<K, V>,\n    map2 : AssocList<K, W>,\n    equal : (K, K) -> Bool,\n    combine : (?V, ?W) -> X\n  ) : AssocList<K, X> {\n    func rec1(al1Rec : AssocList<K, V>) : AssocList<K, X> {\n      switch al1Rec {\n        case (null) {\n          func rec2(al2 : AssocList<K, W>) : AssocList<K, X> {\n            switch al2 {\n              case (null) { null };\n              case (?((k, v2), tl)) {\n                switch (find<K, V>(map1, k, equal)) {\n                  case (null) { ?((k, combine(null, ?v2)), rec2(tl)) };\n                  case (?v1) { ?((k, combine(?v1, ?v2)), rec2(tl)) }\n                }\n              }\n            }\n          };\n          rec2(map2)\n        };\n        case (?((k, v1), tl)) {\n          switch (find<K, W>(map2, k, equal)) {\n            case (null) { ?((k, combine(?v1, null)), rec1(tl)) };\n            case (?_v2) { /* handled above */ rec1(tl) }\n          }\n        }\n      }\n    };\n    rec1(map1)\n  };\n\n  /// Takes the intersection of `map1` and `map2`, only keeping colliding keys\n  /// and combining values using the `combine` function. Keys are compared using\n  /// the `equal` function.\n  ///\n  /// Example:\n  ///\n  /// ```motoko include=import,initialize\n  /// // Create map1 = [(0, 10), (1, 11), (2, 12)]\n  /// var map1 : AssocList<Nat, Nat> = null;\n  /// map1 := AssocList.replace(map1, 0, Nat.equal, ?10).0;\n  /// map1 := AssocList.replace(map1, 1, Nat.equal, ?11).0;\n  /// map1 := AssocList.replace(map1, 2, Nat.equal, ?12).0;\n  ///\n  /// // Create map2 = [(2, 12), (3, 13)]\n  /// var map2 : AssocList<Nat, Nat> = null;\n  /// map2 := AssocList.replace(map2, 2, Nat.equal, ?12).0;\n  /// map2 := AssocList.replace(map2, 3, Nat.equal, ?13).0;\n  ///\n  /// // Take the intersection of the two maps, combining values by adding them\n  /// let newMap = AssocList.join<Nat, Nat, Nat, Nat>(map1, map2, Nat.equal, Nat.add);\n  ///\n  /// List.toArray(newMap)\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size1 * size2)` | `O(size1 + size2)` |\n  public func join<K, V, W, X>(\n    map1 : AssocList<K, V>,\n    map2 : AssocList<K, W>,\n    equal : (K, K) -> Bool,\n    combine : (V, W) -> X\n  ) : AssocList<K, X> {\n    func rec(al1 : AssocList<K, V>) : AssocList<K, X> {\n      switch al1 {\n        case (null) { null };\n        case (?((k, v1), tl)) {\n          switch (find<K, W>(map2, k, equal)) {\n            case (null) { rec(tl) };\n            case (?v2) { ?((k, combine(v1, v2)), rec(tl)) }\n          }\n        }\n      }\n    };\n    rec(map1)\n  };\n\n  /// Collapses the elements in `map` into a single value by starting with `base`\n  /// and progessively combining elements into `base` with `combine`. Iteration runs\n  /// left to right.\n  ///\n  /// Example:\n  ///\n  /// ```motoko include=import,initialize\n  /// // Create map = [(0, 10), (1, 11), (2, 12)]\n  /// var map : AssocList<Nat, Nat> = null;\n  /// map := AssocList.replace(map, 0, Nat.equal, ?10).0;\n  /// map := AssocList.replace(map, 1, Nat.equal, ?11).0;\n  /// map := AssocList.replace(map, 2, Nat.equal, ?12).0;\n  ///\n  /// // (0 * 10) + (1 * 11) + (2 * 12)\n  /// AssocList.fold<Nat, Nat, Nat>(map, 0, func(k, v, sumSoFar) = (k * v) + sumSoFar)\n  /// ```\n  ///\n  /// | Runtime   | Space     |\n  /// |-----------|-----------|\n  /// | `O(size)` | `O(size)` |\n  public func fold<K, V, X>(\n    map : AssocList<K, V>,\n    base : X,\n    combine : (K, V, X) -> X\n  ) : X {\n    func rec(al : AssocList<K, V>) : X {\n      switch al {\n        case null { base };\n        case (?((k, v), t)) { combine(k, v, rec(t)) }\n      }\n    };\n    rec(map)\n  }\n}\n"}}}