motoko 0.0.32

A library for parsing and running Motoko in Rust
Documentation
1
{"name":"base","version":"master","files":{"Blob.mo":{"content":"/// Binary blobs\n\nimport Prim \"mo:⛔\";\nmodule {\n\n  /// An immutable, possibly empty sequence of bytes.\n  /// Given `b : Blob`:\n  ///\n  /// * `b.size() : Nat` returns the number of bytes in the blob;\n  /// * `b.vals() : Iter.Iter<Nat8>` returns an iterator to enumerate the bytes of the blob.\n  ///\n  /// (Direct indexing of Blobs is not yet supported.)\n  public type Blob = Prim.Types.Blob;\n\n  /// Returns a (non-cryptographic) hash of 'b'\n  public let hash : (b : Blob) -> Nat32 = Prim.hashBlob;\n\n  /// Returns `x == y`.\n  public func equal(x : Blob, y : Blob) : Bool { x == y };\n\n  /// Returns `x != y`.\n  public func notEqual(x : Blob, y : Blob) : Bool { x != y };\n\n  /// Returns `x < y`.\n  public func less(x : Blob, y : Blob) : Bool { x < y };\n\n  /// Returns `x <= y`.\n  public func lessOrEqual(x : Blob, y : Blob) : Bool { x <= y };\n\n  /// Returns `x > y`.\n  public func greater(x : Blob, y : Blob) : Bool { x > y };\n\n  /// Returns `x >= y`.\n  public func greaterOrEqual(x : Blob, y : Blob) : Bool { x >= y };\n\n  /// Returns the order of `x` and `y`.\n  public func compare(x : Blob, y : Blob) : { #less; #equal; #greater } {\n    if (x < y) { #less } else if (x == y) { #equal } else { #greater }\n  };\n\n  /// Creates a blob from an array of bytes, by copying each element.\n  public let fromArray : [Nat8] -> Blob = Prim.arrayToBlob;\n\n  /// Creates a blob from a mutable array of bytes, by copying each element.\n  public let fromArrayMut : [var Nat8] -> Blob = Prim.arrayMutToBlob;\n\n  /// Creates an array of bytes from a blob, by copying each element.\n  public let toArray : Blob -> [Nat8] = Prim.blobToArray;\n\n  /// Creates a mutable array of bytes from a blob, by copying each element.\n  public let toArrayMut : Blob -> [var Nat8] = Prim.blobToArrayMut;\n\n}\n"},"CertifiedData.mo":{"content":"/// Certified data.\n///\n/// 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/// This module provides a _low-level_ interface to this API, aimed at advanced\n/// users and library implementors. See the Internet Computer Functional\n/// Specification and corresponding documentation for how to use this to make query\n/// calls to your canister tamperproof.\n\nimport Prim \"mo:⛔\";\n\nmodule {\n\n  /// Set the certified data.\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  /// Example:\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(a);\n  /// CertifiedData.set(blob);\n  /// ```\n  ///\n  /// See a full example on how to use certified variables here: https://github.com/dfinity/examples/tree/master/motoko/cert-var\n  ///\n  public let set : (data : Blob) -> () = Prim.setCertifiedData;\n\n  /// Gets a certificate\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  /// Example:\n  /// ```motoko no-repl\n  /// import CertifiedData \"mo:base/CertifiedData\";\n  /// // Must be in a query call\n  ///\n  /// CertifiedData.getCertificate();\n  /// ```\n  /// See a full example on how to use certified variables here: https://github.com/dfinity/examples/tree/master/motoko/cert-var\n  ///\n  public let getCertificate : () -> ?Blob = Prim.getCertificate;\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  ///   // 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  /// };\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  /// import Debug \"mo:base/Debug\";\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}\n"},"Deque.mo":{"content":"/// Functions for persistent, double-ended queues.\n\nimport List \"List\";\nimport P \"Prelude\";\n\nmodule {\n  type List<T> = List.List<T>;\n\n  /// Double-ended queue\n  public type Deque<T> = (List<T>, List<T>);\n\n  /// Empty queue\n  public func empty<T>() : Deque<T> { (List.nil(), List.nil()) };\n\n  /// True when the queue is empty\n  public func isEmpty<T>(q : Deque<T>) : Bool {\n    switch q {\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 the queue\n  public func pushFront<T>(q : Deque<T>, x : T) : Deque<T> {\n    check(List.push(x, q.0), q.1)\n  };\n\n  /// Inspect the (optional) first element on the front end of the queue\n  public func peekFront<T>(q : Deque<T>) : ?T {\n    switch q {\n      case (?(x, f), r) { ?x };\n      case (null, ?(x, r)) { ?x };\n      case _ { null }\n    }\n  };\n\n  /// Remove the first element on the front end of the queue; Returns null when empty.\n  public func popFront<T>(q : Deque<T>) : ?(T, Deque<T>) {\n    switch q {\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 the queue\n  public func pushBack<T>(q : Deque<T>, x : T) : Deque<T> {\n    check(q.0, List.push(x, q.1))\n  };\n\n  /// Inspect the (optional) first element on the back end of the queue\n  public func peekBack<T>(q : Deque<T>) : ?T {\n    switch q {\n      case (f, ?(x, r)) { ?x };\n      case (?(x, r), null) { ?x };\n      case _ { null }\n    }\n  };\n\n  /// Remove the first element on the back end of the queue; Returns null when empty.\n  public func popBack<T>(q : Deque<T>) : ?(Deque<T>, T) {\n    switch q {\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"},"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: The output is placed in the replica log. When running on mainnet,\n  /// this function has no effect.\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: 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  /// ```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"},"ExperimentalCycles.mo":{"content":"/// Managing cycles\n///\n/// Usage of the Internet Computer is measured, and paid for, in _cycles_.\n/// This library provides imperative operations for observing cycles, transferring cycles and\n/// observing refunds of cycles.\n///\n/// **WARNING:** This low-level API is **experimental** and likely to change or even disappear.\n/// Dedicated syntactic support for manipulating cycles may be added to the language in future, obsoleting this library.\n///\n/// **NOTE:** Since cycles measure computational resources, the value of\n/// `balance()` can change from one call to the next.\n\nimport Prim \"mo:⛔\";\nmodule {\n\n  /// Returns the actor's current balance of cycles as `amount`.\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\n  /// refunded to the caller/context.\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  public let accept : (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**: the implicit register of added amounts is reset to zero on entry to\n  /// a shared function and after each shared function call or resume from an await.\n  public let add : (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  public let refunded : () -> (amount : Nat) = Prim.cyclesRefunded;\n\n}\n"},"ExperimentalInternetComputer.mo":{"content":"/// Low-level interface to the Internet Computer.\n///\n/// **WARNING:** 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  /// Note: `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/developer-docs/build/cdks/motoko-dfinity/language-manual#candid-serialization)\n  public let call : (canister : Principal, name : Text, data : Blob) -> async (reply : Blob) = Prim.call_raw;\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  /// NB: `countInstructions(comp)` will _not_ account for any deferred garbage collection costs incurred by `comp()`.\n  ///\n  /// Example:\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}\n"},"Heap.mo":{"content":"/// Priority Queue\n///\n/// This module provides purely-functional priority queue based on leftist heap\n\nimport O \"Order\";\nimport P \"Prelude\";\nimport L \"List\";\nimport I \"Iter\";\n\nmodule {\n\n  public type Tree<T> = ?(Int, T, Tree<T>, Tree<T>);\n\n  public class Heap<T>(ord : (T, T) -> O.Order) {\n    var heap : Tree<T> = null;\n\n    /// Get purely-functional representation\n    public func share() : Tree<T> {\n      heap\n    };\n\n    /// Put purely-functional representation into class. Need to make sure the tree is constructed with the same compare function\n    public func unsafeUnshare(t : Tree<T>) {\n      heap := t\n    };\n\n    /// Insert an element to the heap\n    public func put(x : T) {\n      heap := merge(heap, ?(1, x, null, null), ord)\n    };\n\n    /// Return the minimal element\n    public func peekMin() : ?T {\n      switch heap {\n        case (null) { null };\n        case (?(_, x, _, _)) { ?x }\n      }\n    };\n\n    /// Delete the minimal element\n    public func deleteMin() {\n      switch heap {\n        case null {};\n        case (?(_, _, a, b)) { heap := merge(a, b, ord) }\n      }\n    };\n\n    /// Remove the minimal element and return its value\n    public func removeMin() : ?T {\n      switch heap {\n        case null { null };\n        case (?(_, x, a, b)) {\n          heap := merge(a, b, ord);\n          ?x\n        }\n      }\n    }\n  };\n\n  func rank<T>(heap : Tree<T>) : Int {\n    switch heap {\n      case null { 0 };\n      case (?(r, _, _, _)) { r }\n    }\n  };\n\n  func makeT<T>(x : T, a : Tree<T>, b : Tree<T>) : Tree<T> {\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<T>(h1 : Tree<T>, h2 : Tree<T>, ord : (T, T) -> O.Order) : Tree<T> {\n    switch (h1, h2) {\n      case (null, h) { h };\n      case (h, null) { h };\n      case (?(_, x, a, b), ?(_, y, c, d)) {\n        switch (ord(x, y)) {\n          case (#less) { makeT(x, a, merge(b, h2, ord)) };\n          case _ { makeT(y, c, merge(d, h1, ord)) }\n        }\n      }\n    }\n  };\n\n  /// Convert iterator into a heap in O(N) time.\n  public func fromIter<T>(iter : I.Iter<T>, ord : (T, T) -> O.Order) : Heap<T> {\n    let heap = Heap<T>(ord);\n    func build(xs : L.List<Tree<T>>) : Tree<T> {\n      func join(xs : L.List<Tree<T>>) : L.List<Tree<T>> {\n        switch (xs) {\n          case (null) { null };\n          case (?(hd, null)) { ?(hd, null) };\n          case (?(h1, ?(h2, tl))) { ?(merge(h1, h2, ord), 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 : T) : Tree<T> { ?(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"},"ExperimentalStableMemory.mo":{"content":"/// Byte-level access to (virtual) _stable memory_.\n///\n/// **WARNING**: As its name suggests, this library is **experimental**, subject to change\n/// and may be replaced by safer alternatives in later versions of Motoko.\n/// Use at your own risk and discretion.\n///\n/// This is a lightweight abstraction over IC _stable memory_ and supports persisting\n/// raw 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///\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 limit on 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 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 stable memory size.\n///\n/// Each `store` operation stores to 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 stable memory 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 page allocation and page contents is preserved across upgrades.\n///\n/// NB: The IC's actual stable memory size (`ic0.stable_size`) may exceed the\n/// page size reported by Motoko function `size()`.\n/// This (and the cap on growth) are to accommodate Motoko's stable variables.\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 (currently 8GiB).\n/// All applications should reserve at least one page for stable variable data, even when no stable variables are used.\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  public let size : () -> (pages : Nat64) = Prim.stableMemorySize;\n\n  /// Grow current `size` of stable memory by `pagecount` pages.\n  /// Each page is 64KiB (65536 bytes).\n  /// Returns 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 0 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  public let grow : (new_pages : 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  public let stableVarQuery : () -> (shared query () -> async { size : Nat64 }) = Prim.stableVarQuery;\n\n  public let loadNat32 : (offset : Nat64) -> Nat32 = Prim.stableMemoryLoadNat32;\n  public let storeNat32 : (offset : Nat64, value : Nat32) -> () = Prim.stableMemoryStoreNat32;\n\n  public let loadNat8 : (offset : Nat64) -> Nat8 = Prim.stableMemoryLoadNat8;\n  public let storeNat8 : (offset : Nat64, value : Nat8) -> () = Prim.stableMemoryStoreNat8;\n\n  public let loadNat16 : (offset : Nat64) -> Nat16 = Prim.stableMemoryLoadNat16;\n  public let storeNat16 : (offset : Nat64, value : Nat16) -> () = Prim.stableMemoryStoreNat16;\n\n  public let loadNat64 : (offset : Nat64) -> Nat64 = Prim.stableMemoryLoadNat64;\n  public let storeNat64 : (offset : Nat64, value : Nat64) -> () = Prim.stableMemoryStoreNat64;\n\n  public let loadInt32 : (offset : Nat64) -> Int32 = Prim.stableMemoryLoadInt32;\n  public let storeInt32 : (offset : Nat64, value : Int32) -> () = Prim.stableMemoryStoreInt32;\n\n  public let loadInt8 : (offset : Nat64) -> Int8 = Prim.stableMemoryLoadInt8;\n  public let storeInt8 : (offset : Nat64, value : Int8) -> () = Prim.stableMemoryStoreInt8;\n\n  public let loadInt16 : (offset : Nat64) -> Int16 = Prim.stableMemoryLoadInt16;\n  public let storeInt16 : (offset : Nat64, value : Int16) -> () = Prim.stableMemoryStoreInt16;\n\n  public let loadInt64 : (offset : Nat64) -> Int64 = Prim.stableMemoryLoadInt64;\n  public let storeInt64 : (offset : Nat64, value : Int64) -> () = Prim.stableMemoryStoreInt64;\n\n  public let loadFloat : (offset : Nat64) -> Float = Prim.stableMemoryLoadFloat;\n  public let storeFloat : (offset : Nat64, value : Float) -> () = Prim.stableMemoryStoreFloat;\n\n  /// Load `size` bytes starting from `offset` as a `Blob`.\n  /// Traps on out-of-bounds access.\n  public let loadBlob : (offset : Nat64, size : Nat) -> Blob = Prim.stableMemoryLoadBlob;\n\n  /// Write bytes of `blob` beginning at `offset`.\n  /// Traps on out-of-bounds access.\n  public let storeBlob : (offset : Nat64, value : Blob) -> () = Prim.stableMemoryStoreBlob;\n\n}\n"},"HashMap.mo":{"content":"/// Mutable hash map (aka Hashtable)\n///\n/// This module defines an imperative hash map (hash table), with a general key and value type.\n///\n/// It has a minimal object-oriented interface: `get`, `set`, `delete`, `count` and `entries`.\n///\n/// The class is parameterized by the key's equality and hash functions,\n/// and an initial capacity.  However, as with the `Buffer` class, no array allocation\n/// happens until the first `set`.\n///\n/// Internally, table growth policy is very simple, for now:\n///  Double the current capacity when the expected bucket list size grows beyond a certain constant.\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  /// An imperative HashMap with a minimal object-oriented interface.\n  /// Maps keys of type `K` to values of type `V`.\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 number of entries in this HashMap.\n    public func size() : Nat = _count;\n\n    /// Deletes the entry with the key `k`. Doesn't do anything if the key doesn't\n    /// exist.\n    public func delete(k : K) = ignore remove(k);\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    /// Removes the entry with the key `k` and returns the associated value if it\n    /// existed or `null` otherwise.\n    public func remove(k : K) : ?V {\n      let m = table.size();\n      if (m > 0) {\n        let h = Prim.nat32ToNat(keyHash(k));\n        let pos = h % m;\n        let (kvs2, ov) = AssocList.replace<Key<K>, V>(table[pos], keyHash_(k), 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    /// Gets the entry with the key `k` and returns its associated value if it\n    /// existed or `null` otherwise.\n    public func get(k : K) : ?V {\n      let h = Prim.nat32ToNat(keyHash(k));\n      let m = table.size();\n      let v = if (m > 0) {\n        AssocList.find<Key<K>, V>(table[h % m], keyHash_(k), keyHashEq)\n      } else {\n        null\n      }\n    };\n\n    /// Insert the value `v` at key `k`. Overwrites an existing entry with key `k`\n    public func put(k : K, v : V) = ignore replace(k, v);\n\n    /// Insert the value `v` at key `k` and returns the previous value stored at\n    /// `k` or `null` if it didn't exist.\n    public func replace(k : K, v : V) : ?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(k));\n      let pos = h % table.size();\n      let (kvs2, ov) = AssocList.replace<Key<K>, V>(table[pos], keyHash_(k), keyHashEq, ?v);\n      table[pos] := kvs2;\n      switch (ov) {\n        case null { _count += 1 };\n        case _ {}\n      };\n      ov\n    };\n\n    /// An `Iter` over the keys.\n    public func keys() : Iter.Iter<K> {\n      Iter.map(entries(), func(kv : (K, V)) : K { kv.0 })\n    };\n\n    /// An `Iter` over the values.\n    public func vals() : Iter.Iter<V> {\n      Iter.map(entries(), func(kv : (K, V)) : V { kv.1 })\n    };\n\n    /// Returns an iterator over the key value pairs in this\n    /// `HashMap`. Does _not_ modify the `HashMap`.\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  /// clone cannot be an efficient object method,\n  /// ...but is still useful in tests, and beyond.\n  public func clone<K, V>(\n    h : HashMap<K, V>,\n    keyEq : (K, K) -> Bool,\n    keyHash : K -> Hash.Hash\n  ) : HashMap<K, V> {\n    let h2 = HashMap<K, V>(h.size(), keyEq, keyHash);\n    for ((k, v) in h.entries()) {\n      h2.put(k, v)\n    };\n    h2\n  };\n\n  /// Clone from any iterator of key-value pairs\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  public func map<K, V1, V2>(\n    h : HashMap<K, V1>,\n    keyEq : (K, K) -> Bool,\n    keyHash : K -> Hash.Hash,\n    mapFn : (K, V1) -> V2\n  ) : HashMap<K, V2> {\n    let h2 = HashMap<K, V2>(h.size(), keyEq, keyHash);\n    for ((k, v1) in h.entries()) {\n      let v2 = mapFn(k, v1);\n      h2.put(k, v2)\n    };\n    h2\n  };\n\n  public func mapFilter<K, V1, V2>(\n    h : HashMap<K, V1>,\n    keyEq : (K, K) -> Bool,\n    keyHash : K -> Hash.Hash,\n    mapFn : (K, V1) -> ?V2\n  ) : HashMap<K, V2> {\n    let h2 = HashMap<K, V2>(h.size(), keyEq, keyHash);\n    for ((k, v1) in h.entries()) {\n      switch (mapFn(k, v1)) {\n        case null {};\n        case (?v2) {\n          h2.put(k, v2)\n        }\n      }\n    };\n    h2\n  };\n\n}\n"},"Prelude.mo":{"content":"/// General utilities\n///\n/// 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  /// Not yet implemented\n  ///\n  /// Mark incomplete code with the `nyi` and `xxx` functions.\n  ///\n  /// Each have calls 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"},"Stack.mo":{"content":"/// Stack collection (LIFO discipline).\n///\n/// Minimal LIFO (last in first out) implementation, as a class.\n/// See library `Deque` for mixed LIFO/FIFO behavior.\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    public func push(x : T) {\n      stack := ?(x, stack)\n    };\n\n    /// True when the stack is empty.\n    public func isEmpty() : Bool {\n      List.isNil<T>(stack)\n    };\n\n    /// Return and retain the top element, or return null.\n    public func peek() : ?T {\n      switch stack {\n        case null { null };\n        case (?(h, t)) { ?h }\n      }\n    };\n\n    /// Remove and return the top element, or return null.\n    public func pop() : ?T {\n      switch stack {\n        case null { null };\n        case (?(h, t)) { stack := t; ?h }\n      }\n    }\n  }\n}\n"},"Option.mo":{"content":"/// Typesafe nulls\n///\n/// 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  /// Asserts that the value is not `null`; fails otherwise.\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  /// @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"},"Iter.mo":{"content":"/// Iterators\n\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 \"o: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  /// 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 Arrays 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, ix : Nat) { buffer.add(x) });\n    return Buffer.toArray(buffer)\n  };\n\n  /// Like `toArray` but for Arrays 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"},"Timer.mo":{"content":"/// Timers for one-off or periodic tasks.\n///\n/// Note: If `moc` is invoked with `-no-timer`, the importing will fail.\n/// Note: 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 heatbeat mechanism should be considered.\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 =\n    fromIntWrap (switch d {\n      case (#seconds s) s * 1000_000_000;\n      case (#nanoseconds ns) ns });\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(d : Duration, job : () -> async ()) : TimerId {\n    setTimerNano(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  /// Note: A duration of 0 will only expire once.\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(d : Duration, job : () -> async ()) : TimerId {\n    setTimerNano(toNanos d, true, job)\n  };\n\n  /// Cancels a still active timer with `(id : TimerId)`. For expired timers\n  /// and not recognised `id`s nothing happens.\n  ///\n  /// ```motoko no-repl\n  /// func deleteAppt(appt : Appointment) {\n  ///   cancelTimer (appt.reminder);\n  ///   // ...\n  /// };\n  /// ```\n  public let cancelTimer : TimerId -> () = cancel;\n\n}\n"},"TrieSet.mo":{"content":"/// Functional set\n///\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// 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\";\n\nmodule {\n\n  public type Hash = Hash.Hash;\n  public type Set<T> = Trie.Trie<T, ()>;\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    // XXX: Todo: use a smarter check\n    func unitEqual(_ : (), _ : ()) : Bool { true };\n    Trie.equalStructure<T, ()>(s1, s2, eq, unitEqual)\n  };\n\n  /// The number of set elements, set's cardinality.\n  public func size<T>(s : Set<T>) : Nat {\n    Trie.foldUp<T, (), Nat>(\n      s,\n      func(n : Nat, m : Nat) : Nat { n + m },\n      func(_ : T, _ : ()) : Nat { 1 },\n      0\n    )\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    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"},"List.mo":{"content":"/// Purely-functional, singly-linked lists.\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  public func nil<T>() : List<T> = null;\n\n  /// Check whether a list is empty and return true if the list is empty.\n  public func isNil<T>(l : List<T>) : Bool {\n    switch l {\n      case null { true };\n      case _ { false }\n    }\n  };\n\n  /// Construct a list by pre-pending a value.\n  /// This function is similar to a `list.cons(item)` function.\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  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  /// Treat the list as a stack.\n  /// This function combines the `head` and (non-failing) `tail` operations into one operation.\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  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: 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  public func get<T>(l : List<T>, n : Nat) : ?T {\n    switch (n, l) {\n      case (_, null) { null };\n      case (0, (?(h, t))) { ?h };\n      case (_, (?(_, t))) { get<T>(t, n - 1) }\n    }\n  };\n\n  /// Reverses the list\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 with each list element in turn.\n  ///\n  /// This function is equivalent to the `app` function in Standard ML Basis,\n  /// and the `iter` function in OCaml.\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 on each list element and collect the results\n  /// in a new list.\n  public func map<T, S>(l : List<T>, f : T -> S) : List<S> {\n    switch l {\n      case null { null };\n      case (?(h, t)) { ?(f(h), map<T, S>(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  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  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  public func mapFilter<T, S>(l : List<T>, f : T -> ?S) : List<S> {\n    switch l {\n      case null { null };\n      case (?(h, t)) {\n        switch (f(h)) {\n          case null { mapFilter<T, S>(t, f) };\n          case (?h_) { ?(h_, mapFilter<T, S>(t, f)) }\n        }\n      }\n    }\n  };\n\n  /// Maps a Result-returning function over a List and returns either\n  /// the first error or a list of successful values.\n  public func mapResult<A, R, E>(xs : List<A>, f : A -> Result.Result<R, E>) : Result.Result<List<R>, E> {\n    func go(xs : List<A>, 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 to another list.\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  public func append<T>(l : List<T>, m : List<T>) : List<T> {\n    revAppend(reverse(l), m)\n  };\n\n  /// Concatenate a list of lists.\n  ///\n  /// In some languages, this operation is also known as a `list join`.\n  //FIXME: this is quadratic, not linear\n  public func flatten<T>(l : List<List<T>>) : List<T> {\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  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  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 ((?(h, t)), m) { drop<T>(t, m - 1) }\n    }\n  };\n\n  /// Fold the list left-to-right using the given function (`f`).\n  public func foldLeft<T, S>(l : List<T>, a : S, f : (S, T) -> S) : S {\n    switch l {\n      case null { a };\n      case (?(h, t)) { foldLeft(t, f(a, h), f) }\n    }\n  };\n\n  /// Fold the list right-to-left using the given function (`f`).\n  public func foldRight<T, S>(l : List<T>, a : S, f : (T, S) -> S) : S {\n    switch l {\n      case null { a };\n      case (?(h, t)) { f(h, foldRight<T, S>(t, a, f)) }\n    }\n  };\n\n  /// Return the first element for which the given predicate `f` is true,\n  /// if such an element exists.\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  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  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 `lte`.\n  public func merge<T>(l1 : List<T>, l2 : List<T>, lte : (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 (lte(h1, h2)) {\n          ?(h1, merge<T>(t1, l2, lte))\n        } else {\n          ?(h2, merge<T>(l1, t2, lte))\n        }\n      }\n    }\n  };\n\n  /// Compare two lists using lexicographic ordering specified by the given relation `lte`.\n  public func compare<T>(l1 : List<T>, l2 : List<T>, compElm : (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        let hOrder = compElm(h1, h2);\n        if (Order.isEqual(hOrder)) {\n          compare<T>(t1, t2, compElm)\n        } else {\n          hOrder\n        }\n      }\n    }\n  };\n\n  /// Compare two lists for equality as specified by the given relation `eq` on the elements.\n  public func equal<T>(l1 : List<T>, l2 : List<T>, eq : (T, T) -> Bool) : Bool {\n    switch (l1, l2) {\n      case (null, null) { true };\n      case (null, _) { false };\n      case (_, null) { false };\n      case (?(h1, t1), ?(h2, t2)) { eq(h1, h2) and equal<T>(t1, t2, eq) }\n    }\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  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  public func make<X>(x : X) : List<X> = ?(x, null);\n\n  /// Create a list of the given length with the same value in each position.\n  public func replicate<X>(n : Nat, x : X) : List<X> {\n    var i = 0;\n    var l : List<X> = 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  public func zip<X, Y>(xs : List<X>, ys : List<Y>) : List<(X, Y)> = zipWith<X, Y, (X, Y)>(xs, ys, func(x, y) { (x, y) });\n\n  /// Create a list in which elements are calculated from the function `f` and\n  /// include elements occuring at the same position in the given 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  public func zipWith<X, Y, Z>(\n    xs : List<X>,\n    ys : List<Y>,\n    f : (X, Y) -> Z\n  ) : List<Z> {\n    switch (pop<X>(xs)) {\n      case (null, _) { null };\n      case (?x, xt) {\n        switch (pop<Y>(ys)) {\n          case (null, _) { null };\n          case (?y, yt) {\n            push<Z>(f(x, y), zipWith<X, Y, Z>(xt, yt, f))\n          }\n        }\n      }\n    }\n  };\n\n  /// Split the given list at the given zero-based index.\n  public func split<X>(n : Nat, xs : List<X>) : (List<X>, List<X>) {\n    if (n == 0) { (null, xs) } else {\n      func rec(n : Nat, xs : List<X>) : (List<X>, List<X>) {\n        switch (pop<X>(xs)) {\n          case (null, _) { (null, null) };\n          case (?h, t) {\n            if (n == 1) { (make<X>(h), t) } else {\n              let (l, r) = rec(n - 1, t);\n              (push<X>(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  public func chunks<X>(n : Nat, xs : List<X>) : List<List<X>> {\n    let (l, r) = split<X>(n, xs);\n    if (isNil<X>(l)) {\n      null\n    } else {\n      push<List<X>>(l, chunks<X>(n, r))\n    }\n  };\n\n  /// Convert an array into a list.\n  public func fromArray<A>(xs : [A]) : List<A> {\n    Array.foldRight<A, List<A>>(\n      xs,\n      nil<A>(),\n      func(x : A, ys : List<A>) : List<A> {\n        push<A>(x, ys)\n      }\n    )\n  };\n\n  /// Convert a mutable array into a list.\n  public func fromVarArray<A>(xs : [var A]) : List<A> = fromArray<A>(Array.freeze<A>(xs));\n\n  /// Create an array from a list.\n  public func toArray<A>(xs : List<A>) : [A] {\n    let length = size<A>(xs);\n    var list = xs;\n    Array.tabulate<A>(\n      length,\n      func(i) {\n        let popped = pop<A>(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  public func toVarArray<A>(xs : List<A>) : [var A] = Array.thaw<A>(toArray<A>(xs));\n\n  /// Create an iterator from a list.\n  public func toIter<A>(xs : List<A>) : Iter.Iter<A> {\n    var state = xs;\n    object {\n      public func next() : ?A = switch state {\n        case (?(hd, tl)) { state := tl; ?hd };\n        case _ null\n      }\n    }\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 underyling hash trie, found in the `Trie`\n/// module. The trie is a binary tree in which the position of elements in the\n/// tree are determined using the hash of the elements.\n///\n/// Note: The `class` `TrieMap` exposes the same interface as `HashMap`.\n///\n/// Creating a map:\n/// The equality function is used to compare keys, and the hash function is used\n/// 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: O(1)\n    /// Space: O(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: O(log(size))\n    /// Space: O(log(size))\n    ///\n    /// *Runtime and space assumes that the trie is reasonably balanced and the\n    /// map is using a constant time and space equality and hash function.\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: O(log(size))\n    /// Space: O(log(size))\n    ///\n    /// *Runtime and space assumes that the trie is reasonably balanced and the\n    /// map is using a constant time and space equality and hash function.\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: O(log(size))\n    /// Space: O(log(size))\n    ///\n    /// *Runtime and space assumes that the trie is reasonably balanced and the\n    /// map is using a constant time and space equality and hash function.\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    /// Example:\n    /// ```motoko include=initialize\n    /// map.put(0, 10);\n    /// map.delete(0);\n    /// map.get(0)\n    /// ```\n    ///\n    /// Runtime: O(log(size))\n    /// Space: O(log(size))\n    ///\n    /// *Runtime and space assumes that the trie is reasonably balanced and the\n    /// map is using a constant time and space equality and hash function.\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    /// Example:\n    /// ```motoko include=initialize\n    /// map.put(0, 10);\n    /// map.remove(0)\n    /// ```\n    ///\n    /// Runtime: O(log(size))\n    /// Space: O(log(size))\n    ///\n    /// *Runtime and space assumes that the trie is reasonably balanced and the\n    /// map is using a constant time and space equality and hash function.\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: O(1)\n    /// Space: O(1)\n    ///\n    /// *The above runtime and space are for the construction of the iterator.\n    /// The iteration itself takes linear time and logarithmic space to execute.\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: O(1)\n    /// Space: O(1)\n    ///\n    /// *The above runtime and space are for the construction of the iterator.\n    /// The iteration itself takes linear time and logarithmic space to execute.\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: O(1)\n    /// Space: O(1)\n    ///\n    /// *The above runtime and space are for the construction of the iterator.\n    /// The iteration itself takes linear time and logarithmic space to execute.\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: O(size * log(size))\n  /// Space: O(size)\n  ///\n  /// *Runtime and space assumes that the trie underlying `map` is reasonably\n  /// balanced and that `keyEq` and `keyHash` run in O(1) time and space.\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: O(size * log(size))\n  /// Space: O(size)\n  ///\n  /// *Runtime and space assumes that `entries` returns elements in O(1) time,\n  /// and `keyEq` and `keyHash` run in O(1) time and space.\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: O(size * log(size))\n  /// Space: O(size)\n  ///\n  /// *Runtime and space assumes that `f`, `keyEq`, and `keyHash` run in O(1)\n  /// time and space.\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: O(size * log(size))\n  /// Space: O(size)\n  ///\n  /// *Runtime and space assumes that `f`, `keyEq`, and `keyHash` run in O(1)\n  /// time and space.\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"},"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: `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 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  /// 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 `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  /// 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  /// Note: this algorithm is intended for use in data structures rather than as a cryptographic hash function.\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"},"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\nimport I \"Iter\";\nimport Option \"Option\";\nimport P \"Prelude\";\nimport Prim \"mo:⛔\";\n\nmodule {\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  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    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 = 0x80 : 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    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    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) { acc := acc * 256 + Prim.nat8ToNat(i) } 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      null\n    };\n\n    /// Counts the number of heads in `n` fair coin tosses.\n    /// Consumes ⌈p/8⌉ bytes of entropy.\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) { acc +%= Prim.popcntNat8(i) } 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      null\n    }\n  };\n\n  let raw_rand = (actor \"aaaaa-aa\" : actor { raw_rand : () -> async Blob }).raw_rand;\n\n  /// Distributes outcomes in the numeric range [0 .. 255].\n  /// Seed blob must contain at least a byte.\n  public func byteFrom(seed : Blob) : Nat8 {\n    switch (seed.vals().next()) {\n      case (?w) { w };\n      case _ { P.unreachable() }\n    }\n  };\n\n  /// Simulates a coin toss.\n  /// Seed blob must contain at least a byte.\n  public func coinFrom(seed : Blob) : Bool {\n    switch (seed.vals().next()) {\n      case (?w) { w > (127 : Nat8) };\n      case _ { P.unreachable() }\n    }\n  };\n\n  /// Obtains a full blob (32 bytes) worth of fresh entropy.\n  public let blob : shared () -> async Blob = raw_rand;\n\n  /// Distributes outcomes in the numeric range [0 .. 2^p - 1].\n  /// Seed blob must contain at least ((p+7) / 8) bytes.\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) { acc := acc * 256 + Prim.nat8ToNat(i) } 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    P.unreachable()\n  };\n\n  /// Counts the number of heads in `n` coin tosses.\n  /// Seed blob must contain at least ((n+7) / 8) bytes.\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) { acc +%= Prim.popcntNat8(i) } 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    P.unreachable()\n  }\n\n}\n"},"Trie.mo":{"content":"/// Functional key-value hash maps.\n///\n/// Functional maps (and sets) whose representation is \"canonical\", and\n/// independent of operation history (unlike other popular search trees).\n///\n/// The representation we use here comes from Section 6 of [\"Incremental computation via function caching\", Pugh & Teitelbaum](https://dl.acm.org/citation.cfm?id=75305).\n///\n/// ## User's overview\n///\n/// This module provides an applicative (functional) hash map.\n/// Notably, each `put` produces a **new trie _and value being replaced, if any_**.\n///\n/// Those looking for a more familiar (imperative,\n/// object-oriented) hash map should consider `TrieMap` or `HashMap` instead.\n///\n/// The basic `Trie` operations consist of:\n/// - `put` - put a key-value into the trie, producing a new version.\n/// - `get` - get a key's value from the trie, or `null` if none.\n/// - `iter` - visit every key-value in the trie.\n///\n/// The `put` and `get` operations work over `Key` records,\n/// which group the hash of the key with its non-hash key value.\n///\n/// ```motoko\n/// import Trie \"mo:base/Trie\";\n/// import Text \"mo:base/Text\";\n///\n/// type Trie<K, V> = Trie.Trie<K, V>;\n/// type Key<K> = Trie.Key<K>;\n///\n/// func key(t: Text) : Key<Text> { { key = t; hash = Text.hash t } };\n///\n/// let t0 : Trie<Text, Nat> = Trie.empty();\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/// let n : ?Nat = Trie.put(t1, key \"hello\", Text.equal, 0).1;\n/// assert (n == ?42);\n/// ```\n///\n\n// ## Implementation overview\n//\n// A (hash) trie is a binary tree container for key-value pairs that\n// consists of leaf and branch nodes.\n//\n// Each internal **branch node**\n// represents having distinguished its key-value pairs on a single bit of\n// the keys.\n// By following paths in the trie, we determine an increasingly smaller\n// and smaller subset of the keys.\n//\n// Each **leaf node** consists of an association list of key-value pairs.\n//\n// Each non-empty trie node stores a size; we discuss that more below.\n//\n// ### Adaptive depth\n//\n// We say that a leaf is valid if it contains no more than `MAX_LEAF_SIZE`\n// key-value pairs.  When a leaf node grows too large, the\n// binary tree produces a new internal binary node, and splits the leaf into\n// a pair of leaves using an additional bit of their keys' hash strings.\n//\n// For small mappings, the trie structure consists of a single\n// leaf, which contains up to MAX_LEAF_SIZE key-value pairs.\n//\n// ### Cached sizes\n//\n// At each branch and leaf, we use a stored size to support a\n// memory-efficient `toArray` function, which itself relies on\n// per-element projection via `nth`; in turn, `nth` directly uses the\n// O(1)-time function `size` for achieving an acceptable level of\n// algorithmic efficiency.  Notably, leaves are generally lists of\n// key-value pairs, and we do not store a size for each Cons cell in the\n// list.\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  /// we never store this bitpos; rather,\n  /// we enforce a style where this position is always known from context.\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  public type Key<K> = {\n    /// `hash` permits fast inequality checks, and permits collisions\n    hash : Hash.Hash;\n    /// `key` permits precise equality checks, but only used after equal hashes.\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) {\n    func(key1 : Key<K>, key2 : Key<K>) : Bool {\n      Hash.equal(key1.hash, key2.hash) and keq(key1.key, key2.key)\n    }\n  };\n\n  /// @deprecated `isValid` is an internal predicate and will be removed in future.\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 {\n      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    };\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  /// layer 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.\n  public func empty<K, V>() : Trie<K, V> { #empty };\n\n  ///  Get the number of key-value pairs in the trie, in constant time.\n\n  /// Get size in O(1) time.\n  public func size<K, V>(t : Trie<K, V>) : Nat {\n    switch t {\n      case (#empty) { 0 };\n      case (#leaf(l)) { l.size };\n      case (#branch(b)) { b.size }\n    }\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    let sum = size(l) + size(r);\n    #branch {\n      size = sum;\n      left = l;\n      right = r\n    }\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> {\n    fromList(null, kvs, bitpos)\n  };\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 {\n        switch l {\n          case null { ?i };\n          case (?(_, t)) {\n            if (i >= max) { null } else { rec(t, max, i + 1) }\n          }\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  /// Replace the given key's value option with the given one, returning the previous one\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\n    func rec(t : Trie<K, V>, bitpos : Nat) : (Trie<K, V>, ?V) {\n      switch t {\n        case (#empty) {\n          let (kvs, _) = AssocList.replace(null, k, key_eq, v);\n          (leaf(kvs, bitpos), null)\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, v_) = rec(b.left, bitpos + 1);\n            (branch(l, b.right), v_)\n          } else {\n            let (r, v_) = rec(b.right, bitpos + 1);\n            (branch(b.left, r), v_)\n          }\n        };\n        case (#leaf(l)) {\n          let (kvs2, old_val) = AssocList.replace(l.keyvals, k, key_eq, v);\n          (leaf(kvs2, bitpos), old_val)\n        }\n      }\n    };\n    let (to, vo) = rec(t, 0);\n    //assert(isValid<K, V>(to, false));\n    (to, vo)\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  public func put<K, V>(t : Trie<K, V>, k : Key<K>, k_eq : (K, K) -> Bool, v : V) : (Trie<K, V>, ?V) {\n    replace(t, k, k_eq, ?v)\n  };\n\n  /// Get the value of the given key in the trie, or return null if nonexistent\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  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 {\n      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    };\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>) {\n    List.partition(\n      al,\n      func((k : Key<K>, v : V)) : Bool {\n        not Hash.bit(k.hash, bitpos)\n      }\n    )\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>) {\n      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    };\n    rec(l)\n  };\n\n  /// Merge tries, preferring the left trie where there are collisions\n  /// in common keys.\n  ///\n  /// note: 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  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> {\n      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 {\n                switch (x, y) {\n                  case (null, null) { P.unreachable() };\n                  case (null, ?v) { v };\n                  case (?v, _) { v }\n                }\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    };\n    rec(0, tl, tr)\n  };\n\n  /// Merge tries like `merge`, except signals a\n  /// dynamic error if there are collisions in common keys between the\n  /// left and right inputs.\n  public func mergeDisjoint<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\n    func rec(bitpos : Nat, tl : Trie<K, V>, tr : Trie<K, V>) : Trie<K, V> {\n      switch (tl, tr) {\n        case (#empty, _) { return tr };\n        case (_, #empty) { return tl };\n        case (#leaf(l1), #leaf(l2)) {\n          leaf(\n            AssocList.disjDisjoint(\n              l1.keyvals,\n              l2.keyvals,\n              func(x : ?V, y : ?V) : V {\n                switch (x, y) {\n                  case (null, ?v) { v };\n                  case (?v, null) { v };\n                  case (_, _) { P.unreachable() }\n                }\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    };\n    rec(0, tl, tr)\n  };\n\n  /// Difference of tries. The output consists are 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  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> {\n      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    };\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> {\n      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\n    /* empty left case; build from right only: */\n    func recR(t : Trie<K, W>, bitpos : Nat) : Trie<K, X> {\n      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\n    /* main recursion */\n    func rec(bitpos : Nat, tl : Trie<K, V>, tr : Trie<K, W>) : Trie<K, X> {\n      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\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> {\n      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\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 {\n      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    };\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> {\n        foldUp(\n          tr,\n          merge,\n          func(k2 : K2, v2 : V2) : Trie<K3, V3> {\n            switch (op(k1, v1, k2, v2)) {\n              case null { #empty };\n              case (?(k3, v3)) { (put(#empty, k3, k3_eq, v3)).0 }\n            }\n          },\n          #empty\n        )\n      },\n      #empty\n    )\n  };\n\n  /// Returns an `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  public func iter<K, V>(t : Trie<K, V>) : I.Iter<(K, V)> {\n    object {\n      var stack = ?(t, null) : List.List<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  /// 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 {\n      switch tb {\n        case (#skip) { 0 };\n        case (#put(_, _, _)) { 1 };\n        case (#seq(seq)) { seq.size }\n      }\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 outer_bin(a : Build<K3, V3>, b : Build<K3, V3>) : Build<K3, V3> {\n        seq(a, b)\n      };\n\n      func inner_bin(a : Build<K3, V3>, b : Build<K3, V3>) : Build<K3, V3> {\n        seq(a, b)\n      };\n\n      /// double-nested folds\n      foldUp(\n        tl,\n        outer_bin,\n        func(k1 : K1, v1 : V1) : Build<K3, V3> {\n          foldUp(\n            tr,\n            inner_bin,\n            func(k2 : K2, v2 : V2) : Build<K3, V3> {\n              switch (op(k1, v1, k2, v2)) {\n                case null { #skip };\n                case (?(k3, v3)) { #put(k3, null, v3) }\n              }\n            },\n            #skip\n          )\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) {\n        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\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> {\n      foldUp(\n        t,\n        func(t1 : Build<K2, V>, t2 : Build<K2, V>) : Build<K2, V> {\n          seq(t1, t2)\n        },\n        func(_ : K1, t : Build<K2, V>) : Build<K2, V> { t },\n        #skip\n      )\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>) {\n        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      };\n      rec(tb);\n      A.tabulate(\n        c,\n        func(i : Nat) : W {\n          switch (a[i]) {\n            case null { P.unreachable() };\n            case (?x) { x }\n          }\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  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 {\n      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    };\n    rec(t, x)\n  };\n\n  /// Test whether a given key-value pair is present, or not.\n  public func some<K, V>(t : Trie<K, V>, f : (K, V) -> Bool) : Bool {\n    func rec(t : Trie<K, V>) : Bool {\n      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    };\n    rec(t)\n  };\n\n  /// Test whether all key-value pairs have a given property.\n  public func all<K, V>(t : Trie<K, V>, f : (K, V) -> Bool) : Bool {\n    func rec(t : Trie<K, V>) : Bool {\n      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    };\n    rec(t)\n  };\n\n  /// Project the nth key-value pair from the trie.\n  ///\n  /// Note: This position is not meaningful; it's only here so that we\n  /// can inject tries into arrays using functions like `Array.tabulate`.\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) {\n      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    };\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  public func toArray<K, V, W>(t : Trie<K, V>, f : (K, V) -> W) : [W] {\n    let a = 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    a\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 {\n    size(t) == 0\n  };\n\n  /// Filter the key-value pairs by a given predicate.\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> {\n      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          if (isEmpty(fl) and isEmpty(fr)) {\n            #empty\n          } else {\n            branch(fl, fr)\n          }\n        }\n      }\n    };\n    rec(t, 0)\n  };\n\n  /// Map and filter the key-value pairs by a given predicate.\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> {\n      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) {\n                switch (f(k.key, v)) {\n                  case null { null };\n                  case (?w) { ?({ key = k.key; hash = k.hash }, w) }\n                }\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          if (isEmpty(fl) and isEmpty(fr)) {\n            #empty\n          } else {\n            branch(fl, fr)\n          }\n        }\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 {\n      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    };\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  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  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 given key's value in the trie; return the new trie\n  public func remove<K, V>(t : Trie<K, V>, k : Key<K>, k_eq : (K, K) -> Bool) : (Trie<K, V>, ?V) {\n    replace(t, k, k_eq, null)\n  };\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) {\n    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\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) {\n    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\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> {\n    foldUp(\n      t,\n      func(t1 : Trie<K2, V>, t2 : Trie<K2, V>) : Trie<K2, V> {\n        mergeDisjoint(t1, t2, k2_eq)\n      },\n      func(_ : K1, t : Trie<K2, V>) : Trie<K2, V> { t },\n      #empty\n    )\n  };\n\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"},"Array.mo":{"content":"/// Provides extended utility functions on Arrays.\n///\n/// Note the difference between mutable and non-mutable arrays below.\n///\n/// WARNING: If you are looking for a list that can grow and shrink in size,\n/// it is recommended you use either the Buffer class or the List class for\n/// those purposes. Arrays must be created with a fixed size.\n///\n/// Import from the base library to use this module.\n/// ```motoko name=import\n/// import Array \"mo:base/Array\";\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: O(size)\n  /// Space: 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: O(size)\n  /// Space: O(size)\n  ///\n  /// *Runtime and space assumes that `generator` runs in O(1) time and space.\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: O(size)\n  /// Space: O(size)\n  ///\n  /// *Runtime and space assumes that `generator` runs in O(1) time and space.\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 = 0;\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: O(size)\n  ///\n  /// Space: 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: O(size)\n  ///\n  /// Space: 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: O(size1 + size2)\n  ///\n  /// Space: O(1)\n  ///\n  /// *Runtime and space assumes that `equal` runs in O(1) time and space.\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  /// Runtime: O(size)\n  ///\n  /// Space: O(1)\n  ///\n  /// *Runtime and space assumes that `predicate` runs in O(1) time and space.\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  /// @deprecated `Array.append` copies its arguments and has linear complexity;\n  /// when used in a loop, consider using a `Buffer`, and `Buffer.append`, instead.\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  /// Runtime: O(size1 + size2)\n  ///\n  /// Space: 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  // FIXME this example stack overflows. Should test with new implementation of sortInPlace\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  /// Runtime: O(size * log(size))\n  ///\n  /// Space: O(size)\n  /// *Runtime and space assumes that `compare` runs in O(1) time and space.\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  ///\n  /// import {compare} \"mo:base/Nat\";\n  ///\n  /// let array = [var 4, 2, 6];\n  /// Array.sortInPlace(array, compare);\n  /// array\n  /// ```\n  /// Runtime: O(size * log(size))\n  ///\n  /// Space: O(size)\n  /// *Runtime and space assumes that `compare` runs in O(1) time and space.\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  ///\n  /// let array = [10, 11, 12];\n  ///\n  /// Array.reverse(array)\n  /// ```\n  ///\n  /// Runtime: O(size)\n  ///\n  /// Space: 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  ///\n  /// let array = [0, 1, 2, 3];\n  /// Array.map<Nat, Nat>(array, func x = x * 3)\n  /// ```\n  ///\n  /// Runtime: O(size)\n  ///\n  /// Space: O(size)\n  ///\n  /// *Runtime and space assumes that `f` runs in O(1) time and space.\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  /// Runtime: O(size)\n  ///\n  /// Space: O(size)\n  /// *Runtime and space assumes that `predicate` runs in O(1) time and space.\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  // FIXME the arguments ordering to the higher order function are flipped\n  // between this and the buffer class\n  // probably can't avoid breaking changes at some point\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  ///\n  /// let array = [10, 10, 10, 10];\n  /// Array.mapEntries<Nat, Nat>(array, func (i, x) = i * x)\n  /// ```\n  ///\n  /// Runtime: O(size)\n  ///\n  /// Space: O(size)\n  ///\n  /// *Runtime and space assumes that `f` runs in O(1) time and space.\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  /// Runtime: O(size)\n  ///\n  /// Space: O(size)\n  /// *Runtime and space assumes that `f` runs in O(1) time and space.\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: O(size)\n  ///\n  /// Space: O(size)\n  ///\n  /// *Runtime and space assumes that `f` runs in O(1) time and space.\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    var target : [var Y] = [var];\n    var isInit = false;\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  /// Runtime: O(size)\n  ///\n  /// Space: O(size)\n  /// *Runtime and space assumes that `k` runs in O(1) time and space.\n  public func chain<X, Y>(array : [X], k : X -> [Y]) : [Y] {\n    var flatSize = 0;\n    let subArrays = 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    // 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        let subArray = subArrays[outer];\n        let element = subArray[inner];\n        inner += 1;\n        if (inner == subArray.size()) {\n          inner := 0;\n          outer += 1\n        };\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: O(size)\n  ///\n  /// Space: O(1)\n  ///\n  /// *Runtime and space assumes that `combine` runs in O(1) time and space.\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  // FIXME the type arguments are reverse order from Buffer\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: O(size)\n  ///\n  /// Space: O(1)\n  ///\n  /// *Runtime and space assumes that `combine` runs in O(1) time and space.\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  ///\n  /// let arrays = [[0, 1, 2], [2, 3], [], [4]];\n  /// Array.flatten<Nat>(arrays)\n  /// ```\n  ///\n  /// Runtime: O(number of elements in array)\n  ///\n  /// Space: O(number of elements in array)\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: O(1)\n  ///\n  /// Space: 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: You can also use `array.vals()` instead of this function. See example\n  /// below.\n  ///\n  /// ```motoko include=import\n  ///\n  /// let array = [10, 11, 12];\n  ///\n  /// var sum = 0;\n  /// for (element in array.vals()) {\n  ///   sum += element;\n  /// };\n  /// sum\n  /// ```\n  ///\n  /// Runtime: O(1)\n  ///\n  /// Space: 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: You can also use `array.keys()` instead of this function. See example\n  /// below.\n  ///\n  /// ```motoko include=import\n  ///\n  /// let array = [10, 11, 12];\n  ///\n  /// var sum = 0;\n  /// for (element in array.keys()) {\n  ///   sum += element;\n  /// };\n  /// sum\n  /// ```\n  ///\n  /// Runtime: O(1)\n  ///\n  /// Space: O(1)\n  public func keys<X>(array : [X]) : I.Iter<Nat> = array.keys();\n\n  /// Returns the size of `array`.\n  ///\n  /// NOTE: You can also use `array.size()` instead of this function. See example\n  /// below.\n  ///\n  /// ```motoko include=import\n  ///\n  /// let array = [10, 11, 12];\n  /// let size = Array.size(array);\n  /// ```\n  ///\n  /// Runtime: O(1)\n  ///\n  /// Space: O(1)\n  public func size<X>(array : [X]) : Nat = array.size()\n}\n"},"Func.mo":{"content":"/// Functions on functions\n///\n/// (Most commonly used when programming in functional style using higher-order\n/// functions.)\n\nmodule {\n\n  /// The composition of two functions `f` and `g` is a function that applies `g` and then `f`.\n  ///\n  /// ```\n  /// compose(f, g)(x) = f(g(x))\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  /// ```motoko\n  /// import Func \"mo:base/Func\";\n  /// assert(Func.identity(10) == 10);\n  /// assert(Func.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  /// ```motoko\n  /// import Func \"mo:base/Func\";\n  /// assert(Func.const<Nat, Text>(10)(\"hello\") == 10);\n  /// assert(Func.const<Bool, Nat>(true)(20) == true);\n  /// ```\n  public func const<A, B>(x : A) : B -> A = func(_) = x\n}\n"},"Float.mo":{"content":"/// 64-bit Floating-point numbers\n\nimport Prim \"mo:⛔\";\nimport Int \"Int\";\n\nmodule {\n\n  /// 64-bit floating point numbers.\n  public type Float = Prim.Types.Float;\n\n  /// Ratio of the circumference of a circle to its diameter.\n  public let pi : Float = 3.14159265358979323846; // taken from musl math.h\n\n  /// Base of the natural logarithm.\n  public let e : Float = 2.7182818284590452354; // taken from musl math.h\n\n  /// Returns the absolute value of `x`.\n  public let abs : (x : Float) -> Float = Prim.floatAbs;\n\n  /// Returns the square root of `x`.\n  public let sqrt : (x : Float) -> Float = Prim.floatSqrt;\n\n  /// Returns the smallest integral float greater than or equal to `x`.\n  public let ceil : (x : Float) -> Float = Prim.floatCeil;\n\n  /// Returns the largest integral float less than or equal to `x`.\n  public let floor : (x : Float) -> Float = Prim.floatFloor;\n\n  /// Returns the nearest integral float not greater in magnitude than `x`.\n  public let trunc : (x : Float) -> Float = Prim.floatTrunc;\n\n  /// Returns the nearest integral float to `x`.\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  public let copySign : (x : Float, y : Float) -> Float = Prim.floatCopySign;\n\n  /// Returns the smaller value of `x` and `y`.\n  public let min : (x : Float, y : Float) -> Float = Prim.floatMin;\n\n  /// Returns the larger value of `x` and `y`.\n  public let max : (x : Float, y : Float) -> Float = Prim.floatMax;\n\n  /// Returns the sine of the radian angle `x`.\n  public let sin : (x : Float) -> Float = Prim.sin;\n\n  /// Returns the cosine of the radian angle `x`.\n  public let cos : (x : Float) -> Float = Prim.cos;\n\n  /// Returns the tangent of the radian angle `x`.\n  public let tan : (x : Float) -> Float = Prim.tan;\n\n  /// Returns the arc sine of `x` in radians.\n  public let arcsin : (x : Float) -> Float = Prim.arcsin;\n\n  /// Returns the arc cosine of `x` in radians.\n  public let arccos : (x : Float) -> Float = Prim.arccos;\n\n  /// Returns the arc tangent of `x` in radians.\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  public let arctan2 : (y : Float, x : Float) -> Float = Prim.arctan2;\n\n  /// Returns the value of `e` raised to the `x`-th power.\n  public let exp : (x : Float) -> Float = Prim.exp;\n\n  /// Returns the natural logarithm (base-`e`) of `x`.\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  /// * `#hex prec` as hexadecimal format with `prec` digits\n  /// * `#exact` as exact format that can be decoded without loss.\n  public func format(fmt : { #fix : Nat8; #exp : Nat8; #gen : Nat8; #hex : 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 (#hex(prec)) { Prim.floatToFormattedText(x, prec, 3) };\n    case (#exact) { Prim.floatToFormattedText(x, 17, 2) }\n  };\n\n  /// Conversion to Text. Use `format(fmt, x)` for more detailed control.\n  public let toText : Float -> Text = Prim.floatToText;\n\n  /// Conversion to Int64 by truncating Float, equivalent to `toInt64(trunc(f))`\n  public let toInt64 : Float -> Int64 = Prim.floatToInt64;\n\n  /// Conversion from Int64.\n  public let fromInt64 : Int64 -> Float = Prim.int64ToFloat;\n\n  /// Conversion to Int.\n  public let toInt : Float -> Int = Prim.floatToInt;\n\n  /// Conversion from Int. May result in `Inf`.\n  public let fromInt : Int -> Float = Prim.intToFloat;\n\n  /// Returns `x == y`.\n  public func equal(x : Float, y : Float) : Bool { x == y };\n\n  /// Returns `x != y`.\n  public func notEqual(x : Float, y : Float) : Bool { x != y };\n\n  /// Returns `x < y`.\n  public func less(x : Float, y : Float) : Bool { x < y };\n\n  /// Returns `x <= y`.\n  public func lessOrEqual(x : Float, y : Float) : Bool { x <= y };\n\n  /// Returns `x > y`.\n  public func greater(x : Float, y : Float) : Bool { x > y };\n\n  /// Returns `x >= y`.\n  public func greaterOrEqual(x : Float, y : Float) : Bool { x >= y };\n\n  /// Returns the order of `x` and `y`.\n  public func compare(x : Float, y : Float) : { #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  public func neq(x : Float) : Float { -x };\n\n  /// Returns the sum of `x` and `y`, `x + y`.\n  public func add(x : Float, y : Float) : Float { x + y };\n\n  /// Returns the difference of `x` and `y`, `x - y`.\n  public func sub(x : Float, y : Float) : Float { x - y };\n\n  /// Returns the product of `x` and `y`, `x * y`.\n  public func mul(x : Float, y : Float) : Float { x * y };\n\n  /// Returns the division of `x` by `y`, `x / y`.\n  public func div(x : Float, y : Float) : Float { x / y };\n\n  /// Returns the remainder of `x` divided by `y`, `x % y`.\n  public func rem(x : Float, y : Float) : Float { x % y };\n\n  /// Returns `x` to the power of `y`, `x ** y`.\n  public func pow(x : Float, y : Float) : Float { x ** y };\n\n}\n"},"Char.mo":{"content":"/// Characters\nimport 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"},"Int64.mo":{"content":"/// 64-bit signed integers with checked arithmetic\n///\n/// Most operations are available as built-in operators (e.g. `1 + 1`).\nimport Int \"Int\";\nimport Prim \"mo:⛔\";\n\nmodule {\n\n  /// 64-bit signed integers.\n  public type Int64 = Prim.Types.Int64;\n\n  /// Conversion.\n  public let toInt : Int64 -> Int = Prim.int64ToInt;\n\n  /// Conversion. Traps on overflow/underflow.\n  public let fromInt : Int -> Int64 = Prim.intToInt64;\n\n  /// Conversion. Wraps on overflow/underflow.\n  public let fromIntWrap : Int -> Int64 = Prim.intToInt64Wrap;\n\n  /// Conversion. Wraps on overflow/underflow.\n  public let fromNat64 : Nat64 -> Int64 = Prim.nat64ToInt64;\n\n  /// Conversion. Wraps on overflow/underflow.\n  public let toNat64 : Int64 -> Nat64 = Prim.int64ToNat64;\n\n  /// Returns the Text representation of `x`.\n  public func toText(x : Int64) : Text {\n    Int.toText(toInt(x))\n  };\n\n  /// Returns the absolute value of `x`. Traps when `x = -2^63`.\n  public func abs(x : Int64) : Int64 {\n    fromInt(Int.abs(toInt(x)))\n  };\n\n  /// Returns the minimum of `x` and `y`.\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  public func max(x : Int64, y : Int64) : Int64 {\n    if (x < y) { y } else { x }\n  };\n\n  /// Returns `x == y`.\n  public func equal(x : Int64, y : Int64) : Bool { x == y };\n\n  /// Returns `x != y`.\n  public func notEqual(x : Int64, y : Int64) : Bool { x != y };\n\n  /// Returns `x < y`.\n  public func less(x : Int64, y : Int64) : Bool { x < y };\n\n  /// Returns `x <= y`.\n  public func lessOrEqual(x : Int64, y : Int64) : Bool { x <= y };\n\n  /// Returns `x > y`.\n  public func greater(x : Int64, y : Int64) : Bool { x > y };\n\n  /// Returns `x >= y`.\n  public func greaterOrEqual(x : Int64, y : Int64) : Bool { x >= y };\n\n  /// Returns the order of `x` and `y`.\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`. Traps on overflow.\n  public func neg(x : Int64) : Int64 { -x };\n\n  /// Returns the sum of `x` and `y`, `x + y`. Traps on overflow.\n  public func add(x : Int64, y : Int64) : Int64 { x + y };\n\n  /// Returns the difference of `x` and `y`, `x - y`. Traps on underflow.\n  public func sub(x : Int64, y : Int64) : Int64 { x - y };\n\n  /// Returns the product of `x` and `y`, `x * y`. Traps on overflow.\n  public func mul(x : Int64, y : Int64) : Int64 { x * y };\n\n  /// Returns the division of `x by y`, `x / y`.\n  /// Traps when `y` is zero.\n  public func div(x : Int64, y : Int64) : Int64 { x / y };\n\n  /// Returns the remainder of `x` divided by `y`, `x % y`.\n  /// Traps when `y` is zero.\n  public func rem(x : Int64, y : Int64) : Int64 { x % y };\n\n  /// Returns `x` to the power of `y`, `x ** y`. Traps on overflow.\n  public func pow(x : Int64, y : Int64) : Int64 { x ** y };\n\n  /// Returns the bitwise negation of `x`, `^x`.\n  public func bitnot(x : Int64, y : Int64) : Int64 { ^x };\n\n  /// Returns the bitwise and of `x` and `y`, `x & y`.\n  public func bitand(x : Int64, y : Int64) : Int64 { x & y };\n\n  /// Returns the bitwise or of `x` and `y`, `x \\| y`.\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  public func bitxor(x : Int64, y : Int64) : Int64 { x ^ y };\n\n  /// Returns the bitwise shift left of `x` by `y`, `x << y`.\n  public func bitshiftLeft(x : Int64, y : Int64) : Int64 { x << y };\n\n  /// Returns the bitwise shift right of `x` by `y`, `x >> y`.\n  public func bitshiftRight(x : Int64, y : Int64) : Int64 { x >> y };\n\n  /// Returns the bitwise rotate left of `x` by `y`, `x <<> y`.\n  public func bitrotLeft(x : Int64, y : Int64) : Int64 { x <<> y };\n\n  /// Returns the bitwise rotate right of `x` by `y`, `x <>> y`.\n  public func bitrotRight(x : Int64, y : Int64) : Int64 { x <>> y };\n\n  /// Returns the value of bit `p mod 64` in `x`, `(x & 2^(p mod 64)) == 2^(p mod 64)`.\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 mod 64` in `x` to `1`.\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 mod 64` in `x` to `0`.\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 mod 64` in `x`.\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  public let bitcountNonZero : (x : Int64) -> Int64 = Prim.popcntInt64;\n\n  /// Returns the count of leading zero bits in `x`.\n  public let bitcountLeadingZero : (x : Int64) -> Int64 = Prim.clzInt64;\n\n  /// Returns the count of trailing zero bits in `x`.\n  public let bitcountTrailingZero : (x : Int64) -> Int64 = Prim.ctzInt64;\n\n  /// Returns the sum of `x` and `y`, `x +% y`. Wraps on overflow.\n  public func addWrap(x : Int64, y : Int64) : Int64 { x +% y };\n\n  /// Returns the difference of `x` and `y`, `x -% y`. Wraps on underflow.\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  public func mulWrap(x : Int64, y : Int64) : Int64 { x *% y };\n\n  /// Returns `x` to the power of `y`, `x **% y`. Wraps on overflow. Traps if `y < 0`.\n  public func powWrap(x : Int64, y : Int64) : Int64 { x **% y };\n\n}\n"},"Principal.mo":{"content":"/// IC principals (user and canister smart contract IDs)\n\nimport Prim \"mo:⛔\";\nimport Blob \"Blob\";\nimport Hash \"Hash\";\nmodule {\n\n  /// Internet Computer principal identifiers.\n  /// Convert to `Blob` for access to bytes.\n  public type Principal = Prim.Types.Principal;\n\n  /// Conversion.\n  public let fromActor : (a : actor {}) -> Principal = Prim.principalOfActor;\n\n  /// Conversion.\n  public let toBlob : (p : Principal) -> Blob = Prim.blobOfPrincipal;\n\n  /// Conversion.\n  public let fromBlob : (b : Blob) -> Principal = Prim.principalOfBlob;\n\n  /// Conversion.\n  public func toText(p : Principal) : Text = debug_show (p);\n\n  private let anonymousPrincipal : Blob = \"\\04\";\n\n  public func isAnonymous(p : Principal) : Bool = Prim.blobOfPrincipal p == anonymousPrincipal;\n\n  public func hash(principal : Principal) : Hash.Hash = Blob.hash(Prim.blobOfPrincipal(principal));\n\n  public func fromText(t : Text) : Principal = fromActor(actor (t));\n\n  /// Returns `x == y`.\n  public func equal(x : Principal, y : Principal) : Bool { x == y };\n\n  /// Returns `x != y`.\n  public func notEqual(x : Principal, y : Principal) : Bool { x != y };\n\n  /// Returns `x < y`.\n  public func less(x : Principal, y : Principal) : Bool { x < y };\n\n  /// Returns `x <= y`.\n  public func lessOrEqual(x : Principal, y : Principal) : Bool { x <= y };\n\n  /// Returns `x > y`.\n  public func greater(x : Principal, y : Principal) : Bool { x > y };\n\n  /// Returns `x >= y`.\n  public func greaterOrEqual(x : Principal, y : Principal) : Bool { x >= y };\n\n  /// Returns the order of `x` and `y`.\n  public func compare(x : Principal, y : Principal) : {\n    #less;\n    #equal;\n    #greater\n  } {\n    if (x < y) { #less } else if (x == y) { #equal } else { #greater }\n  }\n}\n"},"Nat8.mo":{"content":"/// 8-bit unsigned integers with checked arithmetic\n///\n/// Most operations are available as built-in operators (e.g. `1 + 1`).\nimport Nat \"Nat\";\nimport Prim \"mo:⛔\";\n\nmodule {\n\n  /// 8-bit natural numbers.\n  public type Nat8 = Prim.Types.Nat8;\n\n  /// Conversion.\n  public let toNat : Nat8 -> Nat = Prim.nat8ToNat;\n\n  /// Conversion. Traps on overflow/underflow.\n  public let fromNat : Nat -> Nat8 = Prim.natToNat8;\n\n  /// Conversion. Wraps on overflow/underflow.\n  public let fromIntWrap : Int -> Nat8 = Prim.intToNat8Wrap;\n\n  /// Returns the Text representation of `x`.\n  public func toText(x : Nat8) : Text {\n    Nat.toText(toNat(x))\n  };\n\n  /// Returns the minimum of `x` and `y`.\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  public func max(x : Nat8, y : Nat8) : Nat8 {\n    if (x < y) { y } else { x }\n  };\n\n  /// Returns `x == y`.\n  public func equal(x : Nat8, y : Nat8) : Bool { x == y };\n\n  /// Returns `x != y`.\n  public func notEqual(x : Nat8, y : Nat8) : Bool { x != y };\n\n  /// Returns `x < y`.\n  public func less(x : Nat8, y : Nat8) : Bool { x < y };\n\n  /// Returns `x <= y`.\n  public func lessOrEqual(x : Nat8, y : Nat8) : Bool { x <= y };\n\n  /// Returns `x > y`.\n  public func greater(x : Nat8, y : Nat8) : Bool { x > y };\n\n  /// Returns `x >= y`.\n  public func greaterOrEqual(x : Nat8, y : Nat8) : Bool { x >= y };\n\n  /// Returns the order of `x` and `y`.\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`. Traps on overflow.\n  public func add(x : Nat8, y : Nat8) : Nat8 { x + y };\n\n  /// Returns the difference of `x` and `y`, `x - y`. Traps on underflow.\n  public func sub(x : Nat8, y : Nat8) : Nat8 { x - y };\n\n  /// Returns the product of `x` and `y`, `x * y`. Traps on overflow.\n  public func mul(x : Nat8, y : Nat8) : Nat8 { x * y };\n\n  /// Returns the division of `x by y`, `x / y`.\n  /// Traps when `y` is zero.\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  public func rem(x : Nat8, y : Nat8) : Nat8 { x % y };\n\n  /// Returns `x` to the power of `y`, `x ** y`. Traps on overflow.\n  public func pow(x : Nat8, y : Nat8) : Nat8 { x ** y };\n\n  /// Returns the bitwise negation of `x`, `^x`.\n  public func bitnot(x : Nat8, y : Nat8) : Nat8 { ^x };\n\n  /// Returns the bitwise and of `x` and `y`, `x & y`.\n  public func bitand(x : Nat8, y : Nat8) : Nat8 { x & y };\n\n  /// Returns the bitwise or of `x` and `y`, `x \\| y`.\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  public func bitxor(x : Nat8, y : Nat8) : Nat8 { x ^ y };\n\n  /// Returns the bitwise shift left of `x` by `y`, `x << y`.\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  public func bitshiftRight(x : Nat8, y : Nat8) : Nat8 { x >> y };\n\n  /// Returns the bitwise rotate left of `x` by `y`, `x <<> y`.\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  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  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  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  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  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  public let bitcountNonZero : (x : Nat8) -> Nat8 = Prim.popcntNat8;\n\n  /// Returns the count of leading zero bits in `x`.\n  public let bitcountLeadingZero : (x : Nat8) -> Nat8 = Prim.clzNat8;\n\n  /// Returns the count of trailing zero bits in `x`.\n  public let bitcountTrailingZero : (x : Nat8) -> Nat8 = Prim.ctzNat8;\n\n  /// Returns the sum of `x` and `y`, `x +% y`. Wraps on overflow.\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  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  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  public func powWrap(x : Nat8, y : Nat8) : Nat8 { x **% y };\n\n}\n"},"Int.mo":{"content":"/// Signed integer numbers with infinite precision (also called big integers).\n///\n/// Common integer functions.\n/// Most operations on integers (e.g. addition) are also available as built-in operators (e.g. `1 + 1`).\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\n  /// import Int \"mo:base/Int\";\n  ///\n  /// Int.abs(-12) // => 12\n  /// ```\n  public let abs : (x : Int) -> Nat = Prim.abs;\n\n  /// Conversion to Text.\n  /// Formats the integer in decimal representation without underscore separators for blocks of thousands.\n  ///\n  /// Example:\n  /// ```motoko\n  /// import Int \"mo:base/Int\";\n  ///\n  /// Int.toText(-1234) // => \"-1234\"\n  /// ```\n  public let toText : Int -> Text = func(x) {\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\n  /// import Int \"mo:base/Int\";\n  ///\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\n  /// import Int \"mo:base/Int\";\n  ///\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  /// @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  /// Returns `x == y`.\n  ///\n  /// Example:\n  /// ```motoko\n  /// import Int \"mo:base/Int\";\n  ///\n  /// Int.equal(123, 123) // => true\n  /// ```\n  public func equal(x : Int, y : Int) : Bool { x == y };\n\n  /// Returns `x != y`.\n  ///\n  /// Example:\n  /// ```motoko\n  /// import Int \"mo:base/Int\";\n  ///\n  /// Int.notEqual(123, 123) // => false\n  /// ```\n  public func notEqual(x : Int, y : Int) : Bool { x != y };\n\n  /// Returns `x < y`.\n  ///\n  /// Example:\n  /// ```motoko\n  /// import Int \"mo:base/Int\";\n  ///\n  /// Int.less(123, 1234) // => true\n  /// ```\n  public func less(x : Int, y : Int) : Bool { x < y };\n\n  /// Returns `x <= y`.\n  ///\n  /// Example:\n  /// ```motoko\n  /// import Int \"mo:base/Int\";\n  ///\n  /// Int.lessOrEqual(123, 1234) // => true\n  /// ```\n  public func lessOrEqual(x : Int, y : Int) : Bool { x <= y };\n\n  /// Returns `x > y`.\n  ///\n  /// Example:\n  /// ```motoko\n  /// import Int \"mo:base/Int\";\n  ///\n  /// Int.greater(1234, 123) // => true\n  /// ```\n  public func greater(x : Int, y : Int) : Bool { x > y };\n\n  /// Returns `x >= y`.\n  ///\n  /// Example:\n  /// ```motoko\n  /// import Int \"mo:base/Int\";\n  ///\n  /// Int.greaterOrEqual(1234, 123) // => true\n  /// ```\n  public func greaterOrEqual(x : Int, y : Int) : Bool { x >= y };\n\n  /// Returns the order of `x` and `y`.\n  ///\n  /// Example:\n  /// ```motoko\n  /// import Int \"mo:base/Int\";\n  ///\n  /// Int.compare(123, 1234) // => #less\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\n  /// import Int \"mo:base/Int\";\n  ///\n  /// Int.neg(123) // => -123\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\n  /// import Int \"mo:base/Int\";\n  ///\n  /// Int.add(1234, 123) // => 1_357\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\n  /// import Int \"mo:base/Int\";\n  ///\n  /// Int.sub(1234, 123) // => 1_111\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\n  /// import Int \"mo:base/Int\";\n  ///\n  /// Int.mul(123, 100) // => 12_300\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\n  /// import Int \"mo:base/Int\";\n  ///\n  /// Int.div(123, 10) // => 12\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\n  /// import Int \"mo:base/Int\";\n  ///\n  /// Int.rem(123, 10) // => 3\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\n  /// import Int \"mo:base/Int\";\n  ///\n  /// Int.pow(2, 10) // => 1_024\n  /// ```\n  public func pow(x : Int, y : Int) : Int { x ** y };\n\n}\n"},"Hash.mo":{"content":"/// Hash values\n\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  /// @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  /// @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  /// Jenkin's one at a time:\n  ///\n  /// https://en.wikipedia.org/wiki/Jenkins_hash_function#one_at_a_time\n  ///\n  /// The input type should actually be `[Nat8]`.\n  /// Note: Be sure to explode each `Nat8` of a `Nat32` into its own `Nat32`, and to shift into lower 8 bits.\n\n  // should this really be public?\n  // NB: Int.mo contains a local copy of hashNat8 (redefined to suppress the deprecation warning).\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"},"None.mo":{"content":"/// The absent value\n///\n/// 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"},"RBTree.mo":{"content":"/// Red-Black Trees\n\nimport Debug \"Debug\";\nimport I \"Iter\";\nimport List \"List\";\nimport Nat \"Nat\";\nimport O \"Order\";\n\nmodule {\n\n  /// Node color: red or black.\n  public type Color = { #R; #B };\n\n  /// Ordered, (red-black) tree of entries.\n  public type Tree<X, Y> = {\n    #node : (Color, Tree<X, Y>, (X, ?Y), Tree<X, Y>);\n    #leaf\n  };\n\n  /// Create an order map from an order function for its keys.\n  public class RBTree<X, Y>(compareTo : (X, X) -> O.Order) {\n\n    var tree : Tree<X, Y> = (#leaf : Tree<X, Y>);\n\n    /// Tree as sharable data.\n    ///\n    /// Get non-OO, purely-functional representation:\n    /// for drawing, pretty-printing and non-OO contexts\n    /// (e.g., async args and results):\n    public func share() : Tree<X, Y> {\n      tree\n    };\n\n    /// Get the value associated with a given key.\n    public func get(x : X) : ?Y {\n      getRec(x, compareTo, tree)\n    };\n\n    /// Replace the value associated with a given key.\n    public func replace(x : X, y : Y) : ?Y {\n      let (res, t) = insertRoot(x, compareTo, y, tree);\n      tree := t;\n      res\n    };\n\n    /// Put an entry: A value associated with a given key.\n    public func put(x : X, y : Y) {\n      let (res, t) = insertRoot(x, compareTo, y, tree);\n      tree := t\n    };\n\n    /// Delete the entry associated with a given key.\n    public func delete(x : X) {\n      let (res, t) = removeRec(x, compareTo, tree);\n      tree := t\n    };\n\n    /// Remove the entry associated with a given key.\n    public func remove(x : X) : ?Y {\n      let (res, t) = removeRec(x, compareTo, tree);\n      tree := t;\n      res\n    };\n\n    /// An iterator for the key-value entries of the map, in ascending key order.\n    ///\n    /// iterator is persistent, like the tree itself\n    public func entries() : I.Iter<(X, Y)> { iter(tree, #fwd) };\n\n    /// An iterator for the key-value entries of the map, in descending key order.\n    ///\n    /// iterator is persistent, like the tree itself\n    public func entriesRev() : I.Iter<(X, Y)> { iter(tree, #bwd) };\n\n  };\n\n  type IterRep<X, Y> = List.List<{ #tr : Tree<X, Y>; #xy : (X, ?Y) }>;\n\n  /// An iterator for the entries of the map, in ascending (`#fwd`) or descending (`#bwd`) order.\n  public func iter<X, Y>(t : Tree<X, Y>, dir : { #fwd; #bwd }) : I.Iter<(X, Y)> {\n    object {\n      var trees : IterRep<X, Y> = ?(#tr(t), null);\n      public func next() : ?(X, Y) {\n        switch (dir, 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, compareTo : (X, X) -> O.Order, t : Tree<X, Y>) : (?Y, Tree<X, Y>) {\n    switch t {\n      case (#leaf) { (null, #leaf) };\n      case (#node(c, l, xy, r)) {\n        switch (compareTo(x, xy.0)) {\n          case (#less) {\n            let (yo, l2) = removeRec(x, compareTo, l);\n            (yo, #node(c, l2, xy, r))\n          };\n          case (#equal) { (xy.1, #node(c, l, (x, null), r)) };\n          case (#greater) {\n            let (yo, r2) = removeRec(x, compareTo, r);\n            (yo, #node(c, l, xy, r2))\n          }\n        }\n      }\n    }\n  };\n\n  func bal<X, Y>(color : Color, lt : Tree<X, Y>, kv : (X, ?Y), rt : Tree<X, Y>) : Tree<X, Y> {\n    // thank you, algebraic pattern matching!\n    // following notes from [Ravi Chugh](https://www.classes.cs.uchicago.edu/archive/2019/spring/22300-1/lectures/RedBlackTrees/index.html)\n    switch (color, lt, kv, rt) {\n      case (#B, #node(#R, #node(#R, a, x, b), y, c), z, d) {\n        #node(#R, #node(#B, a, x, b), y, #node(#B, c, z, d))\n      };\n      case (#B, #node(#R, a, x, #node(#R, b, y, c)), z, d) {\n        #node(#R, #node(#B, a, x, b), y, #node(#B, c, z, d))\n      };\n      case (#B, a, x, #node(#R, #node(#R, b, y, c), z, d)) {\n        #node(#R, #node(#B, a, x, b), y, #node(#B, c, z, d))\n      };\n      case (#B, a, x, #node(#R, b, y, #node(#R, c, z, d))) {\n        #node(#R, #node(#B, a, x, b), y, #node(#B, c, z, d))\n      };\n      case _ { #node(color, lt, kv, rt) }\n    }\n  };\n\n  func insertRoot<X, Y>(x : X, compareTo : (X, X) -> O.Order, y : Y, t : Tree<X, Y>) : (?Y, Tree<X, Y>) {\n    switch (insertRec(x, compareTo, y, t)) {\n      case (_, #leaf) { assert false; loop {} };\n      case (yo, #node(_, l, xy, r)) { (yo, #node(#B, l, xy, r)) }\n    }\n  };\n\n  func insertRec<X, Y>(x : X, compareTo : (X, X) -> O.Order, y : Y, t : Tree<X, Y>) : (?Y, Tree<X, Y>) {\n    switch t {\n      case (#leaf) { (null, #node(#R, #leaf, (x, ?y), #leaf)) };\n      case (#node(c, l, xy, r)) {\n        switch (compareTo(x, xy.0)) {\n          case (#less) {\n            let (yo, l2) = insertRec(x, compareTo, y, l);\n            (yo, bal(c, l2, xy, r))\n          };\n          case (#equal) { (xy.1, #node(c, l, (x, ?y), r)) };\n          case (#greater) {\n            let (yo, r2) = insertRec(x, compareTo, y, r);\n            (yo, bal(c, l, xy, r2))\n          }\n        }\n      }\n    }\n  };\n\n  func getRec<X, Y>(x : X, compareTo : (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 (compareTo(x, xy.0)) {\n          case (#less) { getRec(x, compareTo, l) };\n          case (#equal) { xy.1 };\n          case (#greater) { getRec(x, compareTo, r) }\n        }\n      }\n    }\n  };\n\n  func height<X, Y>(t : Tree<X, Y>) : Nat {\n    switch t {\n      case (#leaf) { 0 };\n      case (#node(_, l, _, r)) {\n        Nat.max(height(l), height(r)) + 1\n      }\n    }\n  };\n\n  /// The size of the tree as the number of key-value entries.\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}\n"},"Int8.mo":{"content":"/// 8-bit signed integers with checked arithmetic\n///\n/// Most operations are available as built-in operators (e.g. `1 + 1`).\nimport Int \"Int\";\nimport Prim \"mo:⛔\";\n\nmodule {\n\n  /// 8-bit signed integers.\n  public type Int8 = Prim.Types.Int8;\n\n  /// Conversion.\n  public let toInt : Int8 -> Int = Prim.int8ToInt;\n\n  /// Conversion. Traps on overflow/underflow.\n  public let fromInt : Int -> Int8 = Prim.intToInt8;\n\n  /// Conversion. Wraps on overflow/underflow.\n  public let fromIntWrap : Int -> Int8 = Prim.intToInt8Wrap;\n\n  /// Conversion. Wraps on overflow/underflow.\n  public let fromNat8 : Nat8 -> Int8 = Prim.nat8ToInt8;\n\n  /// Conversion. Wraps on overflow/underflow.\n  public let toNat8 : Int8 -> Nat8 = Prim.int8ToNat8;\n\n  /// Returns the Text representation of `x`.\n  public func toText(x : Int8) : Text {\n    Int.toText(toInt(x))\n  };\n\n  /// Returns the absolute value of `x`. Traps when `x = -2^7`.\n  public func abs(x : Int8) : Int8 {\n    fromInt(Int.abs(toInt(x)))\n  };\n\n  /// Returns the minimum of `x` and `y`.\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  public func max(x : Int8, y : Int8) : Int8 {\n    if (x < y) { y } else { x }\n  };\n\n  /// Returns `x == y`.\n  public func equal(x : Int8, y : Int8) : Bool { x == y };\n\n  /// Returns `x != y`.\n  public func notEqual(x : Int8, y : Int8) : Bool { x != y };\n\n  /// Returns `x < y`.\n  public func less(x : Int8, y : Int8) : Bool { x < y };\n\n  /// Returns `x <= y`.\n  public func lessOrEqual(x : Int8, y : Int8) : Bool { x <= y };\n\n  /// Returns `x > y`.\n  public func greater(x : Int8, y : Int8) : Bool { x > y };\n\n  /// Returns `x >= y`.\n  public func greaterOrEqual(x : Int8, y : Int8) : Bool { x >= y };\n\n  /// Returns the order of `x` and `y`.\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`. Traps on overflow.\n  public func neg(x : Int8) : Int8 { -x };\n\n  /// Returns the sum of `x` and `y`, `x + y`. Traps on overflow.\n  public func add(x : Int8, y : Int8) : Int8 { x + y };\n\n  /// Returns the difference of `x` and `y`, `x - y`. Traps on underflow.\n  public func sub(x : Int8, y : Int8) : Int8 { x - y };\n\n  /// Returns the product of `x` and `y`, `x * y`. Traps on overflow.\n  public func mul(x : Int8, y : Int8) : Int8 { x * y };\n\n  /// Returns the division of `x by y`, `x / y`.\n  /// Traps when `y` is zero.\n  public func div(x : Int8, y : Int8) : Int8 { x / y };\n\n  /// Returns the remainder of `x` divided by `y`, `x % y`.\n  /// Traps when `y` is zero.\n  public func rem(x : Int8, y : Int8) : Int8 { x % y };\n\n  /// Returns `x` to the power of `y`, `x ** y`. Traps on overflow.\n  public func pow(x : Int8, y : Int8) : Int8 { x ** y };\n\n  /// Returns the bitwise negation of `x`, `^x`.\n  public func bitnot(x : Int8, y : Int8) : Int8 { ^x };\n\n  /// Returns the bitwise and of `x` and `y`, `x & y`.\n  public func bitand(x : Int8, y : Int8) : Int8 { x & y };\n\n  /// Returns the bitwise or of `x` and `y`, `x \\| y`.\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  public func bitxor(x : Int8, y : Int8) : Int8 { x ^ y };\n\n  /// Returns the bitwise shift left of `x` by `y`, `x << y`.\n  public func bitshiftLeft(x : Int8, y : Int8) : Int8 { x << y };\n\n  /// Returns the bitwise shift right of `x` by `y`, `x >> y`.\n  public func bitshiftRight(x : Int8, y : Int8) : Int8 { x >> y };\n\n  /// Returns the bitwise rotate left of `x` by `y`, `x <<> y`.\n  public func bitrotLeft(x : Int8, y : Int8) : Int8 { x <<> y };\n\n  /// Returns the bitwise rotate right of `x` by `y`, `x <>> y`.\n  public func bitrotRight(x : Int8, y : Int8) : Int8 { x <>> y };\n\n  /// Returns the value of bit `p mod 8` in `x`, `(x & 2^(p mod 8)) == 2^(p mod 8)`.\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 mod 8` in `x` to `1`.\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 mod 8` in `x` to `0`.\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 mod 8` in `x`.\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  public let bitcountNonZero : (x : Int8) -> Int8 = Prim.popcntInt8;\n\n  /// Returns the count of leading zero bits in `x`.\n  public let bitcountLeadingZero : (x : Int8) -> Int8 = Prim.clzInt8;\n\n  /// Returns the count of trailing zero bits in `x`.\n  public let bitcountTrailingZero : (x : Int8) -> Int8 = Prim.ctzInt8;\n\n  /// Returns the sum of `x` and `y`, `x +% y`. Wraps on overflow.\n  public func addWrap(x : Int8, y : Int8) : Int8 { x +% y };\n\n  /// Returns the difference of `x` and `y`, `x -% y`. Wraps on underflow.\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  public func mulWrap(x : Int8, y : Int8) : Int8 { x *% y };\n\n  /// Returns `x` to the power of `y`, `x **% y`. Wraps on overflow. Traps if `y < 0`.\n  public func powWrap(x : Int8, y : Int8) : Int8 { x **% y };\n\n}\n"},"IterType.mo":{"content":"/// The Iterator type\n\n// Just here to break cyclic module definitions\n\nmodule {\n  public type Iter<T> = { next : () -> ?T }\n}\n"},"Int32.mo":{"content":"/// 32-bit signed integers with checked arithmetic\n///\n/// Most operations are available as built-in operators (e.g. `1 + 1`).\nimport Int \"Int\";\nimport Prim \"mo:⛔\";\n\nmodule {\n\n  /// 32-bit signed integers.\n  public type Int32 = Prim.Types.Int32;\n\n  /// Conversion.\n  public let toInt : Int32 -> Int = Prim.int32ToInt;\n\n  /// Conversion. Traps on overflow/underflow.\n  public let fromInt : Int -> Int32 = Prim.intToInt32;\n\n  /// Conversion. Wraps on overflow/underflow.\n  public let fromIntWrap : Int -> Int32 = Prim.intToInt32Wrap;\n\n  /// Conversion. Wraps on overflow/underflow.\n  public let fromNat32 : Nat32 -> Int32 = Prim.nat32ToInt32;\n\n  /// Conversion. Wraps on overflow/underflow.\n  public let toNat32 : Int32 -> Nat32 = Prim.int32ToNat32;\n\n  /// Returns the Text representation of `x`.\n  public func toText(x : Int32) : Text {\n    Int.toText(toInt(x))\n  };\n\n  /// Returns the absolute value of `x`. Traps when `x = -2^31`.\n  public func abs(x : Int32) : Int32 {\n    fromInt(Int.abs(toInt(x)))\n  };\n\n  /// Returns the minimum of `x` and `y`.\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  public func max(x : Int32, y : Int32) : Int32 {\n    if (x < y) { y } else { x }\n  };\n\n  /// Returns `x == y`.\n  public func equal(x : Int32, y : Int32) : Bool { x == y };\n\n  /// Returns `x != y`.\n  public func notEqual(x : Int32, y : Int32) : Bool { x != y };\n\n  /// Returns `x < y`.\n  public func less(x : Int32, y : Int32) : Bool { x < y };\n\n  /// Returns `x <= y`.\n  public func lessOrEqual(x : Int32, y : Int32) : Bool { x <= y };\n\n  /// Returns `x > y`.\n  public func greater(x : Int32, y : Int32) : Bool { x > y };\n\n  /// Returns `x >= y`.\n  public func greaterOrEqual(x : Int32, y : Int32) : Bool { x >= y };\n\n  /// Returns the order of `x` and `y`.\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`. Traps on overflow.\n  public func neg(x : Int32) : Int32 { -x };\n\n  /// Returns the sum of `x` and `y`, `x + y`. Traps on overflow.\n  public func add(x : Int32, y : Int32) : Int32 { x + y };\n\n  /// Returns the difference of `x` and `y`, `x - y`. Traps on underflow.\n  public func sub(x : Int32, y : Int32) : Int32 { x - y };\n\n  /// Returns the product of `x` and `y`, `x * y`. Traps on overflow.\n  public func mul(x : Int32, y : Int32) : Int32 { x * y };\n\n  /// Returns the division of `x by y`, `x / y`.\n  /// Traps when `y` is zero.\n  public func div(x : Int32, y : Int32) : Int32 { x / y };\n\n  /// Returns the remainder of `x` divided by `y`, `x % y`.\n  /// Traps when `y` is zero.\n  public func rem(x : Int32, y : Int32) : Int32 { x % y };\n\n  /// Returns `x` to the power of `y`, `x ** y`. Traps on overflow.\n  public func pow(x : Int32, y : Int32) : Int32 { x ** y };\n\n  /// Returns the bitwise negation of `x`, `^x`.\n  public func bitnot(x : Int32, y : Int32) : Int32 { ^x };\n\n  /// Returns the bitwise and of `x` and `y`, `x & y`.\n  public func bitand(x : Int32, y : Int32) : Int32 { x & y };\n\n  /// Returns the bitwise or of `x` and `y`, `x \\| y`.\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  public func bitxor(x : Int32, y : Int32) : Int32 { x ^ y };\n\n  /// Returns the bitwise shift left of `x` by `y`, `x << y`.\n  public func bitshiftLeft(x : Int32, y : Int32) : Int32 { x << y };\n\n  /// Returns the bitwise shift right of `x` by `y`, `x >> y`.\n  public func bitshiftRight(x : Int32, y : Int32) : Int32 { x >> y };\n\n  /// Returns the bitwise rotate left of `x` by `y`, `x <<> y`.\n  public func bitrotLeft(x : Int32, y : Int32) : Int32 { x <<> y };\n\n  /// Returns the bitwise rotate right of `x` by `y`, `x <>> y`.\n  public func bitrotRight(x : Int32, y : Int32) : Int32 { x <>> y };\n\n  /// Returns the value of bit `p mod 16` in `x`, `(x & 2^(p mod 16)) == 2^(p mod 16)`.\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 mod 16` in `x` to `1`.\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 mod 16` in `x` to `0`.\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 mod 16` in `x`.\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  public let bitcountNonZero : (x : Int32) -> Int32 = Prim.popcntInt32;\n\n  /// Returns the count of leading zero bits in `x`.\n  public let bitcountLeadingZero : (x : Int32) -> Int32 = Prim.clzInt32;\n\n  /// Returns the count of trailing zero bits in `x`.\n  public let bitcountTrailingZero : (x : Int32) -> Int32 = Prim.ctzInt32;\n\n  /// Returns the sum of `x` and `y`, `x +% y`. Wraps on overflow.\n  public func addWrap(x : Int32, y : Int32) : Int32 { x +% y };\n\n  /// Returns the difference of `x` and `y`, `x -% y`. Wraps on underflow.\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  public func mulWrap(x : Int32, y : Int32) : Int32 { x *% y };\n\n  /// Returns `x` to the power of `y`, `x **% y`. Wraps on overflow. Traps if `y < 0`.\n  public func powWrap(x : Int32, y : Int32) : Int32 { x **% y };\n\n}\n"},"Nat16.mo":{"content":"/// 16-bit unsigned integers with checked arithmetic\n///\n/// Most operations are available as built-in operators (e.g. `1 + 1`).\nimport Nat \"Nat\";\nimport Prim \"mo:⛔\";\n\nmodule {\n\n  /// 16-bit natural numbers.\n  public type Nat16 = Prim.Types.Nat16;\n\n  /// Conversion.\n  public let toNat : Nat16 -> Nat = Prim.nat16ToNat;\n\n  /// Conversion. Traps on overflow/underflow.\n  public let fromNat : Nat -> Nat16 = Prim.natToNat16;\n\n  /// Conversion. Wraps on overflow/underflow.\n  public let fromIntWrap : Int -> Nat16 = Prim.intToNat16Wrap;\n\n  /// Returns the Text representation of `x`.\n  public func toText(x : Nat16) : Text {\n    Nat.toText(toNat(x))\n  };\n\n  /// Returns the minimum of `x` and `y`.\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  public func max(x : Nat16, y : Nat16) : Nat16 {\n    if (x < y) { y } else { x }\n  };\n\n  /// Returns `x == y`.\n  public func equal(x : Nat16, y : Nat16) : Bool { x == y };\n\n  /// Returns `x != y`.\n  public func notEqual(x : Nat16, y : Nat16) : Bool { x != y };\n\n  /// Returns `x < y`.\n  public func less(x : Nat16, y : Nat16) : Bool { x < y };\n\n  /// Returns `x <= y`.\n  public func lessOrEqual(x : Nat16, y : Nat16) : Bool { x <= y };\n\n  /// Returns `x > y`.\n  public func greater(x : Nat16, y : Nat16) : Bool { x > y };\n\n  /// Returns `x >= y`.\n  public func greaterOrEqual(x : Nat16, y : Nat16) : Bool { x >= y };\n\n  /// Returns the order of `x` and `y`.\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`. Traps on overflow.\n  public func add(x : Nat16, y : Nat16) : Nat16 { x + y };\n\n  /// Returns the difference of `x` and `y`, `x - y`. Traps on underflow.\n  public func sub(x : Nat16, y : Nat16) : Nat16 { x - y };\n\n  /// Returns the product of `x` and `y`, `x * y`. Traps on overflow.\n  public func mul(x : Nat16, y : Nat16) : Nat16 { x * y };\n\n  /// Returns the division of `x by y`, `x / y`.\n  /// Traps when `y` is zero.\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  public func rem(x : Nat16, y : Nat16) : Nat16 { x % y };\n\n  /// Returns `x` to the power of `y`, `x ** y`. Traps on overflow.\n  public func pow(x : Nat16, y : Nat16) : Nat16 { x ** y };\n\n  /// Returns the bitwise negation of `x`, `^x`.\n  public func bitnot(x : Nat16, y : Nat16) : Nat16 { ^x };\n\n  /// Returns the bitwise and of `x` and `y`, `x & y`.\n  public func bitand(x : Nat16, y : Nat16) : Nat16 { x & y };\n\n  /// Returns the bitwise or of `x` and `y`, `x \\| y`.\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  public func bitxor(x : Nat16, y : Nat16) : Nat16 { x ^ y };\n\n  /// Returns the bitwise shift left of `x` by `y`, `x << y`.\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  public func bitshiftRight(x : Nat16, y : Nat16) : Nat16 { x >> y };\n\n  /// Returns the bitwise rotate left of `x` by `y`, `x <<> y`.\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  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  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  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  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  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  public let bitcountNonZero : (x : Nat16) -> Nat16 = Prim.popcntNat16;\n\n  /// Returns the count of leading zero bits in `x`.\n  public let bitcountLeadingZero : (x : Nat16) -> Nat16 = Prim.clzNat16;\n\n  /// Returns the count of trailing zero bits in `x`.\n  public let bitcountTrailingZero : (x : Nat16) -> Nat16 = Prim.ctzNat16;\n\n  /// Returns the sum of `x` and `y`, `x +% y`. Wraps on overflow.\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  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  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  public func powWrap(x : Nat16, y : Nat16) : Nat16 { x **% y };\n\n}\n"},"Buffer.mo":{"content":"/// Class `Buffer<X>` provides a mutable list of elements of type `X`.\n/// The class wraps and resizes an underyling array that holds the elements,\n/// and thus is comparable to ArrayLists or Vectors in other languages.\n///\n/// When required, the current state of a buffer object can be converted to a fixed-size array of its elements.\n/// This is recommended for example when storing a buffer to a stable variable.\n///\n/// Throughout this documentation, two terms come up that can be confused: `size`\n/// and `capacity`. `size` is the length of the list that the buffer represents.\n/// `capacity` is the length of the underyling array that backs this list.\n/// `capacity` >= `size` is an invariant for this class.\n///\n/// Like arrays, elements in the buffer are ordered by indices from 0 to `size`-1.\n///\n/// WARNING: Certain operations are amortized O(1) time, such as `add`, but run\n/// in worst case O(n) time. These worst case runtimes may exceed the cycles limit\n/// per message if the size of the buffer is large enough. Grow these structures\n/// with discretion. All amortized operations below also list the worst case runtime.\n///\n/// Constructor:\n/// The argument `initCapacity` determines the initial capacity of the array.\n/// The underlying array grows by a factor of 1.5 when its current capacity is\n/// exceeded. Further, when the size of the buffer shrinks to be less than 1/4th\n/// of the capacity, the underyling array is shrunk by a factor of 2.\n///\n/// Example:\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: O(initCapacity)\n///\n/// Space: 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    /// ```motoko include=initialize\n    /// buffer.size()\n    /// ```\n    ///\n    /// Runtime: O(1)\n    ///\n    /// Space: 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    /// ```motoko include=initialize\n    ///\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)\n    /// ```\n    ///\n    /// Amortized Runtime: O(1), Worst Case Runtime: O(size)\n    ///\n    /// Amortized Space: O(1), Worst Case Space: O(size)\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    /// ```motoko include=initialize\n    ///\n    /// buffer.add(10);\n    /// buffer.add(11);\n    /// let x = buffer.get(0); // evaluates to 10\n    /// ```\n    ///\n    /// Runtime: O(1)\n    ///\n    /// Space: 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    /// ```motoko include=initialize\n    ///\n    /// buffer.add(10);\n    /// buffer.add(11);\n    /// let x = buffer.getOpt(0); // evaluates to ?10\n    /// let y = buffer.getOpt(2); // evaluates to null\n    /// ```\n    ///\n    /// Runtime: O(1)\n    ///\n    /// Space: O(1)\n    public func getOpt(index : Nat) : ?X {\n      if (index < _size) {\n        elements[index]\n      } else {\n        null\n      }\n    };\n\n    /// Overwrites the current element at `index` with `element`. Traps if\n    /// `index` >= size. Indexing is zero-based.\n    ///\n    /// Example:\n    /// ```motoko include=initialize\n    ///\n    /// buffer.add(10);\n    /// buffer.put(0, 20); // overwrites 10 at index 0 with 20\n    /// Buffer.toArray(buffer)\n    /// ```\n    ///\n    /// Runtime: O(1)\n    ///\n    /// Space: O(1)\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    /// ```motoko include=initialize\n    ///\n    /// buffer.add(10);\n    /// buffer.add(11);\n    /// let x = buffer.removeLast(); // evaluates to ?11\n    /// ```\n    ///\n    /// Amortized Runtime: O(1), Worst Case Runtime: O(size)\n    ///\n    /// Amortized Space: O(1), Worst Case Space: O(size)\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: Repeated removal of elements using this method is ineffecient\n    /// and might be a sign that you should consider a different data-structure\n    /// for your use case.\n    ///\n    /// Example:\n    /// ```motoko include=initialize\n    ///\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)\n    /// ```\n    ///\n    /// Runtime: O(size)\n    ///\n    /// Amortized Space: O(1), Worst Case Space: O(size)\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    /// ```motoko include=initialize\n    ///\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: O(1)\n    ///\n    /// Space: 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    /// ```motoko include=initialize\n    ///\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)\n    /// ```\n    ///\n    /// Runtime: O(size)\n    ///\n    /// Amortized Space: O(1), Worst Case Space: O(size)\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    /// ```motoko include=initialize\n    ///\n    /// let buffer = Buffer.Buffer<Nat>(2); // underlying array has capacity 2\n    /// buffer.add(10);\n    /// let c1 = buffer.capacity(); // evaluates to 2\n    /// buffer.add(11);\n    /// buffer.add(12); // causes capacity to increase by factor of 1.5\n    /// let c2 = buffer.capacity(); // evaluates to 3\n    /// ```\n    ///\n    /// Runtime: O(1)\n    ///\n    /// Space: 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    ///\n    /// buffer.reserve(4);\n    /// buffer.add(10);\n    /// buffer.add(11);\n    /// let c = buffer.capacity(); // evaluates to 4\n    /// ```\n    ///\n    /// Runtime: O(capacity)\n    ///\n    /// Space: 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)\n    /// ```\n    ///\n    /// Amortized Runtime: O(size2), Worst Case Runtime: O(size1 + size2)\n    ///\n    /// Amortized Space: O(1), Worst Case Space: O(size1 + size2)\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)\n    /// ```\n    ///\n    /// Runtime: O(size)\n    ///\n    /// Amortized Space: O(1), Worst Case Space: O(size)\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)\n    /// ```\n    ///\n    /// Runtime: O(size)\n    ///\n    /// Amortized Space: O(1), Worst Case Space: O(size1 + size2)\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    ///\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)\n    /// ```\n    ///\n    /// Runtime: O(size * log(size))\n    ///\n    /// Space: 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    ///\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\n    /// ```\n    ///\n    /// Runtime: O(1)\n    ///\n    /// Space: 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 static library function instead.\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 static library function instead.\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 static library function instead.\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 iff the buffer is empty.\n  ///\n  /// Runtime: O(1)\n  ///\n  /// Space: O(1)\n  public func isEmpty<X>(buffer : Buffer<X>) : Bool = buffer.size() == 0;\n\n  /// Returns true iff `buffer` contains `element` with respect to equality\n  /// defined by `equal`.\n  ///\n  /// Runtime: O(size)\n  ///\n  /// Space: O(1)\n  ///\n  /// *Runtime and space assumes that `equal` runs in O(1) time and space.\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  /// Runtime: O(size)\n  ///\n  /// Space: 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  /// Runtime: O(size)\n  ///\n  /// Space: O(1)\n  ///\n  /// *Runtime and space assumes that `compare` runs in O(1) time and space.\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  /// Runtime: O(size)\n  ///\n  /// Space: O(1)\n  ///\n  /// *Runtime and space assumes that `compare` runs in O(1) time and space.\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 iff 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  /// Runtime: O(size)\n  ///\n  /// Space: O(1)\n  ///\n  /// *Runtime and space assumes that `equal` runs in O(1) time and space.\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  /// Runtime: O(size)\n  ///\n  /// Space: O(1)\n  ///\n  /// *Runtime and space assumes that `compare` runs in O(1) time and space.\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  /// Runtime: O(size)\n  ///\n  /// Space: O(size)\n  ///\n  /// *Runtime and space assumes that `toText` runs in O(1) time and space.\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  /// Runtime: O(size)\n  ///\n  /// Space: O(1)\n  ///\n  /// *Runtime and space assumes that `hash` runs in O(1) time and space.\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  /// Runtime: O(size)\n  ///\n  /// Space: O(size)\n  ///\n  /// *Runtime and space assumes that `equal` runs in O(1) time and space.\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  /// Runtime: O(size)\n  ///\n  /// Space: O(size)\n  ///\n  /// *Runtime and space assumes that `equal` runs in O(1) time and space.\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  /// Runtime: O(size of buffer + size of subBuffer)\n  ///\n  /// Space: O(size of subBuffer)\n  ///\n  /// *Runtime and space assumes that `equal` runs in O(1) time and space.\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  /// Runtime: O(log(size))\n  ///\n  /// Space: O(1)\n  ///\n  /// *Runtime and space assumes that `compare` runs in O(1) time and space.\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  /// Runtime: O(length)\n  ///\n  /// Space: 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  /// Runtime: O(size of subBuffer + size of buffer)\n  ///\n  /// Space: O(size of subBuffer)\n  ///\n  /// *Runtime and space assumes that `equal` runs in O(1) time and space.\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  /// Runtime: O(size of subBuffer + size of buffer)\n  ///\n  /// Space: O(size of subBuffer)\n  ///\n  /// *Runtime and space assumes that `equal` runs in O(1) time and space.\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  /// Runtime: O(length)\n  ///\n  /// Space: O(length)\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  /// Runtime: O(size of prefix)\n  ///\n  /// Space: O(size of prefix)\n  ///\n  /// *Runtime and space assumes that `equal` runs in O(1) time and space.\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  /// Runtime: O(size of prefix)\n  ///\n  /// Space: O(size of prefix)\n  ///\n  /// *Runtime and space assumes that `equal` runs in O(1) time and space.\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  /// Runtime: O(length)\n  ///\n  /// Space: 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  /// Runtime: O(length of suffix)\n  ///\n  /// Space: O(length of suffix)\n  ///\n  /// *Runtime and space assumes that `equal` runs in O(1) time and space.\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  /// Runtime: O(length of suffix)\n  ///\n  /// Space: O(length of suffix)\n  ///\n  /// *Runtime and space assumes that `equal` runs in O(1) time and space.\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 iff every element in `buffer` satisfies `predicate`.\n  ///\n  /// Runtime: O(size)\n  ///\n  /// Space: O(1)\n  ///\n  /// *Runtime and space assumes that `predicate` runs in O(1) time and space.\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 iff some element in `buffer` satisfies `predicate`.\n  ///\n  /// Runtime: O(size)\n  ///\n  /// Space: O(1)\n  ///\n  /// *Runtime and space assumes that `predicate` runs in O(1) time and space.\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 iff no element in `buffer` satisfies `predicate`.\n  ///\n  /// Runtime: O(size)\n  ///\n  /// Space: O(1)\n  ///\n  /// *Runtime and space assumes that `predicate` runs in O(1) time and space.\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  /// Runtime: O(size)\n  ///\n  /// Space: 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  /// Runtime: O(size)\n  ///\n  /// Space: 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  /// Runtime: O(size)\n  ///\n  /// Space: 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  /// Runtime: O(size)\n  ///\n  /// Space: 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  /// Runtime: O(size)\n  ///\n  /// Space: 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  /// Runtime: O(size)\n  ///\n  /// Space: 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  /// Runtime: O(size)\n  ///\n  /// Space: O(size)\n  ///\n  /// *Runtime and space assumes that `f` runs in O(1) time and space.\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  /// Runtime: O(size)\n  ///\n  /// Space: O(size)\n  ///\n  /// *Runtime and space assumes that `f` runs in O(1) time and space.\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  /// Runtime: O(size)\n  ///\n  /// Space: O(size)\n  ///\n  /// *Runtime and space assumes that `f` runs in O(1) time and space.\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  /// Runtime: O(size)\n  ///\n  /// Space: O(size)\n  ///\n  /// *Runtime and space assumes that `f` runs in O(1) time and space.\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  /// Runtime: O(size)\n  ///\n  /// Space: O(size)\n  ///\n  /// *Runtime and space assumes that `f` runs in O(1) time and space.\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  /// Runtime: O(size)\n  ///\n  /// Space: O(size)\n  ///\n  /// *Runtime and space assumes that `k` runs in O(1) time and space.\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  /// Runtime: O(size)\n  ///\n  /// Space: O(1)\n  ///\n  /// *Runtime and space assumes that `combine` runs in O(1) time and space.\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  /// Runtime: O(size)\n  ///\n  /// Space: O(1)\n  ///\n  /// *Runtime and space assumes that `combine` runs in O(1) time and space.\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  /// Runtime: O(1)\n  ///\n  /// Space: 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  /// Runtime: O(1)\n  ///\n  /// Space: 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  /// Runtime: O(1)\n  ///\n  /// Space: 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  /// Runtime: O(size)\n  ///\n  /// Space: 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  /// Runtime: O(size1 + size2)\n  ///\n  /// Space: O(size1 + size2)\n  ///\n  /// *Runtime and space assumes that `compare` runs in O(1) time and space.\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  /// Runtime: O(size * log(size))\n  ///\n  /// Space: 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  /// Runtime: O(size)\n  ///\n  /// Space: O(size)\n  ///\n  /// *Runtime and space assumes that `predicate` runs in O(1) time and space.\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  /// Runtime: O(size)\n  ///\n  /// Space: O(size)\n  ///\n  /// *Runtime and space assumes that `compare` runs in O(1) time and space.\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  /// Runtime: O(number of elements in buffer)\n  ///\n  /// Space: O(number of elements in buffer)\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  /// Runtime: O(size)\n  ///\n  /// Space: O(size)\n  ///\n  /// *Runtime and space assumes that `equal` runs in O(1) time and space.\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  /// Runtime: O(number of elements in buffer)\n  ///\n  /// Space: 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  /// Runtime: O(min(size1, size2))\n  ///\n  /// Space: 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  /// Runtime: O(min(size1, size2))\n  ///\n  /// Space: O(min(size1, size2))\n  ///\n  /// *Runtime and space assumes that `zip` runs in O(1) time and space.\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  /// Runtime: O(size)\n  ///\n  /// Space: O(size)\n  ///\n  /// *Runtime and space assumes that `predicate` runs in O(1) time and space.\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  /// Runtime: O(size)\n  ///\n  /// Space: O(size)\n  ///\n  /// *Runtime and space assumes that `predicate` runs in O(1) time and space.\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"},"Order.mo":{"content":"/// Order\n\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"},"Int16.mo":{"content":"/// 16-bit signed integers with checked arithmetic\n///\n/// Most operations are available as built-in operators (e.g. `1 + 1`).\nimport Int \"Int\";\nimport Prim \"mo:⛔\";\n\nmodule {\n\n  /// 16-bit signed integers\n  public type Int16 = Prim.Types.Int16;\n\n  /// Conversion.\n  public let toInt : Int16 -> Int = Prim.int16ToInt;\n\n  /// Conversion. Traps on overflow/underflow.\n  public let fromInt : Int -> Int16 = Prim.intToInt16;\n\n  /// Conversion. Wraps on overflow/underflow.\n  public let fromIntWrap : Int -> Int16 = Prim.intToInt16Wrap;\n\n  /// Conversion. Wraps on overflow/underflow.\n  public let fromNat16 : Nat16 -> Int16 = Prim.nat16ToInt16;\n\n  /// Conversion. Wraps on overflow/underflow.\n  public let toNat16 : Int16 -> Nat16 = Prim.int16ToNat16;\n\n  /// Returns the Text representation of `x`.\n  public func toText(x : Int16) : Text {\n    Int.toText(toInt(x))\n  };\n\n  /// Returns the absolute value of `x`. Traps when `x = -2^15`.\n  public func abs(x : Int16) : Int16 {\n    fromInt(Int.abs(toInt(x)))\n  };\n\n  /// Returns the minimum of `x` and `y`.\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  public func max(x : Int16, y : Int16) : Int16 {\n    if (x < y) { y } else { x }\n  };\n\n  /// Returns `x == y`.\n  public func equal(x : Int16, y : Int16) : Bool { x == y };\n\n  /// Returns `x != y`.\n  public func notEqual(x : Int16, y : Int16) : Bool { x != y };\n\n  /// Returns `x < y`.\n  public func less(x : Int16, y : Int16) : Bool { x < y };\n\n  /// Returns `x <= y`.\n  public func lessOrEqual(x : Int16, y : Int16) : Bool { x <= y };\n\n  /// Returns `x > y`.\n  public func greater(x : Int16, y : Int16) : Bool { x > y };\n\n  /// Returns `x >= y`.\n  public func greaterOrEqual(x : Int16, y : Int16) : Bool { x >= y };\n\n  /// Returns the order of `x` and `y`.\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`. Traps on overflow.\n  public func neg(x : Int16) : Int16 { -x };\n\n  /// Returns the sum of `x` and `y`, `x + y`. Traps on overflow.\n  public func add(x : Int16, y : Int16) : Int16 { x + y };\n\n  /// Returns the difference of `x` and `y`, `x - y`. Traps on underflow.\n  public func sub(x : Int16, y : Int16) : Int16 { x - y };\n\n  /// Returns the product of `x` and `y`, `x * y`. Traps on overflow.\n  public func mul(x : Int16, y : Int16) : Int16 { x * y };\n\n  /// Returns the division of `x by y`, `x / y`.\n  /// Traps when `y` is zero.\n  public func div(x : Int16, y : Int16) : Int16 { x / y };\n\n  /// Returns the remainder of `x` divided by `y`, `x % y`.\n  /// Traps when `y` is zero.\n  public func rem(x : Int16, y : Int16) : Int16 { x % y };\n\n  /// Returns `x` to the power of `y`, `x ** y`. Traps on overflow.\n  public func pow(x : Int16, y : Int16) : Int16 { x ** y };\n\n  /// Returns the bitwise negation of `x`, `^x`.\n  public func bitnot(x : Int16, y : Int16) : Int16 { ^x };\n\n  /// Returns the bitwise and of `x` and `y`, `x & y`.\n  public func bitand(x : Int16, y : Int16) : Int16 { x & y };\n\n  /// Returns the bitwise or of `x` and `y`, `x \\| y`.\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  public func bitxor(x : Int16, y : Int16) : Int16 { x ^ y };\n\n  /// Returns the bitwise shift left of `x` by `y`, `x << y`.\n  public func bitshiftLeft(x : Int16, y : Int16) : Int16 { x << y };\n\n  /// Returns the bitwise shift right of `x` by `y`, `x >> y`.\n  public func bitshiftRight(x : Int16, y : Int16) : Int16 { x >> y };\n\n  /// Returns the bitwise rotate left of `x` by `y`, `x <<> y`.\n  public func bitrotLeft(x : Int16, y : Int16) : Int16 { x <<> y };\n\n  /// Returns the bitwise rotate right of `x` by `y`, `x <>> y`.\n  public func bitrotRight(x : Int16, y : Int16) : Int16 { x <>> y };\n\n  /// Returns the value of bit `p mod 16` in `x`, `(x & 2^(p mod 16)) == 2^(p mod 16)`.\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 mod 16` in `x` to `1`.\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 mod 16` in `x` to `0`.\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 mod 16` in `x`.\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  public let bitcountNonZero : (x : Int16) -> Int16 = Prim.popcntInt16;\n\n  /// Returns the count of leading zero bits in `x`.\n  public let bitcountLeadingZero : (x : Int16) -> Int16 = Prim.clzInt16;\n\n  /// Returns the count of trailing zero bits in `x`.\n  public let bitcountTrailingZero : (x : Int16) -> Int16 = Prim.ctzInt16;\n\n  /// Returns the sum of `x` and `y`, `x +% y`. Wraps on overflow.\n  public func addWrap(x : Int16, y : Int16) : Int16 { x +% y };\n\n  /// Returns the difference of `x` and `y`, `x -% y`. Wraps on underflow.\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  public func mulWrap(x : Int16, y : Int16) : Int16 { x *% y };\n\n  /// Returns `x` to the power of `y`, `x **% y`. Wraps on overflow. Traps if `y < 0`.\n  public func powWrap(x : Int16, y : Int16) : Int16 { x **% y }\n}\n"},"AssocList.mo":{"content":"/// Map implemented as a linked-list of key-value pairs (\"Associations\").\n///\n/// NOTE: This map implementation is mainly used as underlying buckets for other map\n/// structures. Thus, other map implementations are easier to use in most cases.\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  /// ```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  /// Runtime: O(size)\n  ///\n  /// Space: O(1)\n  ///\n  /// *Runtime and space assumes that `equal` runs in O(1) time and space.\n  public func find<K, V>(\n    map : AssocList<K, V>,\n    key : K,\n    equal : (K, K) -> Bool\n  ) : ?V {\n    func rec(al : AssocList<K, V>) : ?V {\n      label profile_assocList_find_rec : (?V) switch (al) {\n        case (null) { label profile_assocList_find_end_fail : (?V) { null } };\n        case (?((hd_k, hd_v), tl)) {\n          if (equal(key, hd_k)) {\n            label profile_assocList_find_end_success : (?V) {\n              ?hd_v\n            }\n          } else {\n            rec(tl)\n          }\n        }\n      }\n    };\n    label profile_assocList_find_begin : (?V) {\n      rec(map)\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  /// ```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  /// Runtime: O(size)\n  ///\n  /// Space: O(size)\n  ///\n  /// *Runtime and space assumes that `equal` runs in O(1) time and space.\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    func rec(al : AssocList<K, V>) : (AssocList<K, V>, ?V) {\n      switch (al) {\n        case (null) {\n          switch value {\n            case (null) { (null, null) };\n            case (?value) { (?((key, value), null), null) }\n          }\n        };\n        case (?((hd_k, hd_v), tl)) {\n          if (equal(key, hd_k)) {\n            // if value is null, remove the key; otherwise, replace key's old value\n            // return old value\n            switch value {\n              case (null) { (tl, ?hd_v) };\n              case (?value) { (?((hd_k, value), tl), ?hd_v) }\n            }\n          } else {\n            let (tl2, old_v) = rec(tl);\n            (?((hd_k, hd_v), tl2), old_v)\n          }\n        }\n      }\n    };\n    rec(map)\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  /// ```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  /// Runtime: O(size1 * size2)\n  ///\n  /// Space: O(1)\n  ///\n  /// *Runtime and space assumes that `equal` runs in O(1) time and space.\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\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> = label profile_assocList_mapAppend : AssocList<K, X> {\n    func rec(al1 : AssocList<K, V>, al2 : AssocList<K, W>) : AssocList<K, X> = label profile_assocList_mapAppend_rec : 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  /// ```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  /// Runtime: O(size1 + size2)\n  ///\n  /// Space: O(1)\n  ///\n  /// *Runtime and space assumes that `f` runs in O(1) time and space.\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> = label profile_assocList_disjDisjoint : 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: `combine` will never be applied to `(null, null)`.\n  ///\n  /// Example:\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  /// Runtime: O(size1 * size2)\n  ///\n  /// Space: O(size1 + size2)\n  ///\n  /// *Runtime and space assumes that `equal` and `combine` runs in O(1) time and space.\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  /// ```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  /// Runtime: O(size1 * size2)\n  ///\n  /// Space: O(size1 + size2)\n  ///\n  /// *Runtime and space assumes that `equal` and `combine` runs in O(1) time and space.\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  /// ```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: O(size)\n  ///\n  /// Space: O(size)\n  ///\n  /// *Runtime and space assumes that `combine` runs in O(1) time and space.\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"},"Nat.mo":{"content":"/// Natural numbers\n///\n/// Most operations on natural numbers (e.g. addition) are available as built-in operators (e.g. `1 + 1`).\n/// This module provides equivalent functions and `Text` conversion.\n\nimport Int \"Int\";\nimport Order \"Order\";\nimport Prim \"mo:⛔\";\n\nmodule {\n\n  /// Infinite precision natural numbers.\n  public type Nat = Prim.Types.Nat;\n\n  /// Conversion.\n  public let toText : Nat -> Text = Int.toText;\n\n  /// Returns the minimum of `x` and `y`.\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  public func max(x : Nat, y : Nat) : Nat {\n    if (x < y) { y } else { x }\n  };\n\n  /// Returns `x == y`.\n  public func equal(x : Nat, y : Nat) : Bool { x == y };\n\n  /// Returns `x != y`.\n  public func notEqual(x : Nat, y : Nat) : Bool { x != y };\n\n  /// Returns `x < y`.\n  public func less(x : Nat, y : Nat) : Bool { x < y };\n\n  /// Returns `x <= y`.\n  public func lessOrEqual(x : Nat, y : Nat) : Bool { x <= y };\n\n  /// Returns `x > y`.\n  public func greater(x : Nat, y : Nat) : Bool { x > y };\n\n  /// Returns `x >= y`.\n  public func greaterOrEqual(x : Nat, y : Nat) : Bool { x >= y };\n\n  /// Returns the order of `x` and `y`.\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`.\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.\n  public func sub(x : Nat, y : Nat) : Nat { x - y };\n\n  /// Returns the product of `x` and `y`, `x * y`.\n  public func mul(x : Nat, y : Nat) : Nat { x * y };\n\n  /// Returns the division of `x` by `y`, `x / y`.\n  /// Traps when `y` is zero.\n  public func div(x : Nat, y : Nat) : Nat { x / y };\n\n  /// Returns the remainder of `x` divided by `y`, `x % y`.\n  /// Traps when `y` is zero.\n  public func rem(x : Nat, y : Nat) : Nat { x % y };\n\n  /// Returns `x` to the power of `y`, `x ** y`.\n  public func pow(x : Nat, y : Nat) : Nat { x ** y };\n\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}\n"},"Nat32.mo":{"content":"/// 32-bit unsigned integers with checked arithmetic\n///\n/// Most operations are available as built-in operators (e.g. `1 + 1`).\nimport Nat \"Nat\";\nimport Prim \"mo:⛔\";\n\nmodule {\n\n  /// 32-bit natural numbers.\n  public type Nat32 = Prim.Types.Nat32;\n\n  /// Conversion.\n  public let toNat : Nat32 -> Nat = Prim.nat32ToNat;\n\n  /// Conversion. Traps on overflow/underflow.\n  public let fromNat : Nat -> Nat32 = Prim.natToNat32;\n\n  /// Conversion. Wraps on overflow/underflow.\n  public let fromIntWrap : Int -> Nat32 = Prim.intToNat32Wrap;\n\n  /// Returns the Text representation of `x`.\n  public func toText(x : Nat32) : Text {\n    Nat.toText(toNat(x))\n  };\n\n  /// Returns the minimum of `x` and `y`.\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  public func max(x : Nat32, y : Nat32) : Nat32 {\n    if (x < y) { y } else { x }\n  };\n\n  /// Returns `x == y`.\n  public func equal(x : Nat32, y : Nat32) : Bool { x == y };\n\n  /// Returns `x != y`.\n  public func notEqual(x : Nat32, y : Nat32) : Bool { x != y };\n\n  /// Returns `x < y`.\n  public func less(x : Nat32, y : Nat32) : Bool { x < y };\n\n  /// Returns `x <= y`.\n  public func lessOrEqual(x : Nat32, y : Nat32) : Bool { x <= y };\n\n  /// Returns `x > y`.\n  public func greater(x : Nat32, y : Nat32) : Bool { x > y };\n\n  /// Returns `x >= y`.\n  public func greaterOrEqual(x : Nat32, y : Nat32) : Bool { x >= y };\n\n  /// Returns the order of `x` and `y`.\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`. Traps on overflow.\n  public func add(x : Nat32, y : Nat32) : Nat32 { x + y };\n\n  /// Returns the difference of `x` and `y`, `x - y`. Traps on underflow.\n  public func sub(x : Nat32, y : Nat32) : Nat32 { x - y };\n\n  /// Returns the product of `x` and `y`, `x * y`. Traps on overflow.\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  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  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  public func pow(x : Nat32, y : Nat32) : Nat32 { x ** y };\n\n  /// Returns the bitwise negation of `x`, `^x`.\n  public func bitnot(x : Nat32, y : Nat32) : Nat32 { ^x };\n\n  /// Returns the bitwise and of `x` and `y`, `x & y`.\n  public func bitand(x : Nat32, y : Nat32) : Nat32 { x & y };\n\n  /// Returns the bitwise or of `x` and `y`, `x \\| y`.\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  public func bitxor(x : Nat32, y : Nat32) : Nat32 { x ^ y };\n\n  /// Returns the bitwise shift left of `x` by `y`, `x << y`.\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  public func bitshiftRight(x : Nat32, y : Nat32) : Nat32 { x >> y };\n\n  /// Returns the bitwise rotate left of `x` by `y`, `x <<> y`.\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  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  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  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  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  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  public let bitcountNonZero : (x : Nat32) -> Nat32 = Prim.popcntNat32;\n\n  /// Returns the count of leading zero bits in `x`.\n  public let bitcountLeadingZero : (x : Nat32) -> Nat32 = Prim.clzNat32;\n\n  /// Returns the count of trailing zero bits in `x`.\n  public let bitcountTrailingZero : (x : Nat32) -> Nat32 = Prim.ctzNat32;\n\n  /// Returns the sum of `x` and `y`, `x +% y`. Wraps on overflow.\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  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  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  public func powWrap(x : Nat32, y : Nat32) : Nat32 { x **% y };\n\n}\n"},"Nat64.mo":{"content":"/// 64-bit unsigned integers with checked arithmetic\n///\n/// Most operations are available as built-in operators (e.g. `1 + 1`).\nimport Nat \"Nat\";\nimport Prim \"mo:⛔\";\n\nmodule {\n\n  /// 64-bit natural numbers.\n  public type Nat64 = Prim.Types.Nat64;\n\n  /// Conversion.\n  public let toNat : Nat64 -> Nat = Prim.nat64ToNat;\n\n  /// Conversion. Traps on overflow/underflow.\n  public let fromNat : Nat -> Nat64 = Prim.natToNat64;\n\n  /// Conversion. Wraps on overflow/underflow.\n  public let fromIntWrap : Int -> Nat64 = Prim.intToNat64Wrap;\n\n  /// Returns the Text representation of `x`.\n  public func toText(x : Nat64) : Text {\n    Nat.toText(toNat(x))\n  };\n\n  /// Returns the minimum of `x` and `y`.\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  public func max(x : Nat64, y : Nat64) : Nat64 {\n    if (x < y) { y } else { x }\n  };\n\n  /// Returns `x == y`.\n  public func equal(x : Nat64, y : Nat64) : Bool { x == y };\n\n  /// Returns `x != y`.\n  public func notEqual(x : Nat64, y : Nat64) : Bool { x != y };\n\n  /// Returns `x < y`.\n  public func less(x : Nat64, y : Nat64) : Bool { x < y };\n\n  /// Returns `x <= y`.\n  public func lessOrEqual(x : Nat64, y : Nat64) : Bool { x <= y };\n\n  /// Returns `x > y`.\n  public func greater(x : Nat64, y : Nat64) : Bool { x > y };\n\n  /// Returns `x >= y`.\n  public func greaterOrEqual(x : Nat64, y : Nat64) : Bool { x >= y };\n\n  /// Returns the order of `x` and `y`.\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`. Traps on overflow.\n  public func add(x : Nat64, y : Nat64) : Nat64 { x + y };\n\n  /// Returns the difference of `x` and `y`, `x - y`. Traps on underflow.\n  public func sub(x : Nat64, y : Nat64) : Nat64 { x - y };\n\n  /// Returns the product of `x` and `y`, `x * y`. Traps on overflow.\n  public func mul(x : Nat64, y : Nat64) : Nat64 { x * y };\n\n  /// Returns the division of `x by y`, `x / y`.\n  /// Traps when `y` is zero.\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  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  public func pow(x : Nat64, y : Nat64) : Nat64 { x ** y };\n\n  /// Returns the bitwise negation of `x`, `^x`.\n  public func bitnot(x : Nat64, y : Nat64) : Nat64 { ^x };\n\n  /// Returns the bitwise and of `x` and `y`, `x & y`.\n  public func bitand(x : Nat64, y : Nat64) : Nat64 { x & y };\n\n  /// Returns the bitwise or of `x` and `y`, `x \\| y`.\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  public func bitxor(x : Nat64, y : Nat64) : Nat64 { x ^ y };\n\n  /// Returns the bitwise shift left of `x` by `y`, `x << y`.\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  public func bitshiftRight(x : Nat64, y : Nat64) : Nat64 { x >> y };\n\n  /// Returns the bitwise rotate left of `x` by `y`, `x <<> y`.\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  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  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  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  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  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  public let bitcountNonZero : (x : Nat64) -> Nat64 = Prim.popcntNat64;\n\n  /// Returns the count of leading zero bits in `x`.\n  public let bitcountLeadingZero : (x : Nat64) -> Nat64 = Prim.clzNat64;\n\n  /// Returns the count of trailing zero bits in `x`.\n  public let bitcountTrailingZero : (x : Nat64) -> Nat64 = Prim.ctzNat64;\n\n  /// Returns the sum of `x` and `y`, `x +% y`. Wraps on overflow.\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  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  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  public func powWrap(x : Nat64, y : Nat64) : Nat64 { x **% y };\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: While an implementation will likely try to keep the system time close to the real time, this is not formally guaranteed.\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"}}}