motoko 3.13.0 → 3.13.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"name":"base","version":"moc-0.14.11","files":{"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"},"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(array);\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 /// // Response unknown due to missed deadline.\n /// #system_unknown;\n /// // Destination invalid.\n /// #destination_invalid;\n /// // Explicit reject by canister code.\n /// #canister_reject;\n /// // Canister trapped.\n /// #canister_error;\n /// // Future error code (with unrecognized numeric code).\n /// #future : Nat32;\n /// // Error issuing inter-canister call\n /// // (indicating destination queue full or freezing threshold crossed).\n /// #call_error : { err_code : Nat32 }\n /// };\n /// ```\n public type ErrorCode = Prim.ErrorCode;\n\n /// Create an error from the message with the code `#canister_reject`.\n ///\n /// Example:\n /// ```motoko\n /// import Error \"mo:base/Error\";\n ///\n /// Error.reject(\"Example error\") // can be used as throw argument\n /// ```\n public let reject : (message : Text) -> Error = Prim.error;\n\n /// Returns the code of an error.\n ///\n /// Example:\n /// ```motoko\n /// import Error \"mo:base/Error\";\n ///\n /// let error = Error.reject(\"Example error\");\n /// Error.code(error) // #canister_reject\n /// ```\n public let code : (error : Error) -> ErrorCode = Prim.errorCode;\n\n /// Returns the message of an error.\n ///\n /// Example:\n /// ```motoko\n /// import Error \"mo:base/Error\";\n ///\n /// let error = Error.reject(\"Example error\");\n /// Error.message(error) // \"Example error\"\n /// ```\n public let message : (error : Error) -> Text = Prim.errorMessage;\n\n /// Returns whether retrying to send a message may result in success.\n ///\n /// Example:\n /// ```motoko\n /// import { message; isRetryPossible } \"mo:base/Error\";\n /// import { print } \"mo:base/Debug\";\n ///\n /// try await (with timeout = 3) Actor.call(arg)\n /// catch e { if (isRetryPossible e) print(message e) }\n /// ```\n public func isRetryPossible(error : Error) : Bool =\n switch (code error) {\n case (#system_unknown or #system_transient) true;\n case _ false\n };\n\n}\n"},"Deque.mo":{"content":"/// Double-ended queue (deque) of a generic element type `T`.\n///\n/// The interface to deques is purely functional, not imperative, and deques are immutable values.\n/// In particular, deque operations such as push and pop do not update their input deque but, instead, return the\n/// value of the modified deque, alongside any other data.\n/// The input deque is left unchanged.\n///\n/// Examples of use-cases:\n/// Queue (FIFO) by using `pushBack()` and `popFront()`.\n/// Stack (LIFO) by using `pushFront()` and `popFront()`.\n///\n/// A deque is internally implemented as two lists, a head access list and a (reversed) tail access list,\n/// that are dynamically size-balanced by splitting.\n///\n/// Construction: Create a new deque with the `empty<T>()` function.\n///\n/// Note on the costs of push and pop functions:\n/// * Runtime: `O(1) amortized costs, `O(n)` worst case cost per single call.\n/// * Space: `O(1) amortized costs, `O(n)` worst case cost per single call.\n///\n/// `n` denotes the number of elements stored in the deque.\n\nimport List \"List\";\nimport P \"Prelude\";\n\nmodule {\n type List<T> = List.List<T>;\n\n /// Double-ended queue (deque) data type.\n public type Deque<T> = (List<T>, List<T>);\n\n /// Create a new empty deque.\n ///\n /// Example:\n /// ```motoko\n /// import Deque \"mo:base/Deque\";\n ///\n /// Deque.empty<Nat>()\n /// ```\n ///\n /// Runtime: `O(1)`.\n ///\n /// Space: `O(1)`.\n public func empty<T>() : Deque<T> { (List.nil(), List.nil()) };\n\n /// Determine whether a deque is empty.\n /// Returns true if `deque` is empty, otherwise `false`.\n ///\n /// Example:\n /// ```motoko\n /// import Deque \"mo:base/Deque\";\n ///\n /// let deque = Deque.empty<Nat>();\n /// Deque.isEmpty(deque) // => true\n /// ```\n ///\n /// Runtime: `O(1)`.\n ///\n /// Space: `O(1)`.\n public func isEmpty<T>(deque : Deque<T>) : Bool {\n switch deque {\n case (f, r) { List.isNil(f) and List.isNil(r) }\n }\n };\n\n func check<T>(q : Deque<T>) : Deque<T> {\n switch q {\n case (null, r) {\n let (a, b) = List.split(List.size(r) / 2, r);\n (List.reverse(b), a)\n };\n case (f, null) {\n let (a, b) = List.split(List.size(f) / 2, f);\n (a, List.reverse(b))\n };\n case q { q }\n }\n };\n\n /// Insert a new element on the front end of a deque.\n /// Returns the new deque with `element` in the front followed by the elements of `deque`.\n ///\n /// This may involve dynamic rebalancing of the two, internally used lists.\n ///\n /// Example:\n /// ```motoko\n /// import Deque \"mo:base/Deque\";\n ///\n /// Deque.pushFront(Deque.pushFront(Deque.empty<Nat>(), 2), 1) // deque with elements [1, 2]\n /// ```\n ///\n /// Runtime: `O(n)` worst-case, amortized to `O(1)`.\n ///\n /// Space: `O(n)` worst-case, amortized to `O(1)`.\n ///\n /// `n` denotes the number of elements stored in the deque.\n public func pushFront<T>(deque : Deque<T>, element : T) : Deque<T> {\n check(List.push(element, deque.0), deque.1)\n };\n\n /// Inspect the optional element on the front end of a deque.\n /// Returns `null` if `deque` is empty. Otherwise, the front element of `deque`.\n ///\n /// Example:\n /// ```motoko\n /// import Deque \"mo:base/Deque\";\n ///\n /// let deque = Deque.pushFront(Deque.pushFront(Deque.empty<Nat>(), 2), 1);\n /// Deque.peekFront(deque) // => ?1\n /// ```\n ///\n /// Runtime: `O(1)`.\n ///\n /// Space: `O(1)`.\n ///\n public func peekFront<T>(deque : Deque<T>) : ?T {\n switch deque {\n case (?(x, _f), _r) { ?x };\n case (null, ?(x, _r)) { ?x };\n case _ { null }\n }\n };\n\n /// Remove the element on the front end of a deque.\n /// Returns `null` if `deque` is empty. Otherwise, it returns a pair of\n /// the first element and a new deque that contains all the remaining elements of `deque`.\n ///\n /// This may involve dynamic rebalancing of the two, internally used lists.\n ///\n /// Example:\n /// ```motoko\n /// import Deque \"mo:base/Deque\";\n /// import Debug \"mo:base/Debug\";\n /// let initial = Deque.pushFront(Deque.pushFront(Deque.empty<Nat>(), 2), 1);\n /// // initial deque with elements [1, 2]\n /// let reduced = Deque.popFront(initial);\n /// switch reduced {\n /// case null {\n /// Debug.trap \"Empty queue impossible\"\n /// };\n /// case (?result) {\n /// let removedElement = result.0; // 1\n /// let reducedDeque = result.1; // deque with element [2].\n /// }\n /// }\n /// ```\n ///\n /// Runtime: `O(n)` worst-case, amortized to `O(1)`.\n ///\n /// Space: `O(n)` worst-case, amortized to `O(1)`.\n ///\n /// `n` denotes the number of elements stored in the deque.\n public func popFront<T>(deque : Deque<T>) : ?(T, Deque<T>) {\n switch deque {\n case (?(x, f), r) { ?(x, check(f, r)) };\n case (null, ?(x, r)) { ?(x, check(null, r)) };\n case _ { null }\n }\n };\n\n /// Insert a new element on the back end of a deque.\n /// Returns the new deque with all the elements of `deque`, followed by `element` on the back.\n ///\n /// This may involve dynamic rebalancing of the two, internally used lists.\n ///\n /// Example:\n /// ```motoko\n /// import Deque \"mo:base/Deque\";\n ///\n /// Deque.pushBack(Deque.pushBack(Deque.empty<Nat>(), 1), 2) // deque with elements [1, 2]\n /// ```\n ///\n /// Runtime: `O(n)` worst-case, amortized to `O(1)`.\n ///\n /// Space: `O(n)` worst-case, amortized to `O(1)`.\n ///\n /// `n` denotes the number of elements stored in the deque.\n public func pushBack<T>(deque : Deque<T>, element : T) : Deque<T> {\n check(deque.0, List.push(element, deque.1))\n };\n\n /// Inspect the optional element on the back end of a deque.\n /// Returns `null` if `deque` is empty. Otherwise, the back element of `deque`.\n ///\n /// Example:\n /// ```motoko\n /// import Deque \"mo:base/Deque\";\n ///\n /// let deque = Deque.pushBack(Deque.pushBack(Deque.empty<Nat>(), 1), 2);\n /// Deque.peekBack(deque) // => ?2\n /// ```\n ///\n /// Runtime: `O(1)`.\n ///\n /// Space: `O(1)`.\n ///\n public func peekBack<T>(deque : Deque<T>) : ?T {\n switch deque {\n case (_f, ?(x, _r)) { ?x };\n case (?(x, _r), null) { ?x };\n case _ { null }\n }\n };\n\n /// Remove the element on the back end of a deque.\n /// Returns `null` if `deque` is empty. Otherwise, it returns a pair of\n /// a new deque that contains the remaining elements of `deque`\n /// and, as the second pair item, the removed back element.\n ///\n /// This may involve dynamic rebalancing of the two, internally used lists.\n ///\n /// Example:\n /// ```motoko\n /// import Deque \"mo:base/Deque\";\n /// import Debug \"mo:base/Debug\";\n ///\n /// let initial = Deque.pushBack(Deque.pushBack(Deque.empty<Nat>(), 1), 2);\n /// // initial deque with elements [1, 2]\n /// let reduced = Deque.popBack(initial);\n /// switch reduced {\n /// case null {\n /// Debug.trap \"Empty queue impossible\"\n /// };\n /// case (?result) {\n /// let reducedDeque = result.0; // deque with element [1].\n /// let removedElement = result.1; // 2\n /// }\n /// }\n /// ```\n ///\n /// Runtime: `O(n)` worst-case, amortized to `O(1)`.\n ///\n /// Space: `O(n)` worst-case, amortized to `O(1)`.\n ///\n /// `n` denotes the number of elements stored in the deque.\n public func popBack<T>(deque : Deque<T>) : ?(Deque<T>, T) {\n switch deque {\n case (f, ?(x, r)) { ?(check(f, r), x) };\n case (?(x, f), null) { ?(check(f, null), x) };\n case _ { null }\n }\n }\n}\n"},"ExperimentalCycles.mo":{"content":"/// Managing cycles within actors on the Internet Computer (IC).\n///\n/// The usage of the Internet Computer is measured, and paid for, in _cycles_.\n/// This library provides imperative operations for observing cycles, transferring cycles, and\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 `balance()` can change from one call to the next.\n///\n/// Example for use on IC:\n/// ```motoko no-repl\n/// import Cycles \"mo:base/ExperimentalCycles\";\n/// import Debug \"mo:base/Debug\";\n///\n/// actor {\n/// public func main() : async() {\n/// Debug.print(\"Main balance: \" # debug_show(Cycles.balance()));\n/// Cycles.add<system>(15_000_000);\n/// await operation(); // accepts 10_000_000 cycles\n/// Debug.print(\"Main refunded: \" # debug_show(Cycles.refunded())); // 5_000_000\n/// Debug.print(\"Main balance: \" # debug_show(Cycles.balance())); // decreased by around 10_000_000\n/// };\n///\n/// func operation() : async() {\n/// Debug.print(\"Operation balance: \" # debug_show(Cycles.balance()));\n/// Debug.print(\"Operation available: \" # debug_show(Cycles.available()));\n/// let obtained = Cycles.accept<system>(10_000_000);\n/// Debug.print(\"Operation obtained: \" # debug_show(obtained)); // => 10_000_000\n/// Debug.print(\"Operation balance: \" # debug_show(Cycles.balance())); // increased by 10_000_000\n/// Debug.print(\"Operation available: \" # debug_show(Cycles.available())); // decreased by 10_000_000\n/// }\n/// }\n/// ```\nimport Prim \"mo:⛔\";\nmodule {\n\n /// Returns the actor's current balance of cycles as `amount`.\n ///\n /// Example for use on the IC:\n /// ```motoko no-repl\n /// import Cycles \"mo:base/ExperimentalCycles\";\n /// import Debug \"mo:base/Debug\";\n ///\n /// actor {\n /// public func main() : async() {\n /// let balance = Cycles.balance();\n /// Debug.print(\"Balance: \" # debug_show(balance));\n /// }\n /// }\n /// ```\n public let balance : () -> (amount : Nat) = Prim.cyclesBalance;\n\n /// Returns the currently available `amount` of cycles.\n /// The amount available is the amount received in the current call,\n /// minus the cumulative amount `accept`ed by this call.\n /// On exit from the current shared function or async expression via `return` or `throw`,\n /// any remaining available amount is automatically refunded to the caller/context.\n ///\n /// Example for use on the IC:\n /// ```motoko no-repl\n /// import Cycles \"mo:base/ExperimentalCycles\";\n /// import Debug \"mo:base/Debug\";\n ///\n /// actor {\n /// public func main() : async() {\n /// let available = Cycles.available();\n /// Debug.print(\"Available: \" # debug_show(available));\n /// }\n /// }\n /// ```\n public let available : () -> (amount : Nat) = Prim.cyclesAvailable;\n\n /// Transfers up to `amount` from `available()` to `balance()`.\n /// Returns the amount actually transferred, which may be less than\n /// requested, for example, if less is available, or if canister balance limits are reached.\n ///\n /// Example for use on the IC (for simplicity, only transferring cycles to itself):\n /// ```motoko no-repl\n /// import Cycles \"mo:base/ExperimentalCycles\";\n /// import Debug \"mo:base/Debug\";\n ///\n /// actor {\n /// public func main() : async() {\n /// Cycles.add<system>(15_000_000);\n /// await operation(); // accepts 10_000_000 cycles\n /// };\n ///\n /// func operation() : async() {\n /// let obtained = Cycles.accept<system>(10_000_000);\n /// Debug.print(\"Obtained: \" # debug_show(obtained)); // => 10_000_000\n /// }\n /// }\n /// ```\n public let accept : <system>(amount : Nat) -> (accepted : Nat) = Prim.cyclesAccept;\n\n /// Indicates additional `amount` of cycles to be transferred in\n /// the next call, that is, evaluation of a shared function call or\n /// async expression.\n /// Traps if the current total would exceed `2 ** 128` cycles.\n /// Upon the call, but not before, the total amount of cycles ``add``ed since\n /// the last call is deducted from `balance()`.\n /// If this total exceeds `balance()`, the caller traps, aborting the call.\n ///\n /// **Note**: 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 ///\n /// Example for use on the IC (for simplicity, only transferring cycles to itself):\n /// ```motoko no-repl\n /// import Cycles \"mo:base/ExperimentalCycles\";\n ///\n /// actor {\n /// func operation() : async() {\n /// ignore Cycles.accept<system>(10_000_000);\n /// };\n ///\n /// public func main() : async() {\n /// Cycles.add<system>(15_000_000);\n /// await operation();\n /// }\n /// }\n /// ```\n /// @deprecated This function will be removed in future. Use the parenthetical syntax on message sends and `async` expressions to attach cycles: `(with cycles = <amount>) C.send(...)`.\n public let add : <system>(amount : Nat) -> () = Prim.cyclesAdd;\n\n /// Reports `amount` of cycles refunded in the last `await` of the current\n /// context, or zero if no await has occurred yet.\n /// Calling `refunded()` is solely informational and does not affect `balance()`.\n /// Instead, refunds are automatically added to the current balance,\n /// whether or not `refunded` is used to observe them.\n ///\n /// Example for use on the IC (for simplicity, only transferring cycles to itself):\n /// ```motoko no-repl\n /// import Cycles \"mo:base/ExperimentalCycles\";\n /// import Debug \"mo:base/Debug\";\n ///\n /// actor {\n /// func operation() : async() {\n /// ignore Cycles.accept<system>(10_000_000);\n /// };\n ///\n /// public func main() : async() {\n /// Cycles.add<system>(15_000_000);\n /// await operation(); // accepts 10_000_000 cycles\n /// Debug.print(\"Refunded: \" # debug_show(Cycles.refunded())); // 5_000_000\n /// }\n /// }\n /// ```\n public let refunded : () -> (amount : Nat) = Prim.cyclesRefunded;\n\n /// Attempts to burn `amount` of cycles, deducting `burned` from the canister's\n /// cycle balance. The burned cycles are irrevocably lost and not available to any\n /// other principal either.\n ///\n /// Example for use on the IC:\n /// ```motoko no-repl\n /// import Cycles \"mo:base/ExperimentalCycles\";\n /// import Debug \"mo:base/Debug\";\n ///\n /// actor {\n /// public func main() : async() {\n /// let burnt = Cycles.burn<system>(10_000_000);\n /// Debug.print(\"Burned: \" # debug_show burnt); // 10_000_000\n /// }\n /// }\n /// ```\n public let burn : <system>(amount : Nat) -> (burned : Nat) = Prim.cyclesBurn;\n\n}\n"},"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: When running on an ICP network, all output is written to the [canister log](https://internetcomputer.org/docs/current/developer-docs/smart-contracts/maintain/logs) with the exclusion of any output\n /// produced during the execution of non-replicated queries and composite queries.\n /// In other environments, like the interpreter and stand-alone wasm engines, the output is written to standard out.\n ///\n /// ```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"},"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/// **DEPRECATION**: Use of `ExperimentalStableMemory` library may be deprecated in future.\n/// Going forward, users should consider using library `Region.mo` to allocate *isolated* regions of memory instead.\n/// Using dedicated regions for different user applications ensures that writing\n/// to one region will not affect the state of another, unrelated region.\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 (initially 8GiB, then 32Gib, currently 64Gib).\n/// All applications should reserve at least one page for stable variable data, even when no stable variables are used.\n///\n/// Usage:\n/// ```motoko no-repl\n/// import StableMemory \"mo:base/ExperimentalStableMemory\";\n/// ```\n\nimport Prim \"mo:⛔\";\n\nmodule {\n\n /// Current size of the stable memory, in pages.\n /// Each page is 64KiB (65536 bytes).\n /// Initially `0`.\n /// Preserved across upgrades, together with contents of allocated\n /// stable memory.\n ///\n /// Example:\n /// ```motoko no-repl\n /// let beforeSize = StableMemory.size();\n /// ignore StableMemory.grow(10);\n /// let afterSize = StableMemory.size();\n /// afterSize - beforeSize // => 10\n /// ```\n public let size : () -> (pages : Nat64) = Prim.stableMemorySize;\n\n /// Grow current `size` of stable memory by the given number of pages.\n /// Each page is 64KiB (65536 bytes).\n /// Returns the previous `size` when able to grow.\n /// Returns `0xFFFF_FFFF_FFFF_FFFF` if remaining pages insufficient.\n /// Every new page is zero-initialized, containing byte 0x00 at every offset.\n /// Function `grow` is capped by a soft limit on `size` controlled by compile-time flag\n /// `--max-stable-pages <n>` (the default is 65536, or 4GiB).\n ///\n /// Example:\n /// ```motoko no-repl\n /// import Error \"mo:base/Error\";\n ///\n /// let beforeSize = StableMemory.grow(10);\n /// if (beforeSize == 0xFFFF_FFFF_FFFF_FFFF) {\n /// throw Error.reject(\"Out of memory\");\n /// };\n /// let afterSize = StableMemory.size();\n /// afterSize - beforeSize // => 10\n /// ```\n public let grow : (newPages : Nat64) -> (oldPages : Nat64) = Prim.stableMemoryGrow;\n\n /// Returns a query that, when called, returns the number of bytes of (real) IC stable memory that would be\n /// occupied by persisting its current stable variables before an upgrade.\n /// This function may be used to monitor or limit real stable memory usage.\n /// The query computes the estimate by running the first half of an upgrade, including any `preupgrade` system method.\n /// Like any other query, its state changes are discarded so no actual upgrade (or other state change) takes place.\n /// The query can only be called by the enclosing actor and will trap for other callers.\n ///\n /// Example:\n /// ```motoko no-repl\n /// actor {\n /// stable var state = \"\";\n /// public func example() : async Text {\n /// let memoryUsage = StableMemory.stableVarQuery();\n /// let beforeSize = (await memoryUsage()).size;\n /// state #= \"abcdefghijklmnopqrstuvwxyz\";\n /// let afterSize = (await memoryUsage()).size;\n /// debug_show (afterSize - beforeSize)\n /// };\n /// };\n /// ```\n public let stableVarQuery : () -> (shared query () -> async { size : Nat64 }) = Prim.stableVarQuery;\n\n /// Loads a `Nat32` value from stable memory at the given `offset`.\n /// Traps on an out-of-bounds access.\n ///\n /// Example:\n /// ```motoko no-repl\n /// let offset = 0;\n /// let value = 123;\n /// StableMemory.storeNat32(offset, value);\n /// StableMemory.loadNat32(offset) // => 123\n /// ```\n public let loadNat32 : (offset : Nat64) -> Nat32 = Prim.stableMemoryLoadNat32;\n\n /// Stores a `Nat32` value in stable memory at the given `offset`.\n /// Traps on an out-of-bounds access.\n ///\n /// Example:\n /// ```motoko no-repl\n /// let offset = 0;\n /// let value = 123;\n /// StableMemory.storeNat32(offset, value);\n /// StableMemory.loadNat32(offset) // => 123\n /// ```\n public let storeNat32 : (offset : Nat64, value : Nat32) -> () = Prim.stableMemoryStoreNat32;\n\n /// Loads a `Nat8` value from stable memory at the given `offset`.\n /// Traps on an out-of-bounds access.\n ///\n /// Example:\n /// ```motoko no-repl\n /// let offset = 0;\n /// let value = 123;\n /// StableMemory.storeNat8(offset, value);\n /// StableMemory.loadNat8(offset) // => 123\n /// ```\n public let loadNat8 : (offset : Nat64) -> Nat8 = Prim.stableMemoryLoadNat8;\n\n /// Stores a `Nat8` value in stable memory at the given `offset`.\n /// Traps on an out-of-bounds access.\n ///\n /// Example:\n /// ```motoko no-repl\n /// let offset = 0;\n /// let value = 123;\n /// StableMemory.storeNat8(offset, value);\n /// StableMemory.loadNat8(offset) // => 123\n /// ```\n public let storeNat8 : (offset : Nat64, value : Nat8) -> () = Prim.stableMemoryStoreNat8;\n\n /// Loads a `Nat16` value from stable memory at the given `offset`.\n /// Traps on an out-of-bounds access.\n ///\n /// Example:\n /// ```motoko no-repl\n /// let offset = 0;\n /// let value = 123;\n /// StableMemory.storeNat16(offset, value);\n /// StableMemory.loadNat16(offset) // => 123\n /// ```\n public let loadNat16 : (offset : Nat64) -> Nat16 = Prim.stableMemoryLoadNat16;\n\n /// Stores a `Nat16` value in stable memory at the given `offset`.\n /// Traps on an out-of-bounds access.\n ///\n /// Example:\n /// ```motoko no-repl\n /// let offset = 0;\n /// let value = 123;\n /// StableMemory.storeNat16(offset, value);\n /// StableMemory.loadNat16(offset) // => 123\n /// ```\n public let storeNat16 : (offset : Nat64, value : Nat16) -> () = Prim.stableMemoryStoreNat16;\n\n /// Loads a `Nat64` value from stable memory at the given `offset`.\n /// Traps on an out-of-bounds access.\n ///\n /// Example:\n /// ```motoko no-repl\n /// let offset = 0;\n /// let value = 123;\n /// StableMemory.storeNat64(offset, value);\n /// StableMemory.loadNat64(offset) // => 123\n /// ```\n public let loadNat64 : (offset : Nat64) -> Nat64 = Prim.stableMemoryLoadNat64;\n\n /// Stores a `Nat64` value in stable memory at the given `offset`.\n /// Traps on an out-of-bounds access.\n ///\n /// Example:\n /// ```motoko no-repl\n /// let offset = 0;\n /// let value = 123;\n /// StableMemory.storeNat64(offset, value);\n /// StableMemory.loadNat64(offset) // => 123\n /// ```\n public let storeNat64 : (offset : Nat64, value : Nat64) -> () = Prim.stableMemoryStoreNat64;\n\n /// Loads an `Int32` value from stable memory at the given `offset`.\n /// Traps on an out-of-bounds access.\n ///\n /// Example:\n /// ```motoko no-repl\n /// let offset = 0;\n /// let value = 123;\n /// StableMemory.storeInt32(offset, value);\n /// StableMemory.loadInt32(offset) // => 123\n /// ```\n public let loadInt32 : (offset : Nat64) -> Int32 = Prim.stableMemoryLoadInt32;\n\n /// Stores an `Int32` value in stable memory at the given `offset`.\n /// Traps on an out-of-bounds access.\n ///\n /// Example:\n /// ```motoko no-repl\n /// let offset = 0;\n /// let value = 123;\n /// StableMemory.storeInt32(offset, value);\n /// StableMemory.loadInt32(offset) // => 123\n /// ```\n public let storeInt32 : (offset : Nat64, value : Int32) -> () = Prim.stableMemoryStoreInt32;\n\n /// Loads an `Int8` value from stable memory at the given `offset`.\n /// Traps on an out-of-bounds access.\n ///\n /// Example:\n /// ```motoko no-repl\n /// let offset = 0;\n /// let value = 123;\n /// StableMemory.storeInt8(offset, value);\n /// StableMemory.loadInt8(offset) // => 123\n /// ```\n public let loadInt8 : (offset : Nat64) -> Int8 = Prim.stableMemoryLoadInt8;\n\n /// Stores an `Int8` value in stable memory at the given `offset`.\n /// Traps on an out-of-bounds access.\n ///\n /// Example:\n /// ```motoko no-repl\n /// let offset = 0;\n /// let value = 123;\n /// StableMemory.storeInt8(offset, value);\n /// StableMemory.loadInt8(offset) // => 123\n /// ```\n public let storeInt8 : (offset : Nat64, value : Int8) -> () = Prim.stableMemoryStoreInt8;\n\n /// Loads an `Int16` value from stable memory at the given `offset`.\n /// Traps on an out-of-bounds access.\n ///\n /// Example:\n /// ```motoko no-repl\n /// let offset = 0;\n /// let value = 123;\n /// StableMemory.storeInt16(offset, value);\n /// StableMemory.loadInt16(offset) // => 123\n /// ```\n public let loadInt16 : (offset : Nat64) -> Int16 = Prim.stableMemoryLoadInt16;\n\n /// Stores an `Int16` value in stable memory at the given `offset`.\n /// Traps on an out-of-bounds access.\n ///\n /// Example:\n /// ```motoko no-repl\n /// let offset = 0;\n /// let value = 123;\n /// StableMemory.storeInt16(offset, value);\n /// StableMemory.loadInt16(offset) // => 123\n /// ```\n public let storeInt16 : (offset : Nat64, value : Int16) -> () = Prim.stableMemoryStoreInt16;\n\n /// Loads an `Int64` value from stable memory at the given `offset`.\n /// Traps on an out-of-bounds access.\n ///\n /// Example:\n /// ```motoko no-repl\n /// let offset = 0;\n /// let value = 123;\n /// StableMemory.storeInt64(offset, value);\n /// StableMemory.loadInt64(offset) // => 123\n /// ```\n public let loadInt64 : (offset : Nat64) -> Int64 = Prim.stableMemoryLoadInt64;\n\n /// Stores an `Int64` value in stable memory at the given `offset`.\n /// Traps on an out-of-bounds access.\n ///\n /// Example:\n /// ```motoko no-repl\n /// let offset = 0;\n /// let value = 123;\n /// StableMemory.storeInt64(offset, value);\n /// StableMemory.loadInt64(offset) // => 123\n /// ```\n public let storeInt64 : (offset : Nat64, value : Int64) -> () = Prim.stableMemoryStoreInt64;\n\n /// Loads a `Float` value from stable memory at the given `offset`.\n /// Traps on an out-of-bounds access.\n ///\n /// Example:\n /// ```motoko no-repl\n /// let offset = 0;\n /// let value = 1.25;\n /// StableMemory.storeFloat(offset, value);\n /// StableMemory.loadFloat(offset) // => 1.25\n /// ```\n public let loadFloat : (offset : Nat64) -> Float = Prim.stableMemoryLoadFloat;\n\n /// Stores a `Float` value in stable memory at the given `offset`.\n /// Traps on an out-of-bounds access.\n ///\n /// Example:\n /// ```motoko no-repl\n /// let offset = 0;\n /// let value = 1.25;\n /// StableMemory.storeFloat(offset, value);\n /// StableMemory.loadFloat(offset) // => 1.25\n /// ```\n public let storeFloat : (offset : Nat64, value : Float) -> () = Prim.stableMemoryStoreFloat;\n\n /// Load `size` bytes starting from `offset` as a `Blob`.\n /// Traps on an out-of-bounds access.\n ///\n /// Example:\n /// ```motoko no-repl\n /// import Blob \"mo:base/Blob\";\n ///\n /// let offset = 0;\n /// let value = Blob.fromArray([1, 2, 3]);\n /// let size = value.size();\n /// StableMemory.storeBlob(offset, value);\n /// Blob.toArray(StableMemory.loadBlob(offset, size)) // => [1, 2, 3]\n /// ```\n public let loadBlob : (offset : Nat64, size : Nat) -> Blob = Prim.stableMemoryLoadBlob;\n\n /// Write bytes of `blob` beginning at `offset`.\n /// Traps on an out-of-bounds access.\n ///\n /// Example:\n /// ```motoko no-repl\n /// import Blob \"mo:base/Blob\";\n ///\n /// let offset = 0;\n /// let value = Blob.fromArray([1, 2, 3]);\n /// let size = value.size();\n /// StableMemory.storeBlob(offset, value);\n /// Blob.toArray(StableMemory.loadBlob(offset, size)) // => [1, 2, 3]\n /// ```\n public let storeBlob : (offset : Nat64, value : Blob) -> () = Prim.stableMemoryStoreBlob;\n\n}\n"},"Blob.mo":{"content":"/// Module for working with Blobs: immutable sequence of bytes.\n///\n/// Blobs represent sequences of bytes. They are immutable, iterable, but not indexable and can be empty.\n///\n/// Byte sequences are also often represented as `[Nat8]`, i.e. an array of bytes, but this representation is currently much less compact than `Blob`, taking 4 physical bytes to represent each logical byte in the sequence.\n/// If you would like to manipulate Blobs, it is recommended that you convert\n/// Blobs to `[var Nat8]` or `Buffer<Nat8>`, do the manipulation, then convert back.\n///\n/// Import from the base library to use this module.\n/// ```motoko name=import\n/// import Blob \"mo:base/Blob\";\n/// ```\n///\n/// Some built in features not listed in this module:\n///\n/// * You can create a `Blob` literal from a `Text` literal, provided the context expects an expression of type `Blob`.\n/// * `b.size() : Nat` returns the number of bytes in the blob `b`;\n/// * `b.vals() : Iter.Iter<Nat8>` returns an iterator to enumerate the bytes of the blob `b`.\n///\n/// For example:\n/// ```motoko include=import\n/// import Debug \"mo:base/Debug\";\n/// import Nat8 \"mo:base/Nat8\";\n///\n/// let blob = \"\\00\\00\\00\\ff\" : Blob; // blob literals, where each byte is delimited by a back-slash and represented in hex\n/// let blob2 = \"charsもあり\" : Blob; // you can also use characters in the literals\n/// let numBytes = blob.size(); // => 4 (returns the number of bytes in the Blob)\n/// for (byte : Nat8 in blob.vals()) { // iterator over the Blob\n/// Debug.print(Nat8.toText(byte))\n/// }\n/// ```\nimport Prim \"mo:⛔\";\nmodule {\n public type Blob = Prim.Types.Blob;\n /// Creates a `Blob` from an array of bytes (`[Nat8]`), by copying each element.\n ///\n /// Example:\n /// ```motoko include=import\n /// let bytes : [Nat8] = [0, 255, 0];\n /// let blob = Blob.fromArray(bytes); // => \"\\00\\FF\\00\"\n /// ```\n public func fromArray(bytes : [Nat8]) : Blob = Prim.arrayToBlob bytes;\n\n /// Creates a `Blob` from a mutable array of bytes (`[var Nat8]`), by copying each element.\n ///\n /// Example:\n /// ```motoko include=import\n /// let bytes : [var Nat8] = [var 0, 255, 0];\n /// let blob = Blob.fromArrayMut(bytes); // => \"\\00\\FF\\00\"\n /// ```\n public func fromArrayMut(bytes : [var Nat8]) : Blob = Prim.arrayMutToBlob bytes;\n\n /// Converts a `Blob` to an array of bytes (`[Nat8]`), by copying each element.\n ///\n /// Example:\n /// ```motoko include=import\n /// let blob = \"\\00\\FF\\00\" : Blob;\n /// let bytes = Blob.toArray(blob); // => [0, 255, 0]\n /// ```\n public func toArray(blob : Blob) : [Nat8] = Prim.blobToArray blob;\n\n /// Converts a `Blob` to a mutable array of bytes (`[var Nat8]`), by copying each element.\n ///\n /// Example:\n /// ```motoko include=import\n /// let blob = \"\\00\\FF\\00\" : Blob;\n /// let bytes = Blob.toArrayMut(blob); // => [var 0, 255, 0]\n /// ```\n public func toArrayMut(blob : Blob) : [var Nat8] = Prim.blobToArrayMut blob;\n\n /// Returns the (non-cryptographic) hash of `blob`.\n ///\n /// Example:\n /// ```motoko include=import\n /// let blob = \"\\00\\FF\\00\" : Blob;\n /// Blob.hash(blob) // => 1_818_567_776\n /// ```\n public func hash(blob : Blob) : Nat32 = Prim.hashBlob blob;\n\n /// General purpose comparison function for `Blob` by comparing the value of\n /// the bytes. Returns the `Order` (either `#less`, `#equal`, or `#greater`)\n /// by comparing `blob1` with `blob2`.\n ///\n /// Example:\n /// ```motoko include=import\n /// let blob1 = \"\\00\\00\\00\" : Blob;\n /// let blob2 = \"\\00\\FF\\00\" : Blob;\n /// Blob.compare(blob1, blob2) // => #less\n /// ```\n public func compare(b1 : Blob, b2 : Blob) : { #less; #equal; #greater } {\n let c = Prim.blobCompare(b1, b2);\n if (c < 0) #less else if (c == 0) #equal else #greater\n };\n\n /// Equality function for `Blob` types.\n /// This is equivalent to `blob1 == blob2`.\n ///\n /// Example:\n /// ```motoko include=import\n /// let blob1 = \"\\00\\FF\\00\" : Blob;\n /// let blob2 = \"\\00\\FF\\00\" : Blob;\n /// ignore Blob.equal(blob1, blob2);\n /// blob1 == blob2 // => true\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `==` operator) is so that you can use it as a function value\n /// to pass to a higher order function. It is not possible to use `==` as a\n /// function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Buffer \"mo:base/Buffer\";\n ///\n /// let buffer1 = Buffer.Buffer<Blob>(3);\n /// let buffer2 = Buffer.Buffer<Blob>(3);\n /// Buffer.equal(buffer1, buffer2, Blob.equal) // => true\n /// ```\n public func equal(blob1 : Blob, blob2 : Blob) : Bool { blob1 == blob2 };\n\n /// Inequality function for `Blob` types.\n /// This is equivalent to `blob1 != blob2`.\n ///\n /// Example:\n /// ```motoko include=import\n /// let blob1 = \"\\00\\AA\\AA\" : Blob;\n /// let blob2 = \"\\00\\FF\\00\" : Blob;\n /// ignore Blob.notEqual(blob1, blob2);\n /// blob1 != blob2 // => true\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `!=` operator) is so that you can use it as a function value\n /// to pass to a higher order function. It is not possible to use `!=` as a\n /// function value at the moment.\n public func notEqual(blob1 : Blob, blob2 : Blob) : Bool { blob1 != blob2 };\n\n /// \"Less than\" function for `Blob` types.\n /// This is equivalent to `blob1 < blob2`.\n ///\n /// Example:\n /// ```motoko include=import\n /// let blob1 = \"\\00\\AA\\AA\" : Blob;\n /// let blob2 = \"\\00\\FF\\00\" : Blob;\n /// ignore Blob.less(blob1, blob2);\n /// blob1 < blob2 // => true\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<` operator) is so that you can use it as a function value\n /// to pass to a higher order function. It is not possible to use `<` as a\n /// function value at the moment.\n public func less(blob1 : Blob, blob2 : Blob) : Bool { blob1 < blob2 };\n\n /// \"Less than or equal to\" function for `Blob` types.\n /// This is equivalent to `blob1 <= blob2`.\n ///\n /// Example:\n /// ```motoko include=import\n /// let blob1 = \"\\00\\AA\\AA\" : Blob;\n /// let blob2 = \"\\00\\FF\\00\" : Blob;\n /// ignore Blob.lessOrEqual(blob1, blob2);\n /// blob1 <= blob2 // => true\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<=` operator) is so that you can use it as a function value\n /// to pass to a higher order function. It is not possible to use `<=` as a\n /// function value at the moment.\n public func lessOrEqual(blob1 : Blob, blob2 : Blob) : Bool { blob1 <= blob2 };\n\n /// \"Greater than\" function for `Blob` types.\n /// This is equivalent to `blob1 > blob2`.\n ///\n /// Example:\n /// ```motoko include=import\n /// let blob1 = \"\\BB\\AA\\AA\" : Blob;\n /// let blob2 = \"\\00\\00\\00\" : Blob;\n /// ignore Blob.greater(blob1, blob2);\n /// blob1 > blob2 // => true\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `>` operator) is so that you can use it as a function value\n /// to pass to a higher order function. It is not possible to use `>` as a\n /// function value at the moment.\n public func greater(blob1 : Blob, blob2 : Blob) : Bool { blob1 > blob2 };\n\n /// \"Greater than or equal to\" function for `Blob` types.\n /// This is equivalent to `blob1 >= blob2`.\n ///\n /// Example:\n /// ```motoko include=import\n /// let blob1 = \"\\BB\\AA\\AA\" : Blob;\n /// let blob2 = \"\\00\\00\\00\" : Blob;\n /// ignore Blob.greaterOrEqual(blob1, blob2);\n /// blob1 >= blob2 // => true\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `>=` operator) is so that you can use it as a function value\n /// to pass to a higher order function. It is not possible to use `>=` as a\n /// function value at the moment.\n public func greaterOrEqual(blob1 : Blob, blob2 : Blob) : Bool {\n blob1 >= blob2\n }\n}\n"},"ExperimentalInternetComputer.mo":{"content":"/// Low-level interface to the Internet Computer.\n///\n/// **WARNING:** 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/motoko/main/reference/language-manual#candid-serialization)\n public let call : (canister : Principal, name : Text, data : Blob) -> async (reply : Blob) = Prim.call_raw;\n\n /// `isReplicated` is true for update messages and for queries that passed through consensus.\n public let isReplicated : () -> Bool = Prim.isReplicatedExecution;\n\n /// Given computation, `comp`, counts the number of actual and (for IC system calls) notional WebAssembly\n /// instructions performed during the execution of `comp()`.\n ///\n /// More precisely, returns the difference between the state of the IC instruction counter (_performance counter_ `0`) before and after executing `comp()`\n /// (see [Performance Counter](https://internetcomputer.org/docs/current/references/ic-interface-spec#system-api-performance-counter)).\n ///\n /// 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 /// Returns the current value of IC _performance counter_ `counter`.\n ///\n /// * Counter `0` is the _current execution instruction counter_, counting instructions only since the beginning of the current IC message.\n /// This counter is reset to value `0` on shared function entry and every `await`.\n /// It is therefore only suitable for measuring the cost of synchronous code.\n ///\n /// * Counter `1` is the _call context instruction counter_ for the current shared function call.\n /// For replicated message executing, this excludes the cost of nested IC calls (even to the current canister).\n /// For non-replicated messages, such as composite queries, it includes the cost of nested calls.\n /// The current value of this counter is preserved across `awaits` (unlike counter `0`).\n ///\n /// * The function (currently) traps if `counter` >= 2.\n ///\n /// Consult [Performance Counter](https://internetcomputer.org/docs/current/references/ic-interface-spec#system-api-performance-counter) for details.\n ///\n /// Example:\n /// ```motoko no-repl\n /// import IC \"mo:base/ExperimentalInternetComputer\";\n ///\n /// let c1 = IC.performanceCounter(1);\n /// work();\n /// let diff : Nat64 = IC.performanceCounter(1) - c1;\n /// ```\n public let performanceCounter : (counter : Nat32) -> (value: Nat64) = Prim.performanceCounter;\n\n /// Returns the time (in nanoseconds from the epoch start) by when the update message should\n /// reply to the best effort message so that it can be received by the requesting canister.\n /// Queries and unbounded-time update messages return null.\n public func replyDeadline() : ?Nat {\n let raw = Prim.replyDeadline();\n if (raw == 0) null else ?Prim.nat64ToNat(raw)\n };\n\n /// Returns the subnet's principal for the running actor.\n /// Note: Due to canister migration the hosting subnet can vary with time.\n ///\n /// Example:\n /// ```motoko no-repl\n /// import IC \"mo:base/ExperimentalInternetComputer\";\n ///\n /// let subnetPrincipal = IC.subnet();\n /// ```\n public let subnet : () -> Principal = Prim.canisterSubnet;\n\n}\n"},"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"},"Func.mo":{"content":"/// Functions on functions, creating functions from simpler inputs.\n///\n/// (Most commonly used when programming in functional style using higher-order\n/// functions.)\n\nmodule {\n /// Import from the base library to use this module.\n ///\n /// ```motoko name=import\n /// import { compose; const; identity } = \"mo:base/Func\";\n /// import Text = \"mo:base/Text\";\n /// import Char = \"mo:base/Char\";\n /// ```\n\n /// The composition of two functions `f` and `g` is a function that applies `g` and then `f`.\n ///\n /// Example:\n /// ```motoko include=import\n /// let textFromNat32 = compose(Text.fromChar, Char.fromNat32);\n /// assert textFromNat32(65) == \"A\";\n /// ```\n public func compose<A, B, C>(f : B -> C, g : A -> B) : A -> C {\n func(x : A) : C {\n f(g(x))\n }\n };\n\n /// The `identity` function returns its argument.\n /// Example:\n /// ```motoko include=import\n /// assert identity(10) == 10;\n /// assert identity(true) == true;\n /// ```\n public func identity<A>(x : A) : A = x;\n\n /// The const function is a _curried_ function that accepts an argument `x`,\n /// and then returns a function that discards its argument and always returns\n /// the `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// assert const<Nat, Text>(10)(\"hello\") == 10;\n /// assert const(true)(20) == true;\n /// ```\n public func const<A, B>(x : A) : B -> A = func _ = x\n}\n"},"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"},"Float.mo":{"content":"/// Double precision (64-bit) floating-point numbers in IEEE 754 representation.\n///\n/// This module contains common floating-point constants and utility functions.\n///\n/// Notation for special values in the documentation below:\n/// `+inf`: Positive infinity\n/// `-inf`: Negative infinity\n/// `NaN`: \"not a number\" (can have different sign bit values, but `NaN != NaN` regardless of the sign).\n///\n/// Note:\n/// Floating point numbers have limited precision and operations may inherently result in numerical errors.\n///\n/// Examples of numerical errors:\n/// ```motoko\n/// 0.1 + 0.1 + 0.1 == 0.3 // => false\n/// ```\n///\n/// ```motoko\n/// 1e16 + 1.0 != 1e16 // => false\n/// ```\n///\n/// (and many more cases)\n///\n/// Advice:\n/// * Floating point number comparisons by `==` or `!=` are discouraged. Instead, it is better to compare\n/// floating-point numbers with a numerical tolerance, called epsilon.\n///\n/// Example:\n/// ```motoko\n/// import Float \"mo:base/Float\";\n/// let x = 0.1 + 0.1 + 0.1;\n/// let y = 0.3;\n///\n/// let epsilon = 1e-6; // This depends on the application case (needs a numerical error analysis).\n/// Float.equalWithin(x, y, epsilon) // => true\n/// ```\n///\n/// * For absolute precision, it is recommened to encode the fraction number as a pair of a Nat for the base\n/// and a Nat for the exponent (decimal point).\n///\n/// NaN sign:\n/// * The NaN sign is only applied by `abs`, `neg`, and `copySign`. Other operations can have an arbitrary\n/// sign bit for NaN results.\n\nimport Prim \"mo:⛔\";\nimport Int \"Int\";\n\nmodule {\n\n /// 64-bit floating point number type.\n public type Float = Prim.Types.Float;\n\n /// Ratio of the circumference of a circle to its diameter.\n /// Note: Limited precision.\n public let pi : Float = 3.14159265358979323846; // taken from musl math.h\n\n /// Base of the natural logarithm.\n /// Note: Limited precision.\n public let e : Float = 2.7182818284590452354; // taken from musl math.h\n\n /// Determines whether the `number` is a `NaN` (\"not a number\" in the floating point representation).\n /// Notes:\n /// * Equality test of `NaN` with itself or another number is always `false`.\n /// * There exist many internal `NaN` value representations, such as positive and negative NaN,\n /// signalling and quiet NaNs, each with many different bit representations.\n ///\n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n ///\n /// Float.isNaN(0.0/0.0) // => true\n /// ```\n public func isNaN(number : Float) : Bool {\n number != number\n };\n\n /// Returns the absolute value of `x`.\n ///\n /// Special cases:\n /// ```\n /// abs(+inf) => +inf\n /// abs(-inf) => +inf\n /// abs(-NaN) => +NaN\n /// abs(-0.0) => 0.0\n /// ```\n ///\n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n ///\n /// Float.abs(-1.2) // => 1.2\n /// ```\n public let abs : (x : Float) -> Float = Prim.floatAbs;\n\n /// Returns the square root of `x`.\n ///\n /// Special cases:\n /// ```\n /// sqrt(+inf) => +inf\n /// sqrt(-0.0) => -0.0\n /// sqrt(x) => NaN if x < 0.0\n /// sqrt(NaN) => NaN\n /// ```\n ///\n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n ///\n /// Float.sqrt(6.25) // => 2.5\n /// ```\n public let sqrt : (x : Float) -> Float = Prim.floatSqrt;\n\n /// Returns the smallest integral float greater than or equal to `x`.\n ///\n /// Special cases:\n /// ```\n /// ceil(+inf) => +inf\n /// ceil(-inf) => -inf\n /// ceil(NaN) => NaN\n /// ceil(0.0) => 0.0\n /// ceil(-0.0) => -0.0\n /// ```\n ///\n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n ///\n /// Float.ceil(1.2) // => 2.0\n /// ```\n public let ceil : (x : Float) -> Float = Prim.floatCeil;\n\n /// Returns the largest integral float less than or equal to `x`.\n ///\n /// Special cases:\n /// ```\n /// floor(+inf) => +inf\n /// floor(-inf) => -inf\n /// floor(NaN) => NaN\n /// floor(0.0) => 0.0\n /// floor(-0.0) => -0.0\n /// ```\n ///\n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n ///\n /// Float.floor(1.2) // => 1.0\n /// ```\n public let floor : (x : Float) -> Float = Prim.floatFloor;\n\n /// Returns the nearest integral float not greater in magnitude than `x`.\n /// This is equivalent to returning `x` with truncating its decimal places.\n ///\n /// Special cases:\n /// ```\n /// trunc(+inf) => +inf\n /// trunc(-inf) => -inf\n /// trunc(NaN) => NaN\n /// trunc(0.0) => 0.0\n /// trunc(-0.0) => -0.0\n /// ```\n ///\n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n ///\n /// Float.trunc(2.75) // => 2.0\n /// ```\n public let trunc : (x : Float) -> Float = Prim.floatTrunc;\n\n /// Returns the nearest integral float to `x`.\n /// A decimal place of exactly .5 is rounded up for `x > 0`\n /// and rounded down for `x < 0`\n ///\n /// Special cases:\n /// ```\n /// nearest(+inf) => +inf\n /// nearest(-inf) => -inf\n /// nearest(NaN) => NaN\n /// nearest(0.0) => 0.0\n /// nearest(-0.0) => -0.0\n /// ```\n ///\n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n ///\n /// Float.nearest(2.75) // => 3.0\n /// ```\n public let nearest : (x : Float) -> Float = Prim.floatNearest;\n\n /// Returns `x` if `x` and `y` have same sign, otherwise `x` with negated sign.\n ///\n /// The sign bit of zero, infinity, and `NaN` is considered.\n ///\n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n ///\n /// Float.copySign(1.2, -2.3) // => -1.2\n /// ```\n public let copySign : (x : Float, y : Float) -> Float = Prim.floatCopySign;\n\n /// Returns the smaller value of `x` and `y`.\n ///\n /// Special cases:\n /// ```\n /// min(NaN, y) => NaN for any Float y\n /// min(x, NaN) => NaN for any Float x\n /// ```\n ///\n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n ///\n /// Float.min(1.2, -2.3) // => -2.3 (with numerical imprecision)\n /// ```\n public let min : (x : Float, y : Float) -> Float = Prim.floatMin;\n\n /// Returns the larger value of `x` and `y`.\n ///\n /// Special cases:\n /// ```\n /// max(NaN, y) => NaN for any Float y\n /// max(x, NaN) => NaN for any Float x\n /// ```\n ///\n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n ///\n /// Float.max(1.2, -2.3) // => 1.2\n /// ```\n public let max : (x : Float, y : Float) -> Float = Prim.floatMax;\n\n /// Returns the sine of the radian angle `x`.\n ///\n /// Special cases:\n /// ```\n /// sin(+inf) => NaN\n /// sin(-inf) => NaN\n /// sin(NaN) => NaN\n /// ```\n ///\n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n ///\n /// Float.sin(Float.pi / 2) // => 1.0\n /// ```\n public let sin : (x : Float) -> Float = Prim.sin;\n\n /// Returns the cosine of the radian angle `x`.\n ///\n /// Special cases:\n /// ```\n /// cos(+inf) => NaN\n /// cos(-inf) => NaN\n /// cos(NaN) => NaN\n /// ```\n ///\n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n ///\n /// Float.cos(Float.pi / 2) // => 0.0 (with numerical imprecision)\n /// ```\n public let cos : (x : Float) -> Float = Prim.cos;\n\n /// Returns the tangent of the radian angle `x`.\n ///\n /// Special cases:\n /// ```\n /// tan(+inf) => NaN\n /// tan(-inf) => NaN\n /// tan(NaN) => NaN\n /// ```\n ///\n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n ///\n /// Float.tan(Float.pi / 4) // => 1.0 (with numerical imprecision)\n /// ```\n public let tan : (x : Float) -> Float = Prim.tan;\n\n /// Returns the arc sine of `x` in radians.\n ///\n /// Special cases:\n /// ```\n /// arcsin(x) => NaN if x > 1.0\n /// arcsin(x) => NaN if x < -1.0\n /// arcsin(NaN) => NaN\n /// ```\n ///\n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n ///\n /// Float.arcsin(1.0) // => Float.pi / 2\n /// ```\n public let arcsin : (x : Float) -> Float = Prim.arcsin;\n\n /// Returns the arc cosine of `x` in radians.\n ///\n /// Special cases:\n /// ```\n /// arccos(x) => NaN if x > 1.0\n /// arccos(x) => NaN if x < -1.0\n /// arcos(NaN) => NaN\n /// ```\n ///\n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n ///\n /// Float.arccos(1.0) // => 0.0\n /// ```\n public let arccos : (x : Float) -> Float = Prim.arccos;\n\n /// Returns the arc tangent of `x` in radians.\n ///\n /// Special cases:\n /// ```\n /// arctan(+inf) => pi / 2\n /// arctan(-inf) => -pi / 2\n /// arctan(NaN) => NaN\n /// ```\n ///\n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n ///\n /// Float.arctan(1.0) // => Float.pi / 4\n /// ```\n public let arctan : (x : Float) -> Float = Prim.arctan;\n\n /// Given `(y,x)`, returns the arc tangent in radians of `y/x` based on the signs of both values to determine the correct quadrant.\n ///\n /// Special cases:\n /// ```\n /// arctan2(0.0, 0.0) => 0.0\n /// arctan2(-0.0, 0.0) => -0.0\n /// arctan2(0.0, -0.0) => pi\n /// arctan2(-0.0, -0.0) => -pi\n /// arctan2(+inf, +inf) => pi / 4\n /// arctan2(+inf, -inf) => 3 * pi / 4\n /// arctan2(-inf, +inf) => -pi / 4\n /// arctan2(-inf, -inf) => -3 * pi / 4\n /// arctan2(NaN, x) => NaN for any Float x\n /// arctan2(y, NaN) => NaN for any Float y\n /// ```\n ///\n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n ///\n /// let sqrt2over2 = Float.sqrt(2) / 2;\n /// Float.arctan2(sqrt2over2, sqrt2over2) // => Float.pi / 4\n /// ```\n public let arctan2 : (y : Float, x : Float) -> Float = Prim.arctan2;\n\n /// Returns the value of `e` raised to the `x`-th power.\n ///\n /// Special cases:\n /// ```\n /// exp(+inf) => +inf\n /// exp(-inf) => 0.0\n /// exp(NaN) => NaN\n /// ```\n ///\n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n ///\n /// Float.exp(1.0) // => Float.e\n /// ```\n public let exp : (x : Float) -> Float = Prim.exp;\n\n /// Returns the natural logarithm (base-`e`) of `x`.\n ///\n /// Special cases:\n /// ```\n /// log(0.0) => -inf\n /// log(-0.0) => -inf\n /// log(x) => NaN if x < 0.0\n /// log(+inf) => +inf\n /// log(NaN) => NaN\n /// ```\n ///\n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n ///\n /// Float.log(Float.e) // => 1.0\n /// ```\n public let log : (x : Float) -> Float = Prim.log;\n\n /// Formatting. `format(fmt, x)` formats `x` to `Text` according to the\n /// formatting directive `fmt`, which can take one of the following forms:\n ///\n /// * `#fix prec` as fixed-point format with `prec` digits\n /// * `#exp prec` as exponential format with `prec` digits\n /// * `#gen prec` as generic format with `prec` digits\n /// * `#exact` as exact format that can be decoded without loss.\n ///\n /// `-0.0` is formatted with negative sign bit.\n /// Positive infinity is formatted as \"inf\".\n /// Negative infinity is formatted as \"-inf\".\n ///\n /// Note: The numerical precision and the text format can vary between\n /// Motoko versions and runtime configuration. Moreover, `NaN` can be printed\n /// differently, i.e. \"NaN\" or \"nan\", potentially omitting the `NaN` sign.\n ///\n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n ///\n /// Float.format(#exp 3, 123.0) // => \"1.230e+02\"\n /// ```\n public func format(fmt : { #fix : Nat8; #exp : Nat8; #gen : Nat8; #exact }, x : Float) : Text = switch fmt {\n case (#fix(prec)) { Prim.floatToFormattedText(x, prec, 0) };\n case (#exp(prec)) { Prim.floatToFormattedText(x, prec, 1) };\n case (#gen(prec)) { Prim.floatToFormattedText(x, prec, 2) };\n case (#exact) { Prim.floatToFormattedText(x, 17, 2) }\n };\n\n /// Conversion to Text. Use `format(fmt, x)` for more detailed control.\n ///\n /// `-0.0` is formatted with negative sign bit.\n /// Positive infinity is formatted as `inf`.\n /// Negative infinity is formatted as `-inf`.\n /// `NaN` is formatted as `NaN` or `-NaN` depending on its sign bit.\n ///\n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n ///\n /// Float.toText(0.12) // => \"0.12\"\n /// ```\n public let toText : Float -> Text = Prim.floatToText;\n\n /// Conversion to Int64 by truncating Float, equivalent to `toInt64(trunc(f))`\n ///\n /// Traps if the floating point number is larger or smaller than the representable Int64.\n /// Also traps for `inf`, `-inf`, and `NaN`.\n ///\n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n ///\n /// Float.toInt64(-12.3) // => -12\n /// ```\n public let toInt64 : Float -> Int64 = Prim.floatToInt64;\n\n /// Conversion from Int64.\n ///\n /// Note: The floating point number may be imprecise for large or small Int64.\n ///\n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n ///\n /// Float.fromInt64(-42) // => -42.0\n /// ```\n public let fromInt64 : Int64 -> Float = Prim.int64ToFloat;\n\n /// Conversion to Int.\n ///\n /// Traps for `inf`, `-inf`, and `NaN`.\n ///\n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n ///\n /// Float.toInt(1.2e6) // => +1_200_000\n /// ```\n public let toInt : Float -> Int = Prim.floatToInt;\n\n /// Conversion from Int. May result in `Inf`.\n ///\n /// Note: The floating point number may be imprecise for large or small Int values.\n /// Returns `inf` if the integer is greater than the maximum floating point number.\n /// Returns `-inf` if the integer is less than the minimum floating point number.\n ///\n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n ///\n /// Float.fromInt(-123) // => -123.0\n /// ```\n public let fromInt : Int -> Float = Prim.intToFloat;\n\n /// Returns `x == y`.\n /// @deprecated Use `Float.equalWithin()` as this function does not consider numerical errors.\n public func equal(x : Float, y : Float) : Bool { x == y };\n\n /// Returns `x != y`.\n /// @deprecated Use `Float.notEqualWithin()` as this function does not consider numerical errors.\n public func notEqual(x : Float, y : Float) : Bool { x != y };\n\n /// Determines whether `x` is equal to `y` within the defined tolerance of `epsilon`.\n /// The `epsilon` considers numerical erros, see comment above.\n /// Equivalent to `Float.abs(x - y) <= epsilon` for a non-negative epsilon.\n ///\n /// Traps if `epsilon` is negative or `NaN`.\n ///\n /// Special cases:\n /// ```\n /// equalWithin(+0.0, -0.0, epsilon) => true for any `epsilon >= 0.0`\n /// equalWithin(-0.0, +0.0, epsilon) => true for any `epsilon >= 0.0`\n /// equalWithin(+inf, +inf, epsilon) => true for any `epsilon >= 0.0`\n /// equalWithin(-inf, -inf, epsilon) => true for any `epsilon >= 0.0`\n /// equalWithin(x, NaN, epsilon) => false for any x and `epsilon >= 0.0`\n /// equalWithin(NaN, y, epsilon) => false for any y and `epsilon >= 0.0`\n /// ```\n ///\n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n ///\n /// let epsilon = 1e-6;\n /// Float.equalWithin(-12.3, -1.23e1, epsilon) // => true\n /// ```\n public func equalWithin(x : Float, y : Float, epsilon : Float) : Bool {\n if (not (epsilon >= 0.0)) {\n // also considers NaN, not identical to `epsilon < 0.0`\n Prim.trap(\"epsilon must be greater or equal 0.0\")\n };\n x == y or abs(x - y) <= epsilon // `x == y` to also consider infinity equal\n };\n\n /// Determines whether `x` is not equal to `y` within the defined tolerance of `epsilon`.\n /// The `epsilon` considers numerical erros, see comment above.\n /// Equivalent to `not equal(x, y, epsilon)`.\n ///\n /// Traps if `epsilon` is negative or `NaN`.\n ///\n /// Special cases:\n /// ```\n /// notEqualWithin(+0.0, -0.0, epsilon) => false for any `epsilon >= 0.0`\n /// notEqualWithin(-0.0, +0.0, epsilon) => false for any `epsilon >= 0.0`\n /// notEqualWithin(+inf, +inf, epsilon) => false for any `epsilon >= 0.0`\n /// notEqualWithin(-inf, -inf, epsilon) => false for any `epsilon >= 0.0`\n /// notEqualWithin(x, NaN, epsilon) => true for any x and `epsilon >= 0.0`\n /// notEqualWithin(NaN, y, epsilon) => true for any y and `epsilon >= 0.0`\n /// ```\n ///\n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n ///\n /// let epsilon = 1e-6;\n /// Float.notEqualWithin(-12.3, -1.23e1, epsilon) // => false\n /// ```\n public func notEqualWithin(x : Float, y : Float, epsilon : Float) : Bool {\n not equalWithin(x, y, epsilon)\n };\n\n /// Returns `x < y`.\n ///\n /// Special cases:\n /// ```\n /// less(+0.0, -0.0) => false\n /// less(-0.0, +0.0) => false\n /// less(NaN, y) => false for any Float y\n /// less(x, NaN) => false for any Float x\n /// ```\n ///\n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n ///\n /// Float.less(Float.e, Float.pi) // => true\n /// ```\n public func less(x : Float, y : Float) : Bool { x < y };\n\n /// Returns `x <= y`.\n ///\n /// Special cases:\n /// ```\n /// lessOrEqual(+0.0, -0.0) => true\n /// lessOrEqual(-0.0, +0.0) => true\n /// lessOrEqual(NaN, y) => false for any Float y\n /// lessOrEqual(x, NaN) => false for any Float x\n /// ```\n ///\n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n ///\n /// Float.lessOrEqual(0.123, 0.1234) // => true\n /// ```\n public func lessOrEqual(x : Float, y : Float) : Bool { x <= y };\n\n /// Returns `x > y`.\n ///\n /// Special cases:\n /// ```\n /// greater(+0.0, -0.0) => false\n /// greater(-0.0, +0.0) => false\n /// greater(NaN, y) => false for any Float y\n /// greater(x, NaN) => false for any Float x\n /// ```\n ///\n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n ///\n /// Float.greater(Float.pi, Float.e) // => true\n /// ```\n public func greater(x : Float, y : Float) : Bool { x > y };\n\n /// Returns `x >= y`.\n ///\n /// Special cases:\n /// ```\n /// greaterOrEqual(+0.0, -0.0) => true\n /// greaterOrEqual(-0.0, +0.0) => true\n /// greaterOrEqual(NaN, y) => false for any Float y\n /// greaterOrEqual(x, NaN) => false for any Float x\n /// ```\n ///\n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n ///\n /// Float.greaterOrEqual(0.1234, 0.123) // => true\n /// ```\n public func greaterOrEqual(x : Float, y : Float) : Bool { x >= y };\n\n /// Defines a total order of `x` and `y` for use in sorting.\n ///\n /// Note: Using this operation to determine equality or inequality is discouraged for two reasons:\n /// * It does not consider numerical errors, see comment above. Use `equalWithin(x, y, espilon)` or\n /// `notEqualWithin(x, y, epsilon)` to test for equality or inequality, respectively.\n /// * `NaN` are here considered equal if their sign matches, which is different to the standard equality\n /// by `==` or when using `equal()` or `notEqual()`.\n ///\n /// Total order:\n /// * negative NaN (no distinction between signalling and quiet negative NaN)\n /// * negative infinity\n /// * negative numbers (including negative subnormal numbers in standard order)\n /// * negative zero (`-0.0`)\n /// * positive zero (`+0.0`)\n /// * positive numbers (including positive subnormal numbers in standard order)\n /// * positive infinity\n /// * positive NaN (no distinction between signalling and quiet positive NaN)\n ///\n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n ///\n /// Float.compare(0.123, 0.1234) // => #less\n /// ```\n public func compare(x : Float, y : Float) : { #less; #equal; #greater } {\n if (isNaN(x)) {\n if (isNegative(x)) {\n if (isNaN(y) and isNegative(y)) { #equal } else { #less }\n } else {\n if (isNaN(y) and not isNegative(y)) { #equal } else { #greater }\n }\n } else if (isNaN(y)) {\n if (isNegative(y)) {\n #greater\n } else {\n #less\n }\n } else {\n if (x == y) { #equal } else if (x < y) { #less } else { #greater }\n }\n };\n\n func isNegative(number : Float) : Bool {\n copySign(1.0, number) < 0.0\n };\n\n /// Returns the negation of `x`, `-x` .\n ///\n /// Changes the sign bit for infinity.\n ///\n /// Special cases:\n /// ```\n /// neg(+inf) => -inf\n /// neg(-inf) => +inf\n /// neg(+NaN) => -NaN\n /// neg(-NaN) => +NaN\n /// neg(+0.0) => -0.0\n /// neg(-0.0) => +0.0\n /// ```\n ///\n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n ///\n /// Float.neg(1.23) // => -1.23\n /// ```\n public func neg(x : Float) : Float { -x };\n\n /// Returns the sum of `x` and `y`, `x + y`.\n ///\n /// Note: Numerical errors may occur, see comment above.\n ///\n /// Special cases:\n /// ```\n /// add(+inf, y) => +inf if y is any Float except -inf and NaN\n /// add(-inf, y) => -inf if y is any Float except +inf and NaN\n /// add(+inf, -inf) => NaN\n /// add(NaN, y) => NaN for any Float y\n /// ```\n /// The same cases apply commutatively, i.e. for `add(y, x)`.\n ///\n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n ///\n /// Float.add(1.23, 0.123) // => 1.353\n /// ```\n public func add(x : Float, y : Float) : Float { x + y };\n\n /// Returns the difference of `x` and `y`, `x - y`.\n ///\n /// Note: Numerical errors may occur, see comment above.\n ///\n /// Special cases:\n /// ```\n /// sub(+inf, y) => +inf if y is any Float except +inf or NaN\n /// sub(-inf, y) => -inf if y is any Float except -inf and NaN\n /// sub(x, +inf) => -inf if x is any Float except +inf and NaN\n /// sub(x, -inf) => +inf if x is any Float except -inf and NaN\n /// sub(+inf, +inf) => NaN\n /// sub(-inf, -inf) => NaN\n /// sub(NaN, y) => NaN for any Float y\n /// sub(x, NaN) => NaN for any Float x\n /// ```\n ///\n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n ///\n /// Float.sub(1.23, 0.123) // => 1.107\n /// ```\n public func sub(x : Float, y : Float) : Float { x - y };\n\n /// Returns the product of `x` and `y`, `x * y`.\n ///\n /// Note: Numerical errors may occur, see comment above.\n ///\n /// Special cases:\n /// ```\n /// mul(+inf, y) => +inf if y > 0.0\n /// mul(-inf, y) => -inf if y > 0.0\n /// mul(+inf, y) => -inf if y < 0.0\n /// mul(-inf, y) => +inf if y < 0.0\n /// mul(+inf, 0.0) => NaN\n /// mul(-inf, 0.0) => NaN\n /// mul(NaN, y) => NaN for any Float y\n /// ```\n /// The same cases apply commutatively, i.e. for `mul(y, x)`.\n ///\n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n ///\n /// Float.mul(1.23, 1e2) // => 123.0\n /// ```\n public func mul(x : Float, y : Float) : Float { x * y };\n\n /// Returns the division of `x` by `y`, `x / y`.\n ///\n /// Note: Numerical errors may occur, see comment above.\n ///\n /// Special cases:\n /// ```\n /// div(0.0, 0.0) => NaN\n /// div(x, 0.0) => +inf for x > 0.0\n /// div(x, 0.0) => -inf for x < 0.0\n /// div(x, +inf) => 0.0 for any x except +inf, -inf, and NaN\n /// div(x, -inf) => 0.0 for any x except +inf, -inf, and NaN\n /// div(+inf, y) => +inf if y >= 0.0\n /// div(+inf, y) => -inf if y < 0.0\n /// div(-inf, y) => -inf if y >= 0.0\n /// div(-inf, y) => +inf if y < 0.0\n /// div(NaN, y) => NaN for any Float y\n /// div(x, NaN) => NaN for any Float x\n /// ```\n ///\n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n ///\n /// Float.div(1.23, 1e2) // => 0.0123\n /// ```\n public func div(x : Float, y : Float) : Float { x / y };\n\n /// Returns the floating point division remainder `x % y`,\n /// which is defined as `x - trunc(x / y) * y`.\n ///\n /// Note: Numerical errors may occur, see comment above.\n ///\n /// Special cases:\n /// ```\n /// rem(0.0, 0.0) => NaN\n /// rem(x, y) => +inf if sign(x) == sign(y) for any x and y not being +inf, -inf, or NaN\n /// rem(x, y) => -inf if sign(x) != sign(y) for any x and y not being +inf, -inf, or NaN\n /// rem(x, +inf) => x for any x except +inf, -inf, and NaN\n /// rem(x, -inf) => x for any x except +inf, -inf, and NaN\n /// rem(+inf, y) => NaN for any Float y\n /// rem(-inf, y) => NaN for any Float y\n /// rem(NaN, y) => NaN for any Float y\n /// rem(x, NaN) => NaN for any Float x\n /// ```\n ///\n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n ///\n /// Float.rem(7.2, 2.3) // => 0.3 (with numerical imprecision)\n /// ```\n public func rem(x : Float, y : Float) : Float { x % y };\n\n /// Returns `x` to the power of `y`, `x ** y`.\n ///\n /// Note: Numerical errors may occur, see comment above.\n ///\n /// Special cases:\n /// ```\n /// pow(+inf, y) => +inf for any y > 0.0 including +inf\n /// pow(+inf, 0.0) => 1.0\n /// pow(+inf, y) => 0.0 for any y < 0.0 including -inf\n /// pow(x, +inf) => +inf if x > 0.0 or x < 0.0\n /// pow(0.0, +inf) => 0.0\n /// pow(x, -inf) => 0.0 if x > 0.0 or x < 0.0\n /// pow(0.0, -inf) => +inf\n /// pow(x, y) => NaN if x < 0.0 and y is a non-integral Float\n /// pow(-inf, y) => +inf if y > 0.0 and y is a non-integral or an even integral Float\n /// pow(-inf, y) => -inf if y > 0.0 and y is an odd integral Float\n /// pow(-inf, 0.0) => 1.0\n /// pow(-inf, y) => 0.0 if y < 0.0\n /// pow(-inf, +inf) => +inf\n /// pow(-inf, -inf) => 1.0\n /// pow(NaN, y) => NaN if y != 0.0\n /// pow(NaN, 0.0) => 1.0\n /// pow(x, NaN) => NaN for any Float x\n /// ```\n ///\n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n ///\n /// Float.pow(2.5, 2.0) // => 6.25\n /// ```\n public func pow(x : Float, y : Float) : Float { x ** y };\n\n}\n"},"HashMap.mo":{"content":"/// Class `HashMap<K, V>` provides a hashmap from keys of type `K` to values of type `V`.\n\n/// The class is parameterized by the key's equality and hash functions,\n/// and an initial capacity. However, the underlying allocation happens only when\n/// the first key-value entry is inserted.\n///\n/// Internally, the map is represented as an array of `AssocList` (buckets).\n/// The growth policy of the underyling array is very simple, for now: double\n/// the current capacity when the expected bucket list size grows beyond a\n/// certain constant.\n///\n/// WARNING: Certain operations are amortized O(1) time, such as `put`, but run\n/// in worst case O(size) time. These worst case runtimes may exceed the cycles limit\n/// per message if the size of the map is large enough. Further, this runtime analysis\n/// assumes that the hash functions uniformly maps keys over the hash space. Grow these structures\n/// with discretion, and with good hash functions. All amortized operations\n/// below also list the worst case runtime.\n///\n/// For maps without amortization, see `TrieMap`.\n///\n/// Note on the constructor:\n/// The argument `initCapacity` determines the initial number of buckets in the\n/// underyling array. Also, the runtime and space anlyses in this documentation\n/// assumes that the equality and hash functions for keys used to construct the\n/// map run in O(1) time and space.\n///\n/// Example:\n/// ```motoko name=initialize\n/// import HashMap \"mo:base/HashMap\";\n/// import Text \"mo:base/Text\";\n///\n/// let map = HashMap.HashMap<Text, Nat>(5, Text.equal, Text.hash);\n/// ```\n///\n/// Runtime: O(1)\n///\n/// Space: O(1)\n\nimport Prim \"mo:⛔\";\nimport P \"Prelude\";\nimport A \"Array\";\nimport Hash \"Hash\";\nimport Iter \"Iter\";\nimport AssocList \"AssocList\";\nimport Nat32 \"Nat32\";\n\nmodule {\n\n // hash field avoids re-hashing the key when the array grows.\n type Key<K> = (Hash.Hash, K);\n\n // key-val list type\n type KVs<K, V> = AssocList.AssocList<Key<K>, V>;\n\n public class HashMap<K, V>(\n initCapacity : Nat,\n keyEq : (K, K) -> Bool,\n keyHash : K -> Hash.Hash\n ) {\n\n var table : [var KVs<K, V>] = [var];\n var _count : Nat = 0;\n\n /// Returns the current number of key-value entries in the map.\n ///\n /// Example:\n /// ```motoko include=initialize\n /// map.size() // => 0\n /// ```\n ///\n /// Runtime: O(1)\n ///\n /// Space: O(1)\n public func size() : Nat = _count;\n\n /// Returns the value assocaited with key `key` if present and `null` otherwise.\n ///\n /// Example:\n /// ```motoko include=initialize\n /// map.put(\"key\", 3);\n /// map.get(\"key\") // => ?3\n /// ```\n ///\n /// Expected Runtime: O(1), Worst Case Runtime: O(size)\n ///\n /// Space: O(1)\n public func get(key : K) : (value : ?V) {\n let h = Prim.nat32ToNat(keyHash(key));\n let m = table.size();\n if (m > 0) {\n AssocList.find<Key<K>, V>(table[h % m], keyHash_(key), keyHashEq)\n } else {\n null\n }\n };\n\n /// Insert the value `value` with key `key`. Overwrites any existing entry with key `key`.\n ///\n /// Example:\n /// ```motoko include=initialize\n /// map.put(\"key\", 3);\n /// map.get(\"key\") // => ?3\n /// ```\n ///\n /// Expected Amortized Runtime: O(1), Worst Case Runtime: O(size)\n ///\n /// Expected Amortized Space: O(1), Worst Case Space: O(size)\n ///\n /// Note: If this is the first entry into this map, this operation will cause\n /// the initial allocation of the underlying array.\n public func put(key : K, value : V) = ignore replace(key, value);\n\n /// Insert the value `value` with key `key`. Returns the previous value\n /// associated with key `key` or `null` if no such value exists.\n ///\n /// Example:\n /// ```motoko include=initialize\n /// map.put(\"key\", 3);\n /// ignore map.replace(\"key\", 2); // => ?3\n /// map.get(\"key\") // => ?2\n /// ```\n ///\n /// Expected Amortized Runtime: O(1), Worst Case Runtime: O(size)\n ///\n /// Expected Amortized Space: O(1), Worst Case Space: O(size)\n ///\n /// Note: If this is the first entry into this map, this operation will cause\n /// the initial allocation of the underlying array.\n public func replace(key : K, value : V) : (oldValue : ?V) {\n if (_count >= table.size()) {\n let size = if (_count == 0) {\n if (initCapacity > 0) {\n initCapacity\n } else {\n 1\n }\n } else {\n table.size() * 2\n };\n let table2 = A.init<KVs<K, V>>(size, null);\n for (i in table.keys()) {\n var kvs = table[i];\n label moveKeyVals : () loop {\n switch kvs {\n case null { break moveKeyVals };\n case (?((k, v), kvsTail)) {\n let pos2 = Nat32.toNat(k.0) % table2.size(); // critical: uses saved hash. no re-hash.\n table2[pos2] := ?((k, v), table2[pos2]);\n kvs := kvsTail\n }\n }\n }\n };\n table := table2\n };\n let h = Prim.nat32ToNat(keyHash(key));\n let pos = h % table.size();\n let (kvs2, ov) = AssocList.replace<Key<K>, V>(table[pos], keyHash_(key), keyHashEq, ?value);\n table[pos] := kvs2;\n switch (ov) {\n case null { _count += 1 };\n case _ {}\n };\n ov\n };\n\n /// Deletes the entry with the key `key`. Has no effect if `key` is not\n /// present in the map.\n ///\n /// Example:\n /// ```motoko include=initialize\n /// map.put(\"key\", 3);\n /// map.delete(\"key\");\n /// map.get(\"key\"); // => null\n /// ```\n ///\n /// Expected Runtime: O(1), Worst Case Runtime: O(size)\n ///\n /// Expected Space: O(1), Worst Case Space: O(size)\n public func delete(key : K) = ignore remove(key);\n\n func keyHash_(k : K) : Key<K> = (keyHash(k), k);\n\n func keyHashEq(k1 : Key<K>, k2 : Key<K>) : Bool {\n k1.0 == k2.0 and keyEq(k1.1, k2.1)\n };\n\n /// Deletes the entry with the key `key`. Returns the previous value\n /// associated with key `key` or `null` if no such value exists.\n ///\n /// Example:\n /// ```motoko include=initialize\n /// map.put(\"key\", 3);\n /// map.remove(\"key\"); // => ?3\n /// ```\n ///\n /// Expected Runtime: O(1), Worst Case Runtime: O(size)\n ///\n /// Expected Space: O(1), Worst Case Space: O(size)\n public func remove(key : K) : (oldValue : ?V) {\n let m = table.size();\n if (m > 0) {\n let h = Prim.nat32ToNat(keyHash(key));\n let pos = h % m;\n let (kvs2, ov) = AssocList.replace<Key<K>, V>(table[pos], keyHash_(key), keyHashEq, null);\n table[pos] := kvs2;\n switch (ov) {\n case null {};\n case _ { _count -= 1 }\n };\n ov\n } else {\n null\n }\n };\n\n /// Returns an Iterator (`Iter`) over the keys of the map.\n /// Iterator provides a single method `next()`, which returns\n /// keys in no specific order, or `null` when out of keys to iterate over.\n ///\n /// Example:\n /// ```motoko include=initialize\n ///\n /// map.put(\"key1\", 1);\n /// map.put(\"key2\", 2);\n /// map.put(\"key3\", 3);\n ///\n /// var keys = \"\";\n /// for (key in map.keys()) {\n /// keys := key # \" \" # keys\n /// };\n /// keys // => \"key3 key2 key1 \"\n /// ```\n ///\n /// Cost of iteration over all keys:\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(1)\n public func keys() : Iter.Iter<K> {\n Iter.map(entries(), func(kv : (K, V)) : K { kv.0 })\n };\n\n /// Returns an Iterator (`Iter`) over the values of the map.\n /// Iterator provides a single method `next()`, which returns\n /// values in no specific order, or `null` when out of values to iterate over.\n ///\n /// Example:\n /// ```motoko include=initialize\n ///\n /// map.put(\"key1\", 1);\n /// map.put(\"key2\", 2);\n /// map.put(\"key3\", 3);\n ///\n /// var sum = 0;\n /// for (value in map.vals()) {\n /// sum += value;\n /// };\n /// sum // => 6\n /// ```\n ///\n /// Cost of iteration over all values:\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(1)\n public func vals() : Iter.Iter<V> {\n Iter.map(entries(), func(kv : (K, V)) : V { kv.1 })\n };\n\n /// Returns an Iterator (`Iter`) over the key-value pairs in the map.\n /// Iterator provides a single method `next()`, which returns\n /// pairs in no specific order, or `null` when out of pairs to iterate over.\n ///\n /// Example:\n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n ///\n /// map.put(\"key1\", 1);\n /// map.put(\"key2\", 2);\n /// map.put(\"key3\", 3);\n ///\n /// var pairs = \"\";\n /// for ((key, value) in map.entries()) {\n /// pairs := \"(\" # key # \", \" # Nat.toText(value) # \") \" # pairs\n /// };\n /// pairs // => \"(key3, 3) (key2, 2) (key1, 1)\"\n /// ```\n ///\n /// Cost of iteration over all pairs:\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(1)\n public func entries() : Iter.Iter<(K, V)> {\n if (table.size() == 0) {\n object { public func next() : ?(K, V) { null } }\n } else {\n object {\n var kvs = table[0];\n var nextTablePos = 1;\n public func next() : ?(K, V) {\n switch kvs {\n case (?(kv, kvs2)) {\n kvs := kvs2;\n ?(kv.0.1, kv.1)\n };\n case null {\n if (nextTablePos < table.size()) {\n kvs := table[nextTablePos];\n nextTablePos += 1;\n next()\n } else {\n null\n }\n }\n }\n }\n }\n }\n };\n\n };\n\n /// Returns a copy of `map`, initializing the copy with the provided equality\n /// and hash functions.\n ///\n /// Example:\n /// ```motoko include=initialize\n /// map.put(\"key1\", 1);\n /// map.put(\"key2\", 2);\n /// map.put(\"key3\", 3);\n ///\n /// let map2 = HashMap.clone(map, Text.equal, Text.hash);\n /// map2.get(\"key1\") // => ?1\n /// ```\n ///\n /// Expected Runtime: O(size), Worst Case Runtime: O(size * size)\n ///\n /// Expected Space: O(size), Worst Case Space: O(size)\n public func clone<K, V>(\n map : HashMap<K, V>,\n keyEq : (K, K) -> Bool,\n keyHash : K -> Hash.Hash\n ) : HashMap<K, V> {\n let h2 = HashMap<K, V>(map.size(), keyEq, keyHash);\n for ((k, v) in map.entries()) {\n h2.put(k, v)\n };\n h2\n };\n\n /// Returns a new map, containing all entries given by the iterator `iter`.\n /// The new map is initialized with the provided initial capacity, equality,\n /// and hash functions.\n ///\n /// Example:\n /// ```motoko include=initialize\n /// let entries = [(\"key3\", 3), (\"key2\", 2), (\"key1\", 1)];\n /// let iter = entries.vals();\n ///\n /// let map2 = HashMap.fromIter<Text, Nat>(iter, entries.size(), Text.equal, Text.hash);\n /// map2.get(\"key1\") // => ?1\n /// ```\n ///\n /// Expected Runtime: O(size), Worst Case Runtime: O(size * size)\n ///\n /// Expected Space: O(size), Worst Case Space: O(size)\n public func fromIter<K, V>(\n iter : Iter.Iter<(K, V)>,\n initCapacity : Nat,\n keyEq : (K, K) -> Bool,\n keyHash : K -> Hash.Hash\n ) : HashMap<K, V> {\n let h = HashMap<K, V>(initCapacity, keyEq, keyHash);\n for ((k, v) in iter) {\n h.put(k, v)\n };\n h\n };\n\n /// Creates a new map by applying `f` to each entry in `hashMap`. Each entry\n /// `(k, v)` in the old map is transformed into a new entry `(k, v2)`, where\n /// the new value `v2` is created by applying `f` to `(k, v)`.\n ///\n /// ```motoko include=initialize\n /// map.put(\"key1\", 1);\n /// map.put(\"key2\", 2);\n /// map.put(\"key3\", 3);\n ///\n /// let map2 = HashMap.map<Text, Nat, Nat>(map, Text.equal, Text.hash, func (k, v) = v * 2);\n /// map2.get(\"key2\") // => ?4\n /// ```\n ///\n /// Expected Runtime: O(size), Worst Case Runtime: O(size * size)\n ///\n /// Expected Space: O(size), Worst Case Space: O(size)\n ///\n /// *Runtime and space assumes that `f` runs in O(1) time and space.\n public func map<K, V1, V2>(\n hashMap : HashMap<K, V1>,\n keyEq : (K, K) -> Bool,\n keyHash : K -> Hash.Hash,\n f : (K, V1) -> V2\n ) : HashMap<K, V2> {\n let h2 = HashMap<K, V2>(hashMap.size(), keyEq, keyHash);\n for ((k, v1) in hashMap.entries()) {\n let v2 = f(k, v1);\n h2.put(k, v2)\n };\n h2\n };\n\n /// Creates a new map by applying `f` to each entry in `hashMap`. For each entry\n /// `(k, v)` in the old map, if `f` evaluates to `null`, the entry is discarded.\n /// Otherwise, the entry is transformed into a new entry `(k, v2)`, where\n /// the new value `v2` is the result of applying `f` to `(k, v)`.\n ///\n /// ```motoko include=initialize\n /// map.put(\"key1\", 1);\n /// map.put(\"key2\", 2);\n /// map.put(\"key3\", 3);\n ///\n /// let map2 =\n /// HashMap.mapFilter<Text, Nat, Nat>(\n /// map,\n /// Text.equal,\n /// Text.hash,\n /// func (k, v) = if (v == 2) { null } else { ?(v * 2)}\n /// );\n /// map2.get(\"key3\") // => ?6\n /// ```\n ///\n /// Expected Runtime: O(size), Worst Case Runtime: O(size * size)\n ///\n /// Expected Space: O(size), Worst Case Space: O(size)\n ///\n /// *Runtime and space assumes that `f` runs in O(1) time and space.\n public func mapFilter<K, V1, V2>(\n hashMap : HashMap<K, V1>,\n keyEq : (K, K) -> Bool,\n keyHash : K -> Hash.Hash,\n f : (K, V1) -> ?V2\n ) : HashMap<K, V2> {\n let h2 = HashMap<K, V2>(hashMap.size(), keyEq, keyHash);\n for ((k, v1) in hashMap.entries()) {\n switch (f(k, v1)) {\n case null {};\n case (?v2) {\n h2.put(k, v2)\n }\n }\n };\n h2\n };\n\n}\n"},"Int.mo":{"content":"/// Signed integer numbers with infinite precision (also called big integers).\n///\n/// Most operations on integer numbers (e.g. addition) are available as built-in operators (e.g. `-1 + 1`).\n/// This module provides equivalent functions and `Text` conversion.\n///\n/// Import from the base library to use this module.\n/// ```motoko name=import\n/// import Int \"mo:base/Int\";\n/// ```\n\nimport Prim \"mo:⛔\";\nimport Prelude \"Prelude\";\nimport Hash \"Hash\";\n\nmodule {\n\n /// Infinite precision signed integers.\n public type Int = Prim.Types.Int;\n\n /// Returns the absolute value of `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int.abs(-12) // => 12\n /// ```\n public func abs(x : Int) : Nat {\n Prim.abs(x)\n };\n\n /// Converts an integer number to its textual representation. Textual\n /// representation _do not_ contain underscores to represent commas.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int.toText(-1234) // => \"-1234\"\n /// ```\n public func toText(x : Int) : Text {\n if (x == 0) {\n return \"0\"\n };\n\n let isNegative = x < 0;\n var int = if isNegative { -x } else { x };\n\n var text = \"\";\n let base = 10;\n\n while (int > 0) {\n let rem = int % base;\n text := (\n switch (rem) {\n case 0 { \"0\" };\n case 1 { \"1\" };\n case 2 { \"2\" };\n case 3 { \"3\" };\n case 4 { \"4\" };\n case 5 { \"5\" };\n case 6 { \"6\" };\n case 7 { \"7\" };\n case 8 { \"8\" };\n case 9 { \"9\" };\n case _ { Prelude.unreachable() }\n }\n ) # text;\n int := int / base\n };\n\n return if isNegative { \"-\" # text } else { text }\n };\n\n /// Returns the minimum of `x` and `y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int.min(2, -3) // => -3\n /// ```\n public func min(x : Int, y : Int) : Int {\n if (x < y) { x } else { y }\n };\n\n /// Returns the maximum of `x` and `y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int.max(2, -3) // => 2\n /// ```\n public func max(x : Int, y : Int) : Int {\n if (x < y) { y } else { x }\n };\n\n // this is a local copy of deprecated Hash.hashNat8 (redefined to suppress the warning)\n private func hashNat8(key : [Nat32]) : Hash.Hash {\n var hash : Nat32 = 0;\n for (natOfKey in key.vals()) {\n hash := hash +% natOfKey;\n hash := hash +% hash << 10;\n hash := hash ^ (hash >> 6)\n };\n hash := hash +% hash << 3;\n hash := hash ^ (hash >> 11);\n hash := hash +% hash << 15;\n return hash\n };\n\n /// Computes a hash from the least significant 32-bits of `i`, ignoring other bits.\n /// @deprecated For large `Int` values consider using a bespoke hash function that considers all of the argument's bits.\n public func hash(i : Int) : Hash.Hash {\n // CAUTION: This removes the high bits!\n let j = Prim.int32ToNat32(Prim.intToInt32Wrap(i));\n hashNat8([\n j & (255 << 0),\n j & (255 << 8),\n j & (255 << 16),\n j & (255 << 24)\n ])\n };\n\n /// Computes an accumulated hash from `h1` and the least significant 32-bits of `i`, ignoring other bits in `i`.\n /// @deprecated For large `Int` values consider using a bespoke hash function that considers all of the argument's bits.\n public func hashAcc(h1 : Hash.Hash, i : Int) : Hash.Hash {\n // CAUTION: This removes the high bits!\n let j = Prim.int32ToNat32(Prim.intToInt32Wrap(i));\n hashNat8([\n h1,\n j & (255 << 0),\n j & (255 << 8),\n j & (255 << 16),\n j & (255 << 24)\n ])\n };\n\n /// Equality function for Int types.\n /// This is equivalent to `x == y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int.equal(-1, -1); // => true\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `==` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `==`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Buffer \"mo:base/Buffer\";\n ///\n /// let buffer1 = Buffer.Buffer<Int>(1);\n /// buffer1.add(-3);\n /// let buffer2 = Buffer.Buffer<Int>(1);\n /// buffer2.add(-3);\n /// Buffer.equal(buffer1, buffer2, Int.equal) // => true\n /// ```\n public func equal(x : Int, y : Int) : Bool { x == y };\n\n /// Inequality function for Int types.\n /// This is equivalent to `x != y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int.notEqual(-1, -2); // => true\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `!=` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `!=`\n /// as a function value at the moment.\n public func notEqual(x : Int, y : Int) : Bool { x != y };\n\n /// \"Less than\" function for Int types.\n /// This is equivalent to `x < y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int.less(-2, 1); // => true\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<`\n /// as a function value at the moment.\n public func less(x : Int, y : Int) : Bool { x < y };\n\n /// \"Less than or equal\" function for Int types.\n /// This is equivalent to `x <= y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int.lessOrEqual(-2, 1); // => true\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<=` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<=`\n /// as a function value at the moment.\n public func lessOrEqual(x : Int, y : Int) : Bool { x <= y };\n\n /// \"Greater than\" function for Int types.\n /// This is equivalent to `x > y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int.greater(1, -2); // => true\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `>` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `>`\n /// as a function value at the moment.\n public func greater(x : Int, y : Int) : Bool { x > y };\n\n /// \"Greater than or equal\" function for Int types.\n /// This is equivalent to `x >= y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int.greaterOrEqual(1, -2); // => true\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `>=` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `>=`\n /// as a function value at the moment.\n public func greaterOrEqual(x : Int, y : Int) : Bool { x >= y };\n\n /// General-purpose comparison function for `Int`. Returns the `Order` (\n /// either `#less`, `#equal`, or `#greater`) of comparing `x` with `y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int.compare(-3, 2) // => #less\n /// ```\n ///\n /// This function can be used as value for a high order function, such as a sort function.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.sort([1, -2, -3], Int.compare) // => [-3, -2, 1]\n /// ```\n public func compare(x : Int, y : Int) : { #less; #equal; #greater } {\n if (x < y) { #less } else if (x == y) { #equal } else { #greater }\n };\n\n /// Returns the negation of `x`, `-x` .\n ///\n /// Example:\n /// ```motoko include=import\n /// Int.neg(123) // => -123\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `-` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `-`\n /// as a function value at the moment.\n public func neg(x : Int) : Int { -x };\n\n /// Returns the sum of `x` and `y`, `x + y`.\n ///\n /// No overflow since `Int` has infinite precision.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int.add(1, -2); // => -1\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `+` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `+`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.foldLeft([1, -2, -3], 0, Int.add) // => -4\n /// ```\n public func add(x : Int, y : Int) : Int { x + y };\n\n /// Returns the difference of `x` and `y`, `x - y`.\n ///\n /// No overflow since `Int` has infinite precision.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int.sub(1, 2); // => -1\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `-` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `-`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.foldLeft([1, -2, -3], 0, Int.sub) // => 4\n /// ```\n public func sub(x : Int, y : Int) : Int { x - y };\n\n /// Returns the product of `x` and `y`, `x * y`.\n ///\n /// No overflow since `Int` has infinite precision.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int.mul(-2, 3); // => -6\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `*` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `*`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.foldLeft([1, -2, -3], 1, Int.mul) // => 6\n /// ```\n public func mul(x : Int, y : Int) : Int { x * y };\n\n /// Returns the signed integer division of `x` by `y`, `x / y`.\n /// Rounds the quotient towards zero, which is the same as truncating the decimal places of the quotient.\n ///\n /// Traps when `y` is zero.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int.div(6, -2); // => -3\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `/` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `/`\n /// as a function value at the moment.\n public func div(x : Int, y : Int) : Int { x / y };\n\n /// Returns the remainder of the signed integer division of `x` by `y`, `x % y`,\n /// which is defined as `x - x / y * y`.\n ///\n /// Traps when `y` is zero.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int.rem(6, -4); // => 2\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `%`\n /// as a function value at the moment.\n public func rem(x : Int, y : Int) : Int { x % y };\n\n /// Returns `x` to the power of `y`, `x ** y`.\n ///\n /// Traps when `y` is negative or `y > 2 ** 32 - 1`.\n /// No overflow since `Int` has infinite precision.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int.pow(-2, 3); // => -8\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `**` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `**`\n /// as a function value at the moment.\n public func pow(x : Int, y : Int) : Int { x ** y };\n\n}\n"},"Heap.mo":{"content":"/// Class `Heap<X>` provides a priority queue of elements of type `X`.\n///\n/// The class wraps a purely-functional implementation based on a leftist heap.\n///\n/// Note on the constructor:\n/// The constructor takes in a comparison function `compare` that defines the\n/// ordering between elements of type `X`. Most primitive types have a default\n/// version of this comparison function defined in their modules (e.g. `Nat.compare`).\n/// The runtime analysis in this documentation assumes that the `compare` function\n/// runs in `O(1)` time and space.\n///\n/// Example:\n/// ```motoko name=initialize\n/// import Heap \"mo:base/Heap\";\n/// import Text \"mo:base/Text\";\n///\n/// let heap = Heap.Heap<Text>(Text.compare);\n/// ```\n///\n/// Runtime: `O(1)`\n///\n/// Space: `O(1)`\n\nimport O \"Order\";\nimport P \"Prelude\";\nimport L \"List\";\nimport I \"Iter\";\n\nmodule {\n\n public type Tree<X> = ?(Int, X, Tree<X>, Tree<X>);\n\n public class Heap<X>(compare : (X, X) -> O.Order) {\n var heap : Tree<X> = null;\n\n /// Inserts an element into the heap.\n ///\n /// Example:\n /// ```motoko include=initialize\n ///\n /// heap.put(\"apple\");\n /// heap.peekMin() // => ?\"apple\"\n /// ```\n ///\n /// Runtime: `O(log(n))`\n ///\n /// Space: `O(log(n))`\n public func put(x : X) {\n heap := merge(heap, ?(1, x, null, null), compare)\n };\n\n /// Return the minimal element in the heap, or `null` if the heap is empty.\n ///\n /// Example:\n /// ```motoko include=initialize\n ///\n /// heap.put(\"apple\");\n /// heap.put(\"banana\");\n /// heap.put(\"cantaloupe\");\n /// heap.peekMin() // => ?\"apple\"\n /// ```\n ///\n /// Runtime: `O(1)`\n ///\n /// Space: `O(1)`\n public func peekMin() : ?X {\n switch heap {\n case (null) { null };\n case (?(_, x, _, _)) { ?x }\n }\n };\n\n /// Delete the minimal element in the heap, if it exists.\n ///\n /// Example:\n /// ```motoko include=initialize\n ///\n /// heap.put(\"apple\");\n /// heap.put(\"banana\");\n /// heap.put(\"cantaloupe\");\n /// heap.deleteMin();\n /// heap.peekMin(); // => ?\"banana\"\n /// ```\n ///\n /// Runtime: `O(log(n))`\n ///\n /// Space: `O(log(n))`\n public func deleteMin() {\n switch heap {\n case null {};\n case (?(_, _, a, b)) { heap := merge(a, b, compare) }\n }\n };\n\n /// Delete and return the minimal element in the heap, if it exists.\n ///\n /// Example:\n /// ```motoko include=initialize\n ///\n /// heap.put(\"apple\");\n /// heap.put(\"banana\");\n /// heap.put(\"cantaloupe\");\n /// heap.removeMin(); // => ?\"apple\"\n /// ```\n ///\n /// Runtime: `O(log(n))`\n ///\n /// Space: `O(log(n))`\n public func removeMin() : (minElement : ?X) {\n switch heap {\n case null { null };\n case (?(_, x, a, b)) {\n heap := merge(a, b, compare);\n ?x\n }\n }\n };\n\n /// Return a snapshot of the internal functional tree representation as sharable data.\n /// The returned tree representation is not affected by subsequent changes of the `Heap` instance.\n ///\n /// Example:\n /// ```motoko include=initialize\n ///\n /// heap.put(\"banana\");\n /// heap.share();\n /// ```\n ///\n /// Useful for storing the heap as a stable variable, pretty-printing, and sharing it across async function calls,\n /// i.e. passing it in async arguments or async results.\n ///\n /// Runtime: `O(1)`\n ///\n /// Space: `O(1)`\n public func share() : Tree<X> {\n heap\n };\n\n /// Rewraps a snapshot of a heap (obtained by `share()`) in a `Heap` instance.\n /// The wrapping instance must be initialized with the same `compare`\n /// function that created the snapshot.\n ///\n /// Example:\n /// ```motoko include=initialize\n ///\n /// heap.put(\"apple\");\n /// heap.put(\"banana\");\n /// let snapshot = heap.share();\n /// let heapCopy = Heap.Heap<Text>(Text.compare);\n /// heapCopy.unsafeUnshare(snapshot);\n /// heapCopy.peekMin() // => ?\"apple\"\n /// ```\n ///\n /// Useful for loading a stored heap from a stable variable or accesing a heap\n /// snapshot passed from an async function call.\n ///\n /// Runtime: `O(1)`.\n ///\n /// Space: `O(1)`.\n public func unsafeUnshare(tree : Tree<X>) {\n heap := tree\n };\n\n };\n\n func rank<X>(heap : Tree<X>) : Int {\n switch heap {\n case null { 0 };\n case (?(r, _, _, _)) { r }\n }\n };\n\n func makeT<X>(x : X, a : Tree<X>, b : Tree<X>) : Tree<X> {\n if (rank(a) >= rank(b)) {\n ?(rank(b) + 1, x, a, b)\n } else {\n ?(rank(a) + 1, x, b, a)\n }\n };\n\n func merge<X>(h1 : Tree<X>, h2 : Tree<X>, compare : (X, X) -> O.Order) : Tree<X> {\n switch (h1, h2) {\n case (null, h) { h };\n case (h, null) { h };\n case (?(_, x, a, b), ?(_, y, c, d)) {\n switch (compare(x, y)) {\n case (#less) { makeT(x, a, merge(b, h2, compare)) };\n case _ { makeT(y, c, merge(d, h1, compare)) }\n }\n }\n }\n };\n\n /// Returns a new `Heap`, containing all entries given by the iterator `iter`.\n /// The new map is initialized with the provided `compare` function.\n ///\n /// Example:\n /// ```motoko include=initialize\n /// let entries = [\"banana\", \"apple\", \"cantaloupe\"];\n /// let iter = entries.vals();\n ///\n /// let newHeap = Heap.fromIter<Text>(iter, Text.compare);\n /// newHeap.peekMin() // => ?\"apple\"\n /// ```\n ///\n /// Runtime: `O(size)`\n ///\n /// Space: `O(size)`\n public func fromIter<X>(iter : I.Iter<X>, compare : (X, X) -> O.Order) : Heap<X> {\n let heap = Heap<X>(compare);\n func build(xs : L.List<Tree<X>>) : Tree<X> {\n func join(xs : L.List<Tree<X>>) : L.List<Tree<X>> {\n switch (xs) {\n case (null) { null };\n case (?(hd, null)) { ?(hd, null) };\n case (?(h1, ?(h2, tl))) { ?(merge(h1, h2, compare), join(tl)) }\n }\n };\n switch (xs) {\n case null { P.unreachable() };\n case (?(hd, null)) { hd };\n case _ { build(join(xs)) }\n }\n };\n let list = I.toList(I.map(iter, func(x : X) : Tree<X> { ?(1, x, null, null) }));\n if (not L.isNil(list)) {\n let t = build(list);\n heap.unsafeUnshare(t)\n };\n heap\n };\n\n}\n"},"Int8.mo":{"content":"/// Provides utility functions on 8-bit signed integers.\n///\n/// Note that most operations are available as built-in operators (e.g. `1 + 1`).\n///\n/// Import from the base library to use this module.\n/// ```motoko name=import\n/// import Int8 \"mo:base/Int8\";\n/// ```\nimport Int \"Int\";\nimport Prim \"mo:⛔\";\n\nmodule {\n\n /// 8-bit signed integers.\n public type Int8 = Prim.Types.Int8;\n\n /// Minimum 8-bit integer value, `-2 ** 7`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int8.minimumValue // => -128\n /// ```\n public let minimumValue = -128 : Int8;\n\n /// Maximum 8-bit integer value, `+2 ** 7 - 1`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int8.maximumValue // => +127\n /// ```\n public let maximumValue = 127 : Int8;\n\n /// Converts an 8-bit signed integer to a signed integer with infinite precision.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int8.toInt(123) // => 123 : Int\n /// ```\n public let toInt : Int8 -> Int = Prim.int8ToInt;\n\n /// Converts a signed integer with infinite precision to an 8-bit signed integer.\n ///\n /// Traps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int8.fromInt(123) // => +123 : Int8\n /// ```\n public let fromInt : Int -> Int8 = Prim.intToInt8;\n\n /// Converts a signed integer with infinite precision to an 8-bit signed integer.\n ///\n /// Wraps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int8.fromIntWrap(-123) // => -123 : Int\n /// ```\n public let fromIntWrap : Int -> Int8 = Prim.intToInt8Wrap;\n\n /// Converts a 16-bit signed integer to an 8-bit signed integer.\n ///\n /// Traps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int8.fromInt16(123) // => +123 : Int8\n /// ```\n public let fromInt16 : Int16 -> Int8 = Prim.int16ToInt8;\n\n /// Converts an 8-bit signed integer to a 16-bit signed integer.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int8.toInt16(123) // => +123 : Int16\n /// ```\n public let toInt16 : Int8 -> Int16 = Prim.int8ToInt16;\n\n /// Converts an unsigned 8-bit integer to a signed 8-bit integer.\n ///\n /// Wraps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int8.fromNat8(123) // => +123 : Int8\n /// ```\n public let fromNat8 : Nat8 -> Int8 = Prim.nat8ToInt8;\n\n /// Converts a signed 8-bit integer to an unsigned 8-bit integer.\n ///\n /// Wraps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int8.toNat8(-1) // => 255 : Nat8 // underflow\n /// ```\n public let toNat8 : Int8 -> Nat8 = Prim.int8ToNat8;\n\n /// Converts an integer number to its textual representation.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int8.toText(-123) // => \"-123\"\n /// ```\n public func toText(x : Int8) : Text {\n Int.toText(toInt(x))\n };\n\n /// Returns the absolute value of `x`.\n ///\n /// Traps when `x == -2 ** 7` (the minimum `Int8` value).\n ///\n /// Example:\n /// ```motoko include=import\n /// Int8.abs(-123) // => +123\n /// ```\n public func abs(x : Int8) : Int8 {\n fromInt(Int.abs(toInt(x)))\n };\n\n /// Returns the minimum of `x` and `y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int8.min(+2, -3) // => -3\n /// ```\n public func min(x : Int8, y : Int8) : Int8 {\n if (x < y) { x } else { y }\n };\n\n /// Returns the maximum of `x` and `y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int8.max(+2, -3) // => +2\n /// ```\n public func max(x : Int8, y : Int8) : Int8 {\n if (x < y) { y } else { x }\n };\n\n /// Equality function for Int8 types.\n /// This is equivalent to `x == y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int8.equal(-1, -1); // => true\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `==` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `==`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Buffer \"mo:base/Buffer\";\n ///\n /// let buffer1 = Buffer.Buffer<Int8>(1);\n /// buffer1.add(-3);\n /// let buffer2 = Buffer.Buffer<Int8>(1);\n /// buffer2.add(-3);\n /// Buffer.equal(buffer1, buffer2, Int8.equal) // => true\n /// ```\n public func equal(x : Int8, y : Int8) : Bool { x == y };\n\n /// Inequality function for Int8 types.\n /// This is equivalent to `x != y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int8.notEqual(-1, -2); // => true\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `!=` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `!=`\n /// as a function value at the moment.\n public func notEqual(x : Int8, y : Int8) : Bool { x != y };\n\n /// \"Less than\" function for Int8 types.\n /// This is equivalent to `x < y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int8.less(-2, 1); // => true\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<`\n /// as a function value at the moment.\n public func less(x : Int8, y : Int8) : Bool { x < y };\n\n /// \"Less than or equal\" function for Int8 types.\n /// This is equivalent to `x <= y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int8.lessOrEqual(-2, -2); // => true\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<=` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<=`\n /// as a function value at the moment.\n public func lessOrEqual(x : Int8, y : Int8) : Bool { x <= y };\n\n /// \"Greater than\" function for Int8 types.\n /// This is equivalent to `x > y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int8.greater(-2, -3); // => true\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `>` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `>`\n /// as a function value at the moment.\n public func greater(x : Int8, y : Int8) : Bool { x > y };\n\n /// \"Greater than or equal\" function for Int8 types.\n /// This is equivalent to `x >= y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int8.greaterOrEqual(-2, -2); // => true\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `>=` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `>=`\n /// as a function value at the moment.\n public func greaterOrEqual(x : Int8, y : Int8) : Bool { x >= y };\n\n /// General-purpose comparison function for `Int8`. Returns the `Order` (\n /// either `#less`, `#equal`, or `#greater`) of comparing `x` with `y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int8.compare(-3, 2) // => #less\n /// ```\n ///\n /// This function can be used as value for a high order function, such as a sort function.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.sort([1, -2, -3] : [Int8], Int8.compare) // => [-3, -2, 1]\n /// ```\n public func compare(x : Int8, y : Int8) : { #less; #equal; #greater } {\n if (x < y) { #less } else if (x == y) { #equal } else { #greater }\n };\n\n /// Returns the negation of `x`, `-x`.\n ///\n /// Traps on overflow, i.e. for `neg(-2 ** 7)`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int8.neg(123) // => -123\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `-` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `-`\n /// as a function value at the moment.\n public func neg(x : Int8) : Int8 { -x };\n\n /// Returns the sum of `x` and `y`, `x + y`.\n ///\n /// Traps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int8.add(100, 23) // => +123\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `+` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `+`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.foldLeft<Int8, Int8>([1, -2, -3], 0, Int8.add) // => -4\n /// ```\n public func add(x : Int8, y : Int8) : Int8 { x + y };\n\n /// Returns the difference of `x` and `y`, `x - y`.\n ///\n /// Traps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int8.sub(123, 23) // => +100\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `-` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `-`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.foldLeft<Int8, Int8>([1, -2, -3], 0, Int8.sub) // => 4\n /// ```\n public func sub(x : Int8, y : Int8) : Int8 { x - y };\n\n /// Returns the product of `x` and `y`, `x * y`.\n ///\n /// Traps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int8.mul(12, 10) // => +120\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `*` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `*`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.foldLeft<Int8, Int8>([1, -2, -3], 1, Int8.mul) // => 6\n /// ```\n public func mul(x : Int8, y : Int8) : Int8 { x * y };\n\n /// Returns the signed integer division of `x` by `y`, `x / y`.\n /// Rounds the quotient towards zero, which is the same as truncating the decimal places of the quotient.\n ///\n /// Traps when `y` is zero.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int8.div(123, 10) // => +12\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `/` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `/`\n /// as a function value at the moment.\n public func div(x : Int8, y : Int8) : Int8 { x / y };\n\n /// Returns the remainder of the signed integer division of `x` by `y`, `x % y`,\n /// which is defined as `x - x / y * y`.\n ///\n /// Traps when `y` is zero.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int8.rem(123, 10) // => +3\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `%`\n /// as a function value at the moment.\n public func rem(x : Int8, y : Int8) : Int8 { x % y };\n\n /// Returns `x` to the power of `y`, `x ** y`.\n ///\n /// Traps on overflow/underflow and when `y < 0 or y >= 8`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int8.pow(2, 6) // => +64\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `**` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `**`\n /// as a function value at the moment.\n public func pow(x : Int8, y : Int8) : Int8 { x ** y };\n\n /// Returns the bitwise negation of `x`, `^x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int8.bitnot(-16 /* 0xf0 */) // => +15 // 0x0f\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `^` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `^`\n /// as a function value at the moment.\n public func bitnot(x : Int8) : Int8 { ^x };\n\n /// Returns the bitwise \"and\" of `x` and `y`, `x & y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int8.bitand(0x1f, 0x70) // => +16 // 0x10\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `&` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `&`\n /// as a function value at the moment.\n public func bitand(x : Int8, y : Int8) : Int8 { x & y };\n\n /// Returns the bitwise \"or\" of `x` and `y`, `x | y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int8.bitor(0x0f, 0x70) // => +127 // 0x7f\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `|` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `|`\n /// as a function value at the moment.\n public func bitor(x : Int8, y : Int8) : Int8 { x | y };\n\n /// Returns the bitwise \"exclusive or\" of `x` and `y`, `x ^ y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int8.bitxor(0x70, 0x7f) // => +15 // 0x0f\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `^` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `^`\n /// as a function value at the moment.\n public func bitxor(x : Int8, y : Int8) : Int8 { x ^ y };\n\n /// Returns the bitwise left shift of `x` by `y`, `x << y`.\n /// The right bits of the shift filled with zeros.\n /// Left-overflowing bits, including the sign bit, are discarded.\n ///\n /// For `y >= 8`, the semantics is the same as for `bitshiftLeft(x, y % 8)`.\n /// For `y < 0`, the semantics is the same as for `bitshiftLeft(x, y + y % 8)`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int8.bitshiftLeft(1, 4) // => +16 // 0x10 equivalent to `2 ** 4`.\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<<` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<<`\n /// as a function value at the moment.\n public func bitshiftLeft(x : Int8, y : Int8) : Int8 { x << y };\n\n /// Returns the signed bitwise right shift of `x` by `y`, `x >> y`.\n /// The sign bit is retained and the left side is filled with the sign bit.\n /// Right-underflowing bits are discarded, i.e. not rotated to the left side.\n ///\n /// For `y >= 8`, the semantics is the same as for `bitshiftRight(x, y % 8)`.\n /// For `y < 0`, the semantics is the same as for `bitshiftRight (x, y + y % 8)`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int8.bitshiftRight(64, 4) // => +4 // equivalent to `64 / (2 ** 4)`\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `>>` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `>>`\n /// as a function value at the moment.\n public func bitshiftRight(x : Int8, y : Int8) : Int8 { x >> y };\n\n /// Returns the bitwise left rotatation of `x` by `y`, `x <<> y`.\n /// Each left-overflowing bit is inserted again on the right side.\n /// The sign bit is rotated like other bits, i.e. the rotation interprets the number as unsigned.\n ///\n /// Changes the direction of rotation for negative `y`.\n /// For `y >= 8`, the semantics is the same as for `bitrotLeft(x, y % 8)`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int8.bitrotLeft(0x11 /* 0b0001_0001 */, 2) // => +68 // 0b0100_0100 == 0x44.\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<<>` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<<>`\n /// as a function value at the moment.\n public func bitrotLeft(x : Int8, y : Int8) : Int8 { x <<> y };\n\n /// Returns the bitwise right rotation of `x` by `y`, `x <>> y`.\n /// Each right-underflowing bit is inserted again on the right side.\n /// The sign bit is rotated like other bits, i.e. the rotation interprets the number as unsigned.\n ///\n /// Changes the direction of rotation for negative `y`.\n /// For `y >= 8`, the semantics is the same as for `bitrotRight(x, y % 8)`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int8.bitrotRight(0x11 /* 0b0001_0001 */, 1) // => -120 // 0b1000_1000 == 0x88.\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<>>` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<>>`\n /// as a function value at the moment.\n public func bitrotRight(x : Int8, y : Int8) : Int8 { x <>> y };\n\n /// Returns the value of bit `p` in `x`, `x & 2**p == 2**p`.\n /// If `p >= 8`, the semantics is the same as for `bittest(x, p % 8)`.\n /// This is equivalent to checking if the `p`-th bit is set in `x`, using 0 indexing.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int8.bittest(64, 6) // => true\n /// ```\n public func bittest(x : Int8, p : Nat) : Bool {\n Prim.btstInt8(x, Prim.intToInt8(p))\n };\n\n /// Returns the value of setting bit `p` in `x` to `1`.\n /// If `p >= 8`, the semantics is the same as for `bitset(x, p % 8)`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int8.bitset(0, 6) // => +64\n /// ```\n public func bitset(x : Int8, p : Nat) : Int8 {\n x | (1 << Prim.intToInt8(p))\n };\n\n /// Returns the value of clearing bit `p` in `x` to `0`.\n /// If `p >= 8`, the semantics is the same as for `bitclear(x, p % 8)`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int8.bitclear(-1, 6) // => -65\n /// ```\n public func bitclear(x : Int8, p : Nat) : Int8 {\n x & ^(1 << Prim.intToInt8(p))\n };\n\n /// Returns the value of flipping bit `p` in `x`.\n /// If `p >= 8`, the semantics is the same as for `bitclear(x, p % 8)`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int8.bitflip(127, 6) // => +63\n /// ```\n public func bitflip(x : Int8, p : Nat) : Int8 {\n x ^ (1 << Prim.intToInt8(p))\n };\n\n /// Returns the count of non-zero bits in `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int8.bitcountNonZero(0x0f) // => +4\n /// ```\n public let bitcountNonZero : (x : Int8) -> Int8 = Prim.popcntInt8;\n\n /// Returns the count of leading zero bits in `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int8.bitcountLeadingZero(0x08) // => +4\n /// ```\n public let bitcountLeadingZero : (x : Int8) -> Int8 = Prim.clzInt8;\n\n /// Returns the count of trailing zero bits in `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int8.bitcountTrailingZero(0x10) // => +4\n /// ```\n public let bitcountTrailingZero : (x : Int8) -> Int8 = Prim.ctzInt8;\n\n /// Returns the sum of `x` and `y`, `x +% y`.\n ///\n /// Wraps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int8.addWrap(2 ** 6, 2 ** 6) // => -128 // overflow\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `+%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `+%`\n /// as a function value at the moment.\n public func addWrap(x : Int8, y : Int8) : Int8 { x +% y };\n\n /// Returns the difference of `x` and `y`, `x -% y`.\n ///\n /// Wraps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int8.subWrap(-2 ** 7, 1) // => +127 // underflow\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `-%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `-%`\n /// as a function value at the moment.\n public func subWrap(x : Int8, y : Int8) : Int8 { x -% y };\n\n /// Returns the product of `x` and `y`, `x *% y`. Wraps on overflow.\n ///\n /// Wraps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int8.mulWrap(2 ** 4, 2 ** 4) // => 0 // overflow\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `*%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `*%`\n /// as a function value at the moment.\n public func mulWrap(x : Int8, y : Int8) : Int8 { x *% y };\n\n /// Returns `x` to the power of `y`, `x **% y`.\n ///\n /// Wraps on overflow/underflow.\n /// Traps if `y < 0 or y >= 8`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int8.powWrap(2, 7) // => -128 // overflow\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `**%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `**%`\n /// as a function value at the moment.\n public func powWrap(x : Int8, y : Int8) : Int8 { x **% y };\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"},"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"},"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 \"mo:base/Iter\";\n /// let iter = Iter.range(1, 3);\n /// let mappedIter = Iter.filter(iter, func (x : Nat) : Bool { x % 2 == 1 });\n /// assert(?1 == mappedIter.next());\n /// assert(?3 == mappedIter.next());\n /// assert(null == mappedIter.next());\n /// ```\n public func filter<A>(xs : Iter<A>, f : A -> Bool) : Iter<A> = object {\n public func next() : ?A {\n loop {\n switch (xs.next()) {\n case (null) {\n return null\n };\n case (?x) {\n if (f(x)) {\n return ?x\n }\n }\n }\n };\n null\n }\n };\n\n /// Creates an iterator that produces an infinite sequence of `x`.\n /// ```motoko\n /// import Iter \"mo:base/Iter\";\n /// let iter = Iter.make(10);\n /// assert(?10 == iter.next());\n /// assert(?10 == iter.next());\n /// assert(?10 == iter.next());\n /// // ...\n /// ```\n public func make<A>(x : A) : Iter<A> = object {\n public func next() : ?A {\n ?x\n }\n };\n\n /// Takes two iterators and returns a new iterator that produces\n /// elements from the original iterators sequentally.\n /// ```motoko\n /// import Iter \"mo:base/Iter\";\n /// let iter1 = Iter.range(1, 2);\n /// let iter2 = Iter.range(5, 6);\n /// let concatenatedIter = Iter.concat(iter1, iter2);\n /// assert(?1 == concatenatedIter.next());\n /// assert(?2 == concatenatedIter.next());\n /// assert(?5 == concatenatedIter.next());\n /// assert(?6 == concatenatedIter.next());\n /// assert(null == concatenatedIter.next());\n /// ```\n public func concat<A>(a : Iter<A>, b : Iter<A>) : Iter<A> {\n var aEnded : Bool = false;\n object {\n public func next() : ?A {\n if (aEnded) {\n return b.next();\n };\n switch (a.next()) {\n case (?x) ?x;\n case (null) {\n aEnded := true;\n b.next();\n };\n };\n };\n };\n };\n\n /// Creates an iterator that produces the elements of an Array in ascending index order.\n /// ```motoko\n /// import Iter \"mo:base/Iter\";\n /// let iter = Iter.fromArray([1, 2, 3]);\n /// assert(?1 == iter.next());\n /// assert(?2 == iter.next());\n /// assert(?3 == iter.next());\n /// assert(null == iter.next());\n /// ```\n public func fromArray<A>(xs : [A]) : Iter<A> {\n var ix : Nat = 0;\n let size = xs.size();\n object {\n public func next() : ?A {\n if (ix >= size) {\n return null\n } else {\n let res = ?(xs[ix]);\n ix += 1;\n return res\n }\n }\n }\n };\n\n /// Like `fromArray` but for 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, _ : 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"},"Int16.mo":{"content":"/// Provides utility functions on 16-bit signed integers.\n///\n/// Note that most operations are available as built-in operators (e.g. `1 + 1`).\n///\n/// Import from the base library to use this module.\n/// ```motoko name=import\n/// import Int16 \"mo:base/Int16\";\n/// ```\nimport Int \"Int\";\nimport Prim \"mo:⛔\";\n\nmodule {\n\n /// 16-bit signed integers.\n public type Int16 = Prim.Types.Int16;\n\n /// Minimum 16-bit integer value, `-2 ** 15`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int16.minimumValue // => -32_768 : Int16\n /// ```\n public let minimumValue = -32_768 : Int16;\n\n /// Maximum 16-bit integer value, `+2 ** 15 - 1`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int16.maximumValue // => +32_767 : Int16\n /// ```\n public let maximumValue = 32_767 : Int16;\n\n /// Converts a 16-bit signed integer to a signed integer with infinite precision.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int16.toInt(12_345) // => 12_345 : Int\n /// ```\n public let toInt : Int16 -> Int = Prim.int16ToInt;\n\n /// Converts a signed integer with infinite precision to a 16-bit signed integer.\n ///\n /// Traps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int16.fromInt(12_345) // => +12_345 : Int16\n /// ```\n public let fromInt : Int -> Int16 = Prim.intToInt16;\n\n /// Converts a signed integer with infinite precision to a 16-bit signed integer.\n ///\n /// Wraps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int16.fromIntWrap(-12_345) // => -12_345 : Int\n /// ```\n public let fromIntWrap : Int -> Int16 = Prim.intToInt16Wrap;\n\n /// Converts a 8-bit signed integer to a 16-bit signed integer.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int16.fromInt8(-123) // => -123 : Int16\n /// ```\n public let fromInt8 : Int8 -> Int16 = Prim.int8ToInt16;\n\n /// Converts a 16-bit signed integer to a 8-bit signed integer.\n ///\n /// Traps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int16.toInt8(-123) // => -123 : Int8\n /// ```\n public let toInt8 : Int16 -> Int8 = Prim.int16ToInt8;\n\n /// Converts a 32-bit signed integer to a 16-bit signed integer.\n ///\n /// Traps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int16.fromInt32(-12_345) // => -12_345 : Int16\n /// ```\n public let fromInt32 : Int32 -> Int16 = Prim.int32ToInt16;\n\n /// Converts a 16-bit signed integer to a 32-bit signed integer.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int16.toInt32(-12_345) // => -12_345 : Int32\n /// ```\n public let toInt32 : Int16 -> Int32 = Prim.int16ToInt32;\n\n /// Converts an unsigned 16-bit integer to a signed 16-bit integer.\n ///\n /// Wraps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int16.fromNat16(12_345) // => +12_345 : Int16\n /// ```\n public let fromNat16 : Nat16 -> Int16 = Prim.nat16ToInt16;\n\n /// Converts a signed 16-bit integer to an unsigned 16-bit integer.\n ///\n /// Wraps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int16.toNat16(-1) // => 65_535 : Nat16 // underflow\n /// ```\n public let toNat16 : Int16 -> Nat16 = Prim.int16ToNat16;\n\n /// Returns the Text representation of `x`. Textual representation _do not_\n /// contain underscores to represent commas.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int16.toText(-12345) // => \"-12345\"\n /// ```\n public func toText(x : Int16) : Text {\n Int.toText(toInt(x))\n };\n\n /// Returns the absolute value of `x`.\n ///\n /// Traps when `x == -2 ** 15` (the minimum `Int16` value).\n ///\n /// Example:\n /// ```motoko include=import\n /// Int16.abs(-12345) // => +12_345\n /// ```\n public func abs(x : Int16) : Int16 {\n fromInt(Int.abs(toInt(x)))\n };\n\n /// Returns the minimum of `x` and `y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int16.min(+2, -3) // => -3\n /// ```\n public func min(x : Int16, y : Int16) : Int16 {\n if (x < y) { x } else { y }\n };\n\n /// Returns the maximum of `x` and `y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int16.max(+2, -3) // => +2\n /// ```\n public func max(x : Int16, y : Int16) : Int16 {\n if (x < y) { y } else { x }\n };\n\n /// Equality function for Int16 types.\n /// This is equivalent to `x == y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int16.equal(-1, -1); // => true\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `==` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `==`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Buffer \"mo:base/Buffer\";\n ///\n /// let buffer1 = Buffer.Buffer<Int16>(1);\n /// buffer1.add(-3);\n /// let buffer2 = Buffer.Buffer<Int16>(1);\n /// buffer2.add(-3);\n /// Buffer.equal(buffer1, buffer2, Int16.equal) // => true\n /// ```\n public func equal(x : Int16, y : Int16) : Bool { x == y };\n\n /// Inequality function for Int16 types.\n /// This is equivalent to `x != y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int16.notEqual(-1, -2); // => true\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `!=` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `!=`\n /// as a function value at the moment.\n public func notEqual(x : Int16, y : Int16) : Bool { x != y };\n\n /// \"Less than\" function for Int16 types.\n /// This is equivalent to `x < y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int16.less(-2, 1); // => true\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<`\n /// as a function value at the moment.\n public func less(x : Int16, y : Int16) : Bool { x < y };\n\n /// \"Less than or equal\" function for Int16 types.\n /// This is equivalent to `x <= y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int16.lessOrEqual(-2, -2); // => true\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<=` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<=`\n /// as a function value at the moment.\n public func lessOrEqual(x : Int16, y : Int16) : Bool { x <= y };\n\n /// \"Greater than\" function for Int16 types.\n /// This is equivalent to `x > y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int16.greater(-2, 1); // => false\n /// ```\n public func greater(x : Int16, y : Int16) : Bool { x > y };\n\n /// \"Greater than or equal\" function for Int16 types.\n /// This is equivalent to `x >= y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int16.greaterOrEqual(-2, -2); // => true\n /// ```\n public func greaterOrEqual(x : Int16, y : Int16) : Bool { x >= y };\n\n /// General-purpose comparison function for `Int16`. Returns the `Order` (\n /// either `#less`, `#equal`, or `#greater`) of comparing `x` with `y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int16.compare(-3, 2) // => #less\n /// ```\n ///\n /// This function can be used as value for a high order function, such as a sort function.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.sort([1, -2, -3] : [Int16], Int16.compare) // => [-3, -2, 1]\n /// ```\n public func compare(x : Int16, y : Int16) : { #less; #equal; #greater } {\n if (x < y) { #less } else if (x == y) { #equal } else { #greater }\n };\n\n /// Returns the negation of `x`, `-x`.\n ///\n /// Traps on overflow, i.e. for `neg(-2 ** 15)`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int16.neg(123) // => -123\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `-` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `-`\n /// as a function value at the moment.\n public func neg(x : Int16) : Int16 { -x };\n\n /// Returns the sum of `x` and `y`, `x + y`.\n ///\n /// Traps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int16.add(100, 23) // => +123\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `+` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `+`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.foldLeft<Int16, Int16>([1, -2, -3], 0, Int16.add) // => -4\n /// ```\n public func add(x : Int16, y : Int16) : Int16 { x + y };\n\n /// Returns the difference of `x` and `y`, `x - y`.\n ///\n /// Traps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int16.sub(123, 100) // => +23\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `-` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `-`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.foldLeft<Int16, Int16>([1, -2, -3], 0, Int16.sub) // => 4\n /// ```\n public func sub(x : Int16, y : Int16) : Int16 { x - y };\n\n /// Returns the product of `x` and `y`, `x * y`.\n ///\n /// Traps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int16.mul(12, 10) // => +120\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `*` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `*`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.foldLeft<Int16, Int16>([1, -2, -3], 1, Int16.mul) // => 6\n /// ```\n public func mul(x : Int16, y : Int16) : Int16 { x * y };\n\n /// Returns the signed integer division of `x` by `y`, `x / y`.\n /// Rounds the quotient towards zero, which is the same as truncating the decimal places of the quotient.\n ///\n /// Traps when `y` is zero.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int16.div(123, 10) // => +12\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `/` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `/`\n /// as a function value at the moment.\n public func div(x : Int16, y : Int16) : Int16 { x / y };\n\n /// Returns the remainder of the signed integer division of `x` by `y`, `x % y`,\n /// which is defined as `x - x / y * y`.\n ///\n /// Traps when `y` is zero.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int16.rem(123, 10) // => +3\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `%`\n /// as a function value at the moment.\n public func rem(x : Int16, y : Int16) : Int16 { x % y };\n\n /// Returns `x` to the power of `y`, `x ** y`.\n ///\n /// Traps on overflow/underflow and when `y < 0 or y >= 16`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int16.pow(2, 10) // => +1_024\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `**` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `**`\n /// as a function value at the moment.\n public func pow(x : Int16, y : Int16) : Int16 { x ** y };\n\n /// Returns the bitwise negation of `x`, `^x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int16.bitnot(-256 /* 0xff00 */) // => +255 // 0xff\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `^` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `^`\n /// as a function value at the moment.\n public func bitnot(x : Int16) : Int16 { ^x };\n\n /// Returns the bitwise \"and\" of `x` and `y`, `x & y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int16.bitand(0x0fff, 0x00f0) // => +240 // 0xf0\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `&` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `&`\n /// as a function value at the moment.\n public func bitand(x : Int16, y : Int16) : Int16 { x & y };\n\n /// Returns the bitwise \"or\" of `x` and `y`, `x | y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int16.bitor(0x0f0f, 0x00f0) // => +4_095 // 0x0fff\n /// ```\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `|` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `|`\n /// as a function value at the moment.\n public func bitor(x : Int16, y : Int16) : Int16 { x | y };\n\n /// Returns the bitwise \"exclusive or\" of `x` and `y`, `x ^ y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int16.bitxor(0x0fff, 0x00f0) // => +3_855 // 0x0f0f\n /// ```\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `^` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `^`\n /// as a function value at the moment.\n public func bitxor(x : Int16, y : Int16) : Int16 { x ^ y };\n\n /// Returns the bitwise left shift of `x` by `y`, `x << y`.\n /// The right bits of the shift filled with zeros.\n /// Left-overflowing bits, including the sign bit, are discarded.\n ///\n /// For `y >= 16`, the semantics is the same as for `bitshiftLeft(x, y % 16)`.\n /// For `y < 0`, the semantics is the same as for `bitshiftLeft(x, y + y % 16)`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int16.bitshiftLeft(1, 8) // => +256 // 0x100 equivalent to `2 ** 8`.\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<<` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<<`\n /// as a function value at the moment.\n public func bitshiftLeft(x : Int16, y : Int16) : Int16 { x << y };\n\n /// Returns the signed bitwise right shift of `x` by `y`, `x >> y`.\n /// The sign bit is retained and the left side is filled with the sign bit.\n /// Right-underflowing bits are discarded, i.e. not rotated to the left side.\n ///\n /// For `y >= 16`, the semantics is the same as for `bitshiftRight(x, y % 16)`.\n /// For `y < 0`, the semantics is the same as for `bitshiftRight (x, y + y % 16)`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int16.bitshiftRight(1024, 8) // => +4 // equivalent to `1024 / (2 ** 8)`\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `>>` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `>>`\n /// as a function value at the moment.\n public func bitshiftRight(x : Int16, y : Int16) : Int16 { x >> y };\n\n /// Returns the bitwise left rotatation of `x` by `y`, `x <<> y`.\n /// Each left-overflowing bit is inserted again on the right side.\n /// The sign bit is rotated like other bits, i.e. the rotation interprets the number as unsigned.\n ///\n /// Changes the direction of rotation for negative `y`.\n /// For `y >= 16`, the semantics is the same as for `bitrotLeft(x, y % 16)`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int16.bitrotLeft(0x2001, 4) // => +18 // 0x12.\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<<>` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<<>`\n /// as a function value at the moment.\n public func bitrotLeft(x : Int16, y : Int16) : Int16 { x <<> y };\n\n /// Returns the bitwise right rotation of `x` by `y`, `x <>> y`.\n /// Each right-underflowing bit is inserted again on the right side.\n /// The sign bit is rotated like other bits, i.e. the rotation interprets the number as unsigned.\n ///\n /// Changes the direction of rotation for negative `y`.\n /// For `y >= 16`, the semantics is the same as for `bitrotRight(x, y % 16)`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int16.bitrotRight(0x2010, 8) // => +4_128 // 0x01020.\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<>>` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<>>`\n /// as a function value at the moment.\n public func bitrotRight(x : Int16, y : Int16) : Int16 { x <>> y };\n\n /// Returns the value of bit `p` in `x`, `x & 2**p == 2**p`.\n /// If `p >= 16`, the semantics is the same as for `bittest(x, p % 16)`.\n /// This is equivalent to checking if the `p`-th bit is set in `x`, using 0 indexing.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int16.bittest(128, 7) // => true\n /// ```\n public func bittest(x : Int16, p : Nat) : Bool {\n Prim.btstInt16(x, Prim.intToInt16(p))\n };\n\n /// Returns the value of setting bit `p` in `x` to `1`.\n /// If `p >= 16`, the semantics is the same as for `bitset(x, p % 16)`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int16.bitset(0, 7) // => +128\n /// ```\n public func bitset(x : Int16, p : Nat) : Int16 {\n x | (1 << Prim.intToInt16(p))\n };\n\n /// Returns the value of clearing bit `p` in `x` to `0`.\n /// If `p >= 16`, the semantics is the same as for `bitclear(x, p % 16)`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int16.bitclear(-1, 7) // => -129\n /// ```\n public func bitclear(x : Int16, p : Nat) : Int16 {\n x & ^(1 << Prim.intToInt16(p))\n };\n\n /// Returns the value of flipping bit `p` in `x`.\n /// If `p >= 16`, the semantics is the same as for `bitclear(x, p % 16)`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int16.bitflip(255, 7) // => +127\n /// ```\n public func bitflip(x : Int16, p : Nat) : Int16 {\n x ^ (1 << Prim.intToInt16(p))\n };\n\n /// Returns the count of non-zero bits in `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int16.bitcountNonZero(0xff) // => +8\n /// ```\n public let bitcountNonZero : (x : Int16) -> Int16 = Prim.popcntInt16;\n\n /// Returns the count of leading zero bits in `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int16.bitcountLeadingZero(0x80) // => +8\n /// ```\n public let bitcountLeadingZero : (x : Int16) -> Int16 = Prim.clzInt16;\n\n /// Returns the count of trailing zero bits in `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int16.bitcountTrailingZero(0x0100) // => +8\n /// ```\n public let bitcountTrailingZero : (x : Int16) -> Int16 = Prim.ctzInt16;\n\n /// Returns the upper (i.e. most significant) and lower (least significant) byte of `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int16.explode 0x77ee // => (119, 238)\n /// ```\n public let explode : (x : Int16) -> (msb : Nat8, lsb : Nat8) = Prim.explodeInt16;\n\n /// Returns the sum of `x` and `y`, `x +% y`.\n ///\n /// Wraps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int16.addWrap(2 ** 14, 2 ** 14) // => -32_768 // overflow\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `+%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `+%`\n /// as a function value at the moment.\n public func addWrap(x : Int16, y : Int16) : Int16 { x +% y };\n\n /// Returns the difference of `x` and `y`, `x -% y`.\n ///\n /// Wraps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int16.subWrap(-2 ** 15, 1) // => +32_767 // underflow\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `-%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `-%`\n /// as a function value at the moment.\n public func subWrap(x : Int16, y : Int16) : Int16 { x -% y };\n\n /// Returns the product of `x` and `y`, `x *% y`. Wraps on overflow.\n ///\n /// Wraps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int16.mulWrap(2 ** 8, 2 ** 8) // => 0 // overflow\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `*%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `*%`\n /// as a function value at the moment.\n public func mulWrap(x : Int16, y : Int16) : Int16 { x *% y };\n\n /// Returns `x` to the power of `y`, `x **% y`.\n ///\n /// Wraps on overflow/underflow.\n /// Traps if `y < 0 or y >= 16`.\n ///\n /// Example:\n /// ```motoko include=import\n ///\n /// Int16.powWrap(2, 15) // => -32_768 // overflow\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `**%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `**%`\n /// as a function value at the moment.\n public func powWrap(x : Int16, y : Int16) : Int16 { x **% y }\n}\n"},"Random.mo":{"content":"/// A module for obtaining randomness on the Internet Computer (IC).\n///\n/// This module provides the fundamentals for user abstractions to build on.\n///\n/// Dealing with randomness on a deterministic computing platform, such\n/// as the IC, is intricate. Some basic rules need to be followed by the\n/// user of this module to obtain (and maintain) the benefits of crypto-\n/// graphic randomness:\n///\n/// - cryptographic entropy (randomness source) is only obtainable\n/// asyncronously in discrete chunks of 256 bits (32-byte sized `Blob`s)\n/// - all bets must be closed *before* entropy is being asked for in\n/// order to decide them\n/// - this implies that the same entropy (i.e. `Blob`) - or surplus entropy\n/// not utilised yet - cannot be used for a new round of bets without\n/// losing the cryptographic guarantees.\n///\n/// Concretely, the below class `Finite`, as well as the\n/// `*From` methods risk the carrying-over of state from previous rounds.\n/// These are provided for performance (and convenience) reasons, and need\n/// special care when used. Similar caveats apply for user-defined (pseudo)\n/// random number generators.\n///\n/// Usage:\n/// ```motoko no-repl\n/// import Random \"mo:base/Random\";\n/// ```\n\nimport I \"Iter\";\nimport Option \"Option\";\nimport Prim \"mo:⛔\";\n\nmodule {\n\n let raw_rand = (actor \"aaaaa-aa\" : actor { raw_rand : () -> async Blob }).raw_rand;\n\n /// Obtains a full blob (32 bytes) worth of fresh entropy.\n ///\n /// Example:\n /// ```motoko no-repl\n /// let random = Random.Finite(await Random.blob());\n /// ```\n public let blob : shared () -> async Blob = raw_rand;\n\n /// Drawing from a finite supply of entropy, `Finite` provides\n /// methods to obtain random values. When the entropy is used up,\n /// `null` is returned. Otherwise the outcomes' distributions are\n /// stated for each method. The uniformity of outcomes is\n /// guaranteed only when the supplied entropy is originally obtained\n /// by the `blob()` call, and is never reused.\n ///\n /// Example:\n /// ```motoko no-repl\n /// import Random \"mo:base/Random\";\n ///\n /// let random = Random.Finite(await Random.blob());\n ///\n /// let seed : Blob = \"\\14\\C9\\72\\09\\03\\D4\\D5\\72\\82\\95\\E5\\43\\AF\\FA\\A9\\44\\49\\2F\\25\\56\\13\\F3\\6E\\C7\\B0\\87\\DC\\76\\08\\69\\14\\CF\";\n /// let seedRandom = Random.Finite(seed);\n /// ```\n public class Finite(entropy : Blob) {\n let it : I.Iter<Nat8> = entropy.vals();\n\n /// Uniformly distributes outcomes in the numeric range [0 .. 255].\n /// Consumes 1 byte of entropy.\n ///\n /// Example:\n /// ```motoko no-repl\n /// let seed : Blob = \"\\14\\C9\\72\\09\\03\\D4\\D5\\72\\82\\95\\E5\\43\\AF\\FA\\A9\\44\\49\\2F\\25\\56\\13\\F3\\6E\\C7\\B0\\87\\DC\\76\\08\\69\\14\\CF\";\n /// let random = Random.Finite(seed);\n /// random.byte() // => ?20\n /// ```\n public func byte() : ?Nat8 {\n it.next()\n };\n\n /// Bool iterator splitting up a byte of entropy into 8 bits\n let bit : I.Iter<Bool> = object {\n var mask = 0x00 : Nat8;\n var byte = 0x00 : Nat8;\n public func next() : ?Bool {\n if (0 : Nat8 == mask) {\n switch (it.next()) {\n case null { null };\n case (?w) {\n byte := w;\n mask := 0x40;\n ?(0 : Nat8 != byte & (0x80 : Nat8))\n }\n }\n } else {\n let m = mask;\n mask >>= (1 : Nat8);\n ?(0 : Nat8 != byte & m)\n }\n }\n };\n\n /// Simulates a coin toss. Both outcomes have equal probability.\n /// Consumes 1 bit of entropy (amortised).\n ///\n /// Example:\n /// ```motoko no-repl\n /// let seed : Blob = \"\\14\\C9\\72\\09\\03\\D4\\D5\\72\\82\\95\\E5\\43\\AF\\FA\\A9\\44\\49\\2F\\25\\56\\13\\F3\\6E\\C7\\B0\\87\\DC\\76\\08\\69\\14\\CF\";\n /// let random = Random.Finite(seed);\n /// random.coin() // => ?false\n /// ```\n public func coin() : ?Bool {\n bit.next()\n };\n\n /// Uniformly distributes outcomes in the numeric range [0 .. 2^p - 1].\n /// Consumes ⌈p/8⌉ bytes of entropy.\n ///\n /// Example:\n /// ```motoko no-repl\n /// let seed : Blob = \"\\14\\C9\\72\\09\\03\\D4\\D5\\72\\82\\95\\E5\\43\\AF\\FA\\A9\\44\\49\\2F\\25\\56\\13\\F3\\6E\\C7\\B0\\87\\DC\\76\\08\\69\\14\\CF\";\n /// let random = Random.Finite(seed);\n /// random.range(32) // => ?348746249\n /// ```\n public func range(p : Nat8) : ?Nat {\n var pp = p;\n var acc : Nat = 0;\n for (i in it) {\n if (8 : Nat8 <= pp) {\n acc := acc * 256 + Prim.nat8ToNat(i)\n }\n else if (0 : Nat8 == pp) {\n return ?acc\n } else {\n acc *= Prim.nat8ToNat(1 << pp);\n let mask : Nat8 = 0xff >> (8 - pp);\n return ?(acc + Prim.nat8ToNat(i & mask))\n };\n pp -= 8\n };\n if (0 : Nat8 == pp)\n ?acc\n else null\n };\n\n /// Counts the number of heads in `n` fair coin tosses.\n /// Consumes ⌈n/8⌉ bytes of entropy.\n ///\n /// Example:\n /// ```motoko no-repl\n /// let seed : Blob = \"\\14\\C9\\72\\09\\03\\D4\\D5\\72\\82\\95\\E5\\43\\AF\\FA\\A9\\44\\49\\2F\\25\\56\\13\\F3\\6E\\C7\\B0\\87\\DC\\76\\08\\69\\14\\CF\";\n /// let random = Random.Finite(seed);\n /// random.binomial(5) // => ?1\n /// ```\n public func binomial(n : Nat8) : ?Nat8 {\n var nn = n;\n var acc : Nat8 = 0;\n for (i in it) {\n if (8 : Nat8 <= nn) {\n acc +%= Prim.popcntNat8(i)\n } else if (0 : Nat8 == nn) {\n return ?acc\n } else {\n let mask : Nat8 = 0xff << (8 - nn);\n let residue = Prim.popcntNat8(i & mask);\n return ?(acc +% residue)\n };\n nn -= 8\n };\n if (0 : Nat8 == nn)\n ?acc\n else null\n }\n };\n\n /// Distributes outcomes in the numeric range [0 .. 255].\n /// Seed blob must contain at least a byte.\n ///\n /// Example:\n /// ```motoko no-repl\n /// let seed : Blob = \"\\14\\C9\\72\\09\\03\\D4\\D5\\72\\82\\95\\E5\\43\\AF\\FA\\A9\\44\\49\\2F\\25\\56\\13\\F3\\6E\\C7\\B0\\87\\DC\\76\\08\\69\\14\\CF\";\n /// Random.byteFrom(seed) // => 20\n /// ```\n public func byteFrom(seed : Blob) : Nat8 {\n switch (seed.vals().next()) {\n case (?w) { w };\n case _ { Prim.trap \"Random.byteFrom\" }\n }\n };\n\n /// Simulates a coin toss.\n /// Seed blob must contain at least a byte.\n ///\n /// Example:\n /// ```motoko no-repl\n /// let seed : Blob = \"\\14\\C9\\72\\09\\03\\D4\\D5\\72\\82\\95\\E5\\43\\AF\\FA\\A9\\44\\49\\2F\\25\\56\\13\\F3\\6E\\C7\\B0\\87\\DC\\76\\08\\69\\14\\CF\";\n /// Random.coinFrom(seed) // => false\n /// ```\n public func coinFrom(seed : Blob) : Bool {\n switch (seed.vals().next()) {\n case (?w) { w > (127 : Nat8) };\n case _ { Prim.trap \"Random.coinFrom\" }\n }\n };\n\n /// Distributes outcomes in the numeric range [0 .. 2^p - 1].\n /// Seed blob must contain at least ((p+7) / 8) bytes.\n ///\n /// Example:\n /// ```motoko no-repl\n /// let seed : Blob = \"\\14\\C9\\72\\09\\03\\D4\\D5\\72\\82\\95\\E5\\43\\AF\\FA\\A9\\44\\49\\2F\\25\\56\\13\\F3\\6E\\C7\\B0\\87\\DC\\76\\08\\69\\14\\CF\";\n /// Random.rangeFrom(32, seed) // => 348746249\n /// ```\n public func rangeFrom(p : Nat8, seed : Blob) : Nat {\n rangeIter(p, seed.vals())\n };\n\n // internal worker method, expects iterator with sufficient supply\n func rangeIter(p : Nat8, it : I.Iter<Nat8>) : Nat {\n var pp = p;\n var acc : Nat = 0;\n for (i in it) {\n if (8 : Nat8 <= pp) {\n acc := acc * 256 + Prim.nat8ToNat(i)\n } else if (0 : Nat8 == pp) {\n return acc\n } else {\n acc *= Prim.nat8ToNat(1 << pp);\n let mask : Nat8 = 0xff >> (8 - pp);\n return acc + Prim.nat8ToNat(i & mask)\n };\n pp -= 8\n };\n if (0 : Nat8 == pp) {\n return acc\n }\n else Prim.trap(\"Random.rangeFrom\")\n };\n\n /// Counts the number of heads in `n` coin tosses.\n /// Seed blob must contain at least ((n+7) / 8) bytes.\n ///\n /// Example:\n /// ```motoko no-repl\n /// let seed : Blob = \"\\14\\C9\\72\\09\\03\\D4\\D5\\72\\82\\95\\E5\\43\\AF\\FA\\A9\\44\\49\\2F\\25\\56\\13\\F3\\6E\\C7\\B0\\87\\DC\\76\\08\\69\\14\\CF\";\n /// Random.binomialFrom(5, seed) // => 1\n /// ```\n public func binomialFrom(n : Nat8, seed : Blob) : Nat8 {\n binomialIter(n, seed.vals())\n };\n\n // internal worker method, expects iterator with sufficient supply\n func binomialIter(n : Nat8, it : I.Iter<Nat8>) : Nat8 {\n var nn = n;\n var acc : Nat8 = 0;\n for (i in it) {\n if (8 : Nat8 <= nn) {\n acc +%= Prim.popcntNat8(i)\n } else if (0 : Nat8 == nn) {\n return acc\n } else {\n let mask : Nat8 = 0xff << (8 - nn);\n let residue = Prim.popcntNat8(i & mask);\n return (acc +% residue)\n };\n nn -= 8\n };\n if (0 : Nat8 == nn) {\n return acc\n }\n else Prim.trap(\"Random.binomialFrom\")\n }\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() // => 0\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) // => [0, 1, 2, 3]\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 /// buffer.get(0); // => 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); // => ?10\n /// let y = buffer.getOpt(2); // => 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) // => [20]\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 /// buffer.removeLast(); // => ?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) // => [10, 12]\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) // => [10, 12]\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(); // => 2\n /// buffer.add(11);\n /// buffer.add(12); // causes capacity to increase by factor of 1.5\n /// let c2 = buffer.capacity(); // => 3\n /// ```\n ///\n /// Runtime: 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 /// buffer.capacity(); // => 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) // => [10, 11, 12, 13]\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) // => [10, 9, 11]\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) // => [10, 12, 13, 11]\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) // => [10, 11, 12]\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 // => 33\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 if and only if the buffer is empty.\n ///\n /// Example:\n /// ```motoko include=initialize\n /// buffer.add(2);\n /// buffer.add(0);\n /// buffer.add(3);\n /// Buffer.isEmpty(buffer); // => false\n /// ```\n ///\n /// ```motoko include=initialize\n /// Buffer.isEmpty(buffer); // => true\n /// ```\n ///\n /// Runtime: 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 ///\n /// Example:\n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n ///\n /// buffer.add(2);\n /// buffer.add(0);\n /// buffer.add(3);\n /// Buffer.contains<Nat>(buffer, 2, Nat.equal); // => true\n /// ```\n ///\n /// Runtime: 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 ///\n /// Example:\n /// ```motoko include=initialize\n ///\n /// buffer.add(1);\n ///\n /// let clone = Buffer.clone(buffer);\n /// Buffer.toArray(clone); // => [1]\n /// ```\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 ///\n /// Example:\n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n ///\n /// buffer.add(1);\n /// buffer.add(2);\n ///\n /// Buffer.max(buffer, Nat.compare); // => ?2\n /// ```\n ///\n /// Runtime: 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 /// Example:\n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n ///\n /// buffer.add(1);\n /// buffer.add(2);\n ///\n /// Buffer.min(buffer, Nat.compare); // => ?1\n /// ```\n ///\n /// Runtime: 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 ///\n /// Example:\n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n ///\n /// let buffer1 = Buffer.Buffer<Nat>(2);\n /// buffer1.add(1);\n /// buffer1.add(2);\n ///\n /// let buffer2 = Buffer.Buffer<Nat>(5);\n /// buffer2.add(1);\n /// buffer2.add(2);\n ///\n /// Buffer.equal(buffer1, buffer2, Nat.equal); // => true\n /// ```\n ///\n /// Runtime: 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 ///\n /// Example:\n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n ///\n /// let buffer1 = Buffer.Buffer<Nat>(2);\n /// buffer1.add(1);\n /// buffer1.add(2);\n ///\n /// let buffer2 = Buffer.Buffer<Nat>(3);\n /// buffer2.add(3);\n /// buffer2.add(4);\n ///\n /// Buffer.compare<Nat>(buffer1, buffer2, Nat.compare); // => #less\n /// ```\n ///\n /// Runtime: 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 /// Example:\n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n ///\n /// buffer.add(1);\n /// buffer.add(2);\n /// buffer.add(3);\n /// buffer.add(4);\n ///\n /// Buffer.toText(buffer, Nat.toText); // => \"[1, 2, 3, 4]\"\n /// ```\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 /// Example:\n /// ```motoko include=initialize\n /// import Hash \"mo:base/Hash\";\n ///\n /// buffer.add(1);\n /// buffer.add(2);\n /// buffer.add(3);\n /// buffer.add(1000);\n ///\n /// Buffer.hash<Nat>(buffer, Hash.hash); // => 2_872_640_342\n /// ```\n ///\n /// Runtime: 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 /// Example:\n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n ///\n /// buffer.add(1);\n /// buffer.add(2);\n /// buffer.add(3);\n /// buffer.add(4);\n ///\n /// Buffer.indexOf<Nat>(3, buffer, Nat.equal); // => ?2\n /// ```\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 /// Example:\n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n ///\n /// buffer.add(1);\n /// buffer.add(2);\n /// buffer.add(3);\n /// buffer.add(4);\n /// buffer.add(2);\n /// buffer.add(2);\n ///\n /// Buffer.lastIndexOf<Nat>(2, buffer, Nat.equal); // => ?5\n /// ```\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 /// Example:\n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n ///\n /// buffer.add(1);\n /// buffer.add(2);\n /// buffer.add(3);\n /// buffer.add(4);\n /// buffer.add(5);\n /// buffer.add(6);\n ///\n /// let sub = Buffer.Buffer<Nat>(2);\n /// sub.add(4);\n /// sub.add(5);\n /// sub.add(6);\n ///\n /// Buffer.indexOfBuffer<Nat>(sub, buffer, Nat.equal); // => ?3\n /// ```\n ///\n /// Runtime: 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 /// Example:\n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n ///\n /// buffer.add(1);\n /// buffer.add(4);\n /// buffer.add(5);\n /// buffer.add(6);\n ///\n /// Buffer.binarySearch<Nat>(5, buffer, Nat.compare); // => ?2\n /// ```\n ///\n /// Runtime: 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 /// Example:\n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n ///\n /// buffer.add(1);\n /// buffer.add(2);\n /// buffer.add(3);\n /// buffer.add(4);\n /// buffer.add(5);\n /// buffer.add(6);\n ///\n /// let sub = Buffer.subBuffer(buffer, 3, 2);\n /// Buffer.toText(sub, Nat.toText); // => [4, 5]\n /// ```\n ///\n /// Runtime: 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 /// Example:\n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n ///\n /// buffer.add(1);\n /// buffer.add(2);\n /// buffer.add(3);\n /// buffer.add(4);\n /// buffer.add(5);\n /// buffer.add(6);\n ///\n /// let sub = Buffer.Buffer<Nat>(2);\n /// sub.add(2);\n /// sub.add(3);\n /// Buffer.isSubBufferOf(sub, buffer, Nat.equal); // => true\n /// ```\n ///\n /// Runtime: 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 /// Example:\n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n ///\n /// buffer.add(1);\n /// buffer.add(2);\n /// buffer.add(3);\n /// buffer.add(4);\n ///\n /// let sub = Buffer.Buffer<Nat>(2);\n /// sub.add(2);\n /// sub.add(3);\n /// Buffer.isStrictSubBufferOf(sub, buffer, Nat.equal); // => true\n /// ```\n ///\n /// Runtime: 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 /// Example:\n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n ///\n /// buffer.add(1);\n /// buffer.add(2);\n /// buffer.add(3);\n /// buffer.add(4);\n ///\n /// let pre = Buffer.prefix(buffer, 3); // => [1, 2, 3]\n /// Buffer.toText(pre, Nat.toText);\n /// ```\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 /// Example:\n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n ///\n /// buffer.add(1);\n /// buffer.add(2);\n /// buffer.add(3);\n /// buffer.add(4);\n ///\n /// let pre = Buffer.Buffer<Nat>(2);\n /// pre.add(1);\n /// pre.add(2);\n /// Buffer.isPrefixOf(pre, buffer, Nat.equal); // => true\n /// ```\n ///\n /// Runtime: 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 /// Example:\n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n ///\n /// buffer.add(1);\n /// buffer.add(2);\n /// buffer.add(3);\n /// buffer.add(4);\n ///\n /// let pre = Buffer.Buffer<Nat>(3);\n /// pre.add(1);\n /// pre.add(2);\n /// pre.add(3);\n /// Buffer.isStrictPrefixOf(pre, buffer, Nat.equal); // => true\n /// ```\n ///\n /// Runtime: 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 /// Example:\n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n ///\n /// buffer.add(1);\n /// buffer.add(2);\n /// buffer.add(3);\n /// buffer.add(4);\n ///\n /// let suf = Buffer.suffix(buffer, 3); // => [2, 3, 4]\n /// Buffer.toText(suf, Nat.toText);\n /// ```\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 /// Example:\n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n ///\n /// buffer.add(1);\n /// buffer.add(2);\n /// buffer.add(3);\n /// buffer.add(4);\n ///\n /// let suf = Buffer.Buffer<Nat>(3);\n /// suf.add(2);\n /// suf.add(3);\n /// suf.add(4);\n /// Buffer.isSuffixOf(suf, buffer, Nat.equal); // => true\n /// ```\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 /// Example:\n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n ///\n /// buffer.add(1);\n /// buffer.add(2);\n /// buffer.add(3);\n /// buffer.add(4);\n ///\n /// let suf = Buffer.Buffer<Nat>(3);\n /// suf.add(2);\n /// suf.add(3);\n /// suf.add(4);\n /// Buffer.isStrictSuffixOf(suf, buffer, Nat.equal); // => true\n /// ```\n ///\n /// Runtime: 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 /// Example:\n /// ```motoko include=initialize\n ///\n /// buffer.add(2);\n /// buffer.add(3);\n /// buffer.add(4);\n ///\n /// Buffer.forAll<Nat>(buffer, func x { x > 1 }); // => true\n /// ```\n ///\n /// Runtime: 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 /// Example:\n /// ```motoko include=initialize\n ///\n /// buffer.add(2);\n /// buffer.add(3);\n /// buffer.add(4);\n ///\n /// Buffer.forSome<Nat>(buffer, func x { x > 3 }); // => true\n /// ```\n ///\n /// Runtime: 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 /// Example:\n /// ```motoko include=initialize\n ///\n /// buffer.add(2);\n /// buffer.add(3);\n /// buffer.add(4);\n ///\n /// Buffer.forNone<Nat>(buffer, func x { x == 0 }); // => true\n /// ```\n ///\n /// Runtime: 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 /// Example:\n /// ```motoko include=initialize\n ///\n /// buffer.add(1);\n /// buffer.add(2);\n /// buffer.add(3);\n ///\n /// Buffer.toArray<Nat>(buffer); // => [1, 2, 3]\n ///\n /// ```\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 /// Example:\n /// ```motoko include=initialize\n ///\n /// buffer.add(1);\n /// buffer.add(2);\n /// buffer.add(3);\n ///\n /// Buffer.toVarArray<Nat>(buffer); // => [1, 2, 3]\n /// ```\n ///\n /// Runtime: 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 /// Example:\n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n ///\n /// let array = [2, 3];\n ///\n /// let buf = Buffer.fromArray<Nat>(array); // => [2, 3]\n /// Buffer.toText(buf, Nat.toText);\n /// ```\n ///\n /// Runtime: 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 /// Example:\n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n ///\n /// let array = [var 1, 2, 3];\n ///\n /// let buf = Buffer.fromVarArray<Nat>(array); // => [1, 2, 3]\n /// Buffer.toText(buf, Nat.toText);\n /// ```\n ///\n /// Runtime: 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 /// Example:\n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n ///\n /// let array = [1, 1, 1];\n /// let iter = array.vals();\n ///\n /// let buf = Buffer.fromIter<Nat>(iter); // => [1, 1, 1]\n /// Buffer.toText(buf, Nat.toText);\n /// ```\n ///\n /// Runtime: 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 /// Example:\n /// ```motoko include=initialize\n ///\n /// let buffer = Buffer.Buffer<Nat>(10);\n /// buffer.add(1);\n /// buffer.add(2);\n /// buffer.add(3);\n ///\n /// Buffer.trimToSize<Nat>(buffer);\n /// buffer.capacity(); // => 3\n /// ```\n ///\n /// Runtime: 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 /// Example:\n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n ///\n /// buffer.add(1);\n /// buffer.add(2);\n /// buffer.add(3);\n ///\n /// let newBuf = Buffer.map<Nat, Nat>(buffer, func (x) { x + 1 });\n /// Buffer.toText(newBuf, Nat.toText); // => [2, 3, 4]\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>(buffer : Buffer<X>, f : X -> Y) : Buffer<Y> {\n let newBuffer = Buffer<Y>(buffer.capacity());\n\n for (element in buffer.vals()) {\n newBuffer.add(f element)\n };\n\n newBuffer\n };\n\n /// Applies `f` to each element in `buffer`.\n ///\n /// Example:\n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n /// import Debug \"mo:base/Debug\";\n ///\n /// buffer.add(1);\n /// buffer.add(2);\n /// buffer.add(3);\n ///\n /// Buffer.iterate<Nat>(buffer, func (x) {\n /// Debug.print(Nat.toText(x)); // prints each element in buffer\n /// });\n /// ```\n ///\n /// Runtime: 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 /// Example:\n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n ///\n /// buffer.add(1);\n /// buffer.add(2);\n /// buffer.add(3);\n ///\n /// let newBuf = Buffer.mapEntries<Nat, Nat>(buffer, func (x, i) { x + i + 1 });\n /// Buffer.toText(newBuf, Nat.toText); // => [2, 4, 6]\n /// ```\n ///\n /// Runtime: 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 /// Example:\n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n ///\n /// buffer.add(1);\n /// buffer.add(2);\n /// buffer.add(3);\n ///\n /// let newBuf = Buffer.mapFilter<Nat, Nat>(buffer, func (x) {\n /// if (x > 1) {\n /// ?(x * 2);\n /// } else {\n /// null;\n /// }\n /// });\n /// Buffer.toText(newBuf, Nat.toText); // => [4, 6]\n /// ```\n ///\n /// Runtime: 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 /// Example:\n /// ```motoko include=initialize\n /// import Result \"mo:base/Result\";\n ///\n /// buffer.add(1);\n /// buffer.add(2);\n /// buffer.add(3);\n ///\n /// let result = Buffer.mapResult<Nat, Nat, Text>(buffer, func (k) {\n /// if (k > 0) {\n /// #ok(k);\n /// } else {\n /// #err(\"One or more elements are zero.\");\n /// }\n /// });\n ///\n /// Result.mapOk<Buffer.Buffer<Nat>, [Nat], Text>(result, func buffer = Buffer.toArray(buffer)) // => #ok([1, 2, 3])\n /// ```\n ///\n /// Runtime: 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 /// Example:\n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n ///\n /// buffer.add(1);\n /// buffer.add(2);\n /// buffer.add(3);\n ///\n /// let chain = Buffer.chain<Nat, Nat>(buffer, func (x) {\n /// let b = Buffer.Buffer<Nat>(2);\n /// b.add(x);\n /// b.add(x * 2);\n /// return b;\n /// });\n /// Buffer.toText(chain, Nat.toText); // => [1, 2, 2, 4, 3, 6]\n /// ```\n ///\n /// Runtime: 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 /// Example:\n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n ///\n /// buffer.add(1);\n /// buffer.add(2);\n /// buffer.add(3);\n ///\n /// Buffer.foldLeft<Text, Nat>(buffer, \"\", func (acc, x) { acc # Nat.toText(x)}); // => \"123\"\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<A, X>(buffer : Buffer<X>, base : A, combine : (A, X) -> A) : A {\n var accumulation = base;\n\n for (element in buffer.vals()) {\n accumulation := combine(accumulation, element)\n };\n\n accumulation\n };\n\n /// Collapses the elements in `buffer` into a single value by starting with `base`\n /// and progessively combining elements into `base` with `combine`. Iteration runs\n /// right to left.\n ///\n /// Example:\n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n ///\n /// buffer.add(1);\n /// buffer.add(2);\n /// buffer.add(3);\n ///\n /// Buffer.foldRight<Nat, Text>(buffer, \"\", func (x, acc) { Nat.toText(x) # acc }); // => \"123\"\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>(buffer : Buffer<X>, base : A, combine : (X, A) -> A) : A {\n let size = buffer.size();\n if (size == 0) {\n return base\n };\n var accumulation = base;\n\n var i = size;\n while (i >= 1) {\n i -= 1; // to avoid Nat underflow, subtract first and stop iteration at 1\n accumulation := combine(buffer.get(i), accumulation)\n };\n\n accumulation\n };\n\n /// Returns the first element of `buffer`. Traps if `buffer` is empty.\n ///\n /// Example:\n /// ```motoko include=initialize\n ///\n /// buffer.add(1);\n /// buffer.add(2);\n /// buffer.add(3);\n ///\n /// Buffer.first(buffer); // => 1\n /// ```\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 /// Example:\n /// ```motoko include=initialize\n ///\n /// buffer.add(1);\n /// buffer.add(2);\n /// buffer.add(3);\n ///\n /// Buffer.last(buffer); // => 3\n /// ```\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 /// Example:\n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n ///\n /// let buffer = Buffer.make<Nat>(1);\n /// Buffer.toText(buffer, Nat.toText); // => [1]\n /// ```\n ///\n /// Runtime: 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 /// Example:\n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n ///\n /// buffer.add(1);\n /// buffer.add(2);\n /// buffer.add(3);\n ///\n /// Buffer.reverse(buffer);\n /// Buffer.toText(buffer, Nat.toText); // => [3, 2, 1]\n /// ```\n ///\n /// Runtime: 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 /// Example:\n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n ///\n /// let buffer1 = Buffer.Buffer<Nat>(2);\n /// buffer1.add(1);\n /// buffer1.add(2);\n /// buffer1.add(4);\n ///\n /// let buffer2 = Buffer.Buffer<Nat>(2);\n /// buffer2.add(2);\n /// buffer2.add(4);\n /// buffer2.add(6);\n ///\n /// let merged = Buffer.merge<Nat>(buffer1, buffer2, Nat.compare);\n /// Buffer.toText(merged, Nat.toText); // => [1, 2, 2, 4, 4, 6]\n /// ```\n ///\n /// Runtime: 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 /// Example:\n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n ///\n /// buffer.add(1);\n /// buffer.add(2);\n /// buffer.add(3);\n /// buffer.add(1);\n /// buffer.add(2);\n /// buffer.add(3);\n ///\n /// Buffer.removeDuplicates<Nat>(buffer, Nat.compare);\n /// Buffer.toText(buffer, Nat.toText); // => [1, 2, 3]\n /// ```\n ///\n /// Runtime: 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 /// Example:\n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n ///\n /// buffer.add(1);\n /// buffer.add(2);\n /// buffer.add(3);\n /// buffer.add(4);\n /// buffer.add(5);\n /// buffer.add(6);\n ///\n /// let partitions = Buffer.partition<Nat>(buffer, func (x) { x % 2 == 0 });\n /// (Buffer.toArray(partitions.0), Buffer.toArray(partitions.1)) // => ([2, 4, 6], [1, 3, 5])\n /// ```\n ///\n /// Runtime: 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 /// Example:\n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n ///\n /// buffer.add(1);\n /// buffer.add(2);\n /// buffer.add(3);\n /// buffer.add(4);\n /// buffer.add(5);\n /// buffer.add(6);\n ///\n /// let split = Buffer.split<Nat>(buffer, 3);\n /// (Buffer.toArray(split.0), Buffer.toArray(split.1)) // => ([1, 2, 3], [4, 5, 6])\n /// ```\n ///\n /// Runtime: 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 /// Example:\n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n ///\n /// buffer.add(1);\n /// buffer.add(2);\n /// buffer.add(3);\n /// buffer.add(4);\n /// buffer.add(5);\n /// buffer.add(6);\n ///\n /// let chunks = Buffer.chunk<Nat>(buffer, 3);\n /// Buffer.toText<Buffer.Buffer<Nat>>(chunks, func buf = Buffer.toText(buf, Nat.toText)); // => [[1, 2, 3], [4, 5, 6]]\n /// ```\n ///\n /// Runtime: 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 /// Example:\n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n ///\n /// buffer.add(1);\n /// buffer.add(2);\n /// buffer.add(2);\n /// buffer.add(4);\n /// buffer.add(5);\n /// buffer.add(5);\n ///\n /// let grouped = Buffer.groupBy<Nat>(buffer, func (x, y) { x == y });\n /// Buffer.toText<Buffer.Buffer<Nat>>(grouped, func buf = Buffer.toText(buf, Nat.toText)); // => [[1], [2, 2], [4], [5, 5]]\n /// ```\n ///\n /// Runtime: 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 /// Example:\n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n ///\n /// let buffer = Buffer.Buffer<Buffer.Buffer<Nat>>(1);\n ///\n /// let inner1 = Buffer.Buffer<Nat>(2);\n /// inner1.add(1);\n /// inner1.add(2);\n ///\n /// let inner2 = Buffer.Buffer<Nat>(2);\n /// inner2.add(3);\n /// inner2.add(4);\n ///\n /// buffer.add(inner1);\n /// buffer.add(inner2);\n /// // buffer = [[1, 2], [3, 4]]\n ///\n /// let flat = Buffer.flatten<Nat>(buffer);\n /// Buffer.toText<Nat>(flat, Nat.toText); // => [1, 2, 3, 4]\n /// ```\n ///\n /// Runtime: 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 /// Example:\n /// ```motoko include=initialize\n ///\n /// let buffer1 = Buffer.Buffer<Nat>(2);\n /// buffer1.add(1);\n /// buffer1.add(2);\n /// buffer1.add(3);\n ///\n /// let buffer2 = Buffer.Buffer<Nat>(2);\n /// buffer2.add(4);\n /// buffer2.add(5);\n ///\n /// let zipped = Buffer.zip(buffer1, buffer2);\n /// Buffer.toArray(zipped); // => [(1, 4), (2, 5)]\n /// ```\n ///\n /// Runtime: 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 /// Example:\n /// ```motoko include=initialize\n ///\n /// let buffer1 = Buffer.Buffer<Nat>(2);\n /// buffer1.add(1);\n /// buffer1.add(2);\n /// buffer1.add(3);\n ///\n /// let buffer2 = Buffer.Buffer<Nat>(2);\n /// buffer2.add(4);\n /// buffer2.add(5);\n /// buffer2.add(6);\n ///\n /// let zipped = Buffer.zipWith<Nat, Nat, Nat>(buffer1, buffer2, func (x, y) { x + y });\n /// Buffer.toArray(zipped) // => [5, 7, 9]\n /// ```\n ///\n /// Runtime: 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 /// Example:\n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n ///\n /// buffer.add(1);\n /// buffer.add(2);\n /// buffer.add(3);\n ///\n /// let newBuf = Buffer.takeWhile<Nat>(buffer, func (x) { x < 3 });\n /// Buffer.toText(newBuf, Nat.toText); // => [1, 2]\n /// ```\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 /// Example:\n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n ///\n /// buffer.add(1);\n /// buffer.add(2);\n /// buffer.add(3);\n ///\n /// let newBuf = Buffer.dropWhile<Nat>(buffer, func x { x < 3 }); // => [3]\n /// Buffer.toText(newBuf, Nat.toText);\n /// ```\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"},"Nat8.mo":{"content":"/// Provides utility functions on 8-bit unsigned integers.\n///\n/// Note that most operations are available as built-in operators (e.g. `1 + 1`).\n///\n/// Import from the base library to use this module.\n/// ```motoko name=import\n/// import Nat8 \"mo:base/Nat8\";\n/// ```\nimport Nat \"Nat\";\nimport Prim \"mo:⛔\";\n\nmodule {\n\n /// 8-bit natural numbers.\n public type Nat8 = Prim.Types.Nat8;\n\n /// Maximum 8-bit natural number. `2 ** 8 - 1`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat8.maximumValue; // => 255 : Nat8\n /// ```\n public let maximumValue = 255 : Nat8;\n\n /// Converts an 8-bit unsigned integer to an unsigned integer with infinite precision.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat8.toNat(123); // => 123 : Nat\n /// ```\n public let toNat : Nat8 -> Nat = Prim.nat8ToNat;\n\n /// Converts an unsigned integer with infinite precision to an 8-bit unsigned integer.\n ///\n /// Traps on overflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat8.fromNat(123); // => 123 : Nat8\n /// ```\n public let fromNat : Nat -> Nat8 = Prim.natToNat8;\n\n /// Converts a 16-bit unsigned integer to a 8-bit unsigned integer.\n ///\n /// Traps on overflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat8.fromNat16(123); // => 123 : Nat8\n /// ```\n public let fromNat16 : Nat16 -> Nat8 = Prim.nat16ToNat8;\n\n /// Converts an 8-bit unsigned integer to a 16-bit unsigned integer.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat8.toNat16(123); // => 123 : Nat16\n /// ```\n public let toNat16 : Nat8 -> Nat16 = Prim.nat8ToNat16;\n\n /// Converts a signed integer with infinite precision to an 8-bit unsigned integer.\n ///\n /// Wraps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat8.fromIntWrap(123); // => 123 : Nat8\n /// ```\n public let fromIntWrap : Int -> Nat8 = Prim.intToNat8Wrap;\n\n /// Converts `x` to its textual representation.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat8.toText(123); // => \"123\" : Text\n /// ```\n public func toText(x : Nat8) : Text {\n Nat.toText(toNat(x))\n };\n\n /// Returns the minimum of `x` and `y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat8.min(123, 200); // => 123 : Nat8\n /// ```\n public func min(x : Nat8, y : Nat8) : Nat8 {\n if (x < y) { x } else { y }\n };\n\n /// Returns the maximum of `x` and `y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat8.max(123, 200); // => 200 : Nat8\n /// ```\n public func max(x : Nat8, y : Nat8) : Nat8 {\n if (x < y) { y } else { x }\n };\n\n /// Equality function for Nat8 types.\n /// This is equivalent to `x == y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat8.equal(1, 1); // => true\n /// (1 : Nat8) == (1 : Nat8) // => true\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `==` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `==`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Buffer \"mo:base/Buffer\";\n ///\n /// let buffer1 = Buffer.Buffer<Nat8>(3);\n /// let buffer2 = Buffer.Buffer<Nat8>(3);\n /// Buffer.equal(buffer1, buffer2, Nat8.equal) // => true\n /// ```\n public func equal(x : Nat8, y : Nat8) : Bool { x == y };\n\n /// Inequality function for Nat8 types.\n /// This is equivalent to `x != y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat8.notEqual(1, 2); // => true\n /// (1 : Nat8) != (2 : Nat8) // => true\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `!=` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `!=`\n /// as a function value at the moment.\n public func notEqual(x : Nat8, y : Nat8) : Bool { x != y };\n\n /// \"Less than\" function for Nat8 types.\n /// This is equivalent to `x < y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat8.less(1, 2); // => true\n /// (1 : Nat8) < (2 : Nat8) // => true\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<`\n /// as a function value at the moment.\n public func less(x : Nat8, y : Nat8) : Bool { x < y };\n\n /// \"Less than or equal\" function for Nat8 types.\n /// This is equivalent to `x <= y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat.lessOrEqual(1, 2); // => true\n /// 1 <= 2 // => true\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<=` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<=`\n /// as a function value at the moment.\n public func lessOrEqual(x : Nat8, y : Nat8) : Bool { x <= y };\n\n /// \"Greater than\" function for Nat8 types.\n /// This is equivalent to `x > y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat8.greater(2, 1); // => true\n /// (2 : Nat8) > (1 : Nat8) // => true\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `>` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `>`\n /// as a function value at the moment.\n public func greater(x : Nat8, y : Nat8) : Bool { x > y };\n\n /// \"Greater than or equal\" function for Nat8 types.\n /// This is equivalent to `x >= y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat8.greaterOrEqual(2, 1); // => true\n /// (2 : Nat8) >= (1 : Nat8) // => true\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `>=` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `>=`\n /// as a function value at the moment.\n public func greaterOrEqual(x : Nat8, y : Nat8) : Bool { x >= y };\n\n /// General purpose comparison function for `Nat8`. Returns the `Order` (\n /// either `#less`, `#equal`, or `#greater`) of comparing `x` with `y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat8.compare(2, 3) // => #less\n /// ```\n ///\n /// This function can be used as value for a high order function, such as a sort function.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.sort([2, 3, 1] : [Nat8], Nat8.compare) // => [1, 2, 3]\n /// ```\n public func compare(x : Nat8, y : Nat8) : { #less; #equal; #greater } {\n if (x < y) { #less } else if (x == y) { #equal } else { #greater }\n };\n\n /// Returns the sum of `x` and `y`, `x + y`.\n /// Traps on overflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat8.add(1, 2); // => 3\n /// (1 : Nat8) + (2 : Nat8) // => 3\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `+` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `+`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.foldLeft<Nat8, Nat8>([2, 3, 1], 0, Nat8.add) // => 6\n /// ```\n public func add(x : Nat8, y : Nat8) : Nat8 { x + y };\n\n /// Returns the difference of `x` and `y`, `x - y`.\n /// Traps on underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat8.sub(2, 1); // => 1\n /// (2 : Nat8) - (1 : Nat8) // => 1\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `-` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `-`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.foldLeft<Nat8, Nat8>([2, 3, 1], 20, Nat8.sub) // => 14\n /// ```\n public func sub(x : Nat8, y : Nat8) : Nat8 { x - y };\n\n /// Returns the product of `x` and `y`, `x * y`.\n /// Traps on overflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat8.mul(2, 3); // => 6\n /// (2 : Nat8) * (3 : Nat8) // => 6\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `*` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `*`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.foldLeft<Nat8, Nat8>([2, 3, 1], 1, Nat8.mul) // => 6\n /// ```\n public func mul(x : Nat8, y : Nat8) : Nat8 { x * y };\n\n /// Returns the quotient of `x` divided by `y`, `x / y`.\n /// Traps when `y` is zero.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat8.div(6, 2); // => 3\n /// (6 : Nat8) / (2 : Nat8) // => 3\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `/` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `/`\n /// as a function value at the moment.\n public func div(x : Nat8, y : Nat8) : Nat8 { x / y };\n\n /// Returns the remainder of `x` divided by `y`, `x % y`.\n /// Traps when `y` is zero.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat8.rem(6, 4); // => 2\n /// (6 : Nat8) % (4 : Nat8) // => 2\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `%`\n /// as a function value at the moment.\n public func rem(x : Nat8, y : Nat8) : Nat8 { x % y };\n\n /// Returns `x` to the power of `y`, `x ** y`.\n /// Traps on overflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat8.pow(2, 3); // => 8\n /// (2 : Nat8) ** (3 : Nat8) // => 8\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `**` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `**`\n /// as a function value at the moment.\n public func pow(x : Nat8, y : Nat8) : Nat8 { x ** y };\n\n /// Returns the bitwise negation of `x`, `^x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat8.bitnot(0); // => 255\n /// ^(0 : Nat8) // => 255\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `^` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `^`\n /// as a function value at the moment.\n public func bitnot(x : Nat8) : Nat8 { ^x };\n\n /// Returns the bitwise and of `x` and `y`, `x & y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat8.bitand(3, 2); // => 2\n /// (3 : Nat8) & (2 : Nat8) // => 2\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `&` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `&`\n /// as a function value at the moment.\n public func bitand(x : Nat8, y : Nat8) : Nat8 { x & y };\n\n /// Returns the bitwise or of `x` and `y`, `x | y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat8.bitor(3, 2); // => 3\n /// (3 : Nat8) | (2 : Nat8) // => 3\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `|` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `|`\n /// as a function value at the moment.\n public func bitor(x : Nat8, y : Nat8) : Nat8 { x | y };\n\n /// Returns the bitwise exclusive or of `x` and `y`, `x ^ y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat8.bitxor(3, 2); // => 1\n /// (3 : Nat8) ^ (2 : Nat8) // => 1\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `^` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `^`\n /// as a function value at the moment.\n public func bitxor(x : Nat8, y : Nat8) : Nat8 { x ^ y };\n\n /// Returns the bitwise shift left of `x` by `y`, `x << y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat8.bitshiftLeft(1, 2); // => 4\n /// (1 : Nat8) << (2 : Nat8) // => 4\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<<` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<<`\n /// as a function value at the moment.\n public func bitshiftLeft(x : Nat8, y : Nat8) : Nat8 { x << y };\n\n /// Returns the bitwise shift right of `x` by `y`, `x >> y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat8.bitshiftRight(4, 2); // => 1\n /// (4 : Nat8) >> (2 : Nat8) // => 1\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `>>` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `>>`\n /// as a function value at the moment.\n public func bitshiftRight(x : Nat8, y : Nat8) : Nat8 { x >> y };\n\n /// Returns the bitwise rotate left of `x` by `y`, `x <<> y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat8.bitrotLeft(128, 1); // => 1\n /// (128 : Nat8) <<> (1 : Nat8) // => 1\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<<>` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<<>`\n /// as a function value at the moment.\n public func bitrotLeft(x : Nat8, y : Nat8) : Nat8 { x <<> y };\n\n /// Returns the bitwise rotate right of `x` by `y`, `x <>> y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat8.bitrotRight(1, 1); // => 128\n /// (1 : Nat8) <>> (1 : Nat8) // => 128\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<>>` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<>>`\n /// as a function value at the moment.\n public func bitrotRight(x : Nat8, y : Nat8) : Nat8 { x <>> y };\n\n /// Returns the value of bit `p mod 8` in `x`, `(x & 2^(p mod 8)) == 2^(p mod 8)`.\n /// This is equivalent to checking if the `p`-th bit is set in `x`, using 0 indexing.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat8.bittest(5, 2); // => true\n /// ```\n public func bittest(x : Nat8, p : Nat) : Bool {\n Prim.btstNat8(x, Prim.natToNat8(p))\n };\n\n /// Returns the value of setting bit `p mod 8` in `x` to `1`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat8.bitset(5, 1); // => 7\n /// ```\n public func bitset(x : Nat8, p : Nat) : Nat8 {\n x | (1 << Prim.natToNat8(p))\n };\n\n /// Returns the value of clearing bit `p mod 8` in `x` to `0`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat8.bitclear(5, 2); // => 1\n /// ```\n public func bitclear(x : Nat8, p : Nat) : Nat8 {\n x & ^(1 << Prim.natToNat8(p))\n };\n\n /// Returns the value of flipping bit `p mod 8` in `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat8.bitflip(5, 2); // => 1\n /// ```\n public func bitflip(x : Nat8, p : Nat) : Nat8 {\n x ^ (1 << Prim.natToNat8(p))\n };\n\n /// Returns the count of non-zero bits in `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat8.bitcountNonZero(5); // => 2\n /// ```\n public let bitcountNonZero : (x : Nat8) -> Nat8 = Prim.popcntNat8;\n\n /// Returns the count of leading zero bits in `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat8.bitcountLeadingZero(5); // => 5\n /// ```\n public let bitcountLeadingZero : (x : Nat8) -> Nat8 = Prim.clzNat8;\n\n /// Returns the count of trailing zero bits in `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat8.bitcountTrailingZero(6); // => 1\n /// ```\n public let bitcountTrailingZero : (x : Nat8) -> Nat8 = Prim.ctzNat8;\n\n /// Returns the sum of `x` and `y`, `x +% y`. Wraps on overflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat8.addWrap(230, 26); // => 0\n /// (230 : Nat8) +% (26 : Nat8) // => 0\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `+%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `+%`\n /// as a function value at the moment.\n public func addWrap(x : Nat8, y : Nat8) : Nat8 { x +% y };\n\n /// Returns the difference of `x` and `y`, `x -% y`. Wraps on underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat8.subWrap(0, 1); // => 255\n /// (0 : Nat8) -% (1 : Nat8) // => 255\n /// ```\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `-%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `-%`\n /// as a function value at the moment.\n public func subWrap(x : Nat8, y : Nat8) : Nat8 { x -% y };\n\n /// Returns the product of `x` and `y`, `x *% y`. Wraps on overflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat8.mulWrap(230, 26); // => 92\n /// (230 : Nat8) *% (26 : Nat8) // => 92\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `*%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `*%`\n /// as a function value at the moment.\n public func mulWrap(x : Nat8, y : Nat8) : Nat8 { x *% y };\n\n /// Returns `x` to the power of `y`, `x **% y`. Wraps on overflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat8.powWrap(2, 8); // => 0\n /// (2 : Nat8) **% (8 : Nat8) // => 0\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `**%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `**%`\n /// as a function value at the moment.\n public func powWrap(x : Nat8, y : Nat8) : Nat8 { x **% y };\n\n}\n"},"List.mo":{"content":"/// Purely-functional, singly-linked lists.\n\n/// A list of type `List<T>` is either `null` or an optional pair of a value of type `T` and a tail, itself of type `List<T>`.\n///\n/// To use this library, import it using:\n///\n/// ```motoko name=initialize\n/// import List \"mo:base/List\";\n/// ```\n\nimport Array \"Array\";\nimport Iter \"IterType\";\nimport Option \"Option\";\nimport Order \"Order\";\nimport Result \"Result\";\n\nmodule {\n\n // A singly-linked list consists of zero or more _cons cells_, wherein\n // each cell contains a single list element (the cell's _head_), and a pointer to the\n // remainder of the list (the cell's _tail_).\n public type List<T> = ?(T, List<T>);\n\n /// Create an empty list.\n ///\n /// Example:\n /// ```motoko include=initialize\n /// List.nil<Nat>() // => null\n /// ```\n ///\n /// Runtime: O(1)\n ///\n /// Space: O(1)\n public func nil<T>() : List<T> = null;\n\n /// Check whether a list is empty and return true if the list is empty.\n ///\n /// Example:\n /// ```motoko include=initialize\n /// List.isNil<Nat>(null) // => true\n /// ```\n ///\n /// Runtime: O(1)\n ///\n /// Space: O(1)\n public func isNil<T>(l : List<T>) : Bool {\n switch l {\n case null { true };\n case _ { false }\n }\n };\n\n /// Add `x` to the head of `list`, and return the new list.\n ///\n /// Example:\n /// ```motoko include=initialize\n /// List.push<Nat>(0, null) // => ?(0, null);\n /// ```\n ///\n /// Runtime: O(1)\n ///\n /// Space: O(1)\n public func push<T>(x : T, l : List<T>) : List<T> = ?(x, l);\n\n /// Return the last element of the list, if present.\n /// Example:\n /// ```motoko include=initialize\n /// List.last<Nat>(?(0, ?(1, null))) // => ?1\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(1)\n public func last<T>(l : List<T>) : ?T {\n switch l {\n case null { null };\n case (?(x, null)) { ?x };\n case (?(_, t)) { last<T>(t) }\n }\n };\n\n /// Remove the head of the list, returning the optioned head and the tail of the list in a pair.\n /// Returns `(null, null)` if the list is empty.\n ///\n /// Example:\n /// ```motoko include=initialize\n /// List.pop<Nat>(?(0, ?(1, null))) // => (?0, ?(1, null))\n /// ```\n ///\n /// Runtime: O(1)\n ///\n /// Space: O(1)\n public func pop<T>(l : List<T>) : (?T, List<T>) {\n switch l {\n case null { (null, null) };\n case (?(h, t)) { (?h, t) }\n }\n };\n\n /// Return the length of the list.\n ///\n /// Example:\n /// ```motoko include=initialize\n /// List.size<Nat>(?(0, ?(1, null))) // => 2\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(1)\n public func size<T>(l : List<T>) : Nat {\n func rec(l : List<T>, n : Nat) : Nat {\n switch l {\n case null { n };\n case (?(_, t)) { rec(t, n + 1) }\n }\n };\n rec(l, 0)\n };\n /// Access any item in a list, zero-based.\n ///\n /// NOTE: Indexing into a list is a linear operation, and usually an\n /// indication that a list might not be the best data structure\n /// to use.\n ///\n /// Example:\n /// ```motoko include=initialize\n /// List.get<Nat>(?(0, ?(1, null)), 1) // => ?1\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(1)\n public func get<T>(l : List<T>, n : Nat) : ?T {\n switch (n, l) {\n case (_, null) { null };\n case (0, (?(h, _))) { ?h };\n case (_, (?(_, t))) { get<T>(t, n - 1) }\n }\n };\n\n /// Reverses the list.\n ///\n /// Example:\n /// ```motoko include=initialize\n /// List.reverse<Nat>(?(0, ?(1, ?(2, null)))) // => ?(2, ?(1, ?(0, null)))\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n public func reverse<T>(l : List<T>) : List<T> {\n func rec(l : List<T>, r : List<T>) : List<T> {\n switch l {\n case null { r };\n case (?(h, t)) { rec(t, ?(h, r)) }\n }\n };\n rec(l, null)\n };\n\n /// Call the given function for its side effect, with each list element in turn.\n ///\n /// Example:\n /// ```motoko include=initialize\n /// var sum = 0;\n /// List.iterate<Nat>(?(0, ?(1, ?(2, null))), func n { sum += n });\n /// sum // => 3\n /// ```\n ///\n /// Runtime: 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<T>(l : List<T>, f : T -> ()) {\n switch l {\n case null { () };\n case (?(h, t)) { f(h); iterate<T>(t, f) }\n }\n };\n\n /// Call the given function `f` on each list element and collect the results\n /// in a new list.\n ///\n /// Example:\n /// ```motoko include=initialize\n /// import Nat = \"mo:base/Nat\"\n /// List.map<Nat, Text>(?(0, ?(1, ?(2, null))), Nat.toText) // => ?(\"0\", ?(\"1\", ?(\"2\", null))\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n /// *Runtime and space assumes that `f` runs in O(1) time and space.\n public func map<T, U>(l : List<T>, f : T -> U) : List<U> {\n switch l {\n case null { null };\n case (?(h, t)) { ?(f(h), map<T, U>(t, f)) }\n }\n };\n\n /// Create a new list with only those elements of the original list for which\n /// the given function (often called the _predicate_) returns true.\n ///\n /// Example:\n /// ```motoko include=initialize\n /// List.filter<Nat>(?(0, ?(1, ?(2, null))), func n { n != 1 }) // => ?(0, ?(2, null))\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n public func filter<T>(l : List<T>, f : T -> Bool) : List<T> {\n switch l {\n case null { null };\n case (?(h, t)) {\n if (f(h)) {\n ?(h, filter<T>(t, f))\n } else {\n filter<T>(t, f)\n }\n }\n }\n };\n\n /// Create two new lists from the results of a given function (`f`).\n /// The first list only includes the elements for which the given\n /// function `f` returns true and the second list only includes\n /// the elements for which the function returns false.\n ///\n /// Example:\n /// ```motoko include=initialize\n /// List.partition<Nat>(?(0, ?(1, ?(2, null))), func n { n != 1 }) // => (?(0, ?(2, null)), ?(1, null))\n /// ```\n ///\n /// Runtime: 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 partition<T>(l : List<T>, f : T -> Bool) : (List<T>, List<T>) {\n switch l {\n case null { (null, null) };\n case (?(h, t)) {\n if (f(h)) {\n // call f in-order\n let (l, r) = partition<T>(t, f);\n (?(h, l), r)\n } else {\n let (l, r) = partition<T>(t, f);\n (l, ?(h, r))\n }\n }\n }\n };\n\n /// Call the given function on each list element, and collect the non-null results\n /// in a new list.\n ///\n /// Example:\n /// ```motoko include=initialize\n /// List.mapFilter<Nat, Nat>(\n /// ?(1, ?(2, ?(3, null))),\n /// func n {\n /// if (n > 1) {\n /// ?(n * 2);\n /// } else {\n /// null\n /// }\n /// }\n /// ) // => ?(4, ?(6, null))\n /// ```\n ///\n /// Runtime: 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<T, U>(l : List<T>, f : T -> ?U) : List<U> {\n switch l {\n case null { null };\n case (?(h, t)) {\n switch (f(h)) {\n case null { mapFilter<T, U>(t, f) };\n case (?h_) { ?(h_, mapFilter<T, U>(t, f)) }\n }\n }\n }\n };\n\n /// Maps a Result-returning function `f` over a List and returns either\n /// the first error or a list of successful values.\n ///\n /// Example:\n /// ```motoko include=initialize\n /// List.mapResult<Nat, Nat, Text>(\n /// ?(1, ?(2, ?(3, null))),\n /// func n {\n /// if (n > 0) {\n /// #ok(n * 2);\n /// } else {\n /// #err(\"Some element is zero\")\n /// }\n /// }\n /// ); // => #ok ?(2, ?(4, ?(6, null))\n /// ```\n ///\n /// Runtime: 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<T, R, E>(xs : List<T>, f : T -> Result.Result<R, E>) : Result.Result<List<R>, E> {\n func go(xs : List<T>, acc : List<R>) : Result.Result<List<R>, E> {\n switch xs {\n case null { #ok(acc) };\n case (?(head, tail)) {\n switch (f(head)) {\n case (#err(err)) { #err(err) };\n case (#ok(ok)) { go(tail, ?(ok, acc)) }\n }\n }\n }\n };\n Result.mapOk(go(xs, null), func(xs : List<R>) : List<R> = reverse(xs))\n };\n\n /// Append the elements from the reverse of one list, 'l', to another list, 'm'.\n ///\n /// Example:\n /// ```motoko include=initialize\n /// List.revAppend<Nat>(\n /// ?(2, ?(1, ?(0, null))),\n /// ?(3, ?(4, ?(5, null)))\n /// ); // => ?(0, ?(1, ?(2, ?(3, ?(4, ?(5, null))))))\n /// ```\n ///\n /// Runtime: O(size(l))\n ///\n /// Space: O(size(l))\n func revAppend<T>(l : List<T>, m : List<T>) : List<T> {\n switch l {\n case null { m };\n case (?(h, t)) { revAppend(t, ?(h, m)) }\n }\n };\n\n /// Append the elements from one list to another list.\n ///\n /// Example:\n /// ```motoko include=initialize\n /// List.append<Nat>(\n /// ?(0, ?(1, ?(2, null))),\n /// ?(3, ?(4, ?(5, null)))\n /// ) // => ?(0, ?(1, ?(2, ?(3, ?(4, ?(5, null))))))\n /// ```\n ///\n /// Runtime: O(size(l))\n ///\n /// Space: O(size(l))\n public func append<T>(l : List<T>, m : List<T>) : List<T> {\n revAppend(reverse(l), m)\n };\n\n /// Flatten, or concatenate, a list of lists as a list.\n ///\n /// Example:\n /// ```motoko include=initialize\n /// List.flatten<Nat>(\n /// ?(?(0, ?(1, ?(2, null))),\n /// ?(?(3, ?(4, ?(5, null))),\n /// null))\n /// ); // => ?(0, ?(1, ?(2, ?(3, ?(4, ?(5, null))))))\n /// ```\n ///\n /// Runtime: O(size*size)\n ///\n /// Space: O(size*size)\n public func flatten<T>(l : List<List<T>>) : List<T> {\n //FIXME: this is quadratic, not linear https://github.com/dfinity/motoko-base/issues/459\n foldLeft<List<T>, List<T>>(l, null, func(a, b) { append<T>(a, b) })\n };\n\n /// Returns the first `n` elements of the given list.\n /// If the given list has fewer than `n` elements, this function returns\n /// a copy of the full input list.\n ///\n /// Example:\n /// ```motoko include=initialize\n /// List.take<Nat>(\n /// ?(0, ?(1, ?(2, null))),\n /// 2\n /// ); // => ?(0, ?(1, null))\n /// ```\n ///\n /// Runtime: O(n)\n ///\n /// Space: O(n)\n public func take<T>(l : List<T>, n : Nat) : List<T> {\n switch (l, n) {\n case (_, 0) { null };\n case (null, _) { null };\n case (?(h, t), m) { ?(h, take<T>(t, m - 1)) }\n }\n };\n\n /// Drop the first `n` elements from the given list.\n ///\n /// Example:\n /// ```motoko include=initialize\n /// List.drop<Nat>(\n /// ?(0, ?(1, ?(2, null))),\n /// 2\n /// ); // => ?(2, null)\n /// ```\n ///\n /// Runtime: O(n)\n ///\n /// Space: O(1)\n public func drop<T>(l : List<T>, n : Nat) : List<T> {\n switch (l, n) {\n case (l_, 0) { l_ };\n case (null, _) { null };\n case ((?(_, t)), m) { drop<T>(t, m - 1) }\n }\n };\n\n /// Collapses the elements in `list` into a single value by starting with `base`\n /// and progessively combining elements into `base` with `combine`. Iteration runs\n /// left to right.\n ///\n /// Example:\n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n ///\n /// List.foldLeft<Nat, Text>(\n /// ?(1, ?(2, ?(3, null))),\n /// \"\",\n /// func (acc, x) { acc # Nat.toText(x)}\n /// ) // => \"123\"\n /// ```\n ///\n /// Runtime: O(size(list))\n ///\n /// Space: O(1) heap, O(1) stack\n ///\n /// *Runtime and space assumes that `combine` runs in O(1) time and space.\n public func foldLeft<T, S>(list : List<T>, base : S, combine : (S, T) -> S) : S {\n switch list {\n case null { base };\n case (?(h, t)) { foldLeft(t, combine(base, h), combine) }\n }\n };\n\n /// Collapses the elements in `buffer` into a single value by starting with `base`\n /// and progessively combining elements into `base` with `combine`. Iteration runs\n /// right to left.\n ///\n /// Example:\n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n ///\n /// List.foldRight<Nat, Text>(\n /// ?(1, ?(2, ?(3, null))),\n /// \"\",\n /// func (x, acc) { Nat.toText(x) # acc}\n /// ) // => \"123\"\n /// ```\n ///\n /// Runtime: O(size(list))\n ///\n /// Space: O(1) heap, O(size(list)) stack\n ///\n /// *Runtime and space assumes that `combine` runs in O(1) time and space.\n public func foldRight<T, S>(list : List<T>, base : S, combine : (T, S) -> S) : S {\n switch list {\n case null { base };\n case (?(h, t)) { combine(h, foldRight<T, S>(t, base, combine)) }\n }\n };\n\n /// Return the first element for which the given predicate `f` is true,\n /// if such an element exists.\n ///\n /// Example:\n /// ```motoko include=initialize\n ///\n /// List.find<Nat>(\n /// ?(1, ?(2, ?(3, null))),\n /// func n { n > 1 }\n /// ); // => ?2\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(1)\n ///\n /// *Runtime and space assumes that `f` runs in O(1) time and space.\n public func find<T>(l : List<T>, f : T -> Bool) : ?T {\n switch l {\n case null { null };\n case (?(h, t)) { if (f(h)) { ?h } else { find<T>(t, f) } }\n }\n };\n\n /// Return true if there exists a list element for which\n /// the given predicate `f` is true.\n ///\n /// Example:\n /// ```motoko include=initialize\n ///\n /// List.some<Nat>(\n /// ?(1, ?(2, ?(3, null))),\n /// func n { n > 1 }\n /// ) // => true\n /// ```\n ///\n /// Runtime: O(size(list))\n ///\n /// Space: O(1)\n ///\n /// *Runtime and space assumes that `f` runs in O(1) time and space.\n public func some<T>(l : List<T>, f : T -> Bool) : Bool {\n switch l {\n case null { false };\n case (?(h, t)) { f(h) or some<T>(t, f) }\n }\n };\n\n /// Return true if the given predicate `f` is true for all list\n /// elements.\n ///\n /// Example:\n /// ```motoko include=initialize\n ///\n /// List.all<Nat>(\n /// ?(1, ?(2, ?(3, null))),\n /// func n { n > 1 }\n /// ); // => false\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(1)\n ///\n /// *Runtime and space assumes that `f` runs in O(1) time and space.\n public func all<T>(l : List<T>, f : T -> Bool) : Bool {\n switch l {\n case null { true };\n case (?(h, t)) { f(h) and all<T>(t, f) }\n }\n };\n\n /// Merge two ordered lists into a single ordered list.\n /// This function requires both list to be ordered as specified\n /// by the given relation `lessThanOrEqual`.\n ///\n /// Example:\n /// ```motoko include=initialize\n ///\n /// List.merge<Nat>(\n /// ?(1, ?(2, ?(4, null))),\n /// ?(2, ?(4, ?(6, null))),\n /// func (n1, n2) { n1 <= n2 }\n /// ); // => ?(1, ?(2, ?(2, ?(4, ?(4, ?(6, null))))))),\n /// ```\n ///\n /// Runtime: O(size(l1) + size(l2))\n ///\n /// Space: O(size(l1) + size(l2))\n ///\n /// *Runtime and space assumes that `lessThanOrEqual` runs in O(1) time and space.\n // TODO: replace by merge taking a compare : (T, T) -> Order.Order function?\n public func merge<T>(l1 : List<T>, l2 : List<T>, lessThanOrEqual : (T, T) -> Bool) : List<T> {\n switch (l1, l2) {\n case (null, _) { l2 };\n case (_, null) { l1 };\n case (?(h1, t1), ?(h2, t2)) {\n if (lessThanOrEqual(h1, h2)) {\n ?(h1, merge<T>(t1, l2, lessThanOrEqual))\n } else {\n ?(h2, merge<T>(l1, t2, lessThanOrEqual))\n }\n }\n }\n };\n\n private func compareAux<T>(l1 : List<T>, l2 : List<T>, compare : (T, T) -> Order.Order) : Order.Order {\n switch (l1, l2) {\n case (null, null) { #equal };\n case (null, _) { #less };\n case (_, null) { #greater };\n case (?(h1, t1), ?(h2, t2)) {\n switch (compare(h1, h2)) {\n case (#equal) { compareAux<T>(t1, t2, compare) };\n case other { other }\n }\n }\n }\n };\n\n /// Compare two lists using lexicographic ordering specified by argument function `compare`.\n ///\n /// Example:\n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n ///\n /// List.compare<Nat>(\n /// ?(1, ?(2, null)),\n /// ?(3, ?(4, null)),\n /// Nat.compare\n /// ) // => #less\n /// ```\n ///\n /// Runtime: O(size(l1))\n ///\n /// Space: O(1)\n ///\n /// *Runtime and space assumes that argument `compare` runs in O(1) time and space.\n public func compare<T>(l1 : List<T>, l2 : List<T>, compare : (T, T) -> Order.Order) : Order.Order {\n compareAux<T>(l1, l2, compare);\n };\n\n private func equalAux<T>(l1 : List<T>, l2 : List<T>, equal : (T, T) -> Bool) : Bool {\n switch (l1, l2) {\n case (?(h1, t1), ?(h2, t2)) {\n equal(h1, h2) and equalAux<T>(t1, t2, equal)\n };\n case (null, null) { true };\n case _ { false };\n }\n };\n /// Compare two lists for equality using the argument function `equal` to determine equality of their elements.\n ///\n /// Example:\n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n ///\n /// List.equal<Nat>(\n /// ?(1, ?(2, null)),\n /// ?(3, ?(4, null)),\n /// Nat.equal\n /// ); // => false\n /// ```\n ///\n /// Runtime: O(size(l1))\n ///\n /// Space: O(1)\n ///\n /// *Runtime and space assumes that argument `equal` runs in O(1) time and space.\n public func equal<T>(l1 : List<T>, l2 : List<T>, equal : (T, T) -> Bool) : Bool {\n equalAux<T>(l1, l2, equal);\n };\n\n /// Generate a list based on a length and a function that maps from\n /// a list index to a list element.\n ///\n /// Example:\n /// ```motoko include=initialize\n /// List.tabulate<Nat>(\n /// 3,\n /// func n { n * 2 }\n /// ) // => ?(0, ?(2, (?4, null)))\n /// ```\n ///\n /// Runtime: O(n)\n ///\n /// Space: O(n)\n ///\n /// *Runtime and space assumes that `f` runs in O(1) time and space.\n public func tabulate<T>(n : Nat, f : Nat -> T) : List<T> {\n var i = 0;\n var l : List<T> = null;\n while (i < n) {\n l := ?(f(i), l);\n i += 1\n };\n reverse(l)\n };\n\n /// Create a list with exactly one element.\n ///\n /// Example:\n /// ```motoko include=initialize\n /// List.make<Nat>(\n /// 0\n /// ) // => ?(0, null)\n /// ```\n ///\n /// Runtime: O(1)\n ///\n /// Space: O(1)\n public func make<T>(x : T) : List<T> = ?(x, null);\n\n /// Create a list of the given length with the same value in each position.\n ///\n /// Example:\n /// ```motoko include=initialize\n /// List.replicate<Nat>(\n /// 3,\n /// 0\n /// ) // => ?(0, ?(0, ?(0, null)))\n /// ```\n ///\n /// Runtime: O(n)\n ///\n /// Space: O(n)\n public func replicate<T>(n : Nat, x : T) : List<T> {\n var i = 0;\n var l : List<T> = null;\n while (i < n) {\n l := ?(x, l);\n i += 1\n };\n l\n };\n\n /// Create a list of pairs from a pair of lists.\n ///\n /// If the given lists have different lengths, then the created list will have a\n /// length equal to the length of the smaller list.\n ///\n /// Example:\n /// ```motoko include=initialize\n /// List.zip<Nat, Text>(\n /// ?(0, ?(1, ?(2, null))),\n /// ?(\"0\", ?(\"1\", null)),\n /// ) // => ?((0, \"0\"), ?((1, \"1\"), null))\n /// ```\n ///\n /// Runtime: O(min(size(xs), size(ys)))\n ///\n /// Space: O(min(size(xs), size(ys)))\n public func zip<T, U>(xs : List<T>, ys : List<U>) : List<(T, U)> = zipWith<T, U, (T, U)>(xs, ys, func(x, y) { (x, y) });\n\n /// Create a list in which elements are created by applying function `f` to each pair `(x, y)` of elements\n /// occuring at the same position in list `xs` and list `ys`.\n ///\n /// If the given lists have different lengths, then the created list will have a\n /// length equal to the length of the smaller list.\n ///\n /// Example:\n /// ```motoko include=initialize\n /// import Nat = \"mo:base/Nat\";\n /// import Char = \"mo:base/Char\";\n ///\n /// List.zipWith<Nat, Char, Text>(\n /// ?(0, ?(1, ?(2, null))),\n /// ?('a', ?('b', null)),\n /// func (n, c) { Nat.toText(n) # Char.toText(c) }\n /// ) // => ?(\"0a\", ?(\"1b\", null))\n /// ```\n ///\n /// Runtime: O(min(size(xs), size(ys)))\n ///\n /// Space: O(min(size(xs), size(ys)))\n ///\n /// *Runtime and space assumes that `f` runs in O(1) time and space.\n public func zipWith<T, U, V>(\n xs : List<T>,\n ys : List<U>,\n f : (T, U) -> V\n ) : List<V> {\n switch (pop<T>(xs)) {\n case (null, _) { null };\n case (?x, xt) {\n switch (pop<U>(ys)) {\n case (null, _) { null };\n case (?y, yt) {\n push<V>(f(x, y), zipWith<T, U, V>(xt, yt, f))\n }\n }\n }\n }\n };\n\n /// Split the given list at the given zero-based index.\n ///\n /// Example:\n /// ```motoko include=initialize\n /// List.split<Nat>(\n /// 2,\n /// ?(0, ?(1, ?(2, null)))\n /// ) // => (?(0, ?(1, null)), ?(2, null))\n /// ```\n ///\n /// Runtime: O(n)\n ///\n /// Space: O(n)\n public func split<T>(n : Nat, xs : List<T>) : (List<T>, List<T>) {\n if (n == 0) { (null, xs) } else {\n func rec(n : Nat, xs : List<T>) : (List<T>, List<T>) {\n switch (pop<T>(xs)) {\n case (null, _) { (null, null) };\n case (?h, t) {\n if (n == 1) { (make<T>(h), t) } else {\n let (l, r) = rec(n - 1, t);\n (push<T>(h, l), r)\n }\n }\n }\n };\n rec(n, xs)\n }\n };\n\n /// Split the given list into chunks of length `n`.\n /// The last chunk will be shorter if the length of the given list\n /// does not divide by `n` evenly.\n ///\n /// Example:\n /// ```motoko include=initialize\n /// List.chunks<Nat>(\n /// 2,\n /// ?(0, ?(1, ?(2, ?(3, ?(4, null)))))\n /// )\n /// /* => ?(?(0, ?(1, null)),\n /// ?(?(2, ?(3, null)),\n /// ?(?(4, null),\n /// null)))\n /// */\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n public func chunks<T>(n : Nat, xs : List<T>) : List<List<T>> {\n let (l, r) = split<T>(n, xs);\n if (isNil<T>(l)) {\n null\n } else {\n push<List<T>>(l, chunks<T>(n, r))\n }\n };\n\n /// Convert an array into a list.\n ///\n /// Example:\n /// ```motoko include=initialize\n /// List.fromArray<Nat>([ 0, 1, 2, 3, 4])\n /// // => ?(0, ?(1, ?(2, ?(3, ?(4, null)))))\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n public func fromArray<T>(xs : [T]) : List<T> {\n Array.foldRight<T, List<T>>(\n xs,\n null,\n func(x : T, ys : List<T>) : List<T> {\n push<T>(x, ys)\n }\n )\n };\n\n /// Convert a mutable array into a list.\n ///\n /// Example:\n /// ```motoko include=initialize\n /// List.fromVarArray<Nat>([var 0, 1, 2, 3, 4])\n /// // => ?(0, ?(1, ?(2, ?(3, ?(4, null)))))\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n public func fromVarArray<T>(xs : [var T]) : List<T> = fromArray<T>(Array.freeze<T>(xs));\n\n /// Create an array from a list.\n /// Example:\n /// ```motoko include=initialize\n /// List.toArray<Nat>(?(0, ?(1, ?(2, ?(3, ?(4, null))))))\n /// // => [0, 1, 2, 3, 4]\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n public func toArray<T>(xs : List<T>) : [T] {\n let length = size<T>(xs);\n var list = xs;\n Array.tabulate<T>(\n length,\n func(i) {\n let popped = pop<T>(list);\n list := popped.1;\n switch (popped.0) {\n case null { loop { assert false } };\n case (?x) x\n }\n }\n )\n };\n\n /// Create a mutable array from a list.\n /// Example:\n /// ```motoko include=initialize\n /// List.toVarArray<Nat>(?(0, ?(1, ?(2, ?(3, ?(4, null))))))\n /// // => [var 0, 1, 2, 3, 4]\n /// ```\n ///\n /// Runtime: O(size)\n ///\n /// Space: O(size)\n public func toVarArray<T>(xs : List<T>) : [var T] = Array.thaw<T>(toArray<T>(xs));\n\n /// Create an iterator from a list.\n /// Example:\n /// ```motoko include=initialize\n /// var sum = 0;\n /// for (n in List.toIter<Nat>(?(0, ?(1, ?(2, ?(3, ?(4, null))))))) {\n /// sum += n;\n /// };\n /// sum\n /// // => 10\n /// ```\n ///\n /// Runtime: O(1)\n ///\n /// Space: O(1)\n public func toIter<T>(xs : List<T>) : Iter.Iter<T> {\n var state = xs;\n object {\n public func next() : ?T = switch state {\n case (?(hd, tl)) { state := tl; ?hd };\n case _ null\n }\n }\n }\n\n}\n"},"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"},"Stack.mo":{"content":"/// Class `Stack<X>` provides a Minimal LIFO stack of elements of type `X`.\n///\n/// See library `Deque` for mixed LIFO/FIFO behavior.\n///\n/// Example:\n/// ```motoko name=initialize\n/// import Stack \"mo:base/Stack\";\n///\n/// let stack = Stack.Stack<Nat>(); // create a stack\n/// ```\n/// Runtime: O(1)\n///\n/// Space: O(1)\n\nimport List \"List\";\n\nmodule {\n\n public class Stack<T>() {\n\n var stack : List.List<T> = List.nil<T>();\n\n /// Push an element on the top of the stack.\n ///\n /// Example:\n /// ```motoko include=initialize\n /// stack.push(1);\n /// stack.push(2);\n /// stack.push(3);\n /// stack.peek(); // examine the top most element\n /// ```\n ///\n /// Runtime: O(1)\n ///\n /// Space: O(1)\n public func push(x : T) {\n stack := ?(x, stack)\n };\n\n /// True when the stack is empty and false otherwise.\n ///\n /// Example:\n /// ```motoko include=initialize\n /// stack.isEmpty();\n /// ```\n ///\n /// Runtime: O(1)\n ///\n /// Space: O(1)\n public func isEmpty() : Bool {\n List.isNil<T>(stack)\n };\n\n /// Return (without removing) the top element, or return null if the stack is empty.\n ///\n /// Example:\n /// ```motoko include=initialize\n /// stack.push(1);\n /// stack.push(2);\n /// stack.push(3);\n /// stack.peek();\n /// ```\n ///\n /// Runtime: O(1)\n ///\n /// Space: O(1)\n public func peek() : ?T {\n switch stack {\n case null { null };\n case (?(h, _)) { ?h }\n }\n };\n\n /// Remove and return the top element, or return null if the stack is empty.\n ///\n /// Example:\n /// ```motoko include=initialize\n /// stack.push(1);\n /// ignore stack.pop();\n /// stack.isEmpty();\n /// ```\n ///\n /// Runtime: O(1)\n ///\n /// Space: O(1)\n public func pop() : ?T {\n switch stack {\n case null { null };\n case (?(h, t)) { stack := t; ?h }\n }\n }\n }\n}\n"},"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"},"Nat16.mo":{"content":"/// Provides utility functions on 16-bit unsigned integers.\n///\n/// Note that most operations are available as built-in operators (e.g. `1 + 1`).\n///\n/// Import from the base library to use this module.\n/// ```motoko name=import\n/// import Nat16 \"mo:base/Nat16\";\n/// ```\nimport Nat \"Nat\";\nimport Prim \"mo:⛔\";\n\nmodule {\n\n /// 16-bit natural numbers.\n public type Nat16 = Prim.Types.Nat16;\n\n /// Maximum 16-bit natural number. `2 ** 16 - 1`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat16.maximumValue; // => 65536 : Nat16\n /// ```\n public let maximumValue = 65535 : Nat16;\n\n /// Converts a 16-bit unsigned integer to an unsigned integer with infinite precision.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat16.toNat(123); // => 123 : Nat\n /// ```\n public let toNat : Nat16 -> Nat = Prim.nat16ToNat;\n\n /// Converts an unsigned integer with infinite precision to a 16-bit unsigned integer.\n ///\n /// Traps on overflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat16.fromNat(123); // => 123 : Nat16\n /// ```\n public let fromNat : Nat -> Nat16 = Prim.natToNat16;\n\n /// Converts an 8-bit unsigned integer to a 16-bit unsigned integer.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat16.fromNat8(123); // => 123 : Nat16\n /// ```\n public func fromNat8(x : Nat8) : Nat16 {\n Prim.nat8ToNat16(x)\n };\n\n /// Converts a 16-bit unsigned integer to an 8-bit unsigned integer.\n ///\n /// Traps on overflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat16.toNat8(123); // => 123 : Nat8\n /// ```\n public func toNat8(x : Nat16) : Nat8 {\n Prim.nat16ToNat8(x)\n };\n\n /// Converts a 32-bit unsigned integer to a 16-bit unsigned integer.\n ///\n /// Traps on overflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat16.fromNat32(123); // => 123 : Nat16\n /// ```\n public func fromNat32(x : Nat32) : Nat16 {\n Prim.nat32ToNat16(x)\n };\n\n /// Converts a 16-bit unsigned integer to a 32-bit unsigned integer.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat16.toNat32(123); // => 123 : Nat32\n /// ```\n public func toNat32(x : Nat16) : Nat32 {\n Prim.nat16ToNat32(x)\n };\n\n /// Converts a signed integer with infinite precision to a 16-bit unsigned integer.\n ///\n /// Wraps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat16.fromIntWrap(123 : Int); // => 123 : Nat16\n /// ```\n public let fromIntWrap : Int -> Nat16 = Prim.intToNat16Wrap;\n\n /// Converts `x` to its textual representation. Textual representation _do not_\n /// contain underscores to represent commas.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat16.toText(1234); // => \"1234\" : Text\n /// ```\n public func toText(x : Nat16) : Text {\n Nat.toText(toNat(x))\n };\n\n /// Returns the minimum of `x` and `y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat16.min(123, 200); // => 123 : Nat16\n /// ```\n public func min(x : Nat16, y : Nat16) : Nat16 {\n if (x < y) { x } else { y }\n };\n\n /// Returns the maximum of `x` and `y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat16.max(123, 200); // => 200 : Nat16\n /// ```\n public func max(x : Nat16, y : Nat16) : Nat16 {\n if (x < y) { y } else { x }\n };\n\n /// Equality function for Nat16 types.\n /// This is equivalent to `x == y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat16.equal(1, 1); // => true\n /// (1 : Nat16) == (1 : Nat16) // => true\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `==` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `==`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Buffer \"mo:base/Buffer\";\n ///\n /// let buffer1 = Buffer.Buffer<Nat16>(3);\n /// let buffer2 = Buffer.Buffer<Nat16>(3);\n /// Buffer.equal(buffer1, buffer2, Nat16.equal) // => true\n /// ```\n public func equal(x : Nat16, y : Nat16) : Bool { x == y };\n\n /// Inequality function for Nat16 types.\n /// This is equivalent to `x != y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat16.notEqual(1, 2); // => true\n /// (1 : Nat16) != (2 : Nat16) // => true\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `!=` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `!=`\n /// as a function value at the moment.\n public func notEqual(x : Nat16, y : Nat16) : Bool { x != y };\n\n /// \"Less than\" function for Nat16 types.\n /// This is equivalent to `x < y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat16.less(1, 2); // => true\n /// (1 : Nat16) < (2 : Nat16) // => true\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<`\n /// as a function value at the moment.\n public func less(x : Nat16, y : Nat16) : Bool { x < y };\n\n /// \"Less than or equal\" function for Nat16 types.\n /// This is equivalent to `x <= y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat16.lessOrEqual(1, 2); // => true\n /// (1 : Nat16) <= (2 : Nat16) // => true\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<=` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<=`\n /// as a function value at the moment.\n public func lessOrEqual(x : Nat16, y : Nat16) : Bool { x <= y };\n\n /// \"Greater than\" function for Nat16 types.\n /// This is equivalent to `x > y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat16.greater(2, 1); // => true\n /// (2 : Nat16) > (1 : Nat16) // => true\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `>` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `>`\n /// as a function value at the moment.\n public func greater(x : Nat16, y : Nat16) : Bool { x > y };\n\n /// \"Greater than or equal\" function for Nat16 types.\n /// This is equivalent to `x >= y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat16.greaterOrEqual(2, 1); // => true\n /// (2 : Nat16) >= (1 : Nat16) // => true\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `>=` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `>=`\n /// as a function value at the moment.\n public func greaterOrEqual(x : Nat16, y : Nat16) : Bool { x >= y };\n\n /// General purpose comparison function for `Nat16`. Returns the `Order` (\n /// either `#less`, `#equal`, or `#greater`) of comparing `x` with `y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat16.compare(2, 3) // => #less\n /// ```\n ///\n /// This function can be used as value for a high order function, such as a sort function.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.sort([2, 3, 1] : [Nat16], Nat16.compare) // => [1, 2, 3]\n /// ```\n public func compare(x : Nat16, y : Nat16) : { #less; #equal; #greater } {\n if (x < y) { #less } else if (x == y) { #equal } else { #greater }\n };\n\n /// Returns the sum of `x` and `y`, `x + y`.\n /// Traps on overflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat16.add(1, 2); // => 3\n /// (1 : Nat16) + (2 : Nat16) // => 3\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `+` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `+`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.foldLeft<Nat16, Nat16>([2, 3, 1], 0, Nat16.add) // => 6\n /// ```\n public func add(x : Nat16, y : Nat16) : Nat16 { x + y };\n\n /// Returns the difference of `x` and `y`, `x - y`.\n /// Traps on underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat16.sub(2, 1); // => 1\n /// (2 : Nat16) - (1 : Nat16) // => 1\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `-` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `-`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.foldLeft<Nat16, Nat16>([2, 3, 1], 20, Nat16.sub) // => 14\n /// ```\n public func sub(x : Nat16, y : Nat16) : Nat16 { x - y };\n\n /// Returns the product of `x` and `y`, `x * y`.\n /// Traps on overflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat16.mul(2, 3); // => 6\n /// (2 : Nat16) * (3 : Nat16) // => 6\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `*` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `*`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.foldLeft<Nat16, Nat16>([2, 3, 1], 1, Nat16.mul) // => 6\n /// ```\n public func mul(x : Nat16, y : Nat16) : Nat16 { x * y };\n\n /// Returns the quotient of `x` divided by `y`, `x / y`.\n /// Traps when `y` is zero.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat16.div(6, 2); // => 3\n /// (6 : Nat16) / (2 : Nat16) // => 3\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `/` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `/`\n /// as a function value at the moment.\n public func div(x : Nat16, y : Nat16) : Nat16 { x / y };\n\n /// Returns the remainder of `x` divided by `y`, `x % y`.\n /// Traps when `y` is zero.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat16.rem(6, 4); // => 2\n /// (6 : Nat16) % (4 : Nat16) // => 2\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `%`\n /// as a function value at the moment.\n public func rem(x : Nat16, y : Nat16) : Nat16 { x % y };\n\n /// Returns the power of `x` to `y`, `x ** y`.\n /// Traps on overflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat16.pow(2, 3); // => 8\n /// (2 : Nat16) ** (3 : Nat16) // => 8\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `**` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `**`\n /// as a function value at the moment.\n public func pow(x : Nat16, y : Nat16) : Nat16 { x ** y };\n\n /// Returns the bitwise negation of `x`, `^x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat16.bitnot(0); // => 65535\n /// ^(0 : Nat16) // => 65535\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `^` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `^`\n /// as a function value at the moment.\n public func bitnot(x : Nat16) : Nat16 { ^x };\n\n /// Returns the bitwise and of `x` and `y`, `x & y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat16.bitand(0, 1); // => 0\n /// (0 : Nat16) & (1 : Nat16) // => 0\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `&` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `&`\n /// as a function value at the moment.\n public func bitand(x : Nat16, y : Nat16) : Nat16 { x & y };\n\n /// Returns the bitwise or of `x` and `y`, `x | y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat16.bitor(0, 1); // => 1\n /// (0 : Nat16) | (1 : Nat16) // => 1\n /// ```\n public func bitor(x : Nat16, y : Nat16) : Nat16 { x | y };\n\n /// Returns the bitwise exclusive or of `x` and `y`, `x ^ y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat16.bitxor(0, 1); // => 1\n /// (0 : Nat16) ^ (1 : Nat16) // => 1\n /// ```\n public func bitxor(x : Nat16, y : Nat16) : Nat16 { x ^ y };\n\n /// Returns the bitwise shift left of `x` by `y`, `x << y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat16.bitshiftLeft(1, 3); // => 8\n /// (1 : Nat16) << (3 : Nat16) // => 8\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<<` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<<`\n /// as a function value at the moment.\n public func bitshiftLeft(x : Nat16, y : Nat16) : Nat16 { x << y };\n\n /// Returns the bitwise shift right of `x` by `y`, `x >> y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat16.bitshiftRight(8, 3); // => 1\n /// (8 : Nat16) >> (3 : Nat16) // => 1\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `>>` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `>>`\n /// as a function value at the moment.\n public func bitshiftRight(x : Nat16, y : Nat16) : Nat16 { x >> y };\n\n /// Returns the bitwise rotate left of `x` by `y`, `x <<> y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat16.bitrotLeft(2, 1); // => 4\n /// (2 : Nat16) <<> (1 : Nat16) // => 4\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<<>` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<<>`\n /// as a function value at the moment.\n public func bitrotLeft(x : Nat16, y : Nat16) : Nat16 { x <<> y };\n\n /// Returns the bitwise rotate right of `x` by `y`, `x <>> y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat16.bitrotRight(1, 1); // => 32768\n /// (1 : Nat16) <>> (1 : Nat16) // => 32768\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<>>` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<>>`\n /// as a function value at the moment.\n public func bitrotRight(x : Nat16, y : Nat16) : Nat16 { x <>> y };\n\n /// Returns the value of bit `p mod 16` in `x`, `(x & 2^(p mod 16)) == 2^(p mod 16)`.\n /// This is equivalent to checking if the `p`-th bit is set in `x`, using 0 indexing.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat16.bittest(5, 2); // => true\n /// ```\n public func bittest(x : Nat16, p : Nat) : Bool {\n Prim.btstNat16(x, Prim.natToNat16(p))\n };\n\n /// Returns the value of setting bit `p mod 16` in `x` to `1`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat16.bitset(0, 2); // => 4\n /// ```\n public func bitset(x : Nat16, p : Nat) : Nat16 {\n x | (1 << Prim.natToNat16(p))\n };\n\n /// Returns the value of clearing bit `p mod 16` in `x` to `0`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat16.bitclear(5, 2); // => 1\n /// ```\n public func bitclear(x : Nat16, p : Nat) : Nat16 {\n x & ^(1 << Prim.natToNat16(p))\n };\n\n /// Returns the value of flipping bit `p mod 16` in `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat16.bitflip(5, 2); // => 1\n /// ```\n public func bitflip(x : Nat16, p : Nat) : Nat16 {\n x ^ (1 << Prim.natToNat16(p))\n };\n\n /// Returns the count of non-zero bits in `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat16.bitcountNonZero(5); // => 2\n /// ```\n public let bitcountNonZero : (x : Nat16) -> Nat16 = Prim.popcntNat16;\n\n /// Returns the count of leading zero bits in `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat16.bitcountLeadingZero(5); // => 13\n /// ```\n public let bitcountLeadingZero : (x : Nat16) -> Nat16 = Prim.clzNat16;\n\n /// Returns the count of trailing zero bits in `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat16.bitcountTrailingZero(5); // => 0\n /// ```\n public let bitcountTrailingZero : (x : Nat16) -> Nat16 = Prim.ctzNat16;\n\n /// Returns the upper (i.e. most significant) and lower (least significant) byte of `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat16.explode 0xaa88 // => (170, 136)\n /// ```\n public let explode : (x : Nat16) -> (msb : Nat8, lsb : Nat8) = Prim.explodeNat16;\n\n /// Returns the sum of `x` and `y`, `x +% y`. Wraps on overflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat16.addWrap(65532, 5); // => 1\n /// (65532 : Nat16) +% (5 : Nat16) // => 1\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `+%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `+%`\n /// as a function value at the moment.\n public func addWrap(x : Nat16, y : Nat16) : Nat16 { x +% y };\n\n /// Returns the difference of `x` and `y`, `x -% y`. Wraps on underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat16.subWrap(1, 2); // => 65535\n /// (1 : Nat16) -% (2 : Nat16) // => 65535\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `-%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `-%`\n /// as a function value at the moment.\n public func subWrap(x : Nat16, y : Nat16) : Nat16 { x -% y };\n\n /// Returns the product of `x` and `y`, `x *% y`. Wraps on overflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat16.mulWrap(655, 101); // => 619\n /// (655 : Nat16) *% (101 : Nat16) // => 619\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `*%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `*%`\n /// as a function value at the moment.\n public func mulWrap(x : Nat16, y : Nat16) : Nat16 { x *% y };\n\n /// Returns `x` to the power of `y`, `x **% y`. Wraps on overflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat16.powWrap(2, 16); // => 0\n /// (2 : Nat16) **% (16 : Nat16) // => 0\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `**%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `**%`\n /// as a function value at the moment.\n public func powWrap(x : Nat16, y : Nat16) : Nat16 { 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 /// Converts an upper cased `#Ok`, `#Err` result type into a lowercased `#ok`, `#err` result type.\n /// On the IC, a common convention is to use `#Ok` and `#Err` as the variants of a result type,\n /// but in Motoko, we use `#ok` and `#err` instead.\n public func fromUpper<Ok, Err>(\n result : { #Ok: Ok; #Err: Err }\n ) : Result<Ok, Err> {\n switch result {\n case (#Ok(ok)) { #ok(ok) };\n case (#Err(err)) { #err(err) }\n }\n };\n\n /// Converts a lower cased `#ok`, `#err` result type into an upper cased `#Ok`, `#Err` result type.\n /// On the IC, a common convention is to use `#Ok` and `#Err` as the variants of a result type,\n /// but in Motoko, we use `#ok` and `#err` instead.\n public func toUpper<Ok, Err>(\n result : Result<Ok, Err>\n ) : { #Ok: Ok; #Err: Err } {\n switch result {\n case (#ok(ok)) { #Ok(ok) };\n case (#err(err)) { #Err(err) }\n }\n };\n\n}\n"},"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 /// Returns true if the optional arguments are equal according to the equality function provided, otherwise returns false.\n public func equal<A>(x : ?A, y : ?A, eq : (A, A) -> Bool) : Bool = switch (x, y) {\n case (null, null) { true };\n case (?x_, ?y_) { eq(x_, y_) };\n case (_, _) { false }\n };\n\n /// Asserts that the value is not `null`; fails otherwise.\n /// @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"},"Int64.mo":{"content":"/// Provides utility functions on 64-bit signed integers.\n///\n/// Note that most operations are available as built-in operators (e.g. `1 + 1`).\n///\n/// Import from the base library to use this module.\n/// ```motoko name=import\n/// import Int64 \"mo:base/Int64\";\n/// ```\n\nimport Int \"Int\";\nimport Prim \"mo:⛔\";\n\nmodule {\n\n /// 64-bit signed integers.\n public type Int64 = Prim.Types.Int64;\n\n /// Minimum 64-bit integer value, `-2 ** 63`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int64.minimumValue // => -9_223_372_036_854_775_808\n /// ```\n public let minimumValue = -9_223_372_036_854_775_808 : Int64;\n\n /// Maximum 64-bit integer value, `+2 ** 63 - 1`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int64.maximumValue // => +9_223_372_036_854_775_807\n /// ```\n public let maximumValue = 9_223_372_036_854_775_807 : Int64;\n\n /// Converts a 64-bit signed integer to a signed integer with infinite precision.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int64.toInt(123_456) // => 123_456 : Int\n /// ```\n public let toInt : Int64 -> Int = Prim.int64ToInt;\n\n /// Converts a signed integer with infinite precision to a 64-bit signed integer.\n ///\n /// Traps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int64.fromInt(123_456) // => +123_456 : Int64\n /// ```\n public let fromInt : Int -> Int64 = Prim.intToInt64;\n\n /// Converts a 32-bit signed integer to a 64-bit signed integer.\n ///\n /// Traps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int64.fromInt32(-123_456) // => -123_456 : Int64\n /// ```\n public let fromInt32 : Int32 -> Int64 = Prim.int32ToInt64;\n\n /// Converts a 64-bit signed integer to a 32-bit signed integer.\n ///\n /// Wraps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int64.toInt32(-123_456) // => -123_456 : Int32\n /// ```\n public let toInt32 : Int64 -> Int32 = Prim.int64ToInt32;\n\n /// Converts a signed integer with infinite precision to a 64-bit signed integer.\n ///\n /// Wraps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int64.fromIntWrap(-123_456) // => -123_456 : Int64\n /// ```\n public let fromIntWrap : Int -> Int64 = Prim.intToInt64Wrap;\n\n /// Converts an unsigned 64-bit integer to a signed 64-bit integer.\n ///\n /// Wraps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int64.fromNat64(123_456) // => +123_456 : Int64\n /// ```\n public let fromNat64 : Nat64 -> Int64 = Prim.nat64ToInt64;\n\n /// Converts a signed 64-bit integer to an unsigned 64-bit integer.\n ///\n /// Wraps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int64.toNat64(-1) // => 18_446_744_073_709_551_615 : Nat64 // underflow\n /// ```\n public let toNat64 : Int64 -> Nat64 = Prim.int64ToNat64;\n\n /// Returns the Text representation of `x`. Textual representation _do not_\n /// contain underscores to represent commas.\n ///\n ///\n /// Example:\n /// ```motoko include=import\n /// Int64.toText(-123456) // => \"-123456\"\n /// ```\n public func toText(x : Int64) : Text {\n Int.toText(toInt(x))\n };\n\n /// Returns the absolute value of `x`.\n ///\n /// Traps when `x == -2 ** 63` (the minimum `Int64` value).\n ///\n /// Example:\n /// ```motoko include=import\n /// Int64.abs(-123456) // => +123_456\n /// ```\n public func abs(x : Int64) : Int64 {\n fromInt(Int.abs(toInt(x)))\n };\n\n /// Returns the minimum of `x` and `y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int64.min(+2, -3) // => -3\n /// ```\n public func min(x : Int64, y : Int64) : Int64 {\n if (x < y) { x } else { y }\n };\n\n /// Returns the maximum of `x` and `y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int64.max(+2, -3) // => +2\n /// ```\n public func max(x : Int64, y : Int64) : Int64 {\n if (x < y) { y } else { x }\n };\n\n /// Equality function for Int64 types.\n /// This is equivalent to `x == y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int64.equal(-1, -1); // => true\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `==` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `==`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Buffer \"mo:base/Buffer\";\n ///\n /// let buffer1 = Buffer.Buffer<Int64>(1);\n /// buffer1.add(-3);\n /// let buffer2 = Buffer.Buffer<Int64>(1);\n /// buffer2.add(-3);\n /// Buffer.equal(buffer1, buffer2, Int64.equal) // => true\n /// ```\n public func equal(x : Int64, y : Int64) : Bool { x == y };\n\n /// Inequality function for Int64 types.\n /// This is equivalent to `x != y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int64.notEqual(-1, -2); // => true\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `!=` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `!=`\n /// as a function value at the moment.\n public func notEqual(x : Int64, y : Int64) : Bool { x != y };\n\n /// \"Less than\" function for Int64 types.\n /// This is equivalent to `x < y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int64.less(-2, 1); // => true\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<`\n /// as a function value at the moment.\n public func less(x : Int64, y : Int64) : Bool { x < y };\n\n /// \"Less than or equal\" function for Int64 types.\n /// This is equivalent to `x <= y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int64.lessOrEqual(-2, -2); // => true\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<=` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<=`\n /// as a function value at the moment.\n public func lessOrEqual(x : Int64, y : Int64) : Bool { x <= y };\n\n /// \"Greater than\" function for Int64 types.\n /// This is equivalent to `x > y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int64.greater(-2, -3); // => true\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `>` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `>`\n /// as a function value at the moment.\n public func greater(x : Int64, y : Int64) : Bool { x > y };\n\n /// \"Greater than or equal\" function for Int64 types.\n /// This is equivalent to `x >= y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int64.greaterOrEqual(-2, -2); // => true\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `>=` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `>=`\n /// as a function value at the moment.\n public func greaterOrEqual(x : Int64, y : Int64) : Bool { x >= y };\n\n /// General-purpose comparison function for `Int64`. Returns the `Order` (\n /// either `#less`, `#equal`, or `#greater`) of comparing `x` with `y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int64.compare(-3, 2) // => #less\n /// ```\n ///\n /// This function can be used as value for a high order function, such as a sort function.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.sort([1, -2, -3] : [Int64], Int64.compare) // => [-3, -2, 1]\n /// ```\n public func compare(x : Int64, y : Int64) : { #less; #equal; #greater } {\n if (x < y) { #less } else if (x == y) { #equal } else { #greater }\n };\n\n /// Returns the negation of `x`, `-x`.\n ///\n /// Traps on overflow, i.e. for `neg(-2 ** 63)`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int64.neg(123) // => -123\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `-` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `-`\n /// as a function value at the moment.\n public func neg(x : Int64) : Int64 { -x };\n\n /// Returns the sum of `x` and `y`, `x + y`.\n ///\n /// Traps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int64.add(1234, 123) // => +1_357\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `+` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `+`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.foldLeft<Int64, Int64>([1, -2, -3], 0, Int64.add) // => -4\n /// ```\n public func add(x : Int64, y : Int64) : Int64 { x + y };\n\n /// Returns the difference of `x` and `y`, `x - y`.\n ///\n /// Traps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int64.sub(123, 100) // => +23\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `-` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `-`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.foldLeft<Int64, Int64>([1, -2, -3], 0, Int64.sub) // => 4\n /// ```\n public func sub(x : Int64, y : Int64) : Int64 { x - y };\n\n /// Returns the product of `x` and `y`, `x * y`.\n ///\n /// Traps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int64.mul(123, 10) // => +1_230\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `*` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `*`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.foldLeft<Int64, Int64>([1, -2, -3], 1, Int64.mul) // => 6\n /// ```\n public func mul(x : Int64, y : Int64) : Int64 { x * y };\n\n /// Returns the signed integer division of `x` by `y`, `x / y`.\n /// Rounds the quotient towards zero, which is the same as truncating the decimal places of the quotient.\n ///\n /// Traps when `y` is zero.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int64.div(123, 10) // => +12\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `/` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `/`\n /// as a function value at the moment.\n public func div(x : Int64, y : Int64) : Int64 { x / y };\n\n /// Returns the remainder of the signed integer division of `x` by `y`, `x % y`,\n /// which is defined as `x - x / y * y`.\n ///\n /// Traps when `y` is zero.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int64.rem(123, 10) // => +3\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `%`\n /// as a function value at the moment.\n public func rem(x : Int64, y : Int64) : Int64 { x % y };\n\n /// Returns `x` to the power of `y`, `x ** y`.\n ///\n /// Traps on overflow/underflow and when `y < 0 or y >= 64`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int64.pow(2, 10) // => +1_024\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `**` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `**`\n /// as a function value at the moment.\n public func pow(x : Int64, y : Int64) : Int64 { x ** y };\n\n /// Returns the bitwise negation of `x`, `^x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int64.bitnot(-256 /* 0xffff_ffff_ffff_ff00 */) // => +255 // 0xff\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `^` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `^`\n /// as a function value at the moment.\n public func bitnot(x : Int64) : Int64 { ^x };\n\n /// Returns the bitwise \"and\" of `x` and `y`, `x & y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int64.bitand(0xffff, 0x00f0) // => +240 // 0xf0\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `&` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `&`\n /// as a function value at the moment.\n public func bitand(x : Int64, y : Int64) : Int64 { x & y };\n\n /// Returns the bitwise \"or\" of `x` and `y`, `x | y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int64.bitor(0xffff, 0x00f0) // => +65_535 // 0xffff\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `|` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `|`\n /// as a function value at the moment.\n public func bitor(x : Int64, y : Int64) : Int64 { x | y };\n\n /// Returns the bitwise \"exclusive or\" of `x` and `y`, `x ^ y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int64.bitxor(0xffff, 0x00f0) // => +65_295 // 0xff0f\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `^` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `^`\n /// as a function value at the moment.\n public func bitxor(x : Int64, y : Int64) : Int64 { x ^ y };\n\n /// Returns the bitwise left shift of `x` by `y`, `x << y`.\n /// The right bits of the shift filled with zeros.\n /// Left-overflowing bits, including the sign bit, are discarded.\n ///\n /// For `y >= 64`, the semantics is the same as for `bitshiftLeft(x, y % 64)`.\n /// For `y < 0`, the semantics is the same as for `bitshiftLeft(x, y + y % 64)`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int64.bitshiftLeft(1, 8) // => +256 // 0x100 equivalent to `2 ** 8`.\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<<` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<<`\n /// as a function value at the moment.\n public func bitshiftLeft(x : Int64, y : Int64) : Int64 { x << y };\n\n /// Returns the signed bitwise right shift of `x` by `y`, `x >> y`.\n /// The sign bit is retained and the left side is filled with the sign bit.\n /// Right-underflowing bits are discarded, i.e. not rotated to the left side.\n ///\n /// For `y >= 64`, the semantics is the same as for `bitshiftRight(x, y % 64)`.\n /// For `y < 0`, the semantics is the same as for `bitshiftRight (x, y + y % 64)`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int64.bitshiftRight(1024, 8) // => +4 // equivalent to `1024 / (2 ** 8)`\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `>>` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `>>`\n /// as a function value at the moment.\n public func bitshiftRight(x : Int64, y : Int64) : Int64 { x >> y };\n\n /// Returns the bitwise left rotatation of `x` by `y`, `x <<> y`.\n /// Each left-overflowing bit is inserted again on the right side.\n /// The sign bit is rotated like other bits, i.e. the rotation interprets the number as unsigned.\n ///\n /// Changes the direction of rotation for negative `y`.\n /// For `y >= 64`, the semantics is the same as for `bitrotLeft(x, y % 64)`.\n ///\n /// Example:\n /// ```motoko include=import\n ///\n /// Int64.bitrotLeft(0x2000_0000_0000_0001, 4) // => +18 // 0x12.\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<<>` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<<>`\n /// as a function value at the moment.\n public func bitrotLeft(x : Int64, y : Int64) : Int64 { x <<> y };\n\n /// Returns the bitwise right rotation of `x` by `y`, `x <>> y`.\n /// Each right-underflowing bit is inserted again on the right side.\n /// The sign bit is rotated like other bits, i.e. the rotation interprets the number as unsigned.\n ///\n /// Changes the direction of rotation for negative `y`.\n /// For `y >= 64`, the semantics is the same as for `bitrotRight(x, y % 64)`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int64.bitrotRight(0x0002_0000_0000_0001, 48) // => +65538 // 0x1_0002.\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<>>` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<>>`\n /// as a function value at the moment.\n public func bitrotRight(x : Int64, y : Int64) : Int64 { x <>> y };\n\n /// Returns the value of bit `p` in `x`, `x & 2**p == 2**p`.\n /// If `p >= 64`, the semantics is the same as for `bittest(x, p % 64)`.\n /// This is equivalent to checking if the `p`-th bit is set in `x`, using 0 indexing.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int64.bittest(128, 7) // => true\n /// ```\n public func bittest(x : Int64, p : Nat) : Bool {\n Prim.btstInt64(x, Prim.intToInt64(p))\n };\n\n /// Returns the value of setting bit `p` in `x` to `1`.\n /// If `p >= 64`, the semantics is the same as for `bitset(x, p % 64)`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int64.bitset(0, 7) // => +128\n /// ```\n public func bitset(x : Int64, p : Nat) : Int64 {\n x | (1 << Prim.intToInt64(p))\n };\n\n /// Returns the value of clearing bit `p` in `x` to `0`.\n /// If `p >= 64`, the semantics is the same as for `bitclear(x, p % 64)`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int64.bitclear(-1, 7) // => -129\n /// ```\n public func bitclear(x : Int64, p : Nat) : Int64 {\n x & ^(1 << Prim.intToInt64(p))\n };\n\n /// Returns the value of flipping bit `p` in `x`.\n /// If `p >= 64`, the semantics is the same as for `bitclear(x, p % 64)`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int64.bitflip(255, 7) // => +127\n /// ```\n public func bitflip(x : Int64, p : Nat) : Int64 {\n x ^ (1 << Prim.intToInt64(p))\n };\n\n /// Returns the count of non-zero bits in `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int64.bitcountNonZero(0xffff) // => +16\n /// ```\n public let bitcountNonZero : (x : Int64) -> Int64 = Prim.popcntInt64;\n\n /// Returns the count of leading zero bits in `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int64.bitcountLeadingZero(0x8000_0000) // => +32\n /// ```\n public let bitcountLeadingZero : (x : Int64) -> Int64 = Prim.clzInt64;\n\n /// Returns the count of trailing zero bits in `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int64.bitcountTrailingZero(0x0201_0000) // => +16\n /// ```\n public let bitcountTrailingZero : (x : Int64) -> Int64 = Prim.ctzInt64;\n\n /// Returns the upper (i.e. most significant), lower (least significant)\n /// and in-between bytes of `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int64.explode 0x33772266aa885511 // => (51, 119, 34, 102, 170, 136, 85, 17)\n /// ```\n public let explode : (x : Int64) -> (msb : Nat8, Nat8, Nat8, Nat8, Nat8, Nat8, Nat8, lsb : Nat8) = Prim.explodeInt64;\n\n /// Returns the sum of `x` and `y`, `x +% y`.\n ///\n /// Wraps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int64.addWrap(2 ** 62, 2 ** 62) // => -9_223_372_036_854_775_808 // overflow\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `+%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `+%`\n /// as a function value at the moment.\n public func addWrap(x : Int64, y : Int64) : Int64 { x +% y };\n\n /// Returns the difference of `x` and `y`, `x -% y`.\n ///\n /// Wraps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int64.subWrap(-2 ** 63, 1) // => +9_223_372_036_854_775_807 // underflow\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `-%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `-%`\n /// as a function value at the moment.\n public func subWrap(x : Int64, y : Int64) : Int64 { x -% y };\n\n /// Returns the product of `x` and `y`, `x *% y`. Wraps on overflow.\n ///\n /// Wraps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int64.mulWrap(2 ** 32, 2 ** 32) // => 0 // overflow\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `*%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `*%`\n /// as a function value at the moment.\n public func mulWrap(x : Int64, y : Int64) : Int64 { x *% y };\n\n /// Returns `x` to the power of `y`, `x **% y`.\n ///\n /// Wraps on overflow/underflow.\n /// Traps if `y < 0 or y >= 64`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int64.powWrap(2, 63) // => -9_223_372_036_854_775_808 // overflow\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `**%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `**%`\n /// as a function value at the moment.\n public func powWrap(x : Int64, y : Int64) : Int64 { x **% y }\n}\n"},"OrderedMap.mo":{"content":"/// Stable key-value map implemented as a red-black tree with nodes storing key-value pairs.\n///\n/// A red-black tree is a balanced binary search tree ordered by the keys.\n///\n/// The tree data structure internally colors each of its nodes either red or black,\n/// and uses this information to balance the tree during the modifying operations.\n///\n/// Performance:\n/// * Runtime: `O(log(n))` worst case cost per insertion, removal, and retrieval operation.\n/// * Space: `O(n)` for storing the entire tree.\n/// `n` denotes the number of key-value entries (i.e. nodes) stored in the tree.\n///\n/// Note:\n/// * Map operations, such as retrieval, insertion, and removal create `O(log(n))` temporary objects that become garbage.\n///\n/// Credits:\n///\n/// The core of this implementation is derived from:\n///\n/// * Ken Friis Larsen's [RedBlackMap.sml](https://github.com/kfl/mosml/blob/master/src/mosmllib/Redblackmap.sml), which itself is based on:\n/// * Stefan Kahrs, \"Red-black trees with types\", Journal of Functional Programming, 11(4): 425-432 (2001), [version 1 in web appendix](http://www.cs.ukc.ac.uk/people/staff/smk/redblack/rb.html).\n\nimport Debug \"Debug\";\nimport I \"Iter\";\nimport List \"List\";\nimport Nat \"Nat\";\nimport O \"Order\";\n\nmodule {\n /// Collection of key-value entries, ordered by the keys and key unique.\n /// The keys have the generic type `K` and the values the generic type `V`.\n /// If `K` and `V` is stable types then `Map<K, V>` is also stable. \n /// To ensure that property the `Map<K, V>` does not have any methods, instead \n /// they are gathered in the functor-like class `Operations` (see example there).\n public type Map<K, V> = {\n size : Nat;\n root : Tree<K, V>\n };\n\n // Note: Leaves are considered implicitly black.\n type Tree<K, V> = {\n #red : (Tree<K, V>, K, V, Tree<K, V>);\n #black : (Tree<K, V>, K, V, Tree<K, V>);\n #leaf\n };\n\n /// Class that captures key type `K` along with its ordering function `compare` \n /// and provides all operations to work with a map of type `Map<K, _>`.\n ///\n /// An instance object should be created once as a canister field to ensure \n /// that the same ordering function is used for every operation.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:base/OrderedMap\";\n /// import Nat \"mo:base/Nat\";\n ///\n /// actor {\n /// let natMap = Map.Make<Nat>(Nat.compare); // : Operations<Nat>\n /// stable var keyStorage : Map.Map<Nat, Text> = natMap.empty<Text>();\n /// \n /// public func addKey(id : Nat, key : Text) : async () {\n /// keyStorage := natMap.put(keyStorage, id, key);\n /// }\n /// }\n /// ```\n public class Operations<K>(compare : (K, K) -> O.Order) {\n\n /// Returns a new map, containing all entries given by the iterator `i`.\n /// If there are multiple entries with the same key the last one is taken.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:base/OrderedMap\";\n /// import Nat \"mo:base/Nat\";\n /// import Iter \"mo:base/Iter\";\n /// import Debug \"mo:base/Debug\";\n ///\n /// let natMap = Map.Make<Nat>(Nat.compare);\n /// let m = natMap.fromIter<Text>(Iter.fromArray([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")]));\n ///\n /// Debug.print(debug_show(Iter.toArray(natMap.entries(m))));\n ///\n /// // [(0, \"Zero\"), (1, \"One\"), (2, \"Two\")]\n /// ```\n ///\n /// Runtime: `O(n * log(n))`.\n /// Space: `O(n)` retained memory plus garbage, see the note below.\n /// where `n` denotes the number of key-value entries stored in the map and\n /// assuming that the `compare` function implements an `O(1)` comparison.\n ///\n /// Note: Creates `O(n * log(n))` temporary objects that will be collected as garbage.\n public func fromIter<V>(i : I.Iter<(K, V)>) : Map<K, V>\n = Internal.fromIter(i, compare);\n\n /// Insert the value `value` with key `key` into the map `m`. Overwrites any existing entry with key `key`.\n /// Returns a modified map.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:base/OrderedMap\";\n /// import Nat \"mo:base/Nat\";\n /// import Iter \"mo:base/Iter\";\n /// import Debug \"mo:base/Debug\";\n ///\n /// let natMap = Map.Make<Nat>(Nat.compare);\n /// var map = natMap.empty<Text>();\n ///\n /// map := natMap.put(map, 0, \"Zero\");\n /// map := natMap.put(map, 2, \"Two\");\n /// map := natMap.put(map, 1, \"One\");\n ///\n /// Debug.print(debug_show(Iter.toArray(natMap.entries(map))));\n ///\n /// // [(0, \"Zero\"), (1, \"One\"), (2, \"Two\")]\n /// ```\n ///\n /// Runtime: `O(log(n))`.\n /// Space: `O(log(n))`.\n /// where `n` denotes the number of key-value entries stored in the map and\n /// assuming that the `compare` function implements an `O(1)` comparison.\n /// \n /// Note: The returned map shares with the `m` most of the tree nodes. \n /// Garbage collecting one of maps (e.g. after an assignment `m := natMap.put(m, k)`)\n /// causes collecting `O(log(n))` nodes.\n public func put<V>(m : Map<K, V>, key : K, value : V) : Map<K, V>\n = replace(m, key, value).0;\n\n /// Insert the value `value` with key `key` into the map `m`. Returns modified map and\n /// the previous value associated with key `key` or `null` if no such value exists.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:base/OrderedMap\";\n /// import Nat \"mo:base/Nat\";\n /// import Iter \"mo:base/Iter\";\n /// import Debug \"mo:base/Debug\";\n ///\n /// let natMap = Map.Make<Nat>(Nat.compare);\n /// let map0 = natMap.fromIter<Text>(Iter.fromArray([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")]));\n ///\n /// let (map1, old1) = natMap.replace(map0, 0, \"Nil\");\n ///\n /// Debug.print(debug_show(Iter.toArray(natMap.entries(map1))));\n /// Debug.print(debug_show(old1));\n /// // [(0, \"Nil\"), (1, \"One\"), (2, \"Two\")]\n /// // ?\"Zero\"\n ///\n /// let (map2, old2) = natMap.replace(map0, 3, \"Three\");\n ///\n /// Debug.print(debug_show(Iter.toArray(natMap.entries(map2))));\n /// Debug.print(debug_show(old2));\n /// // [(0, \"Zero\"), (1, \"One\"), (2, \"Two\"), (3, \"Three\")]\n /// // null\n /// ```\n ///\n /// Runtime: `O(log(n))`.\n /// Space: `O(log(n))` retained memory plus garbage, see the note below.\n /// where `n` denotes the number of key-value entries stored in the map and\n /// assuming that the `compare` function implements an `O(1)` comparison.\n ///\n /// Note: The returned map shares with the `m` most of the tree nodes. \n /// Garbage collecting one of maps (e.g. after an assignment `m := natMap.replace(m, k).0`)\n /// causes collecting `O(log(n))` nodes.\n public func replace<V>(m : Map<K, V>, key : K, value : V) : (Map<K, V>, ?V) {\n switch (Internal.replace(m.root, compare, key, value)) {\n case (t, null) { ({root = t; size = m.size + 1}, null) };\n case (t, v) { ({root = t; size = m.size}, v)}\n }\n };\n\n /// Creates a new map by applying `f` to each entry in the map `m`. For each entry\n /// `(k, v)` in the old map, if `f` evaluates to `null`, the entry is discarded.\n /// Otherwise, the entry is transformed into a new entry `(k, v2)`, where\n /// the new value `v2` is the result of applying `f` to `(k, v)`.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:base/OrderedMap\";\n /// import Nat \"mo:base/Nat\";\n /// import Iter \"mo:base/Iter\";\n /// import Debug \"mo:base/Debug\";\n ///\n /// let natMap = Map.Make<Nat>(Nat.compare);\n /// let map = natMap.fromIter<Text>(Iter.fromArray([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")]));\n ///\n /// func f(key : Nat, val : Text) : ?Text {\n /// if(key == 0) {null}\n /// else { ?(\"Twenty \" # val)}\n /// };\n ///\n /// let newMap = natMap.mapFilter(map, f);\n ///\n /// Debug.print(debug_show(Iter.toArray(natMap.entries(newMap))));\n ///\n /// // [(1, \"Twenty One\"), (2, \"Twenty Two\")]\n /// ```\n ///\n /// Runtime: `O(n * log(n))`.\n /// Space: `O(n)` retained memory plus garbage, see the note below.\n /// where `n` denotes the number of key-value entries stored in the map and\n /// assuming that the `compare` function implements an `O(1)` comparison.\n ///\n /// Note: Creates `O(n * log(n))` temporary objects that will be collected as garbage.\n public func mapFilter<V1, V2>(m : Map<K, V1>, f : (K, V1) -> ?V2) : Map<K, V2>\n = Internal.mapFilter(m, compare, f);\n\n /// Get the value associated with key `key` in the given map `m` if present and `null` otherwise.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:base/OrderedMap\";\n /// import Nat \"mo:base/Nat\";\n /// import Iter \"mo:base/Iter\";\n /// import Debug \"mo:base/Debug\";\n ///\n /// let natMap = Map.Make<Nat>(Nat.compare);\n /// let map = natMap.fromIter<Text>(Iter.fromArray([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")]));\n ///\n /// Debug.print(debug_show(natMap.get(map, 1)));\n /// Debug.print(debug_show(natMap.get(map, 42)));\n ///\n /// // ?\"One\"\n /// // null\n /// ```\n ///\n /// Runtime: `O(log(n))`.\n /// Space: `O(1)`.\n /// where `n` denotes the number of key-value entries stored in the map and\n /// assuming that the `compare` function implements an `O(1)` comparison.\n public func get<V>(m : Map<K, V>, key : K) : ?V\n = Internal.get(m.root, compare, key);\n\n /// Test whether the map `m` contains any binding for the given `key`.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:base/OrderedMap\";\n /// import Nat \"mo:base/Nat\";\n /// import Iter \"mo:base/Iter\";\n /// import Debug \"mo:base/Debug\";\n ///\n /// let natMap = Map.Make<Nat>(Nat.compare);\n /// let map = natMap.fromIter<Text>(Iter.fromArray([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")]));\n ///\n /// Debug.print(debug_show natMap.contains(map, 1)); // => true\n /// Debug.print(debug_show natMap.contains(map, 42)); // => false\n /// ```\n ///\n /// Runtime: `O(log(n))`.\n /// Space: `O(1)`.\n /// where `n` denotes the number of key-value entries stored in the map and\n /// assuming that the `compare` function implements an `O(1)` comparison.\n public func contains<V>(m: Map<K, V>, key: K) : Bool \n = Internal.contains(m.root, compare, key);\n\n /// Retrieves a key-value pair from the map `m` with a maximal key. If the map is empty returns `null`.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:base/OrderedMap\";\n /// import Nat \"mo:base/Nat\";\n /// import Iter \"mo:base/Iter\";\n /// import Debug \"mo:base/Debug\";\n ///\n /// let natMap = Map.Make<Nat>(Nat.compare);\n /// let map = natMap.fromIter<Text>(Iter.fromArray([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")]));\n ///\n /// Debug.print(debug_show(natMap.maxEntry(map))); // => ?(2, \"Two\")\n /// Debug.print(debug_show(natMap.maxEntry(natMap.empty()))); // => null\n /// ```\n ///\n /// Runtime: `O(log(n))`.\n /// Space: `O(1)`.\n /// where `n` denotes the number of key-value entries stored in the map.\n public func maxEntry<V>(m: Map<K, V>) : ?(K, V)\n = Internal.maxEntry(m.root);\n\n /// Retrieves a key-value pair from the map `m` with a minimal key. If the map is empty returns `null`.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:base/OrderedMap\";\n /// import Iter \"mo:base/Iter\";\n /// import Nat \"mo:base/Nat\";\n /// import Debug \"mo:base/Debug\";\n ///\n /// let natMap = Map.Make<Nat>(Nat.compare);\n /// let map = natMap.fromIter<Text>(Iter.fromArray([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")]));\n ///\n /// Debug.print(debug_show(natMap.minEntry(map))); // => ?(0, \"Zero\")\n /// Debug.print(debug_show(natMap.minEntry(natMap.empty()))); // => null\n /// ```\n ///\n /// Runtime: `O(log(n))`.\n /// Space: `O(1)`.\n /// where `n` denotes the number of key-value entries stored in the map.\n public func minEntry<V>(m : Map<K, V>) : ?(K, V)\n = Internal.minEntry(m.root);\n\n /// Deletes the entry with the key `key` from the map `m`. Has no effect if `key` is not\n /// present in the map. Returns modified map.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:base/OrderedMap\";\n /// import Nat \"mo:base/Nat\";\n /// import Iter \"mo:base/Iter\";\n /// import Debug \"mo:base/Debug\";\n ///\n /// let natMap = Map.Make<Nat>(Nat.compare);\n /// let map = natMap.fromIter<Text>(Iter.fromArray([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")]));\n ///\n /// Debug.print(debug_show(Iter.toArray(natMap.entries(natMap.delete(map, 1)))));\n /// Debug.print(debug_show(Iter.toArray(natMap.entries(natMap.delete(map, 42)))));\n ///\n /// // [(0, \"Zero\"), (2, \"Two\")]\n /// // [(0, \"Zero\"), (1, \"One\"), (2, \"Two\")]\n /// ```\n ///\n /// Runtime: `O(log(n))`.\n /// Space: `O(log(n))`\n /// where `n` denotes the number of key-value entries stored in the map and\n /// assuming that the `compare` function implements an `O(1)` comparison.\n ///\n /// Note: The returned map shares with the `m` most of the tree nodes. \n /// Garbage collecting one of maps (e.g. after an assignment `m := natMap.delete(m, k).0`)\n /// causes collecting `O(log(n))` nodes.\n public func delete<V>(m : Map<K, V>, key : K) : Map<K, V>\n = remove(m, key).0;\n\n /// Deletes the entry with the key `key`. Returns modified map and the\n /// previous value associated with key `key` or `null` if no such value exists.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:base/OrderedMap\";\n /// import Nat \"mo:base/Nat\";\n /// import Iter \"mo:base/Iter\";\n /// import Debug \"mo:base/Debug\";\n ///\n /// let natMap = Map.Make<Nat>(Nat.compare);\n /// let map0 = natMap.fromIter<Text>(Iter.fromArray([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")]));\n ///\n /// let (map1, old1) = natMap.remove(map0, 0);\n ///\n /// Debug.print(debug_show(Iter.toArray(natMap.entries(map1))));\n /// Debug.print(debug_show(old1));\n /// // [(1, \"One\"), (2, \"Two\")]\n /// // ?\"Zero\"\n ///\n /// let (map2, old2) = natMap.remove(map0, 42);\n ///\n /// Debug.print(debug_show(Iter.toArray(natMap.entries(map2))));\n /// Debug.print(debug_show(old2));\n /// // [(0, \"Zero\"), (1, \"One\"), (2, \"Two\")]\n /// // null\n /// ```\n ///\n /// Runtime: `O(log(n))`.\n /// Space: `O(log(n))`.\n /// where `n` denotes the number of key-value entries stored in the map and\n /// assuming that the `compare` function implements an `O(1)` comparison.\n ///\n /// Note: The returned map shares with the `m` most of the tree nodes. \n /// Garbage collecting one of maps (e.g. after an assignment `m := natMap.remove(m, k)`)\n /// causes collecting `O(log(n))` nodes.\n public func remove<V>(m : Map<K, V>, key : K) : (Map<K, V>, ?V) {\n switch (Internal.remove(m.root, compare, key)) {\n case (t, null) { ({root = t; size = m.size }, null) };\n case (t, v) { ({root = t; size = m.size - 1}, v) }\n }\n };\n\n /// Create a new empty map.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:base/OrderedMap\";\n /// import Nat \"mo:base/Nat\";\n /// import Debug \"mo:base/Debug\";\n ///\n /// let natMap = Map.Make<Nat>(Nat.compare);\n ///\n /// let map = natMap.empty<Text>();\n ///\n /// Debug.print(debug_show(natMap.size(map)));\n ///\n /// // 0\n /// ```\n ///\n /// Cost of empty map creation\n /// Runtime: `O(1)`.\n /// Space: `O(1)`\n public func empty<V>() : Map<K, V> \n = Internal.empty();\n\n /// Returns an Iterator (`Iter`) over the key-value pairs in the map.\n /// Iterator provides a single method `next()`, which returns\n /// pairs in ascending order by keys, or `null` when out of pairs to iterate over.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:base/OrderedMap\";\n /// import Nat \"mo:base/Nat\";\n /// import Iter \"mo:base/Iter\";\n /// import Debug \"mo:base/Debug\";\n ///\n /// let natMap = Map.Make<Nat>(Nat.compare);\n /// let map = natMap.fromIter<Text>(Iter.fromArray([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")]));\n ///\n /// Debug.print(debug_show(Iter.toArray(natMap.entries(map))));\n /// // [(0, \"Zero\"), (1, \"One\"), (2, \"Two\")]\n /// var sum = 0;\n /// for ((k, _) in natMap.entries(map)) { sum += k; };\n /// Debug.print(debug_show(sum)); // => 3\n /// ```\n /// Cost of iteration over all elements:\n /// Runtime: `O(n)`.\n /// Space: `O(log(n))` retained memory plus garbage, see the note below.\n /// where `n` denotes the number of key-value entries stored in the map.\n ///\n /// Note: Full map iteration creates `O(n)` temporary objects that will be collected as garbage.\n public func entries<V>(m : Map<K, V>) : I.Iter<(K, V)> \n = Internal.iter(m.root, #fwd);\n\n /// Same as `entries` but iterates in the descending order.\n public func entriesRev<V>(m : Map<K, V>) : I.Iter<(K, V)> \n = Internal.iter(m.root, #bwd);\n\n /// Returns an Iterator (`Iter`) over the keys of the map.\n /// Iterator provides a single method `next()`, which returns\n /// keys in ascending order, or `null` when out of keys to iterate over.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:base/OrderedMap\";\n /// import Nat \"mo:base/Nat\";\n /// import Iter \"mo:base/Iter\";\n /// import Debug \"mo:base/Debug\";\n ///\n /// let natMap = Map.Make<Nat>(Nat.compare);\n /// let map = natMap.fromIter<Text>(Iter.fromArray([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")]));\n ///\n /// Debug.print(debug_show(Iter.toArray(natMap.keys(map))));\n ///\n /// // [0, 1, 2]\n /// ```\n /// Cost of iteration over all elements:\n /// Runtime: `O(n)`.\n /// Space: `O(log(n))` retained memory plus garbage, see the note below.\n /// where `n` denotes the number of key-value entries stored in the map.\n ///\n /// Note: Full map iteration creates `O(n)` temporary objects that will be collected as garbage.\n public func keys<V>(m : Map<K, V>) : I.Iter<K>\n = I.map(entries(m), func(kv : (K, V)) : K {kv.0});\n\n\n /// Returns an Iterator (`Iter`) over the values of the map.\n /// Iterator provides a single method `next()`, which returns\n /// values in ascending order of associated keys, or `null` when out of values to iterate over.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:base/OrderedMap\";\n /// import Nat \"mo:base/Nat\";\n /// import Iter \"mo:base/Iter\";\n /// import Debug \"mo:base/Debug\";\n ///\n /// let natMap = Map.Make<Nat>(Nat.compare);\n /// let map = natMap.fromIter<Text>(Iter.fromArray([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")]));\n ///\n /// Debug.print(debug_show(Iter.toArray(natMap.vals(map))));\n ///\n /// // [\"Zero\", \"One\", \"Two\"]\n /// ```\n /// Cost of iteration over all elements:\n /// Runtime: `O(n)`.\n /// Space: `O(log(n))` retained memory plus garbage, see the note below.\n /// where `n` denotes the number of key-value entries stored in the map.\n ///\n /// Note: Full map iteration creates `O(n)` temporary objects that will be collected as garbage.\n public func vals<V>(m : Map<K, V>) : I.Iter<V>\n = I.map(entries(m), func(kv : (K, V)) : V {kv.1});\n\n /// Creates a new map by applying `f` to each entry in the map `m`. Each entry\n /// `(k, v)` in the old map is transformed into a new entry `(k, v2)`, where\n /// the new value `v2` is created by applying `f` to `(k, v)`.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:base/OrderedMap\";\n /// import Nat \"mo:base/Nat\";\n /// import Iter \"mo:base/Iter\";\n /// import Debug \"mo:base/Debug\";\n ///\n /// let natMap = Map.Make<Nat>(Nat.compare);\n /// let map = natMap.fromIter<Text>(Iter.fromArray([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")]));\n ///\n /// func f(key : Nat, _val : Text) : Nat = key * 2;\n ///\n /// let resMap = natMap.map(map, f);\n ///\n /// Debug.print(debug_show(Iter.toArray(natMap.entries(resMap))));\n /// // [(0, 0), (1, 2), (2, 4)]\n /// ```\n ///\n /// Cost of mapping all the elements:\n /// Runtime: `O(n)`.\n /// Space: `O(n)` retained memory\n /// where `n` denotes the number of key-value entries stored in the map.\n public func map<V1, V2>(m : Map<K, V1>, f : (K, V1) -> V2) : Map<K, V2>\n = Internal.map(m, f);\n\n /// Determine the size of the map as the number of key-value entries.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:base/OrderedMap\";\n /// import Nat \"mo:base/Nat\";\n /// import Iter \"mo:base/Iter\";\n /// import Debug \"mo:base/Debug\";\n ///\n /// let natMap = Map.Make<Nat>(Nat.compare);\n /// let map = natMap.fromIter<Text>(Iter.fromArray([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")]));\n ///\n /// Debug.print(debug_show(natMap.size(map)));\n /// // 3\n /// ```\n ///\n /// Runtime: `O(n)`.\n /// Space: `O(1)`.\n public func size<V>(m : Map<K, V>) : Nat\n = m.size;\n\n /// Collapses the elements in the `map` into a single value by starting with `base`\n /// and progressively combining keys and values into `base` with `combine`. Iteration runs\n /// left to right.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:base/OrderedMap\";\n /// import Nat \"mo:base/Nat\";\n /// import Iter \"mo:base/Iter\";\n /// import Debug \"mo:base/Debug\";\n ///\n /// let natMap = Map.Make<Nat>(Nat.compare);\n /// let map = natMap.fromIter<Text>(Iter.fromArray([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")]));\n ///\n /// func folder(accum : (Nat, Text), key : Nat, val : Text) : ((Nat, Text))\n /// = (key + accum.0, accum.1 # val);\n ///\n /// Debug.print(debug_show(natMap.foldLeft(map, (0, \"\"), folder)));\n ///\n /// // (3, \"ZeroOneTwo\")\n /// ```\n ///\n /// Cost of iteration over all elements:\n /// Runtime: `O(n)`.\n /// Space: depends on `combine` function plus garbage, see the note below.\n /// where `n` denotes the number of key-value entries stored in the map.\n ///\n /// Note: Full map iteration creates `O(n)` temporary objects that will be collected as garbage.\n public func foldLeft<Value, Accum>(\n map : Map<K, Value>,\n base : Accum,\n combine : (Accum, K, Value) -> Accum\n ) : Accum\n = Internal.foldLeft(map.root, base, combine);\n\n /// Collapses the elements in the `map` into a single value by starting with `base`\n /// and progressively combining keys and values into `base` with `combine`. Iteration runs\n /// right to left.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:base/OrderedMap\";\n /// import Nat \"mo:base/Nat\";\n /// import Iter \"mo:base/Iter\";\n /// import Debug \"mo:base/Debug\";\n ///\n /// let natMap = Map.Make<Nat>(Nat.compare);\n /// let map = natMap.fromIter<Text>(Iter.fromArray([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")]));\n ///\n /// func folder(key : Nat, val : Text, accum : (Nat, Text)) : ((Nat, Text))\n /// = (key + accum.0, accum.1 # val);\n ///\n /// Debug.print(debug_show(natMap.foldRight(map, (0, \"\"), folder)));\n ///\n /// // (3, \"TwoOneZero\")\n /// ```\n ///\n /// Cost of iteration over all elements:\n /// Runtime: `O(n)`.\n /// Space: depends on `combine` function plus garbage, see the note below.\n /// where `n` denotes the number of key-value entries stored in the map.\n ///\n /// Note: Full map iteration creates `O(n)` temporary objects that will be collected as garbage.\n public func foldRight<Value, Accum>(\n map : Map<K, Value>,\n base : Accum,\n combine : (K, Value, Accum) -> Accum\n ) : Accum\n = Internal.foldRight(map.root, base, combine);\n\n /// Test whether all key-value pairs satisfy a given predicate `pred`.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:base/OrderedMap\";\n /// import Nat \"mo:base/Nat\";\n /// import Iter \"mo:base/Iter\";\n /// import Debug \"mo:base/Debug\";\n ///\n /// let natMap = Map.Make<Nat>(Nat.compare);\n /// let map = natMap.fromIter<Text>(Iter.fromArray([(0, \"0\"), (2, \"2\"), (1, \"1\")]));\n ///\n /// Debug.print(debug_show(natMap.all<Text>(map, func (k, v) = (v == debug_show(k)))));\n /// // true\n /// Debug.print(debug_show(natMap.all<Text>(map, func (k, v) = (k < 2))));\n /// // false\n /// ```\n ///\n /// Runtime: `O(n)`.\n /// Space: `O(1)`.\n /// where `n` denotes the number of key-value entries stored in the map.\n public func all<V>(m : Map<K, V>, pred : (K, V) -> Bool) : Bool\n = Internal.all(m.root, pred);\n\n /// Test if there exists a key-value pair satisfying a given predicate `pred`.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:base/OrderedMap\";\n /// import Nat \"mo:base/Nat\";\n /// import Iter \"mo:base/Iter\";\n /// import Debug \"mo:base/Debug\";\n ///\n /// let natMap = Map.Make<Nat>(Nat.compare);\n /// let map = natMap.fromIter<Text>(Iter.fromArray([(0, \"0\"), (2, \"2\"), (1, \"1\")]));\n ///\n /// Debug.print(debug_show(natMap.some<Text>(map, func (k, v) = (k >= 3))));\n /// // false\n /// Debug.print(debug_show(natMap.some<Text>(map, func (k, v) = (k >= 0))));\n /// // true\n /// ```\n ///\n /// Runtime: `O(n)`.\n /// Space: `O(1)`.\n /// where `n` denotes the number of key-value entries stored in the map.\n public func some<V>(m : Map<K, V>, pred : (K, V) -> Bool) : Bool\n = Internal.some(m.root, pred);\n\n /// Debug helper that check internal invariants of the given map `m`. \n /// Raise an error (for a stack trace) if invariants are violated.\n public func validate<V>(m : Map<K, V>) : () {\n Internal.validate(m, compare);\n };\n };\n\n module Internal {\n\n public func empty<K, V>() : Map<K, V> {\n { size = 0; root = #leaf }\n };\n\n public func fromIter<K, V>(i : I.Iter<(K,V)>, compare : (K, K) -> O.Order) : Map<K, V> {\n var map = #leaf : Tree<K, V>;\n var size = 0;\n for(val in i) {\n map := put(map, compare, val.0, val.1);\n size += 1;\n };\n {root = map; size}\n };\n\n type IterRep<K, V> = List.List<{ #tr : Tree<K, V>; #xy : (K, V) }>;\n\n public func iter<K, V>(map : Tree<K, V>, direction : { #fwd; #bwd }) : I.Iter<(K, V)> {\n let turnLeftFirst : MapTraverser<K, V> = func(l, x, y, r, ts) {\n ?(#tr(l), ?(#xy(x, y), ?(#tr(r), ts)))\n };\n\n let turnRightFirst : MapTraverser<K, V> = func(l, x, y, r, ts) {\n ?(#tr(r), ?(#xy(x, y), ?(#tr(l), ts)))\n };\n\n switch direction {\n case (#fwd) IterMap(map, turnLeftFirst);\n case (#bwd) IterMap(map, turnRightFirst)\n }\n };\n\n type MapTraverser<K, V> = (Tree<K, V>, K, V, Tree<K, V>, IterRep<K, V>) -> IterRep<K, V>;\n\n class IterMap<K, V>(tree : Tree<K, V>, mapTraverser : MapTraverser<K, V>) {\n var trees : IterRep<K, V> = ?(#tr(tree), null);\n public func next() : ?(K, V) {\n switch (trees) {\n case (null) { null };\n case (?(#tr(#leaf), ts)) {\n trees := ts;\n next()\n };\n case (?(#xy(xy), ts)) {\n trees := ts;\n ?xy\n };\n case (?(#tr(#red(l, x, y, r)), ts)) {\n trees := mapTraverser(l, x, y, r, ts);\n next()\n };\n case (?(#tr(#black(l, x, y, r)), ts)) {\n trees := mapTraverser(l, x, y, r, ts);\n next()\n }\n }\n }\n };\n\n public func map<K, V1, V2>(map : Map<K, V1>, f : (K, V1) -> V2) : Map<K, V2> {\n func mapRec(m : Tree<K, V1>) : Tree<K, V2> {\n switch m {\n case (#leaf) { #leaf };\n case (#red(l, x, y, r)) {\n #red(mapRec l, x, f(x, y), mapRec r)\n };\n case (#black(l, x, y, r)) {\n #black(mapRec l, x, f(x, y), mapRec r)\n }\n }\n };\n { size = map.size; root = mapRec(map.root) }\n };\n\n public func foldLeft<Key, Value, Accum>(\n map : Tree<Key, Value>,\n base : Accum,\n combine : (Accum, Key, Value) -> Accum\n ) : Accum {\n switch (map) {\n case (#leaf) { base };\n case (#red(l, k, v, r)) {\n let left = foldLeft(l, base, combine);\n let middle = combine(left, k, v);\n foldLeft(r, middle, combine)\n };\n case (#black(l, k, v, r)) {\n let left = foldLeft(l, base, combine);\n let middle = combine(left, k, v);\n foldLeft(r, middle, combine)\n }\n }\n };\n\n public func foldRight<Key, Value, Accum>(\n map : Tree<Key, Value>,\n base : Accum,\n combine : (Key, Value, Accum) -> Accum\n ) : Accum {\n switch (map) {\n case (#leaf) { base };\n case (#red(l, k, v, r)) {\n let right = foldRight(r, base, combine);\n let middle = combine(k, v, right);\n foldRight(l, middle, combine)\n };\n case (#black(l, k, v, r)) {\n let right = foldRight(r, base, combine);\n let middle = combine(k, v, right);\n foldRight(l, middle, combine)\n }\n }\n };\n\n public func mapFilter<K, V1, V2>(map : Map<K, V1>, compare : (K, K) -> O.Order, f : (K, V1) -> ?V2) : Map<K, V2> {\n var size = 0;\n func combine(acc : Tree<K, V2>, key : K, value1 : V1) : Tree<K, V2> {\n switch (f(key, value1)) {\n case null { acc };\n case (?value2) {\n size += 1;\n put(acc, compare, key, value2)\n }\n }\n };\n { root = foldLeft(map.root, #leaf, combine); size }\n };\n\n public func get<K, V>(t : Tree<K, V>, compare : (K, K) -> O.Order, x : K) : ?V {\n switch t {\n case (#red(l, x1, y1, r)) {\n switch (compare(x, x1)) {\n case (#less) { get(l, compare, x) };\n case (#equal) { ?y1 };\n case (#greater) { get(r, compare, x) }\n }\n };\n case (#black(l, x1, y1, r)) {\n switch (compare(x, x1)) {\n case (#less) { get(l, compare, x) };\n case (#equal) { ?y1 };\n case (#greater) { get(r, compare, x) }\n }\n };\n case (#leaf) { null }\n }\n };\n\n public func contains<K, V>(m : Tree<K, V>, compare : (K, K) -> O.Order, key : K) : Bool {\n switch (get(m, compare, key)) {\n case(null) { false }; \n case(_) { true } \n }\n };\n\n public func maxEntry<K, V>(m : Tree<K, V>) : ?(K, V) {\n func rightmost(m : Tree<K, V>) : (K, V) {\n switch m {\n case (#red(_, k, v, #leaf)) { (k, v) };\n case (#red(_, _, _, r)) { rightmost(r) };\n case (#black(_, k, v, #leaf)) { (k, v) };\n case (#black(_, _, _, r)) { rightmost(r) };\n case (#leaf) { Debug.trap \"OrderedMap.impossible\" }\n }\n };\n switch m {\n case (#leaf) { null };\n case (_) { ?rightmost(m) }\n }\n };\n\n public func minEntry<K, V>(m : Tree<K, V>) : ?(K, V) {\n func leftmost(m : Tree<K, V>) : (K, V) {\n switch m {\n case (#red(#leaf, k, v, _)) { (k, v) };\n case (#red(l, _, _, _)) { leftmost(l) };\n case (#black(#leaf, k, v, _)) { (k, v) };\n case (#black(l, _, _, _)) { leftmost(l)};\n case (#leaf) { Debug.trap \"OrderedMap.impossible\" }\n }\n };\n switch m {\n case (#leaf) { null };\n case (_) { ?leftmost(m) }\n }\n };\n\n public func all<K, V>(m : Tree<K, V>, pred : (K, V) -> Bool) : Bool {\n switch m {\n case (#red(l, k, v, r)) {\n pred(k, v) and all(l, pred) and all(r, pred)\n };\n case (#black(l, k, v, r)) {\n pred(k, v) and all(l, pred) and all(r, pred)\n };\n case (#leaf) { true }\n }\n };\n\n public func some<K, V>(m : Tree<K, V>, pred : (K, V) -> Bool) : Bool {\n switch m {\n case (#red(l, k, v, r)) {\n pred(k, v) or some(l, pred) or some(r, pred)\n };\n case (#black(l, k, v, r)) {\n pred(k, v) or some(l, pred) or some(r, pred)\n };\n case (#leaf) { false }\n }\n };\n\n func redden<K, V>(t : Tree<K, V>) : Tree<K, V> {\n switch t {\n case (#black (l, x, y, r)) {\n (#red (l, x, y, r))\n };\n case _ {\n Debug.trap \"OrderedMap.red\"\n }\n }\n };\n\n func lbalance<K, V>(left : Tree<K, V>, x : K, y : V, right : Tree<K, V>) : Tree<K, V> {\n switch (left, right) {\n case (#red(#red(l1, x1, y1, r1), x2, y2, r2), r) {\n #red(\n #black(l1, x1, y1, r1),\n x2,\n y2,\n #black(r2, x, y, r)\n )\n };\n case (#red(l1, x1, y1, #red(l2, x2, y2, r2)), r) {\n #red(\n #black(l1, x1, y1, l2),\n x2,\n y2,\n #black(r2, x, y, r)\n )\n };\n case _ {\n #black(left, x, y, right)\n }\n }\n };\n\n func rbalance<K, V>(left : Tree<K, V>, x : K, y : V, right : Tree<K, V>) : Tree<K, V> {\n switch (left, right) {\n case (l, #red(l1, x1, y1, #red(l2, x2, y2, r2))) {\n #red(\n #black(l, x, y, l1),\n x1,\n y1,\n #black(l2, x2, y2, r2)\n )\n };\n case (l, #red(#red(l1, x1, y1, r1), x2, y2, r2)) {\n #red(\n #black(l, x, y, l1),\n x1,\n y1,\n #black(r1, x2, y2, r2)\n )\n };\n case _ {\n #black(left, x, y, right)\n }\n }\n };\n\n type ClashResolver<A> = { old : A; new : A } -> A;\n\n func insertWith<K, V>(\n m : Tree<K, V>,\n compare : (K, K) -> O.Order,\n key : K,\n val : V,\n onClash : ClashResolver<V>\n ) : Tree<K, V> {\n func ins(tree : Tree<K, V>) : Tree<K, V> {\n switch tree {\n case (#black(left, x, y, right)) {\n switch (compare(key, x)) {\n case (#less) {\n lbalance(ins left, x, y, right)\n };\n case (#greater) {\n rbalance(left, x, y, ins right)\n };\n case (#equal) {\n let newVal = onClash({ new = val; old = y });\n #black(left, key, newVal, right)\n }\n }\n };\n case (#red(left, x, y, right)) {\n switch (compare(key, x)) {\n case (#less) {\n #red(ins left, x, y, right)\n };\n case (#greater) {\n #red(left, x, y, ins right)\n };\n case (#equal) {\n let newVal = onClash { new = val; old = y };\n #red(left, key, newVal, right)\n }\n }\n };\n case (#leaf) {\n #red(#leaf, key, val, #leaf)\n }\n }\n };\n switch (ins m) {\n case (#red(left, x, y, right)) {\n #black(left, x, y, right)\n };\n case other { other }\n }\n };\n\n public func replace<K, V>(\n m : Tree<K, V>,\n compare : (K, K) -> O.Order,\n key : K,\n val : V\n ) : (Tree<K, V>, ?V) {\n var oldVal : ?V = null;\n func onClash(clash : { old : V; new : V }) : V {\n oldVal := ?clash.old;\n clash.new\n };\n let res = insertWith(m, compare, key, val, onClash);\n (res, oldVal)\n };\n\n public func put<K, V>(\n m : Tree<K, V>,\n compare : (K, K) -> O.Order,\n key : K,\n val : V\n ) : Tree<K, V> = replace(m, compare, key, val).0;\n\n func balLeft<K, V>(left : Tree<K, V>, x : K, y : V, right : Tree<K, V>) : Tree<K, V> {\n switch (left, right) {\n case (#red(l1, x1, y1, r1), r) {\n #red(\n #black(l1, x1, y1, r1),\n x,\n y,\n r\n )\n };\n case (_, #black(l2, x2, y2, r2)) {\n rbalance(left, x, y, #red(l2, x2, y2, r2))\n };\n case (_, #red(#black(l2, x2, y2, r2), x3, y3, r3)) {\n #red(\n #black(left, x, y, l2),\n x2,\n y2,\n rbalance(r2, x3, y3, redden r3)\n )\n };\n case _ { Debug.trap \"balLeft\" }\n }\n };\n\n func balRight<K, V>(left : Tree<K, V>, x : K, y : V, right : Tree<K, V>) : Tree<K, V> {\n switch (left, right) {\n case (l, #red(l1, x1, y1, r1)) {\n #red(\n l,\n x,\n y,\n #black(l1, x1, y1, r1)\n )\n };\n case (#black(l1, x1, y1, r1), r) {\n lbalance(#red(l1, x1, y1, r1), x, y, r)\n };\n case (#red(l1, x1, y1, #black(l2, x2, y2, r2)), r3) {\n #red(\n lbalance(redden l1, x1, y1, l2),\n x2,\n y2,\n #black(r2, x, y, r3)\n )\n };\n case _ { Debug.trap \"balRight\" }\n }\n };\n\n func append<K, V>(left : Tree<K, V>, right : Tree<K, V>) : Tree<K, V> {\n switch (left, right) {\n case (#leaf, _) { right };\n case (_, #leaf) { left };\n case (\n #red(l1, x1, y1, r1),\n #red(l2, x2, y2, r2)\n ) {\n switch (append(r1, l2)) {\n case (#red(l3, x3, y3, r3)) {\n #red(\n #red(l1, x1, y1, l3),\n x3,\n y3,\n #red(r3, x2, y2, r2)\n )\n };\n case r1l2 {\n #red(l1, x1, y1, #red(r1l2, x2, y2, r2))\n }\n }\n };\n case (t1, #red(l2, x2, y2, r2)) {\n #red(append(t1, l2), x2, y2, r2)\n };\n case (#red(l1, x1, y1, r1), t2) {\n #red(l1, x1, y1, append(r1, t2))\n };\n case (#black(l1, x1, y1, r1), #black(l2, x2, y2, r2)) {\n switch (append(r1, l2)) {\n case (#red(l3, x3, y3, r3)) {\n #red(\n #black(l1, x1, y1, l3),\n x3,\n y3,\n #black(r3, x2, y2, r2)\n )\n };\n case r1l2 {\n balLeft(\n l1,\n x1,\n y1,\n #black(r1l2, x2, y2, r2)\n )\n }\n }\n }\n }\n };\n\n public func delete<K, V>(m : Tree<K, V>, compare : (K, K) -> O.Order, key : K) : Tree<K, V>\n = remove(m, compare, key).0;\n\n public func remove<K, V>(tree : Tree<K, V>, compare : (K, K) -> O.Order, x : K) : (Tree<K, V>, ?V) {\n var y0 : ?V = null;\n func delNode(left : Tree<K, V>, x1 : K, y1 : V, right : Tree<K, V>) : Tree<K, V> {\n switch (compare(x, x1)) {\n case (#less) {\n let newLeft = del left;\n switch left {\n case (#black(_, _, _, _)) {\n balLeft(newLeft, x1, y1, right)\n };\n case _ {\n #red(newLeft, x1, y1, right)\n }\n }\n };\n case (#greater) {\n let newRight = del right;\n switch right {\n case (#black(_, _, _, _)) {\n balRight(left, x1, y1, newRight)\n };\n case _ {\n #red(left, x1, y1, newRight)\n }\n }\n };\n case (#equal) {\n y0 := ?y1;\n append(left, right)\n }\n }\n };\n func del(tree : Tree<K, V>) : Tree<K, V> {\n switch tree {\n case (#red(left, x, y, right)) {\n delNode(left, x, y, right)\n };\n case (#black(left, x, y, right)) {\n delNode(left, x, y, right)\n };\n case (#leaf) {\n tree\n }\n }\n };\n switch (del(tree)) {\n case (#red(left, x, y, right)) {\n (#black(left, x, y, right), y0)\n };\n case other { (other, y0) }\n }\n };\n\n // Test helper\n public func validate<K, V>(rbMap : Map<K, V>, comp : (K, K) -> O.Order) {\n ignore blackDepth(rbMap.root, comp)\n };\n\n func blackDepth<K, V>(node : Tree<K, V>, comp : (K, K) -> O.Order) : Nat {\n func checkNode(left : Tree<K, V>, key : K, right : Tree<K, V>) : Nat {\n checkKey(left, func(x : K) : Bool { comp(x, key) == #less });\n checkKey(right, func(x : K) : Bool { comp(x, key) == #greater });\n let leftBlacks = blackDepth(left, comp);\n let rightBlacks = blackDepth(right, comp);\n assert (leftBlacks == rightBlacks);\n leftBlacks\n };\n switch node {\n case (#leaf) 0;\n case (#red(left, key, _, right)) {\n let leftBlacks = checkNode(left, key, right);\n assert (not isRed(left));\n assert (not isRed(right));\n leftBlacks\n };\n case (#black(left, key, _, right)) {\n checkNode(left, key, right) + 1\n }\n }\n };\n\n func isRed<K, V>(node : Tree<K, V>) : Bool {\n switch node {\n case (#red(_, _, _, _)) true;\n case _ false\n }\n };\n\n func checkKey<K, V>(node : Tree<K, V>, isValid : K -> Bool) {\n switch node {\n case (#leaf) {};\n case (#red(_, key, _, _)) {\n assert (isValid(key))\n };\n case (#black(_, key, _, _)) {\n assert (isValid(key))\n }\n }\n };\n };\n\n /// Create `OrderedMap.Operations` object capturing key type `K` and `compare` function. \n /// It is an alias for the `Operations` constructor.\n ///\n /// Example:\n /// ```motoko\n /// import Map \"mo:base/OrderedMap\";\n /// import Nat \"mo:base/Nat\";\n ///\n /// actor {\n /// let natMap = Map.Make<Nat>(Nat.compare);\n /// stable var map : Map.Map<Nat, Text> = natMap.empty<Text>();\n /// };\n /// ```\n public let Make : <K>(compare : (K, K) -> O.Order) -> Operations<K> = Operations\n}\n"},"Int32.mo":{"content":"/// Provides utility functions on 32-bit signed integers.\n///\n/// Note that most operations are available as built-in operators (e.g. `1 + 1`).\n///\n/// Import from the base library to use this module.\n/// ```motoko name=import\n/// import Int32 \"mo:base/Int32\";\n/// ```\nimport Int \"Int\";\nimport Prim \"mo:⛔\";\n\nmodule {\n\n /// 32-bit signed integers.\n public type Int32 = Prim.Types.Int32;\n\n /// Minimum 32-bit integer value, `-2 ** 31`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int32.minimumValue // => -2_147_483_648\n /// ```\n public let minimumValue = -2_147_483_648 : Int32;\n\n /// Maximum 32-bit integer value, `+2 ** 31 - 1`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int32.maximumValue // => +2_147_483_647\n /// ```\n public let maximumValue = 2_147_483_647 : Int32;\n\n /// Converts a 32-bit signed integer to a signed integer with infinite precision.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int32.toInt(123_456) // => 123_456 : Int\n /// ```\n public let toInt : Int32 -> Int = Prim.int32ToInt;\n\n /// Converts a signed integer with infinite precision to a 32-bit signed integer.\n ///\n /// Traps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int32.fromInt(123_456) // => +123_456 : Int32\n /// ```\n public let fromInt : Int -> Int32 = Prim.intToInt32;\n\n /// Converts a signed integer with infinite precision to a 32-bit signed integer.\n ///\n /// Wraps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int32.fromIntWrap(-123_456) // => -123_456 : Int\n /// ```\n public let fromIntWrap : Int -> Int32 = Prim.intToInt32Wrap;\n\n /// Converts a 16-bit signed integer to a 32-bit signed integer.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int32.fromInt16(-123) // => -123 : Int32\n /// ```\n public let fromInt16 : Int16 -> Int32 = Prim.int16ToInt32;\n\n /// Converts a 32-bit signed integer to a 16-bit signed integer.\n ///\n /// Traps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int32.toInt16(-123) // => -123 : Int16\n /// ```\n public let toInt16 : Int32 -> Int16 = Prim.int32ToInt16;\n\n /// Converts a 64-bit signed integer to a 32-bit signed integer.\n ///\n /// Traps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int32.fromInt64(-123_456) // => -123_456 : Int32\n /// ```\n public let fromInt64 : Int64 -> Int32 = Prim.int64ToInt32;\n\n /// Converts a 32-bit signed integer to a 64-bit signed integer.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int32.toInt64(-123_456) // => -123_456 : Int64\n /// ```\n public let toInt64 : Int32 -> Int64 = Prim.int32ToInt64;\n\n /// Converts an unsigned 32-bit integer to a signed 32-bit integer.\n ///\n /// Wraps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int32.fromNat32(123_456) // => +123_456 : Int32\n /// ```\n public let fromNat32 : Nat32 -> Int32 = Prim.nat32ToInt32;\n\n /// Converts a signed 32-bit integer to an unsigned 32-bit integer.\n ///\n /// Wraps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int32.toNat32(-1) // => 4_294_967_295 : Nat32 // underflow\n /// ```\n public let toNat32 : Int32 -> Nat32 = Prim.int32ToNat32;\n\n /// Returns the Text representation of `x`. Textual representation _do not_\n /// contain underscores to represent commas.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int32.toText(-123456) // => \"-123456\"\n /// ```\n public func toText(x : Int32) : Text {\n Int.toText(toInt(x))\n };\n\n /// Returns the absolute value of `x`.\n ///\n /// Traps when `x == -2 ** 31` (the minimum `Int32` value).\n ///\n /// Example:\n /// ```motoko include=import\n /// Int32.abs(-123456) // => +123_456\n /// ```\n public func abs(x : Int32) : Int32 {\n fromInt(Int.abs(toInt(x)))\n };\n\n /// Returns the minimum of `x` and `y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int32.min(+2, -3) // => -3\n /// ```\n public func min(x : Int32, y : Int32) : Int32 {\n if (x < y) { x } else { y }\n };\n\n /// Returns the maximum of `x` and `y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int32.max(+2, -3) // => +2\n /// ```\n public func max(x : Int32, y : Int32) : Int32 {\n if (x < y) { y } else { x }\n };\n\n /// Equality function for Int32 types.\n /// This is equivalent to `x == y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int32.equal(-1, -1); // => true\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `==` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `==`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Buffer \"mo:base/Buffer\";\n ///\n /// let buffer1 = Buffer.Buffer<Int32>(1);\n /// buffer1.add(-3);\n /// let buffer2 = Buffer.Buffer<Int32>(1);\n /// buffer2.add(-3);\n /// Buffer.equal(buffer1, buffer2, Int32.equal) // => true\n /// ```\n public func equal(x : Int32, y : Int32) : Bool { x == y };\n\n /// Inequality function for Int32 types.\n /// This is equivalent to `x != y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int32.notEqual(-1, -2); // => true\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `!=` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `!=`\n /// as a function value at the moment.\n public func notEqual(x : Int32, y : Int32) : Bool { x != y };\n\n /// \"Less than\" function for Int32 types.\n /// This is equivalent to `x < y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int32.less(-2, 1); // => true\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<`\n /// as a function value at the moment.\n public func less(x : Int32, y : Int32) : Bool { x < y };\n\n /// \"Less than or equal\" function for Int32 types.\n /// This is equivalent to `x <= y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int32.lessOrEqual(-2, -2); // => true\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<=` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<=`\n /// as a function value at the moment.\n public func lessOrEqual(x : Int32, y : Int32) : Bool { x <= y };\n\n /// \"Greater than\" function for Int32 types.\n /// This is equivalent to `x > y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int32.greater(-2, -3); // => true\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `>` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `>`\n /// as a function value at the moment.\n public func greater(x : Int32, y : Int32) : Bool { x > y };\n\n /// \"Greater than or equal\" function for Int32 types.\n /// This is equivalent to `x >= y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int32.greaterOrEqual(-2, -2); // => true\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `>=` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `>=`\n /// as a function value at the moment.\n public func greaterOrEqual(x : Int32, y : Int32) : Bool { x >= y };\n\n /// General-purpose comparison function for `Int32`. Returns the `Order` (\n /// either `#less`, `#equal`, or `#greater`) of comparing `x` with `y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int32.compare(-3, 2) // => #less\n /// ```\n ///\n /// This function can be used as value for a high order function, such as a sort function.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.sort([1, -2, -3] : [Int32], Int32.compare) // => [-3, -2, 1]\n /// ```\n public func compare(x : Int32, y : Int32) : { #less; #equal; #greater } {\n if (x < y) { #less } else if (x == y) { #equal } else { #greater }\n };\n\n /// Returns the negation of `x`, `-x`.\n ///\n /// Traps on overflow, i.e. for `neg(-2 ** 31)`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int32.neg(123) // => -123\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `-` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `-`\n /// as a function value at the moment.\n public func neg(x : Int32) : Int32 { -x };\n\n /// Returns the sum of `x` and `y`, `x + y`.\n ///\n /// Traps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int32.add(100, 23) // => +123\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `+` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `+`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.foldLeft<Int32, Int32>([1, -2, -3], 0, Int32.add) // => -4\n /// ```\n public func add(x : Int32, y : Int32) : Int32 { x + y };\n\n /// Returns the difference of `x` and `y`, `x - y`.\n ///\n /// Traps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int32.sub(1234, 123) // => +1_111\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `-` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `-`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.foldLeft<Int32, Int32>([1, -2, -3], 0, Int32.sub) // => 6\n /// ```\n public func sub(x : Int32, y : Int32) : Int32 { x - y };\n\n /// Returns the product of `x` and `y`, `x * y`.\n ///\n /// Traps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int32.mul(123, 100) // => +12_300\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `*` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `*`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.foldLeft<Int32, Int32>([1, -2, -3], 1, Int32.mul) // => 6\n /// ```\n public func mul(x : Int32, y : Int32) : Int32 { x * y };\n\n /// Returns the signed integer division of `x` by `y`, `x / y`.\n /// Rounds the quotient towards zero, which is the same as truncating the decimal places of the quotient.\n ///\n /// Traps when `y` is zero.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int32.div(123, 10) // => +12\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `/` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `/`\n /// as a function value at the moment.\n public func div(x : Int32, y : Int32) : Int32 { x / y };\n\n /// Returns the remainder of the signed integer division of `x` by `y`, `x % y`,\n /// which is defined as `x - x / y * y`.\n ///\n /// Traps when `y` is zero.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int32.rem(123, 10) // => +3\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `%`\n /// as a function value at the moment.\n public func rem(x : Int32, y : Int32) : Int32 { x % y };\n\n /// Returns `x` to the power of `y`, `x ** y`.\n ///\n /// Traps on overflow/underflow and when `y < 0 or y >= 32`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int32.pow(2, 10) // => +1_024\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `**` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `**`\n /// as a function value at the moment.\n public func pow(x : Int32, y : Int32) : Int32 { x ** y };\n\n /// Returns the bitwise negation of `x`, `^x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int32.bitnot(-256 /* 0xffff_ff00 */) // => +255 // 0xff\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `^` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `^`\n /// as a function value at the moment.\n public func bitnot(x : Int32) : Int32 { ^x };\n\n /// Returns the bitwise \"and\" of `x` and `y`, `x & y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int32.bitand(0xffff, 0x00f0) // => +240 // 0xf0\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `&` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `&`\n /// as a function value at the moment.\n public func bitand(x : Int32, y : Int32) : Int32 { x & y };\n\n /// Returns the bitwise \"or\" of `x` and `y`, `x | y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int32.bitor(0xffff, 0x00f0) // => +65_535 // 0xffff\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `|` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `|`\n /// as a function value at the moment.\n public func bitor(x : Int32, y : Int32) : Int32 { x | y };\n\n /// Returns the bitwise \"exclusive or\" of `x` and `y`, `x ^ y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int32.bitxor(0xffff, 0x00f0) // => +65_295 // 0xff0f\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `^` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `^`\n /// as a function value at the moment.\n public func bitxor(x : Int32, y : Int32) : Int32 { x ^ y };\n\n /// Returns the bitwise left shift of `x` by `y`, `x << y`.\n /// The right bits of the shift filled with zeros.\n /// Left-overflowing bits, including the sign bit, are discarded.\n ///\n /// For `y >= 32`, the semantics is the same as for `bitshiftLeft(x, y % 32)`.\n /// For `y < 0`, the semantics is the same as for `bitshiftLeft(x, y + y % 32)`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int32.bitshiftLeft(1, 8) // => +256 // 0x100 equivalent to `2 ** 8`.\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<<` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<<`\n /// as a function value at the moment.\n public func bitshiftLeft(x : Int32, y : Int32) : Int32 { x << y };\n\n /// Returns the signed bitwise right shift of `x` by `y`, `x >> y`.\n /// The sign bit is retained and the left side is filled with the sign bit.\n /// Right-underflowing bits are discarded, i.e. not rotated to the left side.\n ///\n /// For `y >= 32`, the semantics is the same as for `bitshiftRight(x, y % 32)`.\n /// For `y < 0`, the semantics is the same as for `bitshiftRight (x, y + y % 32)`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int32.bitshiftRight(1024, 8) // => +4 // equivalent to `1024 / (2 ** 8)`\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `>>` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `>>`\n /// as a function value at the moment.\n public func bitshiftRight(x : Int32, y : Int32) : Int32 { x >> y };\n\n /// Returns the bitwise left rotatation of `x` by `y`, `x <<> y`.\n /// Each left-overflowing bit is inserted again on the right side.\n /// The sign bit is rotated like other bits, i.e. the rotation interprets the number as unsigned.\n ///\n /// Changes the direction of rotation for negative `y`.\n /// For `y >= 32`, the semantics is the same as for `bitrotLeft(x, y % 32)`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int32.bitrotLeft(0x2000_0001, 4) // => +18 // 0x12.\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<<>` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<<>`\n /// as a function value at the moment.\n public func bitrotLeft(x : Int32, y : Int32) : Int32 { x <<> y };\n\n /// Returns the bitwise right rotation of `x` by `y`, `x <>> y`.\n /// Each right-underflowing bit is inserted again on the right side.\n /// The sign bit is rotated like other bits, i.e. the rotation interprets the number as unsigned.\n ///\n /// Changes the direction of rotation for negative `y`.\n /// For `y >= 32`, the semantics is the same as for `bitrotRight(x, y % 32)`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int32.bitrotRight(0x0002_0001, 8) // => +16_777_728 // 0x0100_0200.\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<>>` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<>>`\n /// as a function value at the moment.\n public func bitrotRight(x : Int32, y : Int32) : Int32 { x <>> y };\n\n /// Returns the value of bit `p` in `x`, `x & 2**p == 2**p`.\n /// If `p >= 32`, the semantics is the same as for `bittest(x, p % 32)`.\n /// This is equivalent to checking if the `p`-th bit is set in `x`, using 0 indexing.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int32.bittest(128, 7) // => true\n /// ```\n public func bittest(x : Int32, p : Nat) : Bool {\n Prim.btstInt32(x, Prim.intToInt32(p))\n };\n\n /// Returns the value of setting bit `p` in `x` to `1`.\n /// If `p >= 32`, the semantics is the same as for `bitset(x, p % 32)`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int32.bitset(0, 7) // => +128\n /// ```\n public func bitset(x : Int32, p : Nat) : Int32 {\n x | (1 << Prim.intToInt32(p))\n };\n\n /// Returns the value of clearing bit `p` in `x` to `0`.\n /// If `p >= 32`, the semantics is the same as for `bitclear(x, p % 32)`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int32.bitclear(-1, 7) // => -129\n /// ```\n public func bitclear(x : Int32, p : Nat) : Int32 {\n x & ^(1 << Prim.intToInt32(p))\n };\n\n /// Returns the value of flipping bit `p` in `x`.\n /// If `p >= 32`, the semantics is the same as for `bitclear(x, p % 32)`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int32.bitflip(255, 7) // => +127\n /// ```\n public func bitflip(x : Int32, p : Nat) : Int32 {\n x ^ (1 << Prim.intToInt32(p))\n };\n\n /// Returns the count of non-zero bits in `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int32.bitcountNonZero(0xffff) // => +16\n /// ```\n public let bitcountNonZero : (x : Int32) -> Int32 = Prim.popcntInt32;\n\n /// Returns the count of leading zero bits in `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int32.bitcountLeadingZero(0x8000) // => +16\n /// ```\n public let bitcountLeadingZero : (x : Int32) -> Int32 = Prim.clzInt32;\n\n /// Returns the count of trailing zero bits in `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int32.bitcountTrailingZero(0x0201_0000) // => +16\n /// ```\n public let bitcountTrailingZero : (x : Int32) -> Int32 = Prim.ctzInt32;\n\n /// Returns the upper (i.e. most significant), lower (least significant)\n /// and in-between bytes of `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int32.explode 0x66885511 // => (102, 136, 85, 17)\n /// ```\n public let explode : (x : Int32) -> (msb : Nat8, Nat8, Nat8, lsb : Nat8) = Prim.explodeInt32;\n\n /// Returns the sum of `x` and `y`, `x +% y`.\n ///\n /// Wraps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int32.addWrap(2 ** 30, 2 ** 30) // => -2_147_483_648 // overflow\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `+%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `+%`\n /// as a function value at the moment.\n public func addWrap(x : Int32, y : Int32) : Int32 { x +% y };\n\n /// Returns the difference of `x` and `y`, `x -% y`.\n ///\n /// Wraps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int32.subWrap(-2 ** 31, 1) // => +2_147_483_647 // underflow\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `-%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `-%`\n /// as a function value at the moment.\n public func subWrap(x : Int32, y : Int32) : Int32 { x -% y };\n\n /// Returns the product of `x` and `y`, `x *% y`. Wraps on overflow.\n ///\n /// Wraps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int32.mulWrap(2 ** 16, 2 ** 16) // => 0 // overflow\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `*%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `*%`\n /// as a function value at the moment.\n public func mulWrap(x : Int32, y : Int32) : Int32 { x *% y };\n\n /// Returns `x` to the power of `y`, `x **% y`.\n ///\n /// Wraps on overflow/underflow.\n /// Traps if `y < 0 or y >= 32`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int32.powWrap(2, 31) // => -2_147_483_648 // overflow\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `**%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `**%`\n /// as a function value at the moment.\n public func powWrap(x : Int32, y : Int32) : Int32 { x **% y };\n\n}\n"},"Nat.mo":{"content":"/// Natural numbers with infinite precision.\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///\n/// Import from the base library to use this module.\n/// ```motoko name=import\n/// import Nat \"mo:base/Nat\";\n/// ```\n\nimport Int \"Int\";\nimport Order \"Order\";\nimport Prim \"mo:⛔\";\nimport Char \"Char\";\n\nmodule {\n\n /// Infinite precision natural numbers.\n public type Nat = Prim.Types.Nat;\n\n /// Converts a natural number to its textual representation. Textual\n /// representation _do not_ contain underscores to represent commas.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat.toText 1234 // => \"1234\"\n /// ```\n public func toText(n : Nat) : Text = Int.toText n;\n\n /// Creates a natural number from its textual representation. Returns `null`\n /// if the input is not a valid natural number.\n ///\n /// Note: The textual representation _must not_ contain underscores.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat.fromText \"1234\" // => ?1234\n /// ```\n public func fromText(text : Text) : ?Nat {\n if (text == \"\") {\n return null\n };\n var n = 0;\n for (c in text.chars()) {\n if (Char.isDigit(c)) {\n let charAsNat = Prim.nat32ToNat(Prim.charToNat32(c) -% Prim.charToNat32('0'));\n n := n * 10 + charAsNat\n } else {\n return null\n }\n };\n ?n\n };\n\n /// Returns the minimum of `x` and `y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat.min(1, 2) // => 1\n /// ```\n public func min(x : Nat, y : Nat) : Nat {\n if (x < y) { x } else { y }\n };\n\n /// Returns the maximum of `x` and `y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat.max(1, 2) // => 2\n /// ```\n public func max(x : Nat, y : Nat) : Nat {\n if (x < y) { y } else { x }\n };\n\n /// Equality function for Nat types.\n /// This is equivalent to `x == y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat.equal(1, 1); // => true\n /// 1 == 1 // => true\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `==` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `==`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Buffer \"mo:base/Buffer\";\n ///\n /// let buffer1 = Buffer.Buffer<Nat>(3);\n /// let buffer2 = Buffer.Buffer<Nat>(3);\n /// Buffer.equal(buffer1, buffer2, Nat.equal) // => true\n /// ```\n public func equal(x : Nat, y : Nat) : Bool { x == y };\n\n /// Inequality function for Nat types.\n /// This is equivalent to `x != y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat.notEqual(1, 2); // => true\n /// 1 != 2 // => true\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `!=` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `!=`\n /// as a function value at the moment.\n public func notEqual(x : Nat, y : Nat) : Bool { x != y };\n\n /// \"Less than\" function for Nat types.\n /// This is equivalent to `x < y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat.less(1, 2); // => true\n /// 1 < 2 // => true\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<`\n /// as a function value at the moment.\n public func less(x : Nat, y : Nat) : Bool { x < y };\n\n /// \"Less than or equal\" function for Nat types.\n /// This is equivalent to `x <= y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat.lessOrEqual(1, 2); // => true\n /// 1 <= 2 // => true\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<=` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<=`\n /// as a function value at the moment.\n public func lessOrEqual(x : Nat, y : Nat) : Bool { x <= y };\n\n /// \"Greater than\" function for Nat types.\n /// This is equivalent to `x > y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat.greater(2, 1); // => true\n /// 2 > 1 // => true\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `>` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `>`\n /// as a function value at the moment.\n public func greater(x : Nat, y : Nat) : Bool { x > y };\n\n /// \"Greater than or equal\" function for Nat types.\n /// This is equivalent to `x >= y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat.greaterOrEqual(2, 1); // => true\n /// 2 >= 1 // => true\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `>=` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `>=`\n /// as a function value at the moment.\n public func greaterOrEqual(x : Nat, y : Nat) : Bool { x >= y };\n\n /// General purpose comparison function for `Nat`. Returns the `Order` (\n /// either `#less`, `#equal`, or `#greater`) of comparing `x` with `y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat.compare(2, 3) // => #less\n /// ```\n ///\n /// This function can be used as value for a high order function, such as a sort function.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.sort([2, 3, 1], Nat.compare) // => [1, 2, 3]\n /// ```\n public func compare(x : Nat, y : Nat) : { #less; #equal; #greater } {\n if (x < y) { #less } else if (x == y) { #equal } else { #greater }\n };\n\n /// Returns the sum of `x` and `y`, `x + y`. This operator will never overflow\n /// because `Nat` is infinite precision.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat.add(1, 2); // => 3\n /// 1 + 2 // => 3\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `+` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `+`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.foldLeft([2, 3, 1], 0, Nat.add) // => 6\n /// ```\n public func add(x : Nat, y : Nat) : Nat { x + y };\n\n /// Returns the difference of `x` and `y`, `x - y`.\n /// Traps on underflow below `0`.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat.sub(2, 1); // => 1\n /// // Add a type annotation to avoid a warning about the subtraction\n /// 2 - 1 : Nat // => 1\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `-` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `-`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.foldLeft([2, 3, 1], 10, Nat.sub) // => 4\n /// ```\n public func sub(x : Nat, y : Nat) : Nat { x - y };\n\n /// Returns the product of `x` and `y`, `x * y`. This operator will never\n /// overflow because `Nat` is infinite precision.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat.mul(2, 3); // => 6\n /// 2 * 3 // => 6\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `*` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `*`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.foldLeft([2, 3, 1], 1, Nat.mul) // => 6\n /// ```\n public func mul(x : Nat, y : Nat) : Nat { x * y };\n\n /// Returns the unsigned integer division of `x` by `y`, `x / y`.\n /// Traps when `y` is zero.\n ///\n /// The quotient is rounded down, which is equivalent to truncating the\n /// decimal places of the quotient.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat.div(6, 2); // => 3\n /// 6 / 2 // => 3\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `/` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `/`\n /// as a function value at the moment.\n public func div(x : Nat, y : Nat) : Nat { x / y };\n\n /// Returns the remainder of unsigned integer division of `x` by `y`, `x % y`.\n /// Traps when `y` is zero.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat.rem(6, 4); // => 2\n /// 6 % 4 // => 2\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `%`\n /// as a function value at the moment.\n public func rem(x : Nat, y : Nat) : Nat { x % y };\n\n /// Returns `x` to the power of `y`, `x ** y`. Traps when `y > 2^32`. This operator\n /// will never overflow because `Nat` is infinite precision.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat.pow(2, 3); // => 8\n /// 2 ** 3 // => 8\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `**` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `**`\n /// as a function value at the moment.\n public func pow(x : Nat, y : Nat) : Nat { x ** y };\n\n /// Returns the (conceptual) bitwise shift left of `x` by `y`, `x * (2 ** y)`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat.bitshiftLeft(1, 3); // => 8\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in absence\n /// of the `<<` operator) is so that you can use it as a function\n /// value to pass to a higher order function. While `Nat` is not defined in terms\n /// of bit patterns, conceptually it can be regarded as such, and the operation\n /// is provided as a high-performance version of the corresponding arithmetic\n /// rule.\n public func bitshiftLeft(x : Nat, y : Nat32) : Nat { Prim.shiftLeft(x, y) };\n\n /// Returns the (conceptual) bitwise shift right of `x` by `y`, `x / (2 ** y)`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat.bitshiftRight(8, 3); // => 1\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in absence\n /// of the `>>` operator) is so that you can use it as a function\n /// value to pass to a higher order function. While `Nat` is not defined in terms\n /// of bit patterns, conceptually it can be regarded as such, and the operation\n /// is provided as a high-performance version of the corresponding arithmetic\n /// rule.\n public func bitshiftRight(x : Nat, y : Nat32) : Nat { Prim.shiftRight(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"},"Principal.mo":{"content":"/// Module for interacting with Principals (users and canisters).\n///\n/// Principals are used to identify entities that can interact with the Internet\n/// Computer. These entities are either users or canisters.\n///\n/// Example textual representation of Principals:\n///\n/// `un4fu-tqaaa-aaaab-qadjq-cai`\n///\n/// In Motoko, there is a primitive Principal type called `Principal`. As an example\n/// of where you might see Principals, you can access the Principal of the\n/// caller of your shared function.\n///\n/// ```motoko no-repl\n/// shared(msg) func foo() {\n/// let caller : Principal = msg.caller;\n/// };\n/// ```\n///\n/// Then, you can use this module to work with the `Principal`.\n///\n/// Import from the base library to use this module.\n/// ```motoko name=import\n/// import Principal \"mo:base/Principal\";\n/// ```\n\nimport Prim \"mo:⛔\";\nimport Blob \"Blob\";\nimport Hash \"Hash\";\nimport Array \"Array\";\nimport Nat8 \"Nat8\";\nimport Nat32 \"Nat32\";\nimport Nat64 \"Nat64\";\nimport Text \"Text\";\n\nmodule {\n\n public type Principal = Prim.Types.Principal;\n\n /// Get the `Principal` identifier of an actor.\n ///\n /// Example:\n /// ```motoko include=import no-repl\n /// actor MyCanister {\n /// func getPrincipal() : Principal {\n /// let principal = Principal.fromActor(MyCanister);\n /// }\n /// }\n /// ```\n public func fromActor(a : actor {}) : Principal = Prim.principalOfActor a;\n\n /// Compute the Ledger account identifier of a principal. Optionally specify a sub-account.\n ///\n /// Example:\n /// ```motoko include=import\n /// let principal = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n /// let subAccount : Blob = \"\\4A\\8D\\3F\\2B\\6E\\01\\C8\\7D\\9E\\03\\B4\\56\\7C\\F8\\9A\\01\\D2\\34\\56\\78\\9A\\BC\\DE\\F0\\12\\34\\56\\78\\9A\\BC\\DE\\F0\";\n /// let account = Principal.toLedgerAccount(principal, ?subAccount); // => \\8C\\5C\\20\\C6\\15\\3F\\7F\\51\\E2\\0D\\0F\\0F\\B5\\08\\51\\5B\\47\\65\\63\\A9\\62\\B4\\A9\\91\\5F\\4F\\02\\70\\8A\\ED\\4F\\82\n /// ```\n public func toLedgerAccount(principal : Principal, subAccount : ?Blob) : Blob {\n let sha224 = SHA224();\n let accountSeparator : Blob = \"\\0Aaccount-id\";\n sha224.writeBlob(accountSeparator);\n sha224.writeBlob(toBlob(principal));\n switch subAccount {\n case (?subAccount) {\n sha224.writeBlob(subAccount)\n };\n case (null) {\n let defaultSubAccount = Array.tabulate<Nat8>(32, func _ = 0);\n sha224.writeArray(defaultSubAccount)\n }\n };\n\n let hashSum = sha224.sum();\n\n // hashBlob is a CRC32 implementation\n let crc32Bytes = nat32ToByteArray(Prim.hashBlob hashSum);\n\n Blob.fromArray(Array.append(crc32Bytes, Blob.toArray(hashSum)))\n };\n\n /// Convert a `Principal` to its `Blob` (bytes) representation.\n ///\n /// Example:\n /// ```motoko include=import\n /// let principal = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n /// let blob = Principal.toBlob(principal); // => \\00\\00\\00\\00\\00\\30\\00\\D3\\01\\01\n /// ```\n public func toBlob(p : Principal) : Blob = Prim.blobOfPrincipal p;\n\n /// Converts a `Blob` (bytes) representation of a `Principal` to a `Principal` value.\n ///\n /// Example:\n /// ```motoko include=import\n /// let blob = \"\\00\\00\\00\\00\\00\\30\\00\\D3\\01\\01\" : Blob;\n /// let principal = Principal.fromBlob(blob);\n /// Principal.toText(principal) // => \"un4fu-tqaaa-aaaab-qadjq-cai\"\n /// ```\n public func fromBlob(b : Blob) : Principal = Prim.principalOfBlob b;\n\n /// Converts a `Principal` to its `Text` representation.\n ///\n /// Example:\n /// ```motoko include=import\n /// let principal = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n /// Principal.toText(principal) // => \"un4fu-tqaaa-aaaab-qadjq-cai\"\n /// ```\n public func toText(p : Principal) : Text = debug_show (p);\n\n /// Converts a `Text` representation of a `Principal` to a `Principal` value.\n ///\n /// Example:\n /// ```motoko include=import\n /// let principal = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n /// Principal.toText(principal) // => \"un4fu-tqaaa-aaaab-qadjq-cai\"\n /// ```\n public func fromText(t : Text) : Principal = fromActor(actor (t));\n\n private let anonymousPrincipal : Blob = \"\\04\";\n\n /// Checks if the given principal represents an anonymous user.\n ///\n /// Example:\n /// ```motoko include=import\n /// let principal = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n /// Principal.isAnonymous(principal) // => false\n /// ```\n public func isAnonymous(p : Principal) : Bool = Prim.blobOfPrincipal p == anonymousPrincipal;\n\n /// Checks if the given principal can control this canister.\n ///\n /// Example:\n /// ```motoko include=import\n /// let principal = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n /// Principal.isController(principal) // => false\n /// ```\n public func isController(p : Principal) : Bool = Prim.isController p;\n\n /// Hashes the given principal by hashing its `Blob` representation.\n ///\n /// Example:\n /// ```motoko include=import\n /// let principal = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n /// Principal.hash(principal) // => 2_742_573_646\n /// ```\n public func hash(principal : Principal) : Hash.Hash = Blob.hash(Prim.blobOfPrincipal(principal));\n\n /// General purpose comparison function for `Principal`. Returns the `Order` (\n /// either `#less`, `#equal`, or `#greater`) of comparing `principal1` with\n /// `principal2`.\n ///\n /// Example:\n /// ```motoko include=import\n /// let principal1 = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n /// let principal2 = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n /// Principal.compare(principal1, principal2) // => #equal\n /// ```\n public func compare(principal1 : Principal, principal2 : Principal) : {\n #less;\n #equal;\n #greater\n } {\n if (principal1 < principal2) {\n #less\n } else if (principal1 == principal2) {\n #equal\n } else {\n #greater\n }\n };\n\n /// Equality function for Principal types.\n /// This is equivalent to `principal1 == principal2`.\n ///\n /// Example:\n /// ```motoko include=import\n /// let principal1 = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n /// let principal2 = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n /// ignore Principal.equal(principal1, principal2);\n /// principal1 == principal2 // => true\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `==` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `==`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Buffer \"mo:base/Buffer\";\n ///\n /// let buffer1 = Buffer.Buffer<Principal>(3);\n /// let buffer2 = Buffer.Buffer<Principal>(3);\n /// Buffer.equal(buffer1, buffer2, Principal.equal) // => true\n /// ```\n public func equal(principal1 : Principal, principal2 : Principal) : Bool {\n principal1 == principal2\n };\n\n /// Inequality function for Principal types.\n /// This is equivalent to `principal1 != principal2`.\n ///\n /// Example:\n /// ```motoko include=import\n /// let principal1 = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n /// let principal2 = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n /// ignore Principal.notEqual(principal1, principal2);\n /// principal1 != principal2 // => false\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `!=` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `!=`\n /// as a function value at the moment.\n public func notEqual(principal1 : Principal, principal2 : Principal) : Bool {\n principal1 != principal2\n };\n\n /// \"Less than\" function for Principal types.\n /// This is equivalent to `principal1 < principal2`.\n ///\n /// Example:\n /// ```motoko include=import\n /// let principal1 = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n /// let principal2 = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n /// ignore Principal.less(principal1, principal2);\n /// principal1 < principal2 // => false\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<`\n /// as a function value at the moment.\n public func less(principal1 : Principal, principal2 : Principal) : Bool {\n principal1 < principal2\n };\n\n /// \"Less than or equal to\" function for Principal types.\n /// This is equivalent to `principal1 <= principal2`.\n ///\n /// Example:\n /// ```motoko include=import\n /// let principal1 = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n /// let principal2 = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n /// ignore Principal.lessOrEqual(principal1, principal2);\n /// principal1 <= principal2 // => true\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<=` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<=`\n /// as a function value at the moment.\n public func lessOrEqual(principal1 : Principal, principal2 : Principal) : Bool {\n principal1 <= principal2\n };\n\n /// \"Greater than\" function for Principal types.\n /// This is equivalent to `principal1 > principal2`.\n ///\n /// Example:\n /// ```motoko include=import\n /// let principal1 = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n /// let principal2 = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n /// ignore Principal.greater(principal1, principal2);\n /// principal1 > principal2 // => false\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `>` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `>`\n /// as a function value at the moment.\n public func greater(principal1 : Principal, principal2 : Principal) : Bool {\n principal1 > principal2\n };\n\n /// \"Greater than or equal to\" function for Principal types.\n /// This is equivalent to `principal1 >= principal2`.\n ///\n /// Example:\n /// ```motoko include=import\n /// let principal1 = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n /// let principal2 = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n /// ignore Principal.greaterOrEqual(principal1, principal2);\n /// principal1 >= principal2 // => true\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `>=` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `>=`\n /// as a function value at the moment.\n public func greaterOrEqual(principal1 : Principal, principal2 : Principal) : Bool {\n principal1 >= principal2\n };\n\n /**\n * SHA224 Utilities used in toAccount().\n * Utilities are not exposed as public functions.\n * Taken with permission from https://github.com/research-ag/sha2\n **/\n let K00 : Nat32 = 0x428a2f98;\n let K01 : Nat32 = 0x71374491;\n let K02 : Nat32 = 0xb5c0fbcf;\n let K03 : Nat32 = 0xe9b5dba5;\n let K04 : Nat32 = 0x3956c25b;\n let K05 : Nat32 = 0x59f111f1;\n let K06 : Nat32 = 0x923f82a4;\n let K07 : Nat32 = 0xab1c5ed5;\n let K08 : Nat32 = 0xd807aa98;\n let K09 : Nat32 = 0x12835b01;\n let K10 : Nat32 = 0x243185be;\n let K11 : Nat32 = 0x550c7dc3;\n let K12 : Nat32 = 0x72be5d74;\n let K13 : Nat32 = 0x80deb1fe;\n let K14 : Nat32 = 0x9bdc06a7;\n let K15 : Nat32 = 0xc19bf174;\n let K16 : Nat32 = 0xe49b69c1;\n let K17 : Nat32 = 0xefbe4786;\n let K18 : Nat32 = 0x0fc19dc6;\n let K19 : Nat32 = 0x240ca1cc;\n let K20 : Nat32 = 0x2de92c6f;\n let K21 : Nat32 = 0x4a7484aa;\n let K22 : Nat32 = 0x5cb0a9dc;\n let K23 : Nat32 = 0x76f988da;\n let K24 : Nat32 = 0x983e5152;\n let K25 : Nat32 = 0xa831c66d;\n let K26 : Nat32 = 0xb00327c8;\n let K27 : Nat32 = 0xbf597fc7;\n let K28 : Nat32 = 0xc6e00bf3;\n let K29 : Nat32 = 0xd5a79147;\n let K30 : Nat32 = 0x06ca6351;\n let K31 : Nat32 = 0x14292967;\n let K32 : Nat32 = 0x27b70a85;\n let K33 : Nat32 = 0x2e1b2138;\n let K34 : Nat32 = 0x4d2c6dfc;\n let K35 : Nat32 = 0x53380d13;\n let K36 : Nat32 = 0x650a7354;\n let K37 : Nat32 = 0x766a0abb;\n let K38 : Nat32 = 0x81c2c92e;\n let K39 : Nat32 = 0x92722c85;\n let K40 : Nat32 = 0xa2bfe8a1;\n let K41 : Nat32 = 0xa81a664b;\n let K42 : Nat32 = 0xc24b8b70;\n let K43 : Nat32 = 0xc76c51a3;\n let K44 : Nat32 = 0xd192e819;\n let K45 : Nat32 = 0xd6990624;\n let K46 : Nat32 = 0xf40e3585;\n let K47 : Nat32 = 0x106aa070;\n let K48 : Nat32 = 0x19a4c116;\n let K49 : Nat32 = 0x1e376c08;\n let K50 : Nat32 = 0x2748774c;\n let K51 : Nat32 = 0x34b0bcb5;\n let K52 : Nat32 = 0x391c0cb3;\n let K53 : Nat32 = 0x4ed8aa4a;\n let K54 : Nat32 = 0x5b9cca4f;\n let K55 : Nat32 = 0x682e6ff3;\n let K56 : Nat32 = 0x748f82ee;\n let K57 : Nat32 = 0x78a5636f;\n let K58 : Nat32 = 0x84c87814;\n let K59 : Nat32 = 0x8cc70208;\n let K60 : Nat32 = 0x90befffa;\n let K61 : Nat32 = 0xa4506ceb;\n let K62 : Nat32 = 0xbef9a3f7;\n let K63 : Nat32 = 0xc67178f2;\n\n let ivs : [[Nat32]] = [\n [\n // 224\n 0xc1059ed8,\n 0x367cd507,\n 0x3070dd17,\n 0xf70e5939,\n 0xffc00b31,\n 0x68581511,\n 0x64f98fa7,\n 0xbefa4fa4\n ],\n [\n // 256\n 0x6a09e667,\n 0xbb67ae85,\n 0x3c6ef372,\n 0xa54ff53a,\n 0x510e527f,\n 0x9b05688c,\n 0x1f83d9ab,\n 0x5be0cd19\n ]\n ];\n\n let rot = Nat32.bitrotRight;\n\n class SHA224() {\n let (sum_bytes, iv) = (28, 0);\n\n var s0 : Nat32 = 0;\n var s1 : Nat32 = 0;\n var s2 : Nat32 = 0;\n var s3 : Nat32 = 0;\n var s4 : Nat32 = 0;\n var s5 : Nat32 = 0;\n var s6 : Nat32 = 0;\n var s7 : Nat32 = 0;\n\n let msg : [var Nat32] = Array.init<Nat32>(16, 0);\n let digest = Array.init<Nat8>(sum_bytes, 0);\n var word : Nat32 = 0;\n\n var i_msg : Nat8 = 0;\n var i_byte : Nat8 = 4;\n var i_block : Nat64 = 0;\n\n public func reset() {\n i_msg := 0;\n i_byte := 4;\n i_block := 0;\n s0 := ivs[iv][0];\n s1 := ivs[iv][1];\n s2 := ivs[iv][2];\n s3 := ivs[iv][3];\n s4 := ivs[iv][4];\n s5 := ivs[iv][5];\n s6 := ivs[iv][6];\n s7 := ivs[iv][7]\n };\n\n reset();\n\n private func writeByte(val : Nat8) : () {\n word := (word << 8) ^ Nat32.fromIntWrap(Nat8.toNat(val));\n i_byte -%= 1;\n if (i_byte == 0) {\n msg[Nat8.toNat(i_msg)] := word;\n word := 0;\n i_byte := 4;\n i_msg +%= 1;\n if (i_msg == 16) {\n process_block();\n i_msg := 0;\n i_block +%= 1\n }\n }\n };\n\n private func process_block() : () {\n let w00 = msg[0];\n let w01 = msg[1];\n let w02 = msg[2];\n let w03 = msg[3];\n let w04 = msg[4];\n let w05 = msg[5];\n let w06 = msg[6];\n let w07 = msg[7];\n let w08 = msg[8];\n let w09 = msg[9];\n let w10 = msg[10];\n let w11 = msg[11];\n let w12 = msg[12];\n let w13 = msg[13];\n let w14 = msg[14];\n let w15 = msg[15];\n let w16 = w00 +% rot(w01, 07) ^ rot(w01, 18) ^ (w01 >> 03) +% w09 +% rot(w14, 17) ^ rot(w14, 19) ^ (w14 >> 10);\n let w17 = w01 +% rot(w02, 07) ^ rot(w02, 18) ^ (w02 >> 03) +% w10 +% rot(w15, 17) ^ rot(w15, 19) ^ (w15 >> 10);\n let w18 = w02 +% rot(w03, 07) ^ rot(w03, 18) ^ (w03 >> 03) +% w11 +% rot(w16, 17) ^ rot(w16, 19) ^ (w16 >> 10);\n let w19 = w03 +% rot(w04, 07) ^ rot(w04, 18) ^ (w04 >> 03) +% w12 +% rot(w17, 17) ^ rot(w17, 19) ^ (w17 >> 10);\n let w20 = w04 +% rot(w05, 07) ^ rot(w05, 18) ^ (w05 >> 03) +% w13 +% rot(w18, 17) ^ rot(w18, 19) ^ (w18 >> 10);\n let w21 = w05 +% rot(w06, 07) ^ rot(w06, 18) ^ (w06 >> 03) +% w14 +% rot(w19, 17) ^ rot(w19, 19) ^ (w19 >> 10);\n let w22 = w06 +% rot(w07, 07) ^ rot(w07, 18) ^ (w07 >> 03) +% w15 +% rot(w20, 17) ^ rot(w20, 19) ^ (w20 >> 10);\n let w23 = w07 +% rot(w08, 07) ^ rot(w08, 18) ^ (w08 >> 03) +% w16 +% rot(w21, 17) ^ rot(w21, 19) ^ (w21 >> 10);\n let w24 = w08 +% rot(w09, 07) ^ rot(w09, 18) ^ (w09 >> 03) +% w17 +% rot(w22, 17) ^ rot(w22, 19) ^ (w22 >> 10);\n let w25 = w09 +% rot(w10, 07) ^ rot(w10, 18) ^ (w10 >> 03) +% w18 +% rot(w23, 17) ^ rot(w23, 19) ^ (w23 >> 10);\n let w26 = w10 +% rot(w11, 07) ^ rot(w11, 18) ^ (w11 >> 03) +% w19 +% rot(w24, 17) ^ rot(w24, 19) ^ (w24 >> 10);\n let w27 = w11 +% rot(w12, 07) ^ rot(w12, 18) ^ (w12 >> 03) +% w20 +% rot(w25, 17) ^ rot(w25, 19) ^ (w25 >> 10);\n let w28 = w12 +% rot(w13, 07) ^ rot(w13, 18) ^ (w13 >> 03) +% w21 +% rot(w26, 17) ^ rot(w26, 19) ^ (w26 >> 10);\n let w29 = w13 +% rot(w14, 07) ^ rot(w14, 18) ^ (w14 >> 03) +% w22 +% rot(w27, 17) ^ rot(w27, 19) ^ (w27 >> 10);\n let w30 = w14 +% rot(w15, 07) ^ rot(w15, 18) ^ (w15 >> 03) +% w23 +% rot(w28, 17) ^ rot(w28, 19) ^ (w28 >> 10);\n let w31 = w15 +% rot(w16, 07) ^ rot(w16, 18) ^ (w16 >> 03) +% w24 +% rot(w29, 17) ^ rot(w29, 19) ^ (w29 >> 10);\n let w32 = w16 +% rot(w17, 07) ^ rot(w17, 18) ^ (w17 >> 03) +% w25 +% rot(w30, 17) ^ rot(w30, 19) ^ (w30 >> 10);\n let w33 = w17 +% rot(w18, 07) ^ rot(w18, 18) ^ (w18 >> 03) +% w26 +% rot(w31, 17) ^ rot(w31, 19) ^ (w31 >> 10);\n let w34 = w18 +% rot(w19, 07) ^ rot(w19, 18) ^ (w19 >> 03) +% w27 +% rot(w32, 17) ^ rot(w32, 19) ^ (w32 >> 10);\n let w35 = w19 +% rot(w20, 07) ^ rot(w20, 18) ^ (w20 >> 03) +% w28 +% rot(w33, 17) ^ rot(w33, 19) ^ (w33 >> 10);\n let w36 = w20 +% rot(w21, 07) ^ rot(w21, 18) ^ (w21 >> 03) +% w29 +% rot(w34, 17) ^ rot(w34, 19) ^ (w34 >> 10);\n let w37 = w21 +% rot(w22, 07) ^ rot(w22, 18) ^ (w22 >> 03) +% w30 +% rot(w35, 17) ^ rot(w35, 19) ^ (w35 >> 10);\n let w38 = w22 +% rot(w23, 07) ^ rot(w23, 18) ^ (w23 >> 03) +% w31 +% rot(w36, 17) ^ rot(w36, 19) ^ (w36 >> 10);\n let w39 = w23 +% rot(w24, 07) ^ rot(w24, 18) ^ (w24 >> 03) +% w32 +% rot(w37, 17) ^ rot(w37, 19) ^ (w37 >> 10);\n let w40 = w24 +% rot(w25, 07) ^ rot(w25, 18) ^ (w25 >> 03) +% w33 +% rot(w38, 17) ^ rot(w38, 19) ^ (w38 >> 10);\n let w41 = w25 +% rot(w26, 07) ^ rot(w26, 18) ^ (w26 >> 03) +% w34 +% rot(w39, 17) ^ rot(w39, 19) ^ (w39 >> 10);\n let w42 = w26 +% rot(w27, 07) ^ rot(w27, 18) ^ (w27 >> 03) +% w35 +% rot(w40, 17) ^ rot(w40, 19) ^ (w40 >> 10);\n let w43 = w27 +% rot(w28, 07) ^ rot(w28, 18) ^ (w28 >> 03) +% w36 +% rot(w41, 17) ^ rot(w41, 19) ^ (w41 >> 10);\n let w44 = w28 +% rot(w29, 07) ^ rot(w29, 18) ^ (w29 >> 03) +% w37 +% rot(w42, 17) ^ rot(w42, 19) ^ (w42 >> 10);\n let w45 = w29 +% rot(w30, 07) ^ rot(w30, 18) ^ (w30 >> 03) +% w38 +% rot(w43, 17) ^ rot(w43, 19) ^ (w43 >> 10);\n let w46 = w30 +% rot(w31, 07) ^ rot(w31, 18) ^ (w31 >> 03) +% w39 +% rot(w44, 17) ^ rot(w44, 19) ^ (w44 >> 10);\n let w47 = w31 +% rot(w32, 07) ^ rot(w32, 18) ^ (w32 >> 03) +% w40 +% rot(w45, 17) ^ rot(w45, 19) ^ (w45 >> 10);\n let w48 = w32 +% rot(w33, 07) ^ rot(w33, 18) ^ (w33 >> 03) +% w41 +% rot(w46, 17) ^ rot(w46, 19) ^ (w46 >> 10);\n let w49 = w33 +% rot(w34, 07) ^ rot(w34, 18) ^ (w34 >> 03) +% w42 +% rot(w47, 17) ^ rot(w47, 19) ^ (w47 >> 10);\n let w50 = w34 +% rot(w35, 07) ^ rot(w35, 18) ^ (w35 >> 03) +% w43 +% rot(w48, 17) ^ rot(w48, 19) ^ (w48 >> 10);\n let w51 = w35 +% rot(w36, 07) ^ rot(w36, 18) ^ (w36 >> 03) +% w44 +% rot(w49, 17) ^ rot(w49, 19) ^ (w49 >> 10);\n let w52 = w36 +% rot(w37, 07) ^ rot(w37, 18) ^ (w37 >> 03) +% w45 +% rot(w50, 17) ^ rot(w50, 19) ^ (w50 >> 10);\n let w53 = w37 +% rot(w38, 07) ^ rot(w38, 18) ^ (w38 >> 03) +% w46 +% rot(w51, 17) ^ rot(w51, 19) ^ (w51 >> 10);\n let w54 = w38 +% rot(w39, 07) ^ rot(w39, 18) ^ (w39 >> 03) +% w47 +% rot(w52, 17) ^ rot(w52, 19) ^ (w52 >> 10);\n let w55 = w39 +% rot(w40, 07) ^ rot(w40, 18) ^ (w40 >> 03) +% w48 +% rot(w53, 17) ^ rot(w53, 19) ^ (w53 >> 10);\n let w56 = w40 +% rot(w41, 07) ^ rot(w41, 18) ^ (w41 >> 03) +% w49 +% rot(w54, 17) ^ rot(w54, 19) ^ (w54 >> 10);\n let w57 = w41 +% rot(w42, 07) ^ rot(w42, 18) ^ (w42 >> 03) +% w50 +% rot(w55, 17) ^ rot(w55, 19) ^ (w55 >> 10);\n let w58 = w42 +% rot(w43, 07) ^ rot(w43, 18) ^ (w43 >> 03) +% w51 +% rot(w56, 17) ^ rot(w56, 19) ^ (w56 >> 10);\n let w59 = w43 +% rot(w44, 07) ^ rot(w44, 18) ^ (w44 >> 03) +% w52 +% rot(w57, 17) ^ rot(w57, 19) ^ (w57 >> 10);\n let w60 = w44 +% rot(w45, 07) ^ rot(w45, 18) ^ (w45 >> 03) +% w53 +% rot(w58, 17) ^ rot(w58, 19) ^ (w58 >> 10);\n let w61 = w45 +% rot(w46, 07) ^ rot(w46, 18) ^ (w46 >> 03) +% w54 +% rot(w59, 17) ^ rot(w59, 19) ^ (w59 >> 10);\n let w62 = w46 +% rot(w47, 07) ^ rot(w47, 18) ^ (w47 >> 03) +% w55 +% rot(w60, 17) ^ rot(w60, 19) ^ (w60 >> 10);\n let w63 = w47 +% rot(w48, 07) ^ rot(w48, 18) ^ (w48 >> 03) +% w56 +% rot(w61, 17) ^ rot(w61, 19) ^ (w61 >> 10);\n\n /*\n for ((i, j, k, l, m) in expansion_rounds.vals()) {\n // (j,k,l,m) = (i+1,i+9,i+14,i+16)\n let (v0, v1) = (msg[j], msg[l]);\n let s0 = rot(v0, 07) ^ rot(v0, 18) ^ (v0 >> 03);\n let s1 = rot(v1, 17) ^ rot(v1, 19) ^ (v1 >> 10);\n msg[m] := msg[i] +% s0 +% msg[k] +% s1;\n };\n */\n // compress\n var a = s0;\n var b = s1;\n var c = s2;\n var d = s3;\n var e = s4;\n var f = s5;\n var g = s6;\n var h = s7;\n var t = 0 : Nat32;\n\n t := h +% K00 +% w00 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K01 +% w01 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K02 +% w02 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K03 +% w03 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K04 +% w04 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K05 +% w05 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K06 +% w06 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K07 +% w07 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K08 +% w08 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K09 +% w09 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K10 +% w10 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K11 +% w11 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K12 +% w12 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K13 +% w13 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K14 +% w14 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K15 +% w15 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K16 +% w16 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K17 +% w17 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K18 +% w18 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K19 +% w19 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K20 +% w20 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K21 +% w21 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K22 +% w22 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K23 +% w23 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K24 +% w24 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K25 +% w25 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K26 +% w26 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K27 +% w27 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K28 +% w28 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K29 +% w29 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K30 +% w30 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K31 +% w31 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K32 +% w32 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K33 +% w33 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K34 +% w34 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K35 +% w35 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K36 +% w36 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K37 +% w37 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K38 +% w38 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K39 +% w39 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K40 +% w40 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K41 +% w41 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K42 +% w42 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K43 +% w43 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K44 +% w44 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K45 +% w45 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K46 +% w46 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K47 +% w47 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K48 +% w48 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K49 +% w49 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K50 +% w50 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K51 +% w51 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K52 +% w52 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K53 +% w53 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K54 +% w54 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K55 +% w55 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K56 +% w56 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K57 +% w57 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K58 +% w58 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K59 +% w59 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K60 +% w60 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K61 +% w61 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K62 +% w62 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K63 +% w63 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n\n /*\n for (i in compression_rounds.keys()) {\n let ch = (e & f) ^ (^ e & g);\n let maj = (a & b) ^ (a & c) ^ (b & c);\n let sigma0 = rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n let sigma1 = rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n let t = h +% K[i] +% msg[i] +% ch +% sigma1;\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% maj +% sigma0;\n };\n */\n // final addition\n s0 +%= a;\n s1 +%= b;\n s2 +%= c;\n s3 +%= d;\n s4 +%= e;\n s5 +%= f;\n s6 +%= g;\n s7 +%= h\n };\n\n public func writeIter(iter : { next() : ?Nat8 }) : () {\n label reading loop {\n switch (iter.next()) {\n case (?val) {\n writeByte(val);\n continue reading\n };\n case (null) {\n break reading\n }\n }\n }\n };\n\n public func writeArray(arr : [Nat8]) : () = writeIter(arr.vals());\n public func writeBlob(blob : Blob) : () = writeIter(blob.vals());\n\n public func sum() : Blob {\n // calculate padding\n // t = bytes in the last incomplete block (0-63)\n let t : Nat8 = (i_msg << 2) +% 4 -% i_byte;\n // p = length of padding (1-64)\n var p : Nat8 = if (t < 56) (56 -% t) else (120 -% t);\n // n_bits = length of message in bits\n let n_bits : Nat64 = ((i_block << 6) +% Nat64.fromIntWrap(Nat8.toNat(t))) << 3;\n\n // write padding\n writeByte(0x80);\n p -%= 1;\n while (p != 0) {\n writeByte(0x00);\n p -%= 1\n };\n\n // write length (8 bytes)\n // Note: this exactly fills the block buffer, hence process_block will get\n // triggered by the last writeByte\n writeByte(Nat8.fromIntWrap(Nat64.toNat((n_bits >> 56) & 0xff)));\n writeByte(Nat8.fromIntWrap(Nat64.toNat((n_bits >> 48) & 0xff)));\n writeByte(Nat8.fromIntWrap(Nat64.toNat((n_bits >> 40) & 0xff)));\n writeByte(Nat8.fromIntWrap(Nat64.toNat((n_bits >> 32) & 0xff)));\n writeByte(Nat8.fromIntWrap(Nat64.toNat((n_bits >> 24) & 0xff)));\n writeByte(Nat8.fromIntWrap(Nat64.toNat((n_bits >> 16) & 0xff)));\n writeByte(Nat8.fromIntWrap(Nat64.toNat((n_bits >> 8) & 0xff)));\n writeByte(Nat8.fromIntWrap(Nat64.toNat(n_bits & 0xff)));\n\n // retrieve sum\n digest[0] := Nat8.fromIntWrap(Nat32.toNat((s0 >> 24) & 0xff));\n digest[1] := Nat8.fromIntWrap(Nat32.toNat((s0 >> 16) & 0xff));\n digest[2] := Nat8.fromIntWrap(Nat32.toNat((s0 >> 8) & 0xff));\n digest[3] := Nat8.fromIntWrap(Nat32.toNat(s0 & 0xff));\n digest[4] := Nat8.fromIntWrap(Nat32.toNat((s1 >> 24) & 0xff));\n digest[5] := Nat8.fromIntWrap(Nat32.toNat((s1 >> 16) & 0xff));\n digest[6] := Nat8.fromIntWrap(Nat32.toNat((s1 >> 8) & 0xff));\n digest[7] := Nat8.fromIntWrap(Nat32.toNat(s1 & 0xff));\n digest[8] := Nat8.fromIntWrap(Nat32.toNat((s2 >> 24) & 0xff));\n digest[9] := Nat8.fromIntWrap(Nat32.toNat((s2 >> 16) & 0xff));\n digest[10] := Nat8.fromIntWrap(Nat32.toNat((s2 >> 8) & 0xff));\n digest[11] := Nat8.fromIntWrap(Nat32.toNat(s2 & 0xff));\n digest[12] := Nat8.fromIntWrap(Nat32.toNat((s3 >> 24) & 0xff));\n digest[13] := Nat8.fromIntWrap(Nat32.toNat((s3 >> 16) & 0xff));\n digest[14] := Nat8.fromIntWrap(Nat32.toNat((s3 >> 8) & 0xff));\n digest[15] := Nat8.fromIntWrap(Nat32.toNat(s3 & 0xff));\n digest[16] := Nat8.fromIntWrap(Nat32.toNat((s4 >> 24) & 0xff));\n digest[17] := Nat8.fromIntWrap(Nat32.toNat((s4 >> 16) & 0xff));\n digest[18] := Nat8.fromIntWrap(Nat32.toNat((s4 >> 8) & 0xff));\n digest[19] := Nat8.fromIntWrap(Nat32.toNat(s4 & 0xff));\n digest[20] := Nat8.fromIntWrap(Nat32.toNat((s5 >> 24) & 0xff));\n digest[21] := Nat8.fromIntWrap(Nat32.toNat((s5 >> 16) & 0xff));\n digest[22] := Nat8.fromIntWrap(Nat32.toNat((s5 >> 8) & 0xff));\n digest[23] := Nat8.fromIntWrap(Nat32.toNat(s5 & 0xff));\n digest[24] := Nat8.fromIntWrap(Nat32.toNat((s6 >> 24) & 0xff));\n digest[25] := Nat8.fromIntWrap(Nat32.toNat((s6 >> 16) & 0xff));\n digest[26] := Nat8.fromIntWrap(Nat32.toNat((s6 >> 8) & 0xff));\n digest[27] := Nat8.fromIntWrap(Nat32.toNat(s6 & 0xff));\n\n return Blob.fromArrayMut(digest)\n }\n }; // class SHA224\n\n func nat32ToByteArray(n : Nat32) : [Nat8] {\n func byte(n : Nat32) : Nat8 {\n Nat8.fromNat(Nat32.toNat(n & 0xff))\n };\n [byte(n >> 24), byte(n >> 16), byte(n >> 8), byte(n)]\n }\n}\n"},"Timer.mo":{"content":"/// Timers for one-off or periodic tasks. Applicable as part of the default mechanism.\n/// If `moc` is invoked with `-no-timer`, the importing will fail. Furthermore, if passed `--trap-on-call-error`, a congested canister send queue may prevent timer expirations to execute at runtime. It may also deactivate the global timer.\n///\n/// The resolution of the timers is similar to the block rate,\n/// so durations should be chosen well above that. For frequent\n/// canister wake-ups, consider using the [heartbeat](https://internetcomputer.org/docs/current/motoko/main/writing-motoko/heartbeats) mechanism; however, when possible, canisters should prefer timers.\n///\n/// The functionality described below is enabled only when the actor does not override it by declaring an explicit `system func timer`.\n///\n/// Timers are _not_ persisted across upgrades. One possible strategy\n/// to re-establish timers after an upgrade is to use stable variables\n/// in the `post_upgrade` hook and distill necessary timer information\n/// from there.\n///\n/// Using timers for security (e.g., access control) is strongly discouraged.\n/// Make sure to inform yourself about state-of-the-art dapp security.\n/// If you must use timers for security controls, be sure\n/// to consider reentrancy issues as well as the vanishing of timers on upgrades\n/// and reinstalls.\n///\n/// For further usage information for timers on the IC, please consult\n/// [the documentation](https://internetcomputer.org/docs/current/developer-docs/backend/periodic-tasks#timers-library-limitations).\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<system>(d : Duration, job : () -> async ()) : TimerId {\n setTimerNano<system>(toNanos d, false, job)\n };\n\n /// Installs a recurring timer that upon expiration after given duration `d`\n /// executes the future `job()` and reinserts itself for another expiration.\n ///\n /// 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<system>(d : Duration, job : () -> async ()) : TimerId {\n setTimerNano<system>(toNanos d, true, job)\n };\n\n /// Cancels a still active timer with `(id : TimerId)`. For expired timers\n /// and not recognised `id`s nothing happens.\n ///\n /// ```motoko no-repl\n /// func deleteAppointment(appointment : Appointment) {\n /// cancelTimer (appointment.reminder);\n /// // ...\n /// };\n /// ```\n public let cancelTimer : TimerId -> () = cancel;\n\n}\n"},"RBTree.mo":{"content":"/// Key-value map implemented as a red-black tree (RBTree) with nodes storing key-value pairs.\n///\n/// A red-black tree is a balanced binary search tree ordered by the keys.\n///\n/// The tree data structure internally colors each of its nodes either red or black,\n/// and uses this information to balance the tree during the modifying operations.\n///\n/// Creation:\n/// Instantiate class `RBTree<K, V>` that provides a map from keys of type `K` to values of type `V`.\n///\n/// Example:\n/// ```motoko\n/// import RBTree \"mo:base/RBTree\";\n/// import Nat \"mo:base/Nat\";\n/// import Debug \"mo:base/Debug\";\n///\n/// let tree = RBTree.RBTree<Nat, Text>(Nat.compare); // Create a new red-black tree mapping Nat to Text\n/// tree.put(1, \"one\");\n/// tree.put(2, \"two\");\n/// tree.put(3, \"tree\");\n/// for (entry in tree.entries()) {\n/// Debug.print(\"Entry key=\" # debug_show(entry.0) # \" value=\\\"\" # entry.1 #\"\\\"\");\n/// }\n/// ```\n///\n/// Performance:\n/// * Runtime: `O(log(n))` worst case cost per insertion, removal, and retrieval operation.\n/// * Heap space: `O(n)` for storing the entire tree.\n/// * Stack space: `O(log(n)) for storing the entire tree.\n/// `n` denotes the number of key-value entries (i.e. nodes) stored in the tree.\n///\n/// Note:\n/// * Tree insertion, replacement, and removal produce `O(log(n))` garbage objects.\n///\n/// Credits:\n///\n/// The core of this implementation is derived from:\n///\n/// * Ken Friis Larsen's [RedBlackMap.sml](https://github.com/kfl/mosml/blob/master/src/mosmllib/Redblackmap.sml), which itself is based on:\n/// * Stefan Kahrs, \"Red-black trees with types\", Journal of Functional Programming, 11(4): 425-432 (2001), [version 1 in web appendix](http://www.cs.ukc.ac.uk/people/staff/smk/redblack/rb.html).\n\n\nimport Debug \"Debug\";\nimport I \"Iter\";\nimport List \"List\";\nimport Nat \"Nat\";\nimport O \"Order\";\n\n// TODO: a faster, more compact and less indirect representation would be:\n// type Tree<K, V> = {\n// #red : (Tree<K, V>, K, V, Tree<K, V>);\n// #black : (Tree<K, V>, K, V, Tree<K, V>);\n// #leaf\n//};\n// (this inlines the colors into the variant, flattens a tuple, and removes a (now) redundant optin, for considerable heap savings.)\n// It would also make sense to maintain the size in a separate root for 0(1) access.\n\n// FUTURE: deprecate RBTree.mo and replace by RedBlackMap.mo, using this new representation\n\nmodule {\n\n /// Node color: Either red (`#R`) or black (`#B`).\n public type Color = { #R; #B };\n\n /// Red-black tree of nodes with key-value entries, ordered by the keys.\n /// The keys have the generic type `K` and the values the generic type `V`.\n /// Leaves are considered implicitly black.\n public type Tree<K, V> = {\n #node : (Color, Tree<K, V>, (K, ?V), Tree<K, V>);\n #leaf\n };\n\n\n\n /// A map from keys of type `K` to values of type `V` implemented as a red-black tree.\n /// The entries of key-value pairs are ordered by `compare` function applied to the keys.\n ///\n /// The class enables imperative usage in object-oriented-style.\n /// However, internally, the class uses a functional implementation.\n ///\n /// The `compare` function should implement a consistent total order among all possible values of `K` and\n /// for efficiency, only involves `O(1)` runtime costs without space allocation.\n ///\n /// Example:\n /// ```motoko name=initialize\n /// import RBTree \"mo:base/RBTree\";\n /// import Nat \"mo:base/Nat\";\n ///\n /// let tree = RBTree.RBTree<Nat, Text>(Nat.compare); // Create a map of `Nat` to `Text` using the `Nat.compare` order\n /// ```\n ///\n /// Costs of instantiation (only empty tree):\n /// Runtime: `O(1)`.\n /// Heap space: `O(1)`.\n /// Stack space: `O(1)`.\n public class RBTree<K, V>(compare : (K, K) -> O.Order) {\n\n var tree : Tree<K, V> = (#leaf : Tree<K, V>);\n\n /// Return a snapshot of the internal functional tree representation as sharable data.\n /// The returned tree representation is not affected by subsequent changes of the `RBTree` instance.\n ///\n ///\n /// Example:\n /// ```motoko include=initialize\n ///\n /// tree.put(1, \"one\");\n /// let treeSnapshot = tree.share();\n /// tree.put(2, \"second\");\n /// RBTree.size(treeSnapshot) // => 1 (Only the first insertion is part of the snapshot.)\n /// ```\n ///\n /// Useful for storing the state of a tree object as a stable variable, determining its size, pretty-printing, and sharing it across async function calls,\n /// i.e. passing it in async arguments or async results.\n ///\n /// Runtime: `O(1)`.\n /// Heap space: `O(1)`.\n /// Stack space: `O(1)`.\n public func share() : Tree<K, V> {\n tree\n };\n\n /// Reset the current state of the tree object from a functional tree representation.\n ///\n /// Example:\n /// ```motoko include=initialize\n /// import Iter \"mo:base/Iter\";\n ///\n /// tree.put(1, \"one\");\n /// let snapshot = tree.share(); // save the current state of the tree object in a snapshot\n /// tree.put(2, \"two\");\n /// tree.unshare(snapshot); // restore the tree object from the snapshot\n /// Iter.toArray(tree.entries()) // => [(1, \"one\")]\n /// ```\n ///\n /// Useful for restoring the state of a tree object from stable data, saved, for example, in a stable variable.\n ///\n /// Runtime: `O(1)`.\n /// Heap space: `O(1)`.\n /// Stack space: `O(1)`.\n public func unshare(t : Tree<K, V>) : () {\n tree := t\n };\n\n\n /// Retrieve the value associated with a given key, if present. Returns `null`, if the key is absent.\n /// The key is searched according to the `compare` function defined on the class instantiation.\n ///\n /// Example:\n /// ```motoko include=initialize\n ///\n /// tree.put(1, \"one\");\n /// tree.put(2, \"two\");\n ///\n /// tree.get(1) // => ?\"one\"\n /// ```\n ///\n /// Runtime: `O(log(n))`.\n /// Heap space: `O(1)`.\n /// Stack space: `O(log(n))`.\n /// where `n` denotes the number of key-value entries stored in the tree and\n /// assuming that the `compare` function implements an `O(1)` comparison.\n public func get(key : K) : ?V {\n getRec(key, compare, tree)\n };\n\n /// Replace the value associated with a given key, if the key is present.\n /// Otherwise, if the key does not yet exist, insert the key-value entry.\n ///\n /// Returns the previous value of the key, if the key already existed.\n /// Otherwise, `null`, if the key did not yet exist before.\n ///\n /// Example:\n /// ```motoko include=initialize\n /// import Iter \"mo:base/Iter\";\n ///\n /// tree.put(1, \"old one\");\n /// tree.put(2, \"two\");\n ///\n /// ignore tree.replace(1, \"new one\");\n /// Iter.toArray(tree.entries()) // => [(1, \"new one\"), (2, \"two\")]\n /// ```\n ///\n /// Runtime: `O(log(n))`.\n /// Heap space: `O(1)` retained memory plus garbage, see the note below.\n /// Stack space: `O(log(n))`.\n /// where `n` denotes the number of key-value entries stored in the tree and\n /// assuming that the `compare` function implements an `O(1)` comparison.\n ///\n /// Note: Creates `O(log(n))` garbage objects.\n public func replace(key : K, value : V) : ?V {\n let (t, res) = insert(tree, compare, key, value);\n tree := t;\n res\n };\n\n /// Insert a key-value entry in the tree. If the key already exists, it overwrites the associated value.\n ///\n /// Example:\n /// ```motoko include=initialize\n /// import Iter \"mo:base/Iter\";\n ///\n /// tree.put(1, \"one\");\n /// tree.put(2, \"two\");\n /// tree.put(3, \"three\");\n /// Iter.toArray(tree.entries()) // now contains three entries\n /// ```\n ///\n /// Runtime: `O(log(n))`.\n /// Heap space: `O(1)` retained memory plus garbage, see the note below.\n /// Stack space: `O(log(n))`.\n /// where `n` denotes the number of key-value entries stored in the tree and\n /// assuming that the `compare` function implements an `O(1)` comparison.\n ///\n /// Note: Creates `O(log(n))` garbage objects.\n public func put(key : K, value : V) {\n let (t, _res) = insert(tree, compare, key, value);\n tree := t\n };\n\n /// Delete the entry associated with a given key, if the key exists.\n /// No effect if the key is absent. Same as `remove(key)` except that it\n /// does not have a return value.\n ///\n /// Example:\n /// ```motoko include=initialize\n /// import Iter \"mo:base/Iter\";\n ///\n /// tree.put(1, \"one\");\n /// tree.put(2, \"two\");\n ///\n /// tree.delete(1);\n /// Iter.toArray(tree.entries()) // => [(2, \"two\")].\n /// ```\n ///\n /// Runtime: `O(log(n))`.\n /// Heap space: `O(1)` retained memory plus garbage, see the note below.\n /// Stack space: `O(log(n))`.\n /// where `n` denotes the number of key-value entries stored in the tree and\n /// assuming that the `compare` function implements an `O(1)` comparison.\n ///\n /// Note: Creates `O(log(n))` temporary objects that will be collected as garbage.\n public func delete(key : K) {\n let (_res, t) = removeRec(key, compare, tree);\n tree := t\n };\n\n /// Remove the entry associated with a given key, if the key exists, and return the associated value.\n /// Returns `null` without any other effect if the key is absent.\n ///\n /// Example:\n /// ```motoko include=initialize\n /// import Iter \"mo:base/Iter\";\n ///\n /// tree.put(1, \"one\");\n /// tree.put(2, \"two\");\n ///\n /// ignore tree.remove(1);\n /// Iter.toArray(tree.entries()) // => [(2, \"two\")].\n /// ```\n ///\n /// Runtime: `O(log(n))`.\n /// Heap space: `O(1)` retained memory plus garbage, see the note below.\n /// Stack space: `O(log(n))`.\n /// where `n` denotes the number of key-value entries stored in the tree and\n /// assuming that the `compare` function implements an `O(1)` comparison.\n ///\n /// Note: Creates `O(log(n))` garbage objects.\n public func remove(key : K) : ?V {\n let (res, t) = removeRec(key, compare, tree);\n tree := t;\n res\n };\n\n /// An iterator for the key-value entries of the map, in ascending key order.\n /// The iterator takes a snapshot view of the tree and is not affected by concurrent modifications.\n ///\n /// Example:\n /// ```motoko include=initialize\n /// import Debug \"mo:base/Debug\";\n ///\n /// tree.put(1, \"one\");\n /// tree.put(2, \"two\");\n /// tree.put(3, \"two\");\n ///\n /// for (entry in tree.entries()) {\n /// Debug.print(\"Entry key=\" # debug_show(entry.0) # \" value=\\\"\" # entry.1 #\"\\\"\");\n /// }\n ///\n /// // Entry key=1 value=\"one\"\n /// // Entry key=2 value=\"two\"\n /// // Entry key=3 value=\"three\"\n /// ```\n ///\n /// Cost of iteration over all elements:\n /// Runtime: `O(n)`.\n /// Heap space: `O(log(n))` retained memory plus garbage, see the note below.\n /// Stack space: `O(log(n))`.\n /// where `n` denotes the number of key-value entries stored in the tree.\n ///\n /// Note: Full tree iteration creates `O(n)` temporary objects that will be collected as garbage.\n public func entries() : I.Iter<(K, V)> { iter(tree, #fwd) };\n\n /// An iterator for the key-value entries of the map, in descending key order.\n /// The iterator takes a snapshot view of the tree and is not affected by concurrent modifications.\n ///\n /// Example:\n /// ```motoko include=initialize\n /// import Debug \"mo:base/Debug\";\n ///\n /// let tree = RBTree.RBTree<Nat, Text>(Nat.compare);\n /// tree.put(1, \"one\");\n /// tree.put(2, \"two\");\n /// tree.put(3, \"two\");\n ///\n /// for (entry in tree.entriesRev()) {\n /// Debug.print(\"Entry key=\" # debug_show(entry.0) # \" value=\\\"\" # entry.1 #\"\\\"\");\n /// }\n ///\n /// // Entry key=3 value=\"three\"\n /// // Entry key=2 value=\"two\"\n /// // Entry key=1 value=\"one\"\n /// ```\n ///\n /// Cost of iteration over all elements:\n /// Runtime: `O(n)`.\n /// Heap space: `O(log(n))` retained memory plus garbage, see the note below.\n /// Stack space: `O(log(n))`.\n /// where `n` denotes the number of key-value entries stored in the tree.\n ///\n /// Note: Full tree iteration creates `O(n)` temporary objects that will be collected as garbage.\n public func entriesRev() : I.Iter<(K, V)> { iter(tree, #bwd) };\n\n }; // end class\n\n type IterRep<X, Y> = List.List<{ #tr : Tree<X, Y>; #xy : (X, ?Y) }>;\n\n /// Get an iterator for the entries of the `tree`, in ascending (`#fwd`) or descending (`#bwd`) order as specified by `direction`.\n /// The iterator takes a snapshot view of the tree and is not affected by concurrent modifications.\n ///\n /// Example:\n /// ```motoko\n /// import RBTree \"mo:base/RBTree\";\n /// import Nat \"mo:base/Nat\";\n /// import Debug \"mo:base/Debug\";\n ///\n /// let tree = RBTree.RBTree<Nat, Text>(Nat.compare);\n /// tree.put(1, \"one\");\n /// tree.put(2, \"two\");\n /// tree.put(3, \"two\");\n ///\n /// for (entry in RBTree.iter(tree.share(), #bwd)) { // backward iteration\n /// Debug.print(\"Entry key=\" # debug_show(entry.0) # \" value=\\\"\" # entry.1 #\"\\\"\");\n /// }\n ///\n /// // Entry key=3 value=\"three\"\n /// // Entry key=2 value=\"two\"\n /// // Entry key=1 value=\"one\"\n /// ```\n ///\n /// Cost of iteration over all elements:\n /// Runtime: `O(n)`.\n /// Heap space: `O(log(n))` retained memory plus garbage, see the note below.\n /// Stack space: `O(log(n))`.\n /// where `n` denotes the number of key-value entries stored in the tree.\n ///\n /// Note: Full tree iteration creates `O(n)` temporary objects that will be collected as garbage.\n public func iter<X, Y>(tree : Tree<X, Y>, direction : { #fwd; #bwd }) : I.Iter<(X, Y)> {\n object {\n var trees : IterRep<X, Y> = ?(#tr(tree), null);\n public func next() : ?(X, Y) {\n switch (direction, trees) {\n case (_, null) { null };\n case (_, ?(#tr(#leaf), ts)) {\n trees := ts;\n next()\n };\n case (_, ?(#xy(xy), ts)) {\n trees := ts;\n switch (xy.1) {\n case null { next() };\n case (?y) { ?(xy.0, y) }\n }\n };\n case (#fwd, ?(#tr(#node(_, l, xy, r)), ts)) {\n trees := ?(#tr(l), ?(#xy(xy), ?(#tr(r), ts)));\n next()\n };\n case (#bwd, ?(#tr(#node(_, l, xy, r)), ts)) {\n trees := ?(#tr(r), ?(#xy(xy), ?(#tr(l), ts)));\n next()\n }\n }\n }\n }\n };\n\n /// Remove the value associated with a given key.\n func removeRec<X, Y>(x : X, compare : (X, X) -> O.Order, t : Tree<X, Y>) : (?Y, Tree<X, Y>) {\n let (t1, r) = remove(t, compare, x);\n (r, t1);\n };\n\n func getRec<X, Y>(x : X, compare : (X, X) -> O.Order, t : Tree<X, Y>) : ?Y {\n switch t {\n case (#leaf) { null };\n case (#node(_c, l, xy, r)) {\n switch (compare(x, xy.0)) {\n case (#less) { getRec(x, compare, l) };\n case (#equal) { xy.1 };\n case (#greater) { getRec(x, compare, r) }\n }\n }\n }\n };\n\n /// Determine the size of the tree as the number of key-value entries.\n ///\n /// Example:\n /// ```motoko\n /// import RBTree \"mo:base/RBTree\";\n /// import Nat \"mo:base/Nat\";\n ///\n /// let tree = RBTree.RBTree<Nat, Text>(Nat.compare);\n /// tree.put(1, \"one\");\n /// tree.put(2, \"two\");\n /// tree.put(3, \"three\");\n ///\n /// RBTree.size(tree.share()) // 3 entries\n /// ```\n ///\n /// Runtime: `O(log(n))`.\n /// Heap space: `O(1)`.\n /// Stack space: `O(log(n))`.\n /// where `n` denotes the number of key-value entries stored in the tree.\n public func size<X, Y>(t : Tree<X, Y>) : Nat {\n switch t {\n case (#leaf) { 0 };\n case (#node(_, l, xy, r)) {\n size(l) + size(r) + (switch (xy.1) { case null 0; case _ 1 })\n }\n }\n };\n\n func redden<X, Y>(t : Tree<X, Y>) : Tree<X, Y> {\n switch t {\n case (#node (#B, l, xy, r)) {\n (#node (#R, l, xy, r))\n };\n case _ {\n Debug.trap \"RBTree.red\"\n }\n }\n };\n\n func lbalance<X,Y>(left : Tree<X, Y>, xy : (X,?Y), right : Tree<X, Y>) : Tree<X,Y> {\n switch (left, right) {\n case (#node(#R, #node(#R, l1, xy1, r1), xy2, r2), r) {\n #node(\n #R,\n #node(#B, l1, xy1, r1),\n xy2,\n #node(#B, r2, xy, r))\n };\n case (#node(#R, l1, xy1, #node(#R, l2, xy2, r2)), r) {\n #node(\n #R,\n #node(#B, l1, xy1, l2),\n xy2,\n #node(#B, r2, xy, r))\n };\n case _ {\n #node(#B, left, xy, right)\n }\n }\n };\n\n func rbalance<X,Y>(left : Tree<X, Y>, xy : (X,?Y), right : Tree<X, Y>) : Tree<X,Y> {\n switch (left, right) {\n case (l, #node(#R, l1, xy1, #node(#R, l2, xy2, r2))) {\n #node(\n #R,\n #node(#B, l, xy, l1),\n xy1,\n #node(#B, l2, xy2, r2))\n };\n case (l, #node(#R, #node(#R, l1, xy1, r1), xy2, r2)) {\n #node(\n #R,\n #node(#B, l, xy, l1),\n xy1,\n #node(#B, r1, xy2, r2))\n };\n case _ {\n #node(#B, left, xy, right)\n };\n }\n };\n\n func insert<X, Y>(\n tree : Tree<X, Y>,\n compare : (X, X) -> O.Order,\n x : X,\n y : Y\n )\n : (Tree<X,Y>, ?Y) {\n var y0 : ?Y = null;\n func ins(tree : Tree<X,Y>) : Tree<X,Y> {\n switch tree {\n case (#leaf) {\n #node(#R, #leaf, (x,?y), #leaf)\n };\n case (#node(#B, left, xy, right)) {\n switch (compare (x, xy.0)) {\n case (#less) {\n lbalance(ins left, xy, right)\n };\n case (#greater) {\n rbalance(left, xy, ins right)\n };\n case (#equal) {\n y0 := xy.1;\n #node(#B, left, (x,?y), right)\n }\n }\n };\n case (#node(#R, left, xy, right)) {\n switch (compare (x, xy.0)) {\n case (#less) {\n #node(#R, ins left, xy, right)\n };\n case (#greater) {\n #node(#R, left, xy, ins right)\n };\n case (#equal) {\n y0 := xy.1;\n #node(#R, left, (x,?y), right)\n }\n }\n }\n };\n };\n switch (ins tree) {\n case (#node(#R, left, xy, right)) {\n (#node(#B, left, xy, right), y0);\n };\n case other { (other, y0) };\n };\n };\n\n\n func balLeft<X,Y>(left : Tree<X, Y>, xy : (X,?Y), right : Tree<X, Y>) : Tree<X,Y> {\n switch (left, right) {\n case (#node(#R, l1, xy1, r1), r) {\n #node(\n #R,\n #node(#B, l1, xy1, r1),\n xy,\n r)\n };\n case (_, #node(#B, l2, xy2, r2)) {\n rbalance(left, xy, #node(#R, l2, xy2, r2))\n };\n case (_, #node(#R, #node(#B, l2, xy2, r2), xy3, r3)) {\n #node(#R,\n #node(#B, left, xy, l2),\n xy2,\n rbalance(r2, xy3, redden r3))\n };\n case _ { Debug.trap \"balLeft\" };\n }\n };\n\n func balRight<X,Y>(left : Tree<X, Y>, xy : (X,?Y), right : Tree<X, Y>) : Tree<X,Y> {\n switch (left, right) {\n case (l, #node(#R, l1, xy1, r1)) {\n #node(#R,\n l,\n xy,\n #node(#B, l1, xy1, r1))\n };\n case (#node(#B, l1, xy1, r1), r) {\n lbalance(#node(#R, l1, xy1, r1), xy, r);\n };\n case (#node(#R, l1, xy1, #node(#B, l2, xy2, r2)), r3) {\n #node(#R,\n lbalance(redden l1, xy1, l2),\n xy2,\n #node(#B, r2, xy, r3))\n };\n case _ { Debug.trap \"balRight\" };\n }\n };\n\n func append<X,Y>(left : Tree<X, Y>, right: Tree<X, Y>) : Tree<X, Y> {\n switch (left, right) {\n case (#leaf, _) { right };\n case (_, #leaf) { left };\n case (#node (#R, l1, xy1, r1),\n #node (#R, l2, xy2, r2)) {\n switch (append (r1, l2)) {\n case (#node (#R, l3, xy3, r3)) {\n #node(\n #R,\n #node(#R, l1, xy1, l3),\n xy3,\n #node(#R, r3, xy2, r2))\n };\n case r1l2 {\n #node(#R, l1, xy1, #node(#R, r1l2, xy2, r2))\n }\n }\n };\n case (t1, #node(#R, l2, xy2, r2)) {\n #node(#R, append(t1, l2), xy2, r2)\n };\n case (#node(#R, l1, xy1, r1), t2) {\n #node(#R, l1, xy1, append(r1, t2))\n };\n case (#node(#B, l1, xy1, r1), #node (#B, l2, xy2, r2)) {\n switch (append (r1, l2)) {\n case (#node (#R, l3, xy3, r3)) {\n #node(#R,\n #node(#B, l1, xy1, l3),\n xy3,\n #node(#B, r3, xy2, r2))\n };\n case r1l2 {\n balLeft (\n l1,\n xy1,\n #node(#B, r1l2, xy2, r2)\n )\n }\n }\n }\n }\n };\n\n func remove<X, Y>(tree : Tree<X, Y>, compare : (X, X) -> O.Order, x : X) : (Tree<X,Y>, ?Y) {\n var y0 : ?Y = null;\n func delNode(left : Tree<X,Y>, xy : (X, ?Y), right : Tree<X,Y>) : Tree<X,Y> {\n switch (compare (x, xy.0)) {\n case (#less) {\n let newLeft = del left;\n switch left {\n case (#node(#B, _, _, _)) {\n balLeft(newLeft, xy, right)\n };\n case _ {\n #node(#R, newLeft, xy, right)\n }\n }\n };\n case (#greater) {\n let newRight = del right;\n switch right {\n case (#node(#B, _, _, _)) {\n balRight(left, xy, newRight)\n };\n case _ {\n #node(#R, left, xy, newRight)\n }\n }\n };\n case (#equal) {\n y0 := xy.1;\n append(left, right)\n };\n }\n };\n func del(tree : Tree<X,Y>) : Tree<X,Y> {\n switch tree {\n case (#leaf) {\n tree\n };\n case (#node(_, left, xy, right)) {\n delNode(left, xy, right)\n }\n };\n };\n switch (del(tree)) {\n case (#node(#R, left, xy, right)) {\n (#node(#B, left, xy, right), y0);\n };\n case other { (other, y0) };\n };\n }\n\n}\n"},"Nat64.mo":{"content":"/// Provides utility functions on 64-bit unsigned integers.\n///\n/// Note that most operations are available as built-in operators (e.g. `1 + 1`).\n///\n/// Import from the base library to use this module.\n/// ```motoko name=import\n/// import Nat64 \"mo:base/Nat64\";\n/// ```\nimport Nat \"Nat\";\nimport Prim \"mo:⛔\";\n\nmodule {\n\n /// 64-bit natural numbers.\n public type Nat64 = Prim.Types.Nat64;\n\n /// Maximum 64-bit natural number. `2 ** 64 - 1`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat64.maximumValue; // => 18446744073709551615 : Nat64\n /// ```\n\n public let maximumValue = 18446744073709551615 : Nat64;\n\n /// Converts a 64-bit unsigned integer to an unsigned integer with infinite precision.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat64.toNat(123); // => 123 : Nat\n /// ```\n public let toNat : Nat64 -> Nat = Prim.nat64ToNat;\n\n /// Converts an unsigned integer with infinite precision to a 64-bit unsigned integer.\n ///\n /// Traps on overflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat64.fromNat(123); // => 123 : Nat64\n /// ```\n public let fromNat : Nat -> Nat64 = Prim.natToNat64;\n\n /// Converts a 32-bit unsigned integer to a 64-bit unsigned integer.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat64.fromNat32(123); // => 123 : Nat64\n /// ```\n public func fromNat32(x : Nat32) : Nat64 {\n Prim.nat32ToNat64(x)\n };\n\n /// Converts a 64-bit unsigned integer to a 32-bit unsigned integer.\n ///\n /// Traps on overflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat64.toNat32(123); // => 123 : Nat32\n /// ```\n public func toNat32(x : Nat64) : Nat32 {\n Prim.nat64ToNat32(x)\n };\n\n /// Converts a signed integer with infinite precision to a 64-bit unsigned integer.\n ///\n /// Traps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat64.fromIntWrap(123); // => 123 : Nat64\n /// ```\n public let fromIntWrap : Int -> Nat64 = Prim.intToNat64Wrap;\n\n /// Converts `x` to its textual representation. Textual representation _do not_\n /// contain underscores to represent commas.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat64.toText(1234); // => \"1234\" : Text\n /// ```\n public func toText(x : Nat64) : Text {\n Nat.toText(toNat(x))\n };\n\n /// Returns the minimum of `x` and `y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat64.min(123, 456); // => 123 : Nat64\n /// ```\n public func min(x : Nat64, y : Nat64) : Nat64 {\n if (x < y) { x } else { y }\n };\n\n /// Returns the maximum of `x` and `y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat64.max(123, 456); // => 456 : Nat64\n /// ```\n public func max(x : Nat64, y : Nat64) : Nat64 {\n if (x < y) { y } else { x }\n };\n\n /// Equality function for Nat64 types.\n /// This is equivalent to `x == y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat64.equal(1, 1); // => true\n /// (1 : Nat64) == (1 : Nat64) // => true\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `==` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `==`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Buffer \"mo:base/Buffer\";\n ///\n /// let buffer1 = Buffer.Buffer<Nat64>(3);\n /// let buffer2 = Buffer.Buffer<Nat64>(3);\n /// Buffer.equal(buffer1, buffer2, Nat64.equal) // => true\n /// ```\n public func equal(x : Nat64, y : Nat64) : Bool { x == y };\n\n /// Inequality function for Nat64 types.\n /// This is equivalent to `x != y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat64.notEqual(1, 2); // => true\n /// (1 : Nat64) != (2 : Nat64) // => true\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `!=` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `!=`\n /// as a function value at the moment.\n public func notEqual(x : Nat64, y : Nat64) : Bool { x != y };\n\n /// \"Less than\" function for Nat64 types.\n /// This is equivalent to `x < y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat64.less(1, 2); // => true\n /// (1 : Nat64) < (2 : Nat64) // => true\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<`\n /// as a function value at the moment.\n public func less(x : Nat64, y : Nat64) : Bool { x < y };\n\n /// \"Less than or equal\" function for Nat64 types.\n /// This is equivalent to `x <= y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat64.lessOrEqual(1, 2); // => true\n /// (1 : Nat64) <= (2 : Nat64) // => true\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<=` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<=`\n /// as a function value at the moment.\n public func lessOrEqual(x : Nat64, y : Nat64) : Bool { x <= y };\n\n /// \"Greater than\" function for Nat64 types.\n /// This is equivalent to `x > y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat64.greater(2, 1); // => true\n /// (2 : Nat64) > (1 : Nat64) // => true\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `>` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `>`\n /// as a function value at the moment.\n public func greater(x : Nat64, y : Nat64) : Bool { x > y };\n\n /// \"Greater than or equal\" function for Nat64 types.\n /// This is equivalent to `x >= y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat64.greaterOrEqual(2, 1); // => true\n /// (2 : Nat64) >= (1 : Nat64) // => true\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `>=` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `>=`\n /// as a function value at the moment.\n public func greaterOrEqual(x : Nat64, y : Nat64) : Bool { x >= y };\n\n /// General purpose comparison function for `Nat64`. Returns the `Order` (\n /// either `#less`, `#equal`, or `#greater`) of comparing `x` with `y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat64.compare(2, 3) // => #less\n /// ```\n ///\n /// This function can be used as value for a high order function, such as a sort function.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.sort([2, 3, 1] : [Nat64], Nat64.compare) // => [1, 2, 3]\n /// ```\n public func compare(x : Nat64, y : Nat64) : { #less; #equal; #greater } {\n if (x < y) { #less } else if (x == y) { #equal } else { #greater }\n };\n\n /// Returns the sum of `x` and `y`, `x + y`.\n /// Traps on overflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat64.add(1, 2); // => 3\n /// (1 : Nat64) + (2 : Nat64) // => 3\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `+` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `+`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.foldLeft<Nat64, Nat64>([2, 3, 1], 0, Nat64.add) // => 6\n /// ```\n public func add(x : Nat64, y : Nat64) : Nat64 { x + y };\n\n /// Returns the difference of `x` and `y`, `x - y`.\n /// Traps on underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat64.sub(3, 1); // => 2\n /// (3 : Nat64) - (1 : Nat64) // => 2\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `-` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `-`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.foldLeft<Nat64, Nat64>([2, 3, 1], 10, Nat64.sub) // => 4\n /// ```\n public func sub(x : Nat64, y : Nat64) : Nat64 { x - y };\n\n /// Returns the product of `x` and `y`, `x * y`.\n /// Traps on overflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat64.mul(2, 3); // => 6\n /// (2 : Nat64) * (3 : Nat64) // => 6\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `*` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `*`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.foldLeft<Nat64, Nat64>([2, 3, 1], 1, Nat64.mul) // => 6\n /// ```\n public func mul(x : Nat64, y : Nat64) : Nat64 { x * y };\n\n /// Returns the quotient of `x` divided by `y`, `x / y`.\n /// Traps when `y` is zero.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat64.div(6, 2); // => 3\n /// (6 : Nat64) / (2 : Nat64) // => 3\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `/` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `/`\n /// as a function value at the moment.\n public func div(x : Nat64, y : Nat64) : Nat64 { x / y };\n\n /// Returns the remainder of `x` divided by `y`, `x % y`.\n /// Traps when `y` is zero.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat64.rem(6, 4); // => 2\n /// (6 : Nat64) % (4 : Nat64) // => 2\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `%`\n /// as a function value at the moment.\n public func rem(x : Nat64, y : Nat64) : Nat64 { x % y };\n\n /// Returns `x` to the power of `y`, `x ** y`. Traps on overflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat64.pow(2, 3); // => 8\n /// (2 : Nat64) ** (3 : Nat64) // => 8\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `**` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `**`\n /// as a function value at the moment.\n public func pow(x : Nat64, y : Nat64) : Nat64 { x ** y };\n\n /// Returns the bitwise negation of `x`, `^x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat64.bitnot(0); // => 18446744073709551615\n /// ^(0 : Nat64) // => 18446744073709551615\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `^` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `^`\n /// as a function value at the moment.\n public func bitnot(x : Nat64) : Nat64 { ^x };\n\n /// Returns the bitwise and of `x` and `y`, `x & y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat64.bitand(1, 3); // => 1\n /// (1 : Nat64) & (3 : Nat64) // => 1\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `&` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `&`\n /// as a function value at the moment.\n public func bitand(x : Nat64, y : Nat64) : Nat64 { x & y };\n\n /// Returns the bitwise or of `x` and `y`, `x | y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat64.bitor(1, 3); // => 3\n /// (1 : Nat64) | (3 : Nat64) // => 3\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `|` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `|`\n /// as a function value at the moment.\n public func bitor(x : Nat64, y : Nat64) : Nat64 { x | y };\n\n /// Returns the bitwise exclusive or of `x` and `y`, `x ^ y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat64.bitxor(1, 3); // => 2\n /// (1 : Nat64) ^ (3 : Nat64) // => 2\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `^` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `^`\n /// as a function value at the moment.\n public func bitxor(x : Nat64, y : Nat64) : Nat64 { x ^ y };\n\n /// Returns the bitwise shift left of `x` by `y`, `x << y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat64.bitshiftLeft(1, 3); // => 8\n /// (1 : Nat64) << (3 : Nat64) // => 8\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<<` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<<`\n /// as a function value at the moment.\n public func bitshiftLeft(x : Nat64, y : Nat64) : Nat64 { x << y };\n\n /// Returns the bitwise shift right of `x` by `y`, `x >> y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat64.bitshiftRight(8, 3); // => 1\n /// (8 : Nat64) >> (3 : Nat64) // => 1\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `>>` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `>>`\n /// as a function value at the moment.\n public func bitshiftRight(x : Nat64, y : Nat64) : Nat64 { x >> y };\n\n /// Returns the bitwise rotate left of `x` by `y`, `x <<> y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat64.bitrotLeft(1, 3); // => 8\n /// (1 : Nat64) <<> (3 : Nat64) // => 8\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<<>` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<<>`\n /// as a function value at the moment.\n public func bitrotLeft(x : Nat64, y : Nat64) : Nat64 { x <<> y };\n\n /// Returns the bitwise rotate right of `x` by `y`, `x <>> y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat64.bitrotRight(8, 3); // => 1\n /// (8 : Nat64) <>> (3 : Nat64) // => 1\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<>>` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<>>`\n /// as a function value at the moment.\n public func bitrotRight(x : Nat64, y : Nat64) : Nat64 { x <>> y };\n\n /// Returns the value of bit `p mod 64` in `x`, `(x & 2^(p mod 64)) == 2^(p mod 64)`.\n /// This is equivalent to checking if the `p`-th bit is set in `x`, using 0 indexing.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat64.bittest(5, 2); // => true\n /// ```\n public func bittest(x : Nat64, p : Nat) : Bool {\n Prim.btstNat64(x, Prim.natToNat64(p))\n };\n\n /// Returns the value of setting bit `p mod 64` in `x` to `1`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat64.bitset(5, 1); // => 7\n /// ```\n public func bitset(x : Nat64, p : Nat) : Nat64 {\n x | (1 << Prim.natToNat64(p))\n };\n\n /// Returns the value of clearing bit `p mod 64` in `x` to `0`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat64.bitclear(5, 2); // => 1\n /// ```\n public func bitclear(x : Nat64, p : Nat) : Nat64 {\n x & ^(1 << Prim.natToNat64(p))\n };\n\n /// Returns the value of flipping bit `p mod 64` in `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat64.bitflip(5, 2); // => 1\n /// ```\n public func bitflip(x : Nat64, p : Nat) : Nat64 {\n x ^ (1 << Prim.natToNat64(p))\n };\n\n /// Returns the count of non-zero bits in `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat64.bitcountNonZero(5); // => 2\n /// ```\n public let bitcountNonZero : (x : Nat64) -> Nat64 = Prim.popcntNat64;\n\n /// Returns the count of leading zero bits in `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat64.bitcountLeadingZero(5); // => 61\n /// ```\n public let bitcountLeadingZero : (x : Nat64) -> Nat64 = Prim.clzNat64;\n\n /// Returns the count of trailing zero bits in `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat64.bitcountTrailingZero(16); // => 4\n /// ```\n public let bitcountTrailingZero : (x : Nat64) -> Nat64 = Prim.ctzNat64;\n\n /// Returns the upper (i.e. most significant), lower (least significant)\n /// and in-between bytes of `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat64.explode 0xbb772266aa885511 // => (187, 119, 34, 102, 170, 136, 85, 17)\n /// ```\n public let explode : (x : Nat64) -> (msb : Nat8, Nat8, Nat8, Nat8, Nat8, Nat8, Nat8, lsb : Nat8) = Prim.explodeNat64;\n\n /// Returns the sum of `x` and `y`, `x +% y`. Wraps on overflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat64.addWrap(Nat64.maximumValue, 1); // => 0\n /// Nat64.maximumValue +% (1 : Nat64) // => 0\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `+%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `+%`\n /// as a function value at the moment.\n public func addWrap(x : Nat64, y : Nat64) : Nat64 { x +% y };\n\n /// Returns the difference of `x` and `y`, `x -% y`. Wraps on underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat64.subWrap(0, 1); // => 18446744073709551615\n /// (0 : Nat64) -% (1 : Nat64) // => 18446744073709551615\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `-%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `-%`\n /// as a function value at the moment.\n public func subWrap(x : Nat64, y : Nat64) : Nat64 { x -% y };\n\n /// Returns the product of `x` and `y`, `x *% y`. Wraps on overflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat64.mulWrap(4294967296, 4294967296); // => 0\n /// (4294967296 : Nat64) *% (4294967296 : Nat64) // => 0\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `*%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `*%`\n /// as a function value at the moment.\n public func mulWrap(x : Nat64, y : Nat64) : Nat64 { x *% y };\n\n /// Returns `x` to the power of `y`, `x **% y`. Wraps on overflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat64.powWrap(2, 64); // => 0\n /// (2 : Nat64) **% (64 : Nat64) // => 0\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `**%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `**%`\n /// as a function value at the moment.\n public func powWrap(x : Nat64, y : Nat64) : Nat64 { x **% y };\n\n}\n"},"Nat32.mo":{"content":"/// Provides utility functions on 32-bit unsigned integers.\n///\n/// Note that most operations are available as built-in operators (e.g. `1 + 1`).\n///\n/// Import from the base library to use this module.\n/// ```motoko name=import\n/// import Nat32 \"mo:base/Nat32\";\n/// ```\nimport Nat \"Nat\";\nimport Prim \"mo:⛔\";\n\nmodule {\n\n /// 32-bit natural numbers.\n public type Nat32 = Prim.Types.Nat32;\n\n /// Maximum 32-bit natural number. `2 ** 32 - 1`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat32.maximumValue; // => 4294967295 : Nat32\n /// ```\n public let maximumValue = 4294967295 : Nat32;\n\n /// Converts a 32-bit unsigned integer to an unsigned integer with infinite precision.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat32.toNat(123); // => 123 : Nat\n /// ```\n public let toNat : Nat32 -> Nat = Prim.nat32ToNat;\n\n /// Converts an unsigned integer with infinite precision to a 32-bit unsigned integer.\n ///\n /// Traps on overflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat32.fromNat(123); // => 123 : Nat32\n /// ```\n public let fromNat : Nat -> Nat32 = Prim.natToNat32;\n\n /// Converts a 16-bit unsigned integer to a 32-bit unsigned integer.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat32.fromNat16(123); // => 123 : Nat32\n /// ```\n public func fromNat16(x : Nat16) : Nat32 {\n Prim.nat16ToNat32(x)\n };\n\n /// Converts a 32-bit unsigned integer to a 16-bit unsigned integer.\n ///\n /// Traps on overflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat32.toNat16(123); // => 123 : Nat16\n /// ```\n public func toNat16(x : Nat32) : Nat16 {\n Prim.nat32ToNat16(x)\n };\n\n /// Converts a 64-bit unsigned integer to a 32-bit unsigned integer.\n ///\n /// Traps on overflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat32.fromNat64(123); // => 123 : Nat32\n /// ```\n public func fromNat64(x : Nat64) : Nat32 {\n Prim.nat64ToNat32(x)\n };\n\n /// Converts a 32-bit unsigned integer to a 64-bit unsigned integer.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat32.toNat64(123); // => 123 : Nat64\n /// ```\n public func toNat64(x : Nat32) : Nat64 {\n Prim.nat32ToNat64(x)\n };\n\n /// Converts a signed integer with infinite precision to a 32-bit unsigned integer.\n ///\n /// Traps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat32.fromIntWrap(123); // => 123 : Nat32\n /// ```\n public let fromIntWrap : Int -> Nat32 = Prim.intToNat32Wrap;\n\n /// Converts `x` to its textual representation. Textual representation _do not_\n /// contain underscores to represent commas.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat32.toText(1234); // => \"1234\" : Text\n /// ```\n public func toText(x : Nat32) : Text {\n Nat.toText(toNat(x))\n };\n\n /// Returns the minimum of `x` and `y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat32.min(123, 456); // => 123 : Nat32\n /// ```\n public func min(x : Nat32, y : Nat32) : Nat32 {\n if (x < y) { x } else { y }\n };\n\n /// Returns the maximum of `x` and `y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat32.max(123, 456); // => 456 : Nat32\n /// ```\n public func max(x : Nat32, y : Nat32) : Nat32 {\n if (x < y) { y } else { x }\n };\n\n /// Equality function for Nat32 types.\n /// This is equivalent to `x == y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat32.equal(1, 1); // => true\n /// (1 : Nat32) == (1 : Nat32) // => true\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `==` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `==`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Buffer \"mo:base/Buffer\";\n ///\n /// let buffer1 = Buffer.Buffer<Nat32>(3);\n /// let buffer2 = Buffer.Buffer<Nat32>(3);\n /// Buffer.equal(buffer1, buffer2, Nat32.equal) // => true\n /// ```\n public func equal(x : Nat32, y : Nat32) : Bool { x == y };\n\n /// Inequality function for Nat32 types.\n /// This is equivalent to `x != y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat32.notEqual(1, 2); // => true\n /// (1 : Nat32) != (2 : Nat32) // => true\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `!=` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `!=`\n /// as a function value at the moment.\n public func notEqual(x : Nat32, y : Nat32) : Bool { x != y };\n\n /// \"Less than\" function for Nat32 types.\n /// This is equivalent to `x < y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat32.less(1, 2); // => true\n /// (1 : Nat32) < (2 : Nat32) // => true\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<`\n /// as a function value at the moment.\n public func less(x : Nat32, y : Nat32) : Bool { x < y };\n\n /// \"Less than or equal\" function for Nat32 types.\n /// This is equivalent to `x <= y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat32.lessOrEqual(1, 2); // => true\n /// (1 : Nat32) <= (2 : Nat32) // => true\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<=` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<=`\n /// as a function value at the moment.\n public func lessOrEqual(x : Nat32, y : Nat32) : Bool { x <= y };\n\n /// \"Greater than\" function for Nat32 types.\n /// This is equivalent to `x > y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat32.greater(2, 1); // => true\n /// (2 : Nat32) > (1 : Nat32) // => true\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `>` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `>`\n /// as a function value at the moment.\n public func greater(x : Nat32, y : Nat32) : Bool { x > y };\n\n /// \"Greater than or equal\" function for Nat32 types.\n /// This is equivalent to `x >= y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat32.greaterOrEqual(2, 1); // => true\n /// (2 : Nat32) >= (1 : Nat32) // => true\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `>=` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `>=`\n /// as a function value at the moment.\n public func greaterOrEqual(x : Nat32, y : Nat32) : Bool { x >= y };\n\n /// General purpose comparison function for `Nat32`. Returns the `Order` (\n /// either `#less`, `#equal`, or `#greater`) of comparing `x` with `y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat32.compare(2, 3) // => #less\n /// ```\n ///\n /// This function can be used as value for a high order function, such as a sort function.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.sort([2, 3, 1] : [Nat32], Nat32.compare) // => [1, 2, 3]\n /// ```\n public func compare(x : Nat32, y : Nat32) : { #less; #equal; #greater } {\n if (x < y) { #less } else if (x == y) { #equal } else { #greater }\n };\n\n /// Returns the sum of `x` and `y`, `x + y`.\n /// Traps on overflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat32.add(1, 2); // => 3\n /// (1 : Nat32) + (2 : Nat32) // => 3\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `+` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `+`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.foldLeft<Nat32, Nat32>([2, 3, 1], 0, Nat32.add) // => 6\n /// ```\n public func add(x : Nat32, y : Nat32) : Nat32 { x + y };\n\n /// Returns the difference of `x` and `y`, `x - y`.\n /// Traps on underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat32.sub(2, 1); // => 1\n /// (2 : Nat32) - (1 : Nat32) // => 1\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `-` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `-`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.foldLeft<Nat32, Nat32>([2, 3, 1], 20, Nat32.sub) // => 14\n /// ```\n public func sub(x : Nat32, y : Nat32) : Nat32 { x - y };\n\n /// Returns the product of `x` and `y`, `x * y`.\n /// Traps on overflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat32.mul(2, 3); // => 6\n /// (2 : Nat32) * (3 : Nat32) // => 6\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `*` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `*`\n /// as a function value at the moment.\n ///\n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.foldLeft<Nat32, Nat32>([2, 3, 1], 1, Nat32.mul) // => 6\n /// ```\n public func mul(x : Nat32, y : Nat32) : Nat32 { x * y };\n\n /// Returns the division of `x by y`, `x / y`.\n /// Traps when `y` is zero.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat32.div(6, 2); // => 3\n /// (6 : Nat32) / (2 : Nat32) // => 3\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `/` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `/`\n /// as a function value at the moment.\n public func div(x : Nat32, y : Nat32) : Nat32 { x / y };\n\n /// Returns the remainder of `x` divided by `y`, `x % y`.\n /// Traps when `y` is zero.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat32.rem(6, 4); // => 2\n /// (6 : Nat32) % (4 : Nat32) // => 2\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `%`\n /// as a function value at the moment.\n public func rem(x : Nat32, y : Nat32) : Nat32 { x % y };\n\n /// Returns `x` to the power of `y`, `x ** y`. Traps on overflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat32.pow(2, 3); // => 8\n /// (2 : Nat32) ** (3 : Nat32) // => 8\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `**` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `**`\n /// as a function value at the moment.\n public func pow(x : Nat32, y : Nat32) : Nat32 { x ** y };\n\n /// Returns the bitwise negation of `x`, `^x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat32.bitnot(0) // => 4294967295\n /// ^(0 : Nat32) // => 4294967295\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `^` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `^`\n /// as a function value at the moment.\n public func bitnot(x : Nat32) : Nat32 { ^x };\n\n /// Returns the bitwise and of `x` and `y`, `x & y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat32.bitand(1, 3); // => 1\n /// (1 : Nat32) & (3 : Nat32) // => 1\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `&` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `&`\n /// as a function value at the moment.\n public func bitand(x : Nat32, y : Nat32) : Nat32 { x & y };\n\n /// Returns the bitwise or of `x` and `y`, `x | y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat32.bitor(1, 3); // => 3\n /// (1 : Nat32) | (3 : Nat32) // => 3\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `|` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `|`\n /// as a function value at the moment.\n public func bitor(x : Nat32, y : Nat32) : Nat32 { x | y };\n\n /// Returns the bitwise exclusive or of `x` and `y`, `x ^ y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat32.bitxor(1, 3); // => 2\n /// (1 : Nat32) ^ (3 : Nat32) // => 2\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `^` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `^`\n /// as a function value at the moment.\n public func bitxor(x : Nat32, y : Nat32) : Nat32 { x ^ y };\n\n /// Returns the bitwise shift left of `x` by `y`, `x << y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat32.bitshiftLeft(1, 3); // => 8\n /// (1 : Nat32) << (3 : Nat32) // => 8\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<<` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<<`\n /// as a function value at the moment.\n public func bitshiftLeft(x : Nat32, y : Nat32) : Nat32 { x << y };\n\n /// Returns the bitwise shift right of `x` by `y`, `x >> y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat32.bitshiftRight(8, 3); // => 1\n /// (8 : Nat32) >> (3 : Nat32) // => 1\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `>>` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `>>`\n /// as a function value at the moment.\n public func bitshiftRight(x : Nat32, y : Nat32) : Nat32 { x >> y };\n\n /// Returns the bitwise rotate left of `x` by `y`, `x <<> y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat32.bitrotLeft(1, 3); // => 8\n /// (1 : Nat32) <<> (3 : Nat32) // => 8\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<<>` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<<>`\n /// as a function value at the moment.\n public func bitrotLeft(x : Nat32, y : Nat32) : Nat32 { x <<> y };\n\n /// Returns the bitwise rotate right of `x` by `y`, `x <>> y`.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat32.bitrotRight(1, 1); // => 2147483648\n /// (1 : Nat32) <>> (1 : Nat32) // => 2147483648\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `<>>` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `<>>`\n /// as a function value at the moment.\n public func bitrotRight(x : Nat32, y : Nat32) : Nat32 { x <>> y };\n\n /// Returns the value of bit `p mod 32` in `x`, `(x & 2^(p mod 32)) == 2^(p mod 32)`.\n /// This is equivalent to checking if the `p`-th bit is set in `x`, using 0 indexing.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat32.bittest(5, 2); // => true\n /// ```\n public func bittest(x : Nat32, p : Nat) : Bool {\n Prim.btstNat32(x, Prim.natToNat32(p))\n };\n\n /// Returns the value of setting bit `p mod 32` in `x` to `1`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat32.bitset(5, 1); // => 7\n /// ```\n public func bitset(x : Nat32, p : Nat) : Nat32 {\n x | (1 << Prim.natToNat32(p))\n };\n\n /// Returns the value of clearing bit `p mod 32` in `x` to `0`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat32.bitclear(5, 2); // => 1\n /// ```\n public func bitclear(x : Nat32, p : Nat) : Nat32 {\n x & ^(1 << Prim.natToNat32(p))\n };\n\n /// Returns the value of flipping bit `p mod 32` in `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat32.bitflip(5, 2); // => 1\n /// ```\n public func bitflip(x : Nat32, p : Nat) : Nat32 {\n x ^ (1 << Prim.natToNat32(p))\n };\n\n /// Returns the count of non-zero bits in `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat32.bitcountNonZero(5); // => 2\n /// ```\n public let bitcountNonZero : (x : Nat32) -> Nat32 = Prim.popcntNat32;\n\n /// Returns the count of leading zero bits in `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat32.bitcountLeadingZero(5); // => 29\n /// ```\n public let bitcountLeadingZero : (x : Nat32) -> Nat32 = Prim.clzNat32;\n\n /// Returns the count of trailing zero bits in `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat32.bitcountTrailingZero(16); // => 4\n /// ```\n public let bitcountTrailingZero : (x : Nat32) -> Nat32 = Prim.ctzNat32;\n\n /// Returns the upper (i.e. most significant), lower (least significant)\n /// and in-between bytes of `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat32.explode 0xaa885511 // => (170, 136, 85, 17)\n /// ```\n public let explode : (x : Nat32) -> (msb : Nat8, Nat8, Nat8, lsb : Nat8) = Prim.explodeNat32;\n\n /// Returns the sum of `x` and `y`, `x +% y`. Wraps on overflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat32.addWrap(4294967295, 1); // => 0\n /// (4294967295 : Nat32) +% (1 : Nat32) // => 0\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `+%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `+%`\n /// as a function value at the moment.\n public func addWrap(x : Nat32, y : Nat32) : Nat32 { x +% y };\n\n /// Returns the difference of `x` and `y`, `x -% y`. Wraps on underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat32.subWrap(0, 1); // => 4294967295\n /// (0 : Nat32) -% (1 : Nat32) // => 4294967295\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `-%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `-%`\n /// as a function value at the moment.\n public func subWrap(x : Nat32, y : Nat32) : Nat32 { x -% y };\n\n /// Returns the product of `x` and `y`, `x *% y`. Wraps on overflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat32.mulWrap(2147483648, 2); // => 0\n /// (2147483648 : Nat32) *% (2 : Nat32) // => 0\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `*%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `*%`\n /// as a function value at the moment.\n public func mulWrap(x : Nat32, y : Nat32) : Nat32 { x *% y };\n\n /// Returns `x` to the power of `y`, `x **% y`. Wraps on overflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat32.powWrap(2, 32); // => 0\n /// (2 : Nat32) **% (32 : Nat32) // => 0\n /// ```\n ///\n /// Note: The reason why this function is defined in this library (in addition\n /// to the existing `**%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `**%`\n /// as a function value at the moment.\n public func powWrap(x : Nat32, y : Nat32) : Nat32 { x **% y };\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/// LIMITATIONS: This data structure allows at most MAX_LEAF_SIZE=8 hash collisions:\n/// attempts to insert more than MAX_LEAF_SIZE elements (whether directly via `put` or indirectly via other operations) with the same hash value will trap.\n/// This limitation is inherited from the underlying `Trie` data structure.\n\n// TODO-Matthew:\n// ---------------\n//\n// - for now, we pass a hash value each time we pass an element value;\n// in the future, we might avoid passing element hashes with each element in the API;\n// related to: https://dfinity.atlassian.net/browse/AST-32\n//\n// - similarly, we pass an equality function when we do some operations.\n// in the future, we might avoid this via https://dfinity.atlassian.net/browse/AST-32\nimport Trie \"Trie\";\nimport Hash \"Hash\";\nimport List \"List\";\nimport Iter \"Iter\";\n\nmodule {\n\n public type Hash = Hash.Hash;\n public type Set<T> = Trie.Trie<T, ()>;\n type Key<K> = Trie.Key<K>;\n type Trie<K, V> = Trie.Trie<K, V>;\n\n // helper for defining equal and sub, avoiding Trie.diff.\n // TODO: add to Trie.mo?\n private func keys<K>(t : Trie<K, Any>) : Iter.Iter<Key<K>> {\n object {\n var stack = ?(t, null) : List.List<Trie<K, Any>>;\n public func next() : ?Key<K> {\n switch stack {\n case null { null };\n case (?(trie, stack2)) {\n switch trie {\n case (#empty) {\n stack := stack2;\n next()\n };\n case (#leaf({ keyvals = null })) {\n stack := stack2;\n next()\n };\n case (#leaf({ size = c; keyvals = ?((k, _v), kvs) })) {\n stack := ?(#leaf({ size = c - 1; keyvals = kvs }), stack2);\n ?k\n };\n case (#branch(br)) {\n stack := ?(br.left, ?(br.right, stack2));\n next()\n }\n }\n }\n }\n }\n }\n };\n\n /// Empty set.\n public func empty<T>() : Set<T> { Trie.empty<T, ()>() };\n\n /// Put an element into the set.\n public func put<T>(s : Set<T>, x : T, xh : Hash, eq : (T, T) -> Bool) : Set<T> {\n let (s2, _) = Trie.put<T, ()>(s, { key = x; hash = xh }, eq, ());\n s2\n };\n\n /// Delete an element from the set.\n public func delete<T>(s : Set<T>, x : T, xh : Hash, eq : (T, T) -> Bool) : Set<T> {\n let (s2, _) = Trie.remove<T, ()>(s, { key = x; hash = xh }, eq);\n s2\n };\n\n /// Test if two sets are equal.\n public func equal<T>(s1 : Set<T>, s2 : Set<T>, eq : (T, T) -> Bool) : Bool {\n if (Trie.size(s1) != Trie.size(s2)) return false;\n for (k in keys(s1)) {\n if (Trie.find<T,()>(s2, k, eq) == null) {\n return false;\n }\n };\n return true;\n };\n\n /// The number of set elements, set's cardinality.\n public func size<T>(s : Set<T>) : Nat {\n Trie.size(s);\n };\n\n /// Test if `s` is the empty set.\n public func isEmpty<T>(s : Set<T>) : Bool {\n Trie.size(s) == 0;\n };\n\n /// Test if `s1` is a subset of `s2`.\n public func isSubset<T>(s1 : Set<T>, s2 : Set<T>, eq : (T, T) -> Bool) : Bool {\n if (Trie.size(s1) > Trie.size(s2)) return false;\n for (k in keys(s1)) {\n if (Trie.find<T,()>(s2, k, eq) == null) {\n return false;\n }\n };\n return true;\n };\n\n /// @deprecated: use `TrieSet.contains()`\n ///\n /// Test if a set contains a given element.\n public func mem<T>(s : Set<T>, x : T, xh : Hash, eq : (T, T) -> Bool) : Bool {\n contains(s, x, xh, eq)\n };\n\n /// Test if a set contains a given element.\n public func contains<T>(s : Set<T>, x : T, xh : Hash, eq : (T, T) -> Bool) : Bool {\n switch (Trie.find<T, ()>(s, { key = x; hash = xh }, eq)) {\n case null { false };\n case (?_) { true }\n }\n };\n\n /// [Set union](https://en.wikipedia.org/wiki/Union_(set_theory)).\n public func union<T>(s1 : Set<T>, s2 : Set<T>, eq : (T, T) -> Bool) : Set<T> {\n let s3 = Trie.merge<T, ()>(s1, s2, eq);\n s3\n };\n\n /// [Set difference](https://en.wikipedia.org/wiki/Difference_(set_theory)).\n public func diff<T>(s1 : Set<T>, s2 : Set<T>, eq : (T, T) -> Bool) : Set<T> {\n let s3 = Trie.diff<T, (), ()>(s1, s2, eq);\n s3\n };\n\n /// [Set intersection](https://en.wikipedia.org/wiki/Intersection_(set_theory)).\n public func intersect<T>(s1 : Set<T>, s2 : Set<T>, eq : (T, T) -> Bool) : Set<T> {\n let noop : ((), ()) -> (()) = func(_ : (), _ : ()) : (()) = ();\n let s3 = Trie.join<T, (), (), ()>(s1, s2, eq, noop);\n s3\n };\n\n //// Construct a set from an array.\n public func fromArray<T>(arr : [T], elemHash : T -> Hash, eq : (T, T) -> Bool) : Set<T> {\n var s = empty<T>();\n for (elem in arr.vals()) {\n s := put<T>(s, elem, elemHash(elem), eq)\n };\n s\n };\n\n //// Returns the set as an array.\n public func toArray<T>(s : Set<T>) : [T] {\n Trie.toArray(s, func(t : T, _ : ()) : T { t })\n }\n\n}\n"},"Region.mo":{"content":"/// Byte-level access to isolated, (virtual) stable memory _regions_.\n///\n/// This is a moderately lightweight abstraction over IC _stable memory_ and supports persisting\n/// regions of binary data across Motoko upgrades.\n/// Use of this module is fully compatible with Motoko's use of\n/// _stable variables_, whose persistence mechanism also uses (real) IC stable memory internally, but does not interfere with this API.\n/// It is also fully compatible with existing uses of the `ExperimentalStableMemory` library, which has a similar interface, but,\n/// only supported a single memory region, without isolation between different applications.\n///\n/// The `Region` type is stable and can be used in stable data structures.\n///\n/// A new, empty `Region` is allocated using function `new()`.\n///\n/// Regions are stateful objects and can be distinguished by the numeric identifier returned by function `id(region)`.\n/// Every region owns an initially empty, but growable sequence of virtual IC stable memory pages. \n/// The current size, in pages, of a region is returned by function `size(region)`.\n/// The size of a region determines the range, [ 0, ..., size(region)*2^16 ), of valid byte-offsets into the region; these offsets are used as the source and destination of `load`/`store` operations on the region.\n///\n/// Memory is allocated to a region, using function `grow(region, pages)`, sequentially and on demand, in units of 64KiB logical pages, starting with 0 allocated pages.\n/// A call to `grow` may succeed, returning the previous size of the region, or fail, returning a sentinel value. New pages are zero initialized.\n///\n/// A size of a region can only grow and never shrink.\n/// In addition, the stable memory pages allocated to a region will *not* be reclaimed by garbage collection, even\n/// if the region object itself becomes unreachable. \n///\n/// Growth is capped by a soft limit on physical page count controlled by compile-time flag\n/// `--max-stable-pages <n>` (the default is 65536, or 4GiB).\n///\n/// Each `load` operation loads from region relative byte address `offset` in little-endian\n/// format using the natural bit-width of the type in question.\n/// The operation traps if attempting to read beyond the current region size.\n///\n/// Each `store` operation stores to region relative byte address `offset` in little-endian format using the natural bit-width of the type in question.\n/// The operation traps if attempting to write beyond the current region size.\n///\n/// Text values can be handled by using `Text.decodeUtf8` and `Text.encodeUtf8`, in conjunction with `loadBlob` and `storeBlob`.\n///\n/// The current region allocation and region contents are preserved across upgrades.\n///\n/// NB: The IC's actual stable memory size (`ic0.stable_size`) may exceed the\n/// total page size reported by summing all regions sizes.\n/// This (and the cap on growth) are to accommodate Motoko's stable variables and bookkeeping for regions.\n/// Applications that plan to use Motoko stable variables sparingly or not at all can\n/// increase `--max-stable-pages` as desired, approaching the IC maximum (initially 8GiB, then 32Gib, currently 64Gib).\n/// All applications should reserve at least one page for stable variable data, even when no stable variables are used.\n///\n/// Usage:\n/// ```motoko no-repl\n/// import Region \"mo:base/Region\";\n/// ```\n\nimport Prim \"mo:⛔\";\n\nmodule {\n\n /// A stateful handle to an isolated region of IC stable memory.\n /// `Region` is a stable type and regions can be stored in stable variables.\n public type Region = Prim.Types.Region;\n\n /// Allocate a new, isolated Region of size 0.\n ///\n /// Example:\n ///\n /// ```motoko no-repl\n /// let region = Region.new();\n /// assert Region.size(region) == 0;\n /// ```\n public let new : () -> Region = Prim.regionNew;\n\n /// Return a Nat identifying the given region.\n /// Maybe be used for equality, comparison and hashing.\n /// NB: Regions returned by `new()` are numbered from 16\n /// (regions 0..15 are currently reserved for internal use).\n /// Allocate a new, isolated Region of size 0.\n ///\n /// Example:\n ///\n /// ```motoko no-repl\n /// let region = Region.new();\n /// assert Region.id(region) == 16;\n /// ```\n public let id : Region -> Nat = Prim.regionId;\n\n /// Current size of `region`, in pages.\n /// Each page is 64KiB (65536 bytes).\n /// Initially `0`.\n /// Preserved across upgrades, together with contents of allocated\n /// stable memory.\n ///\n /// Example:\n /// ```motoko no-repl\n /// let region = Region.new();\n /// let beforeSize = Region.size(region);\n /// ignore Region.grow(region, 10);\n /// let afterSize = Region.size(region);\n /// afterSize - beforeSize // => 10\n /// ```\n public let size : (region : Region) -> (pages : Nat64) = Prim.regionSize;\n\n /// Grow current `size` of `region` by the given number of pages.\n /// Each page is 64KiB (65536 bytes).\n /// Returns the previous `size` when able to grow.\n /// Returns `0xFFFF_FFFF_FFFF_FFFF` if remaining pages insufficient.\n /// Every new page is zero-initialized, containing byte 0x00 at every offset.\n /// Function `grow` is capped by a soft limit on `size` controlled by compile-time flag\n /// `--max-stable-pages <n>` (the default is 65536, or 4GiB).\n ///\n /// Example:\n /// ```motoko no-repl\n /// import Error \"mo:base/Error\";\n ///\n /// let region = Region.new();\n /// let beforeSize = Region.grow(region, 10);\n /// if (beforeSize == 0xFFFF_FFFF_FFFF_FFFF) {\n /// throw Error.reject(\"Out of memory\");\n /// };\n /// let afterSize = Region.size(region);\n /// afterSize - beforeSize // => 10\n /// ```\n public let grow : (region : Region, newPages : Nat64) -> (oldPages : Nat64) = Prim.regionGrow;\n\n\n /// Within `region`, load a `Nat8` value from `offset`.\n /// Traps on an out-of-bounds access.\n ///\n /// Example:\n /// ```motoko no-repl\n /// let region = Region.new();\n /// let offset = 0;\n /// let value = 123;\n /// Region.storeNat8(region, offset, value);\n /// Region.loadNat8(region, offset) // => 123\n /// ```\n public let loadNat8 : (region : Region, offset : Nat64) -> Nat8 = Prim.regionLoadNat8;\n\n /// Within `region`, store a `Nat8` value at `offset`.\n /// Traps on an out-of-bounds access.\n ///\n /// Example:\n /// ```motoko no-repl\n /// let region = Region.new();\n /// let offset = 0;\n /// let value = 123;\n /// Region.storeNat8(region, offset, value);\n /// Region.loadNat8(region, offset) // => 123\n /// ```\n public let storeNat8 : (region : Region, offset : Nat64, value : Nat8) -> () = Prim.regionStoreNat8;\n\n /// Within `region`, load a `Nat16` value from `offset`.\n /// Traps on an out-of-bounds access.\n ///\n /// Example:\n /// ```motoko no-repl\n /// let region = Region.new();\n /// let offset = 0;\n /// let value = 123;\n /// Region.storeNat16(region, offset, value);\n /// Region.loadNat16(region, offset) // => 123\n /// ```\n public let loadNat16 : (region : Region, offset : Nat64) -> Nat16 = Prim.regionLoadNat16;\n\n /// Within `region`, store a `Nat16` value at `offset`.\n /// Traps on an out-of-bounds access.\n ///\n /// Example:\n /// ```motoko no-repl\n /// let region = Region.new();\n /// let offset = 0;\n /// let value = 123;\n /// Region.storeNat16(region, offset, value);\n /// Region.loadNat16(region, offset) // => 123\n /// ```\n public let storeNat16 : (region : Region, offset : Nat64, value : Nat16) -> () = Prim.regionStoreNat16;\n\n /// Within `region`, load a `Nat32` value from `offset`.\n /// Traps on an out-of-bounds access.\n ///\n /// Example:\n /// ```motoko no-repl\n /// let region = Region.new();\n /// let offset = 0;\n /// let value = 123;\n /// Region.storeNat32(region, offset, value);\n /// Region.loadNat32(region, offset) // => 123\n /// ```\n public let loadNat32 : (region : Region, offset : Nat64) -> Nat32 = Prim.regionLoadNat32;\n\n /// Within `region`, store a `Nat32` value at `offset`.\n /// Traps on an out-of-bounds access.\n ///\n /// Example:\n /// ```motoko no-repl\n /// let region = Region.new();\n /// let offset = 0;\n /// let value = 123;\n /// Region.storeNat32(region, offset, value);\n /// Region.loadNat32(region, offset) // => 123\n /// ```\n public let storeNat32 : (region : Region, offset : Nat64, value : Nat32) -> () = Prim.regionStoreNat32;\n\n /// Within `region`, load a `Nat64` value from `offset`.\n /// Traps on an out-of-bounds access.\n ///\n /// Example:\n /// ```motoko no-repl\n /// let region = Region.new();\n /// let offset = 0;\n /// let value = 123;\n /// Region.storeNat64(region, offset, value);\n /// Region.loadNat64(region, offset) // => 123\n /// ```\n public let loadNat64 : (region : Region, offset : Nat64) -> Nat64 = Prim.regionLoadNat64;\n\n /// Within `region`, store a `Nat64` value at `offset`.\n /// Traps on an out-of-bounds access.\n ///\n /// Example:\n /// ```motoko no-repl\n /// let region = Region.new();\n /// let offset = 0;\n /// let value = 123;\n /// Region.storeNat64(region, offset, value);\n /// Region.loadNat64(region, offset) // => 123\n /// ```\n public let storeNat64 : (region : Region, offset : Nat64, value : Nat64) -> () = Prim.regionStoreNat64;\n\n /// Within `region`, load a `Int8` value from `offset`.\n /// Traps on an out-of-bounds access.\n ///\n /// Example:\n /// ```motoko no-repl\n /// let region = Region.new();\n /// let offset = 0;\n /// let value = 123;\n /// Region.storeInt8(region, offset, value);\n /// Region.loadInt8(region, offset) // => 123\n /// ```\n public let loadInt8 : (region : Region, offset : Nat64) -> Int8 = Prim.regionLoadInt8;\n\n /// Within `region`, store a `Int8` value at `offset`.\n /// Traps on an out-of-bounds access.\n ///\n /// Example:\n /// ```motoko no-repl\n /// let region = Region.new();\n /// let offset = 0;\n /// let value = 123;\n /// Region.storeInt8(region, offset, value);\n /// Region.loadInt8(region, offset) // => 123\n /// ```\n public let storeInt8 : (region : Region, offset : Nat64, value : Int8) -> () = Prim.regionStoreInt8;\n\n /// Within `region`, load a `Int16` value from `offset`.\n /// Traps on an out-of-bounds access.\n ///\n /// Example:\n /// ```motoko no-repl\n /// let region = Region.new();\n /// let offset = 0;\n /// let value = 123;\n /// Region.storeInt16(region, offset, value);\n /// Region.loadInt16(region, offset) // => 123\n /// ```\n public let loadInt16 : (region : Region, offset : Nat64) -> Int16 = Prim.regionLoadInt16;\n\n /// Within `region`, store a `Int16` value at `offset`.\n /// Traps on an out-of-bounds access.\n ///\n /// Example:\n /// ```motoko no-repl\n /// let region = Region.new();\n /// let offset = 0;\n /// let value = 123;\n /// Region.storeInt16(region, offset, value);\n /// Region.loadInt16(region, offset) // => 123\n /// ```\n public let storeInt16 : (region : Region, offset : Nat64, value : Int16) -> () = Prim.regionStoreInt16;\n\n /// Within `region`, load a `Int32` value from `offset`.\n /// Traps on an out-of-bounds access.\n ///\n /// Example:\n /// ```motoko no-repl\n /// let region = Region.new();\n /// let offset = 0;\n /// let value = 123;\n /// Region.storeInt32(region, offset, value);\n /// Region.loadInt32(region, offset) // => 123\n /// ```\n public let loadInt32 : (region : Region, offset : Nat64) -> Int32 = Prim.regionLoadInt32;\n\n /// Within `region`, store a `Int32` value at `offset`.\n /// Traps on an out-of-bounds access.\n ///\n /// Example:\n /// ```motoko no-repl\n /// let region = Region.new();\n /// let offset = 0;\n /// let value = 123;\n /// Region.storeInt32(region, offset, value);\n /// Region.loadInt32(region, offset) // => 123\n /// ```\n public let storeInt32 : (region : Region, offset : Nat64, value : Int32) -> () = Prim.regionStoreInt32;\n\n /// Within `region`, load a `Int64` value from `offset`.\n /// Traps on an out-of-bounds access.\n ///\n /// Example:\n /// ```motoko no-repl\n /// let region = Region.new();\n /// let offset = 0;\n /// let value = 123;\n /// Region.storeInt64(region, offset, value);\n /// Region.loadInt64(region, offset) // => 123\n /// ```\n public let loadInt64 : (region : Region, offset : Nat64) -> Int64 = Prim.regionLoadInt64;\n\n /// Within `region`, store a `Int64` value at `offset`.\n /// Traps on an out-of-bounds access.\n ///\n /// Example:\n /// ```motoko no-repl\n /// let region = Region.new();\n /// let offset = 0;\n /// let value = 123;\n /// Region.storeInt64(region, offset, value);\n /// Region.loadInt64(region, offset) // => 123\n /// ```\n public let storeInt64 : (region : Region, offset : Nat64, value : Int64) -> () = Prim.regionStoreInt64;\n\n\n /// Within `region`, loads a `Float` value from the given `offset`.\n /// Traps on an out-of-bounds access.\n ///\n /// Example:\n /// ```motoko no-repl\n /// let region = Region.new();\n /// let offset = 0;\n /// let value = 1.25;\n /// Region.storeFloat(region, offset, value);\n /// Region.loadFloat(region, offset) // => 1.25\n /// ```\n public let loadFloat : (region : Region, offset : Nat64) -> Float = Prim.regionLoadFloat;\n\n /// Within `region`, store float `value` at the given `offset`.\n /// Traps on an out-of-bounds access.\n ///\n /// Example:\n /// ```motoko no-repl\n /// let region = Region.new();\n /// let offset = 0;\n /// let value = 1.25;\n /// Region.storeFloat(region, offset, value);\n /// Region.loadFloat(region, offset) // => 1.25\n /// ```\n public let storeFloat : (region: Region, offset : Nat64, value : Float) -> () = Prim.regionStoreFloat;\n\n /// Within `region,` load `size` bytes starting from `offset` as a `Blob`.\n /// Traps on an out-of-bounds access.\n ///\n /// Example:\n /// ```motoko no-repl\n /// import Blob \"mo:base/Blob\";\n ///\n /// let region = Region.new();\n /// let offset = 0;\n /// let value = Blob.fromArray([1, 2, 3]);\n /// let size = value.size();\n /// Region.storeBlob(region, offset, value);\n /// Blob.toArray(Region.loadBlob(region, offset, size)) // => [1, 2, 3]\n /// ```\n public let loadBlob : (region : Region, offset : Nat64, size : Nat) -> Blob = Prim.regionLoadBlob;\n\n /// Within `region, write `blob.size()` bytes of `blob` beginning at `offset`.\n /// Traps on an out-of-bounds access.\n ///\n /// Example:\n /// ```motoko no-repl\n /// import Blob \"mo:base/Blob\";\n ///\n /// let region = Region.new();\n /// let offset = 0;\n /// let value = Blob.fromArray([1, 2, 3]);\n /// let size = value.size();\n /// Region.storeBlob(region, offset, value);\n /// Blob.toArray(Region.loadBlob(region, offset, size)) // => [1, 2, 3]\n /// ```\n public let storeBlob : (region : Region, offset : Nat64, value : Blob) -> () = Prim.regionStoreBlob;\n\n}\n"},"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/// LIMITATIONS: This data structure allows at most MAX_LEAF_SIZE=8 hash collisions:\n/// attempts to insert more than MAX_LEAF_SIZE keys (whether directly via `put` or indirectly via other operations) with the same hash value will trap.\n/// This limitation is inherited from the underlying `Trie` data structure.\n///\n///\n/// Note: 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 /// Note: The deletion of an existing key shrinks the trie map.\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 /// Note: The deletion of an existing key shrinks the trie map.\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"},"OrderedSet.mo":{"content":"/// Stable ordered set implemented as a red-black tree.\n///\n/// A red-black tree is a balanced binary search tree ordered by the elements.\n///\n/// The tree data structure internally colors each of its nodes either red or black,\n/// and uses this information to balance the tree during the modifying operations.\n///\n/// Performance:\n/// * Runtime: `O(log(n))` worst case cost per insertion, removal, and retrieval operation.\n/// * Space: `O(n)` for storing the entire tree.\n/// `n` denotes the number of elements (i.e. nodes) stored in the tree.\n///\n/// Credits:\n///\n/// The core of this implementation is derived from:\n///\n/// * Ken Friis Larsen's [RedBlackMap.sml](https://github.com/kfl/mosml/blob/master/src/mosmllib/Redblackmap.sml), which itself is based on:\n/// * Stefan Kahrs, \"Red-black trees with types\", Journal of Functional Programming, 11(4): 425-432 (2001), [version 1 in web appendix](http://www.cs.ukc.ac.uk/people/staff/smk/redblack/rb.html).\n\nimport Debug \"Debug\";\nimport Buffer \"Buffer\";\nimport I \"Iter\";\nimport List \"List\";\nimport Nat \"Nat\";\nimport O \"Order\";\n\nmodule {\n /// Red-black tree of nodes with ordered set elements.\n /// Leaves are considered implicitly black.\n type Tree<T> = {\n #red : (Tree<T>, T, Tree<T>);\n #black : (Tree<T>, T, Tree<T>);\n #leaf\n };\n\n /// Ordered collection of unique elements of the generic type `T`.\n /// If type `T` is stable then `Set<T>` is also stable.\n /// To ensure that property the `Set<T>` does not have any methods,\n /// instead they are gathered in the functor-like class `Operations` (see example there).\n public type Set<T> = { size : Nat; root : Tree<T> };\n\n /// Class that captures element type `T` along with its ordering function `compare`\n /// and provide all operations to work with a set of type `Set<T>`.\n ///\n /// An instance object should be created once as a canister field to ensure\n /// that the same ordering function is used for every operation.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:base/OrderedSet\";\n /// import Nat \"mo:base/Nat\";\n ///\n /// actor {\n /// let natSet = Set.Make<Nat>(Nat.compare); // : Operations<Nat>\n /// stable var usedIds : Set.Set<Nat> = natSet.empty();\n /// \n /// public func createId(id : Nat) : async () {\n /// usedIds := natSet.put(usedIds, id);\n /// };\n /// \n /// public func idIsUsed(id: Nat) : async Bool {\n /// natSet.contains(usedIds, id)\n /// }\n /// }\n /// ```\n public class Operations<T>(compare : (T, T) -> O.Order) {\n\n /// Returns a new Set, containing all entries given by the iterator `i`.\n /// If there are multiple identical entries only one is taken.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:base/OrderedSet\";\n /// import Nat \"mo:base/Nat\";\n /// import Iter \"mo:base/Iter\";\n /// import Debug \"mo:base/Debug\";\n ///\n /// let natSet = Set.Make<Nat>(Nat.compare);\n /// let set = natSet.fromIter(Iter.fromArray([0, 2, 1]));\n ///\n /// Debug.print(debug_show(Iter.toArray(natSet.vals(set))));\n /// // [0, 1, 2]\n /// ```\n ///\n /// Runtime: `O(n * log(n))`.\n /// Space: `O(n)` retained memory plus garbage, see the note below.\n /// where `n` denotes the number of elements stored in the set and\n /// assuming that the `compare` function implements an `O(1)` comparison.\n ///\n /// Note: Creates `O(n * log(n))` temporary objects that will be collected as garbage.\n public func fromIter(i : I.Iter<T>) : Set<T> {\n var set = empty() : Set<T>;\n for (val in i) {\n set := Internal.put(set, compare, val)\n };\n set\n };\n\n /// Insert the value `value` into the set `s`. Has no effect if `value` is already\n /// present in the set. Returns a modified set.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:base/OrderedSet\";\n /// import Nat \"mo:base/Nat\";\n /// import Iter \"mo:base/Iter\";\n /// import Debug \"mo:base/Debug\";\n ///\n /// let natSet = Set.Make<Nat>(Nat.compare);\n /// var set = natSet.empty();\n ///\n /// set := natSet.put(set, 0);\n /// set := natSet.put(set, 2);\n /// set := natSet.put(set, 1);\n ///\n /// Debug.print(debug_show(Iter.toArray(natSet.vals(set))));\n /// // [0, 1, 2]\n /// ```\n ///\n /// Runtime: `O(log(n))`.\n /// Space: `O(log(n))`.\n /// where `n` denotes the number of elements stored in the set and\n /// assuming that the `compare` function implements an `O(1)` comparison.\n ///\n /// Note: The returned set shares with the `s` most of the tree nodes. \n /// Garbage collecting one of sets (e.g. after an assignment `m := natSet.delete(m, k)`)\n /// causes collecting `O(log(n))` nodes.\n public func put(s : Set<T>, value : T) : Set<T> \n = Internal.put(s, compare, value);\n\n /// Deletes the value `value` from the set `s`. Has no effect if `value` is not\n /// present in the set. Returns modified set.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:base/OrderedSet\";\n /// import Nat \"mo:base/Nat\";\n /// import Iter \"mo:base/Iter\";\n /// import Debug \"mo:base/Debug\";\n ///\n /// let natSet = Set.Make<Nat>(Nat.compare);\n /// let set = natSet.fromIter(Iter.fromArray([0, 2, 1]));\n ///\n /// Debug.print(debug_show(Iter.toArray(natSet.vals(natSet.delete(set, 1)))));\n /// Debug.print(debug_show(Iter.toArray(natSet.vals(natSet.delete(set, 42)))));\n /// // [0, 2]\n /// // [0, 1, 2]\n /// ```\n ///\n /// Runtime: `O(log(n))`.\n /// Space: `O(log(n))`.\n /// where `n` denotes the number of elements stored in the set and\n /// assuming that the `compare` function implements an `O(1)` comparison.\n ///\n /// Note: The returned set shares with the `s` most of the tree nodes. \n /// Garbage collecting one of sets (e.g. after an assignment `m := natSet.delete(m, k)`)\n /// causes collecting `O(log(n))` nodes.\n public func delete(s : Set<T>, value : T) : Set<T> \n = Internal.delete(s, compare, value);\n\n /// Test if the set 's' contains a given element.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:base/OrderedSet\";\n /// import Nat \"mo:base/Nat\";\n /// import Iter \"mo:base/Iter\";\n /// import Debug \"mo:base/Debug\";\n ///\n /// let natSet = Set.Make<Nat>(Nat.compare);\n /// let set = natSet.fromIter(Iter.fromArray([0, 2, 1]));\n ///\n /// Debug.print(debug_show natSet.contains(set, 1)); // => true\n /// Debug.print(debug_show natSet.contains(set, 42)); // => false\n /// ```\n ///\n /// Runtime: `O(log(n))`.\n /// Space: `O(1)` retained memory plus garbage, see the note below.\n /// where `n` denotes the number of elements stored in the set and\n /// assuming that the `compare` function implements an `O(1)` comparison.\n public func contains(s : Set<T>, value : T) : Bool \n = Internal.contains(s.root, compare, value);\n\n /// Get a maximal element of the set `s` if it is not empty, otherwise returns `null`\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:base/OrderedSet\";\n /// import Nat \"mo:base/Nat\";\n /// import Iter \"mo:base/Iter\";\n /// import Debug \"mo:base/Debug\";\n ///\n /// let natSet = Set.Make<Nat>(Nat.compare);\n /// let s1 = natSet.fromIter(Iter.fromArray([0, 2, 1]));\n /// let s2 = natSet.empty();\n ///\n /// Debug.print(debug_show(natSet.max(s1))); // => ?2\n /// Debug.print(debug_show(natSet.max(s2))); // => null\n /// ```\n ///\n /// Runtime: `O(log(n))`.\n /// Space: `O(1)`.\n /// where `n` denotes the number of elements in the set\n public func max(s : Set<T>) : ?T\n = Internal.max(s.root);\n\n /// Get a minimal element of the set `s` if it is not empty, otherwise returns `null`\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:base/OrderedSet\";\n /// import Nat \"mo:base/Nat\";\n /// import Iter \"mo:base/Iter\";\n /// import Debug \"mo:base/Debug\";\n ///\n /// let natSet = Set.Make<Nat>(Nat.compare);\n /// let s1 = natSet.fromIter(Iter.fromArray([0, 2, 1]));\n /// let s2 = natSet.empty();\n ///\n /// Debug.print(debug_show(natSet.min(s1))); // => ?0\n /// Debug.print(debug_show(natSet.min(s2))); // => null\n /// ```\n ///\n /// Runtime: `O(log(n))`.\n /// Space: `O(1)`.\n /// where `n` denotes the number of elements in the set\n public func min(s : Set<T>) : ?T\n = Internal.min(s.root);\n\n /// [Set union](https://en.wikipedia.org/wiki/Union_(set_theory)) operation.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:base/OrderedSet\";\n /// import Nat \"mo:base/Nat\";\n /// import Iter \"mo:base/Iter\";\n /// import Debug \"mo:base/Debug\";\n ///\n /// let natSet = Set.Make<Nat>(Nat.compare);\n /// let set1 = natSet.fromIter(Iter.fromArray([0, 1, 2]));\n /// let set2 = natSet.fromIter(Iter.fromArray([2, 3, 4]));\n ///\n /// Debug.print(debug_show Iter.toArray(natSet.vals(natSet.union(set1, set2))));\n /// // [0, 1, 2, 3, 4]\n /// ```\n ///\n /// Runtime: `O(m * log(n))`.\n /// Space: `O(m)`, retained memory plus garbage, see the note below.\n /// where `m` and `n` denote the number of elements in the sets, and `m <= n`.\n ///\n /// Note: Creates `O(m * log(n))` temporary objects that will be collected as garbage.\n public func union(s1 : Set<T>, s2 : Set<T>) : Set<T> {\n if (size(s1) < size(s2)) {\n foldLeft(s1, s2, func(acc : Set<T>, elem : T) : Set<T> { Internal.put(acc, compare, elem) })\n } else {\n foldLeft(s2, s1, func(acc : Set<T>, elem : T) : Set<T> { Internal.put(acc, compare, elem) })\n }\n };\n\n /// [Set intersection](https://en.wikipedia.org/wiki/Intersection_(set_theory)) operation.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:base/OrderedSet\";\n /// import Nat \"mo:base/Nat\";\n /// import Iter \"mo:base/Iter\";\n /// import Debug \"mo:base/Debug\";\n ///\n /// let natSet = Set.Make<Nat>(Nat.compare);\n /// let set1 = natSet.fromIter(Iter.fromArray([0, 1, 2]));\n /// let set2 = natSet.fromIter(Iter.fromArray([1, 2, 3]));\n ///\n /// Debug.print(debug_show Iter.toArray(natSet.vals(natSet.intersect(set1, set2))));\n /// // [1, 2]\n /// ```\n ///\n /// Runtime: `O(m * log(n))`.\n /// Space: `O(m)`, retained memory plus garbage, see the note below.\n /// where `m` and `n` denote the number of elements in the sets, and `m <= n`.\n ///\n /// Note: Creates `O(m)` temporary objects that will be collected as garbage.\n public func intersect(s1 : Set<T>, s2 : Set<T>) : Set<T> {\n let elems = Buffer.Buffer<T>(Nat.min(Nat.min(s1.size, s2.size), 100));\n if (s1.size < s2.size) {\n Internal.iterate(s1.root, func (x: T) {\n if (Internal.contains(s2.root, compare, x)) {\n elems.add(x)\n }\n });\n } else {\n Internal.iterate(s2.root, func (x: T) {\n if (Internal.contains(s1.root, compare, x)) {\n elems.add(x)\n }\n });\n };\n { root = Internal.buildFromSorted(elems); size = elems.size() }\n };\n\n /// [Set difference](https://en.wikipedia.org/wiki/Difference_(set_theory)).\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:base/OrderedSet\";\n /// import Nat \"mo:base/Nat\";\n /// import Iter \"mo:base/Iter\";\n /// import Debug \"mo:base/Debug\";\n ///\n /// let natSet = Set.Make<Nat>(Nat.compare);\n /// let set1 = natSet.fromIter(Iter.fromArray([0, 1, 2]));\n /// let set2 = natSet.fromIter(Iter.fromArray([1, 2, 3]));\n ///\n /// Debug.print(debug_show Iter.toArray(natSet.vals(natSet.diff(set1, set2))));\n /// // [0]\n /// ```\n ///\n /// Runtime: `O(m * log(n))`.\n /// Space: `O(m)`, retained memory plus garbage, see the note below.\n /// where `m` and `n` denote the number of elements in the sets, and `m <= n`.\n ///\n /// Note: Creates `O(m * log(n))` temporary objects that will be collected as garbage.\n public func diff(s1 : Set<T>, s2 : Set<T>) : Set<T> {\n if (size(s1) < size(s2)) {\n let elems = Buffer.Buffer<T>(Nat.min(s1.size, 100));\n Internal.iterate(s1.root, func (x : T) {\n if (not Internal.contains(s2.root, compare, x)) { \n elems.add(x)\n }\n }\n );\n { root = Internal.buildFromSorted(elems); size = elems.size() }\n }\n else {\n foldLeft(s2, s1,\n func (acc : Set<T>, elem : T) : Set<T> {\n if (Internal.contains(acc.root, compare, elem)) { Internal.delete(acc, compare, elem) } else { acc }\n }\n )\n }\n };\n\n /// Creates a new `Set` by applying `f` to each entry in the set `s`. Each element\n /// `x` in the old set is transformed into a new entry `x2`, where\n /// the new value `x2` is created by applying `f` to `x`.\n /// The result set may be smaller than the original set due to duplicate elements.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:base/OrderedSet\";\n /// import Nat \"mo:base/Nat\";\n /// import Iter \"mo:base/Iter\";\n /// import Debug \"mo:base/Debug\";\n ///\n /// let natSet = Set.Make<Nat>(Nat.compare);\n /// let set = natSet.fromIter(Iter.fromArray([0, 1, 2, 3]));\n ///\n /// func f(x : Nat) : Nat = if (x < 2) { x } else { 0 };\n ///\n /// let resSet = natSet.map(set, f);\n ///\n /// Debug.print(debug_show(Iter.toArray(natSet.vals(resSet))));\n /// // [0, 1]\n /// ```\n ///\n /// Cost of mapping all the elements:\n /// Runtime: `O(n * log(n))`.\n /// Space: `O(n)` retained memory\n /// where `n` denotes the number of elements stored in the set.\n ///\n /// Note: Creates `O(n * log(n))` temporary objects that will be collected as garbage.\n public func map<T1>(s : Set<T1>, f : T1 -> T) : Set<T>\n = Internal.foldLeft(s.root, empty(), func (acc : Set<T>, elem : T1) : Set<T> { Internal.put(acc, compare, f(elem)) });\n\n /// Creates a new set by applying `f` to each element in the set `s`. For each element\n /// `x` in the old set, if `f` evaluates to `null`, the element is discarded.\n /// Otherwise, the entry is transformed into a new entry `x2`, where\n /// the new value `x2` is the result of applying `f` to `x`.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:base/OrderedSet\";\n /// import Nat \"mo:base/Nat\";\n /// import Iter \"mo:base/Iter\";\n /// import Debug \"mo:base/Debug\";\n ///\n /// let natSet = Set.Make<Nat>(Nat.compare);\n /// let set = natSet.fromIter(Iter.fromArray([0, 1, 2, 3]));\n ///\n /// func f(x : Nat) : ?Nat {\n /// if(x == 0) {null}\n /// else { ?( x * 2 )}\n /// };\n ///\n /// let newRbSet = natSet.mapFilter(set, f);\n ///\n /// Debug.print(debug_show(Iter.toArray(natSet.vals(newRbSet))));\n /// // [2, 4, 6]\n /// ```\n ///\n /// Runtime: `O(n * log(n))`.\n /// Space: `O(n)` retained memory plus garbage, see the note below.\n /// where `n` denotes the number of elements stored in the set and\n /// assuming that the `compare` function implements an `O(1)` comparison.\n ///\n /// Note: Creates `O(n * log(n))` temporary objects that will be collected as garbage.\n public func mapFilter<T1>(s : Set<T1>, f : T1 -> ?T) : Set<T> {\n func combine(acc : Set<T>, elem : T1) : Set<T> {\n switch (f(elem)) {\n case null { acc };\n case (?elem2) {\n Internal.put(acc, compare, elem2)\n }\n }\n };\n Internal.foldLeft(s.root, empty(), combine)\n };\n\n /// Test if `set1` is subset of `set2`.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:base/OrderedSet\";\n /// import Nat \"mo:base/Nat\";\n /// import Iter \"mo:base/Iter\";\n /// import Debug \"mo:base/Debug\";\n ///\n /// let natSet = Set.Make<Nat>(Nat.compare);\n /// let set1 = natSet.fromIter(Iter.fromArray([1, 2]));\n /// let set2 = natSet.fromIter(Iter.fromArray([0, 2, 1]));\n ///\n /// Debug.print(debug_show natSet.isSubset(set1, set2)); // => true\n /// ```\n ///\n /// Runtime: `O(m * log(n))`.\n /// Space: `O(1)` retained memory plus garbage, see the note below.\n /// where `m` and `n` denote the number of elements stored in the sets set1 and set2, respectively,\n /// and assuming that the `compare` function implements an `O(1)` comparison.\n public func isSubset(s1 : Set<T>, s2 : Set<T>) : Bool {\n if (s1.size > s2.size) { return false };\n isSubsetHelper(s1.root, s2.root)\n };\n\n /// Test if two sets are equal.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:base/OrderedSet\";\n /// import Nat \"mo:base/Nat\";\n /// import Iter \"mo:base/Iter\";\n /// import Debug \"mo:base/Debug\";\n ///\n /// let natSet = Set.Make<Nat>(Nat.compare);\n /// let set1 = natSet.fromIter(Iter.fromArray([0, 2, 1]));\n /// let set2 = natSet.fromIter(Iter.fromArray([1, 2]));\n ///\n /// Debug.print(debug_show natSet.equals(set1, set1)); // => true\n /// Debug.print(debug_show natSet.equals(set1, set2)); // => false\n /// ```\n ///\n /// Runtime: `O(m * log(n))`.\n /// Space: `O(1)` retained memory plus garbage, see the note below.\n /// where `m` and `n` denote the number of elements stored in the sets set1 and set2, respectively,\n /// and assuming that the `compare` function implements an `O(1)` comparison.\n public func equals(s1 : Set<T>, s2 : Set<T>) : Bool {\n if (s1.size != s2.size) { return false };\n isSubsetHelper(s1.root, s2.root)\n };\n\n func isSubsetHelper(t1 : Tree<T>, t2 : Tree<T>) : Bool {\n switch (t1, t2) {\n case (#leaf, _) { true };\n case (_, #leaf) { false };\n case ((#red(t1l, x1, t1r) or #black(t1l, x1, t1r)), (#red(t2l, x2, t2r)) or #black(t2l, x2, t2r)) {\n switch (compare(x1, x2)) {\n case (#equal) { isSubsetHelper(t1l, t2l) and isSubsetHelper(t1r, t2r) };\n // x1 < x2 ==> x1 \\in t2l /\\ t1l \\subset t2l\n case (#less) { Internal.contains(t2l, compare, x1) and isSubsetHelper(t1l, t2l) and isSubsetHelper(t1r, t2) };\n // x2 < x1 ==> x1 \\in t2r /\\ t1r \\subset t2r \n case (#greater) { Internal.contains(t2r, compare, x1) and isSubsetHelper(t1l, t2) and isSubsetHelper(t1r, t2r) }\n }\n }\n }\n };\n\n /// Returns an Iterator (`Iter`) over the elements of the set.\n /// Iterator provides a single method `next()`, which returns\n /// elements in ascending order, or `null` when out of elements to iterate over.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:base/OrderedSet\";\n /// import Nat \"mo:base/Nat\";\n /// import Iter \"mo:base/Iter\";\n /// import Debug \"mo:base/Debug\";\n ///\n /// let natSet = Set.Make<Nat>(Nat.compare);\n /// let set = natSet.fromIter(Iter.fromArray([0, 2, 1]));\n ///\n /// Debug.print(debug_show(Iter.toArray(natSet.vals(set))));\n /// // [0, 1, 2]\n /// ```\n /// Cost of iteration over all elements:\n /// Runtime: `O(n)`.\n /// Space: `O(log(n))` retained memory plus garbage, see the note below.\n /// where `n` denotes the number of elements stored in the set.\n ///\n /// Note: Full set iteration creates `O(n)` temporary objects that will be collected as garbage.\n public func vals(s : Set<T>) : I.Iter<T> \n = Internal.iter(s.root, #fwd);\n\n /// Same as `vals()` but iterates over elements of the set `s` in the descending order.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:base/OrderedSet\";\n /// import Nat \"mo:base/Nat\";\n /// import Iter \"mo:base/Iter\";\n /// import Debug \"mo:base/Debug\";\n ///\n /// let natSet = Set.Make<Nat>(Nat.compare);\n /// let set = natSet.fromIter(Iter.fromArray([0, 2, 1]));\n ///\n /// Debug.print(debug_show(Iter.toArray(natSet.valsRev(set))));\n /// // [2, 1, 0]\n /// ```\n /// Cost of iteration over all elements:\n /// Runtime: `O(n)`.\n /// Space: `O(log(n))` retained memory plus garbage, see the note below.\n /// where `n` denotes the number of elements stored in the set.\n ///\n /// Note: Full set iteration creates `O(n)` temporary objects that will be collected as garbage.\n public func valsRev(s : Set<T>) : I.Iter<T>\n = Internal.iter(s.root, #bwd);\n\n /// Create a new empty Set.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:base/OrderedSet\";\n /// import Nat \"mo:base/Nat\";\n /// import Debug \"mo:base/Debug\";\n /// \n /// let natSet = Set.Make<Nat>(Nat.compare);\n /// let set = natSet.empty();\n /// \n /// Debug.print(debug_show(natSet.size(set))); // => 0\n /// ```\n ///\n /// Cost of empty set creation\n /// Runtime: `O(1)`.\n /// Space: `O(1)`\n public func empty() : Set<T> \n = { root = #leaf; size = 0};\n\n /// Returns the number of elements in the set.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:base/OrderedSet\";\n /// import Nat \"mo:base/Nat\";\n /// import Iter \"mo:base/Iter\";\n /// import Debug \"mo:base/Debug\";\n ///\n /// let natSet = Set.Make<Nat>(Nat.compare);\n /// let set = natSet.fromIter(Iter.fromArray([0, 2, 1]));\n ///\n /// Debug.print(debug_show(natSet.size(set))); // => 3\n /// ```\n ///\n /// Runtime: `O(1)`.\n /// Space: `O(1)`.\n public func size(s : Set<T>) : Nat\n = s.size;\n\n /// Collapses the elements in `set` into a single value by starting with `base`\n /// and progessively combining elements into `base` with `combine`. Iteration runs\n /// left to right.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:base/OrderedSet\";\n /// import Nat \"mo:base/Nat\";\n /// import Iter \"mo:base/Iter\";\n /// import Debug \"mo:base/Debug\";\n ///\n /// let natSet = Set.Make<Nat>(Nat.compare);\n /// let set = natSet.fromIter(Iter.fromArray([0, 2, 1]));\n ///\n /// func folder(accum : Nat, val : Nat) : Nat = val + accum;\n ///\n /// Debug.print(debug_show(natSet.foldLeft(set, 0, folder)));\n /// // 3\n /// ```\n ///\n /// Cost of iteration over all elements:\n /// Runtime: `O(n)`.\n /// Space: depends on `combine` function plus garbage, see the note below.\n /// where `n` denotes the number of elements stored in the set.\n ///\n /// Note: Full set iteration creates `O(n)` temporary objects that will be collected as garbage.\n public func foldLeft<Accum>(\n set : Set<T>,\n base : Accum,\n combine : (Accum, T) -> Accum\n ) : Accum\n = Internal.foldLeft(set.root, base, combine);\n\n /// Collapses the elements in `set` into a single value by starting with `base`\n /// and progessively combining elements into `base` with `combine`. Iteration runs\n /// right to left.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:base/OrderedSet\";\n /// import Nat \"mo:base/Nat\";\n /// import Iter \"mo:base/Iter\";\n /// import Debug \"mo:base/Debug\";\n ///\n /// let natSet = Set.Make<Nat>(Nat.compare);\n /// let set = natSet.fromIter(Iter.fromArray([0, 2, 1]));\n ///\n /// func folder(val : Nat, accum : Nat) : Nat = val + accum;\n ///\n /// Debug.print(debug_show(natSet.foldRight(set, 0, folder)));\n /// // 3\n /// ```\n ///\n /// Cost of iteration over all elements:\n /// Runtime: `O(n)`.\n /// Space: depends on `combine` function plus garbage, see the note below.\n /// where `n` denotes the number of elements stored in the set.\n ///\n /// Note: Full set iteration creates `O(n)` temporary objects that will be collected as garbage.\n public func foldRight<Accum>(\n set : Set<T>,\n base : Accum,\n combine : (T, Accum) -> Accum\n ) : Accum\n = Internal.foldRight(set.root, base, combine);\n\n /// Test if the given set `s` is empty.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:base/OrderedSet\";\n /// import Nat \"mo:base/Nat\";\n /// import Debug \"mo:base/Debug\";\n /// \n /// let natSet = Set.Make<Nat>(Nat.compare);\n /// let set = natSet.empty();\n /// \n /// Debug.print(debug_show(natSet.isEmpty(set))); // => true\n /// ```\n ///\n /// Runtime: `O(1)`.\n /// Space: `O(1)`.\n public func isEmpty(s : Set<T>) : Bool {\n switch (s.root) {\n case (#leaf) { true };\n case _ { false }\n }\n };\n\n /// Test whether all values in the set `s` satisfy a given predicate `pred`.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:base/OrderedSet\";\n /// import Nat \"mo:base/Nat\";\n /// import Iter \"mo:base/Iter\";\n /// import Debug \"mo:base/Debug\";\n ///\n /// let natSet = Set.Make<Nat>(Nat.compare);\n /// let set = natSet.fromIter(Iter.fromArray([0, 2, 1]));\n ///\n /// Debug.print(debug_show(natSet.all(set, func (v) = (v < 10))));\n /// // true\n /// Debug.print(debug_show(natSet.all(set, func (v) = (v < 2))));\n /// // false\n /// ```\n ///\n /// Runtime: `O(n)`.\n /// Space: `O(1)`.\n /// where `n` denotes the number of elements stored in the set.\n public func all(s : Set<T>, pred : T -> Bool) : Bool\n = Internal.all(s.root, pred);\n\n /// Test if there exists an element in the set `s` satisfying the given predicate `pred`.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:base/OrderedSet\";\n /// import Nat \"mo:base/Nat\";\n /// import Iter \"mo:base/Iter\";\n /// import Debug \"mo:base/Debug\";\n ///\n /// let natSet = Set.Make<Nat>(Nat.compare);\n /// let set = natSet.fromIter(Iter.fromArray([0, 2, 1]));\n ///\n /// Debug.print(debug_show(natSet.some(set, func (v) = (v >= 3))));\n /// // false\n /// Debug.print(debug_show(natSet.some(set, func (v) = (v >= 0))));\n /// // true\n /// ```\n ///\n /// Runtime: `O(n)`.\n /// Space: `O(1)`.\n /// where `n` denotes the number of elements stored in the set.\n public func some(s : Set<T>, pred : (T) -> Bool) : Bool\n = Internal.some(s.root, pred);\n\n /// Test helper that check internal invariant for the given set `s`. \n /// Raise an error (for a stack trace) if invariants are violated.\n public func validate(s : Set<T>): () {\n Internal.validate(s, compare);\n }\n };\n\n module Internal {\n public func contains<T>(tree : Tree<T>, compare : (T, T) -> O.Order, elem : T) : Bool {\n func f(t : Tree<T>, x : T) : Bool {\n switch t {\n case (#black(l, x1, r)) {\n switch (compare(x, x1)) {\n case (#less) { f(l, x) };\n case (#equal) { true };\n case (#greater) { f(r, x) }\n }\n };\n case (#red(l, x1, r)) {\n switch (compare(x, x1)) {\n case (#less) { f(l, x) };\n case (#equal) { true };\n case (#greater) { f(r, x) }\n }\n };\n case (#leaf) { false }\n }\n };\n f(tree, elem)\n };\n\n public func max<V>(m : Tree<V>) : ?V {\n func rightmost(m : Tree<V>) : V {\n switch m {\n case (#red(_, v, #leaf)) { v };\n case (#red(_, _, r)) { rightmost(r) };\n case (#black(_, v, #leaf)) { v };\n case (#black(_, _, r)) { rightmost(r) };\n case (#leaf) { Debug.trap \"OrderedSet.impossible\" }\n }\n };\n switch m {\n case (#leaf) { null };\n case (_) { ?rightmost(m) }\n }\n };\n\n public func min<V>(m : Tree<V>) : ?V {\n func leftmost(m : Tree<V>) : V {\n switch m {\n case (#red(#leaf, v, _)) { v };\n case (#red(l, _, _)) { leftmost(l) };\n case (#black(#leaf, v, _)) { v };\n case (#black(l, _, _)) { leftmost(l)};\n case (#leaf) { Debug.trap \"OrderedSet.impossible\" }\n }\n };\n switch m {\n case (#leaf) { null };\n case (_) { ?leftmost(m) }\n }\n };\n\n public func all<V>(m : Tree<V>, pred : V -> Bool) : Bool {\n switch m {\n case (#red(l, v, r)) {\n pred(v) and all(l, pred) and all(r, pred)\n };\n case (#black(l, v, r)) {\n pred(v) and all(l, pred) and all(r, pred)\n };\n case (#leaf) { true }\n }\n };\n\n public func some<V>(m : Tree<V>, pred : V -> Bool) : Bool {\n switch m {\n case (#red(l, v, r)) {\n pred(v) or some(l, pred) or some(r, pred)\n };\n case (#black(l, v, r)) {\n pred(v) or some(l, pred) or some(r, pred)\n };\n case (#leaf) { false }\n }\n };\n\n public func iterate<V>(m : Tree<V>, f : V -> ()) {\n switch m {\n case (#leaf) { };\n case (#black(l, v, r)) { iterate(l, f); f(v); iterate(r, f) };\n case (#red(l, v, r)) { iterate(l, f); f(v); iterate(r, f) }\n }\n };\n\n // build tree from elements arr[l]..arr[r-1]\n public func buildFromSorted<V>(buf : Buffer.Buffer<V>) : Tree<V> {\n var maxDepth = 0;\n var maxSize = 1;\n while (maxSize < buf.size()) {\n maxDepth += 1;\n maxSize += maxSize + 1;\n };\n maxDepth := if (maxDepth == 0) {1} else {maxDepth}; // keep root black for 1 element tree\n func buildFromSortedHelper(l : Nat, r : Nat, depth : Nat) : Tree<V> {\n if (l + 1 == r) {\n if (depth == maxDepth) {\n return #red(#leaf, buf.get(l), #leaf);\n } else {\n return #black(#leaf, buf.get(l), #leaf);\n }\n };\n if (l >= r) {\n return #leaf;\n };\n let m = (l + r) / 2;\n return #black(\n buildFromSortedHelper(l, m, depth+1), \n buf.get(m), \n buildFromSortedHelper(m+1, r, depth+1)\n )\n };\n buildFromSortedHelper(0, buf.size(), 0);\n };\n\n type IterRep<T> = List.List<{ #tr : Tree<T>; #x : T }>;\n\n type SetTraverser<T> = (Tree<T>, T, Tree<T>, IterRep<T>) -> IterRep<T>;\n\n class IterSet<T>(tree : Tree<T>, setTraverser : SetTraverser<T>) {\n var trees : IterRep<T> = ?(#tr(tree), null);\n public func next() : ?T {\n switch (trees) {\n case (null) { null };\n case (?(#tr(#leaf), ts)) {\n trees := ts;\n next()\n };\n case (?(#x(x), ts)) {\n trees := ts;\n ?x\n };\n case (?(#tr(#black(l, x, r)), ts)) {\n trees := setTraverser(l, x, r, ts);\n next()\n };\n case (?(#tr(#red(l, x, r)), ts)) {\n trees := setTraverser(l, x, r, ts);\n next()\n }\n }\n }\n };\n\n public func iter<T>(s : Tree<T>, direction : {#fwd; #bwd}) : I.Iter<T> {\n let turnLeftFirst : SetTraverser<T>\n = func (l, x, r, ts) { ?(#tr(l), ?(#x(x), ?(#tr(r), ts))) };\n\n let turnRightFirst : SetTraverser<T>\n = func (l, x, r, ts) { ?(#tr(r), ?(#x(x), ?(#tr(l), ts))) };\n\n switch direction {\n case (#fwd) IterSet(s, turnLeftFirst);\n case (#bwd) IterSet(s, turnRightFirst)\n }\n };\n\n public func foldLeft<T, Accum>(\n tree : Tree<T>,\n base : Accum,\n combine : (Accum, T) -> Accum\n ) : Accum {\n switch (tree) {\n case (#leaf) { base };\n case (#black(l, x, r)) {\n let left = foldLeft(l, base, combine);\n let middle = combine(left, x);\n foldLeft(r, middle, combine)\n };\n case (#red(l, x, r)) {\n let left = foldLeft(l, base, combine);\n let middle = combine(left, x);\n foldLeft(r, middle, combine)\n }\n }\n };\n\n public func foldRight<T, Accum>(\n tree : Tree<T>,\n base : Accum,\n combine : (T, Accum) -> Accum\n ) : Accum {\n switch (tree) {\n case (#leaf) { base };\n case (#black(l, x, r)) {\n let right = foldRight(r, base, combine);\n let middle = combine(x, right);\n foldRight(l, middle, combine)\n };\n case (#red(l, x, r)) {\n let right = foldRight(r, base, combine);\n let middle = combine(x, right);\n foldRight(l, middle, combine)\n }\n }\n };\n\n func redden<T>(t : Tree<T>) : Tree<T> {\n switch t {\n case (#black(l, x, r)) {\n (#red (l, x, r))\n };\n case _ {\n Debug.trap \"OrderedSet.red\"\n }\n }\n };\n\n func lbalance<T>(left : Tree<T>, x : T, right : Tree<T>) : Tree<T> {\n switch (left, right) {\n case (#red(#red(l1, x1, r1), x2, r2), r) {\n #red(\n #black(l1, x1, r1),\n x2,\n #black(r2, x, r)\n )\n };\n case (#red(l1, x1, #red(l2, x2, r2)), r) {\n #red(\n #black(l1, x1, l2),\n x2,\n #black(r2, x, r)\n )\n };\n case _ {\n #black(left, x, right)\n }\n }\n };\n\n func rbalance<T>(left : Tree<T>, x : T, right : Tree<T>) : Tree<T> {\n switch (left, right) {\n case (l, #red(l1, x1, #red(l2, x2, r2))) {\n #red(\n #black(l, x, l1),\n x1,\n #black(l2, x2, r2)\n )\n };\n case (l, #red(#red(l1, x1, r1), x2, r2)) {\n #red(\n #black(l, x, l1),\n x1,\n #black(r1, x2, r2)\n )\n };\n case _ {\n #black(left, x, right)\n }\n }\n };\n\n public func put<T>(\n s : Set<T>,\n compare : (T, T) -> O.Order,\n elem : T\n ) : Set<T> {\n var newNodeIsCreated : Bool = false;\n func ins(tree : Tree<T>) : Tree<T> {\n switch tree {\n case (#black(left, x, right)) {\n switch (compare(elem, x)) {\n case (#less) {\n lbalance(ins left, x, right)\n };\n case (#greater) {\n rbalance(left, x, ins right)\n };\n case (#equal) {\n #black(left, x, right)\n }\n }\n };\n case (#red(left, x, right)) {\n switch (compare(elem, x)) {\n case (#less) {\n #red(ins left, x, right)\n };\n case (#greater) {\n #red(left, x, ins right)\n };\n case (#equal) {\n #red(left, x, right)\n }\n }\n };\n case (#leaf) {\n newNodeIsCreated := true;\n #red(#leaf, elem, #leaf)\n }\n }\n };\n let newRoot = switch (ins(s.root)) {\n case (#red(left, x, right)) {\n #black(left, x, right)\n };\n case other { other }\n };\n { root = newRoot; \n size = if newNodeIsCreated { s.size + 1 } else { s.size } }\n };\n\n func balLeft<T>(left : Tree<T>, x : T, right : Tree<T>) : Tree<T> {\n switch (left, right) {\n case (#red(l1, x1, r1), r) {\n #red(#black(l1, x1, r1), x, r)\n };\n case (_, #black(l2, x2, r2)) {\n rbalance(left, x, #red(l2, x2, r2))\n };\n case (_, #red(#black(l2, x2, r2), x3, r3)) {\n #red(\n #black(left, x, l2),\n x2,\n rbalance(r2, x3, redden r3)\n )\n };\n case _ { Debug.trap \"balLeft\" }\n }\n };\n\n func balRight<T>(left : Tree<T>, x : T, right : Tree<T>) : Tree<T> {\n switch (left, right) {\n case (l, #red(l1, x1, r1)) {\n #red(l, x, #black(l1, x1, r1))\n };\n case (#black(l1, x1, r1), r) {\n lbalance(#red(l1, x1, r1), x, r)\n };\n case (#red(l1, x1, #black(l2, x2, r2)), r3) {\n #red(\n lbalance(redden l1, x1, l2),\n x2,\n #black(r2, x, r3)\n )\n };\n case _ { Debug.trap \"balRight\" }\n }\n };\n\n func append<T>(left : Tree<T>, right : Tree<T>) : Tree<T> {\n switch (left, right) {\n case (#leaf, _) { right };\n case (_, #leaf) { left };\n case (\n #red(l1, x1, r1),\n #red(l2, x2, r2)\n ) {\n switch (append(r1, l2)) {\n case (#red(l3, x3, r3)) {\n #red(\n #red(l1, x1, l3),\n x3,\n #red(r3, x2, r2)\n )\n };\n case r1l2 {\n #red(l1, x1, #red(r1l2, x2, r2))\n }\n }\n };\n case (t1, #red(l2, x2, r2)) {\n #red(append(t1, l2), x2, r2)\n };\n case (#red(l1, x1, r1), t2) {\n #red(l1, x1, append(r1, t2))\n };\n case (#black(l1, x1, r1), #black(l2, x2, r2)) {\n switch (append(r1, l2)) {\n case (#red(l3, x3, r3)) {\n #red(\n #black(l1, x1, l3),\n x3,\n #black(r3, x2, r2)\n )\n };\n case r1l2 {\n balLeft(\n l1,\n x1,\n #black(r1l2, x2, r2)\n )\n }\n }\n }\n }\n };\n\n public func delete<T>(s : Set<T>, compare : (T, T) -> O.Order, x : T) : Set<T> {\n var changed : Bool = false;\n func delNode(left : Tree<T>, x1 : T, right : Tree<T>) : Tree<T> {\n switch (compare(x, x1)) {\n case (#less) {\n let newLeft = del left;\n switch left {\n case (#black(_, _, _)) {\n balLeft(newLeft, x1, right)\n };\n case _ {\n #red(newLeft, x1, right)\n }\n }\n };\n case (#greater) {\n let newRight = del right;\n switch right {\n case (#black(_, _, _)) {\n balRight(left, x1, newRight)\n };\n case _ {\n #red(left, x1, newRight)\n }\n }\n };\n case (#equal) {\n changed := true;\n append(left, right)\n }\n }\n };\n func del(tree : Tree<T>) : Tree<T> {\n switch tree {\n case (#black(left, x1, right)) {\n delNode(left, x1, right)\n };\n case (#red(left, x1, right)) {\n delNode(left, x1, right)\n };\n case (#leaf) {\n tree\n }\n }\n };\n let newRoot = switch (del(s.root)) {\n case (#red(left, x1, right)) {\n #black(left, x1, right)\n };\n case other { other }\n };\n { root = newRoot;\n size = if changed { s.size -1 } else { s.size } }\n };\n\n // check binary search tree order of elements and black depth invariant of the RB-tree\n public func validate<T>(s : Set<T>, comp : (T, T) -> O.Order) {\n ignore blackDepth(s.root, comp)\n };\n\n func blackDepth<T>(node : Tree<T>, comp : (T, T) -> O.Order) : Nat {\n func checkNode(left : Tree<T>, x1 : T, right : Tree<T>) : Nat {\n checkElem(left, func(x: T) : Bool { comp(x, x1) == #less });\n checkElem(right, func(x: T) : Bool { comp(x, x1) == #greater });\n let leftBlacks = blackDepth(left, comp);\n let rightBlacks = blackDepth(right, comp);\n assert (leftBlacks == rightBlacks);\n leftBlacks\n };\n switch node {\n case (#leaf) 0;\n case (#red(left, x1, right)) {\n assert (not isRed(left));\n assert (not isRed(right));\n checkNode(left, x1, right)\n };\n case (#black(left, x1, right)) {\n checkNode(left, x1, right) + 1\n }\n }\n };\n\n func isRed<T>(node : Tree<T>) : Bool {\n switch node {\n case (#red(_, _, _)) true;\n case _ false\n }\n };\n\n func checkElem<T>(node : Tree<T>, isValid : T -> Bool) {\n switch node {\n case (#leaf) {};\n case (#black(_, elem, _)) {\n assert (isValid(elem))\n };\n case (#red(_, elem, _)) {\n assert (isValid(elem))\n }\n }\n }\n };\n\n /// Create `OrderedSet.Operations` object capturing element type `T` and `compare` function. \n /// It is an alias for the `Operations` constructor.\n ///\n /// Example:\n /// ```motoko\n /// import Set \"mo:base/OrderedSet\";\n /// import Nat \"mo:base/Nat\";\n ///\n /// actor {\n /// let natSet = Set.Make<Nat>(Nat.compare);\n /// stable var set : Set.Set<Nat> = natSet.empty();\n /// };\n /// ```\n public let Make : <T>(compare : (T, T) -> O.Order) -> Operations<T> = Operations\n}\n"},"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 List \"List\";\nimport Stack \"Stack\";\nimport Prim \"mo:⛔\";\n\nmodule {\n\n /// The type corresponding to primitive `Text` values.\n ///\n /// ```motoko\n /// let hello = \"Hello!\";\n /// let emoji = \"👋\";\n /// let concat = hello # \" \" # emoji; // \"Hello! 👋\"\n /// ```\n public type Text = Prim.Types.Text;\n\n /// Converts the given `Char` to a `Text` value.\n ///\n /// ```motoko include=import\n /// let text = Text.fromChar('A'); // \"A\"\n /// ```\n public let fromChar : (c : Char) -> Text = Prim.charToText;\n\n /// Converts the given `[Char]` to a `Text` value.\n ///\n /// ```motoko include=import\n /// let text = Text.fromArray(['A', 'v', 'o', 'c', 'a', 'd', 'o']); // \"Avocado\"\n /// ```\n ///\n /// Runtime: O(a.size())\n /// Space: O(a.size())\n public func fromArray(a : [Char]) : Text = fromIter(a.vals());\n\n /// Converts the given `[var Char]` to a `Text` value.\n ///\n /// ```motoko include=import\n /// let text = Text.fromVarArray([var 'E', 'g', 'g', 'p', 'l', 'a', 'n', 't']); // \"Eggplant\"\n /// ```\n ///\n /// Runtime: O(a.size())\n /// Space: O(a.size())\n public func fromVarArray(a : [var Char]) : Text = fromIter(a.vals());\n\n /// Iterates over each `Char` value in the given `Text`.\n ///\n /// Equivalent to calling the `t.chars()` method where `t` is a `Text` value.\n ///\n /// ```motoko include=import\n /// import { print } \"mo:base/Debug\";\n ///\n /// for (c in Text.toIter(\"abc\")) {\n /// print(debug_show c);\n /// }\n /// ```\n public func toIter(t : Text) : Iter.Iter<Char> = t.chars();\n\n /// Creates a new `Array` containing characters of the given `Text`.\n ///\n /// Equivalent to `Iter.toArray(t.chars())`.\n ///\n /// ```motoko include=import\n /// assert Text.toArray(\"Café\") == ['C', 'a', 'f', 'é'];\n /// ```\n ///\n /// Runtime: O(t.size())\n /// Space: O(t.size())\n public func toArray(t : Text) : [Char] {\n let cs = t.chars();\n // We rely on Array_tabulate's implementation details: it fills\n // the array from left to right sequentially.\n Prim.Array_tabulate<Char>(\n t.size(),\n func _ {\n switch (cs.next()) {\n case (?c) { c };\n case null { Prim.trap(\"Text.toArray\") };\n };\n }\n )\n };\n\n /// Creates a new mutable `Array` containing characters of the given `Text`.\n ///\n /// Equivalent to `Iter.toArrayMut(t.chars())`.\n ///\n /// ```motoko include=import\n /// assert Text.toVarArray(\"Café\") == [var 'C', 'a', 'f', 'é'];\n /// ```\n ///\n /// Runtime: O(t.size())\n /// Space: O(t.size())\n public func toVarArray(t : Text) : [var Char] {\n let n = t.size();\n if (n == 0) {\n return [var];\n };\n let array = Prim.Array_init<Char>(n, ' ');\n var i = 0;\n for (c in t.chars()) {\n array[i] := c;\n i += 1;\n };\n array\n };\n\n /// Creates a `Text` value from a `Char` iterator.\n ///\n /// ```motoko include=import\n /// let text = Text.fromIter(['a', 'b', 'c'].vals()); // \"abc\"\n /// ```\n public func fromIter(cs : Iter.Iter<Char>) : Text {\n var r = \"\";\n for (c in cs) {\n r #= Prim.charToText(c)\n };\n return r\n };\n\n /// Create a text from a character list.\n /// Example:\n /// ```motoko include=initialize\n /// fromList(?('H', ?('e', ?('l', ?('l', ?('o', null))))));\n /// // => \"Hello\"\n /// ```\n ///\n /// Runtime: O(size cs)\n /// Space: O(size cs)\n public func fromList(cs : List.List<Char>) : Text = fromIter(List.toIter cs);\n\n /// Create a character list from a text.\n /// Example:\n /// ```motoko include=initialize\n /// toList(\"Hello\");\n /// // => ?('H', ?('e', ?('l', ?('l', ?('o', null)))))\n /// ```\n ///\n /// Runtime: O(t.size())\n /// Space: O(t.size())\n public func toList(t : Text) : List.List<Char> {\n var acc : List.List<Char> = null;\n for (c in t.chars()) {\n acc := ?(c, acc)\n };\n List.reverse acc\n };\n\n /// Returns the number of characters in the given `Text`.\n ///\n /// Equivalent to calling `t.size()` where `t` is a `Text` value.\n ///\n /// ```motoko include=import\n /// let size = Text.size(\"abc\"); // 3\n /// ```\n public func size(t : Text) : Nat { t.size() };\n\n /// Returns a hash obtained by using the `djb2` algorithm ([more details](http://www.cse.yorku.ca/~oz/hash.html)).\n ///\n /// ```motoko include=import\n /// let hash = Text.hash(\"abc\");\n /// ```\n ///\n /// 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 /// Returns the text argument in lowercase.\n /// WARNING: Unicode compliant only when compiled, not interpreted.\n ///\n /// ```motoko include=import\n /// let text = Text.toLowercase(\"Good Day\"); // ?\"good day\"\n /// ```\n public let toLowercase : Text -> Text = Prim.textLowercase;\n\n /// Returns the text argument in uppercase. Unicode compliant.\n /// WARNING: Unicode compliant only when compiled, not interpreted.\n ///\n /// ```motoko include=import\n /// let text = Text.toUppercase(\"Good Day\"); // ?\"GOOD DAY\"\n /// ```\n public let toUppercase : Text -> Text = Prim.textUppercase;\n}\n"},"Trie.mo":{"content":"/// Functional key-value hash maps.\n///\n/// This module provides an applicative (functional) hash map, called a trie.\n/// Notably, each operation produces a new trie rather than destructively updating an existing trie.\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/// - `remove` - remove a key's value from the trie\n/// - `iter` - visit every key-value in the trie.\n///\n/// The `put`, `get` and `remove` operations work over `Key` records,\n/// which group the hash of the key with its non-hash key value.\n///\n/// LIMITATIONS: This data structure allows at most MAX_LEAF_SIZE=8 hash collisions:\n/// attempts to insert more than MAX_LEAF_SIZE keys (whether directly via `put` or indirectly via other operations) with the same hash value will trap.\n///\n/// CREDITS: Based on Section 6 of [\"Incremental computation via function caching\", Pugh & Teitelbaum](https://dl.acm.org/citation.cfm?id=75305).\n///\n///\n/// Example:\n/// ```motoko\n/// import Trie \"mo:base/Trie\";\n/// import Text \"mo:base/Text\";\n///\n/// // we do this to have shorter type names and thus\n/// // better readibility\n/// type Trie<K, V> = Trie.Trie<K, V>;\n/// type Key<K> = Trie.Key<K>;\n///\n/// // we have to provide `put`, `get` and `remove` with\n/// // a record of type `Key<K> = { hash : Hash.Hash; key : K }`;\n/// // thus we define the following function that takes a value of type `K`\n/// // (in this case `Text`) and returns a `Key<K>` record.\n/// func key(t: Text) : Key<Text> { { hash = Text.hash t; key = t } };\n///\n/// // we start off by creating an empty `Trie`\n/// let t0 : Trie<Text, Nat> = Trie.empty();\n///\n/// // `put` requires 4 arguments:\n/// // - the trie we want to insert the value into,\n/// // - the key of the value we want to insert (note that we use the `key` function defined above),\n/// // - a function that checks for equality of keys, and\n/// // - the value we want to insert.\n/// //\n/// // When inserting a value, `put` returns a tuple of type `(Trie<K, V>, ?V)`.\n/// // to get the new trie that contains the value, we use the `0` projection\n/// // and assign it to `t1` and `t2` respectively.\n/// let t1 : Trie<Text, Nat> = Trie.put(t0, key \"hello\", Text.equal, 42).0;\n/// let t2 : Trie<Text, Nat> = Trie.put(t1, key \"world\", Text.equal, 24).0;\n///\n/// // If for a given key there already was a value in the trie, `put` returns\n/// // that previous value as the second element of the tuple.\n/// // in our case we have already inserted the value 42 for the key \"hello\", so\n/// // `put` returns 42 as the second element of the tuple.\n/// let (t3, n) : (Trie<Text, Nat>, ?Nat) = Trie.put(\n/// t2,\n/// key \"hello\",\n/// Text.equal,\n/// 0,\n/// );\n/// assert (n == ?42);\n///\n/// // `get` requires 3 arguments:\n/// // - the trie we want to get the value from\n/// // - the key of the value we want to get (note that we use the `key` function defined above)\n/// // - a function that checks for equality of keys\n/// //\n/// // If the given key is nonexistent in the trie, `get` returns `null`.\n/// var value = Trie.get(t3, key \"hello\", Text.equal); // Returns `?42`\n/// assert(value == ?0);\n/// value := Trie.get(t3, key \"universe\", Text.equal); // Returns `null`\n/// assert(value == null);\n///\n/// // `remove` requires 3 arguments:\n/// // - the trie we want to remove the value from,\n/// // - the key of the value we want to remove (note that we use the `key` function defined above), and\n/// // - a function that checks for equality of keys.\n/// //\n/// // In the case of keys of type `Text`, we can use `Text.equal`\n/// // to check for equality of keys. Function `remove` returns a tuple of type `(Trie<K, V>, ?V)`.\n/// // where the second element of the tuple is the value that was removed, or `null` if\n/// // there was no value for the given key.\n/// let removedValue : ?Nat = Trie.remove(\n/// t3,\n/// key \"hello\",\n/// Text.equal,\n/// ).1;\n/// assert (removedValue == ?0);\n///\n/// // To iterate over the Trie, we use the `iter` function that takes a trie\n/// // of type `Trie<K,V>` and returns an iterator of type `Iter<(K,V)>`:\n/// var sum : Nat = 0;\n/// for (kv in Trie.iter(t3)) {\n/// sum += kv.1;\n/// };\n/// assert(sum == 24);\n/// ```\n\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 /// This bit position is not stored in the branch but determined from\n /// the context of the branch.\n public type Branch<K, V> = {\n size : Nat;\n left : Trie<K, V>;\n right : Trie<K, V>\n };\n\n public type AssocList<K, V> = AssocList.AssocList<K, V>;\n\n /// A `Key` for the trie has an associated hash value\n /// - `hash` permits fast inequality checks, and permits collisions, while\n /// - `key` permits precise equality checks, but is only used on values with equal hashes.\n public type Key<K> = {\n hash : Hash.Hash;\n key : K\n };\n\n type List<T> = List.List<T>;\n\n /// Equality function for two `Key<K>`s, in terms of equality of `K`'s.\n public func equalKey<K>(keq : (K, K) -> Bool) : ((Key<K>, Key<K>) -> Bool) =\n func(key1 : Key<K>, key2 : Key<K>) : Bool =\n Hash.equal(key1.hash, key2.hash) and keq(key1.key, key2.key);\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 rec(t, null, 0, 0)\n };\n\n /// A 2D trie maps dimension-1 keys to another\n /// layer of tries, each keyed on the dimension-2 keys.\n public type Trie2D<K1, K2, V> = Trie<K1, Trie<K2, V>>;\n\n /// A 3D trie maps dimension-1 keys to another\n /// Composition of 2D tries, each keyed on the dimension-2 and dimension-3 keys.\n public type Trie3D<K1, K2, K3, V> = Trie<K1, Trie2D<K2, K3, V>>;\n\n /// An empty trie. This is usually the starting point for building a trie.\n ///\n /// Example:\n /// ```motoko name=initialize\n /// import { print } \"mo:base/Debug\";\n /// import Trie \"mo:base/Trie\";\n /// import Text \"mo:base/Text\";\n ///\n /// // we do this to have shorter type names and thus\n /// // better readibility\n /// type Trie<K, V> = Trie.Trie<K, V>;\n /// type Key<K> = Trie.Key<K>;\n ///\n /// // We have to provide `put`, `get` and `remove` with\n /// // a function of return type `Key<K> = { hash : Hash.Hash; key : K }`\n /// func key(t: Text) : Key<Text> { { hash = Text.hash t; key = t } };\n /// // We start off by creating an empty `Trie`\n /// var trie : Trie<Text, Nat> = Trie.empty();\n /// ```\n public func empty<K, V>() : Trie<K, V> = #empty;\n\n /// Get the size in O(1) time.\n ///\n /// For a more detailed overview of how to use a `Trie`,\n /// see the [User's Overview](#overview).\n ///\n /// Example:\n /// ```motoko include=initialize\n /// var size = Trie.size(trie); // Returns 0, as `trie` is empty\n /// assert(size == 0);\n /// trie := Trie.put(trie, key \"hello\", Text.equal, 42).0;\n /// size := Trie.size(trie); // Returns 1, as we just added a new entry\n /// assert(size == 1);\n /// ```\n\n public func size<K, V>(t : Trie<K, V>) : Nat =\n switch t {\n case (#empty) { 0 };\n case (#leaf l) { l.size };\n case (#branch b) { b.size }\n };\n\n /// Construct a branch node, computing the size stored there.\n public func branch<K, V>(l : Trie<K, V>, r : Trie<K, V>) : Trie<K, V> =\n #branch {\n size = size l + size r;\n left = l;\n right = r\n };\n\n /// Construct a leaf node, computing the size stored there.\n ///\n /// This helper function automatically enforces the MAX_LEAF_SIZE\n /// by constructing branches as necessary; to do so, it also needs the bitpos\n /// of the leaf.\n public func leaf<K, V>(kvs : AssocList<Key<K>, V>, bitpos : Nat) : Trie<K, V> =\n fromList(null, kvs, bitpos);\n\n module ListUtil {\n /* Deprecated: List.lenClamp */\n /// Return the list length unless the number of items in the list exceeds\n /// a maximum value. If the list length exceed the maximum, the function\n /// returns `null`.\n public func lenClamp<T>(l : List<T>, max : Nat) : ?Nat {\n func rec(l : List<T>, max : Nat, i : Nat) : ?Nat =\n switch l {\n case null { ?i };\n case (?(_, t)) {\n if (i >= max) { null } else { rec(t, max, i + 1) }\n }\n };\n rec(l, max, 0)\n }\n };\n\n /// Transform a list into a trie, splitting input list into small (leaf) lists, if necessary.\n public func fromList<K, V>(kvc : ?Nat, kvs : AssocList<Key<K>, V>, bitpos : Nat) : Trie<K, V> {\n func rec(kvc : ?Nat, kvs : AssocList<Key<K>, V>, bitpos : Nat) : Trie<K, V> {\n switch kvc {\n case null {\n switch (ListUtil.lenClamp(kvs, MAX_LEAF_SIZE)) {\n case null {} /* fall through to branch case. */;\n case (?len) {\n return #leaf { size = len; keyvals = kvs }\n }\n }\n };\n case (?c) {\n if (c == 0) {\n return #empty\n } else if (c <= MAX_LEAF_SIZE) {\n return #leaf { size = c; keyvals = kvs }\n } else {\n\n //fall through to branch case\n }\n }\n };\n let (ls, l, rs, r) = splitList(kvs, bitpos);\n if (ls == 0 and rs == 0) {\n #empty\n } else if (rs == 0 and ls <= MAX_LEAF_SIZE) {\n #leaf { size = ls; keyvals = l }\n } else if (ls == 0 and rs <= MAX_LEAF_SIZE) {\n #leaf { size = rs; keyvals = r }\n } else {\n branch(rec(?ls, l, bitpos + 1), rec(?rs, r, bitpos + 1))\n }\n };\n rec(kvc, kvs, bitpos)\n };\n\n /// Clone the trie efficiently, via sharing.\n ///\n /// Purely-functional representation permits _O(1)_ copy, via persistent sharing.\n public func clone<K, V>(t : Trie<K, V>) : Trie<K, V> = t;\n\n /// Combine two nodes that may have a reduced size after an entry deletion.\n func combineReducedNodes<K, V>(left : Trie<K, V>, right : Trie<K, V>) : Trie<K, V> =\n switch (left, right) {\n case (#empty, #empty) {\n #empty\n };\n case (#leaf _, #empty) {\n left\n };\n case (#empty, #leaf _) {\n right\n };\n case (#leaf leftLeaf, #leaf rightLeaf) {\n let size = leftLeaf.size + rightLeaf.size;\n if (size <= MAX_LEAF_SIZE) {\n let union = List.append(leftLeaf.keyvals, rightLeaf.keyvals);\n #leaf { size; keyvals = union }\n } else {\n branch(left, right)\n }\n };\n case (left, right) {\n branch(left, right)\n }\n };\n\n /// Replace the given key's value option with the given value, returning the modified trie.\n /// Also returns the replaced value if the key existed and `null` otherwise.\n /// Compares keys using the provided function `k_eq`.\n ///\n /// Note: Replacing a key's value by `null` removes the key and also shrinks the trie.\n ///\n /// For a more detailed overview of how to use a `Trie`,\n /// see the [User's Overview](#overview).\n ///\n /// Example:\n /// ```motoko include=initialize\n /// trie := Trie.put(trie, key \"test\", Text.equal, 1).0;\n /// trie := Trie.replace(trie, key \"test\", Text.equal, 42).0;\n /// assert (Trie.get(trie, key \"hello\", Text.equal) == ?42);\n /// ```\n public func replace<K, V>(t : Trie<K, V>, k : Key<K>, k_eq : (K, K) -> Bool, v : ?V) : (Trie<K, V>, ?V) {\n let key_eq = equalKey(k_eq);\n var replacedValue: ?V = null;\n\n func recursiveReplace(t : Trie<K, V>, bitpos : Nat) : Trie<K, V> =\n switch t {\n case (#empty) {\n let (kvs, _) = AssocList.replace(null, k, key_eq, v);\n leaf(kvs, bitpos)\n };\n case (#branch b) {\n let bit = Hash.bit(k.hash, bitpos);\n // rebuild either the left or right path with the (k, v) pair\n if (not bit) {\n let l = recursiveReplace(b.left, bitpos + 1);\n combineReducedNodes(l, b.right)\n } else {\n let r = recursiveReplace(b.right, bitpos + 1);\n combineReducedNodes(b.left, r)\n }\n };\n case (#leaf l) {\n let (kvs2, oldValue) = AssocList.replace(l.keyvals, k, key_eq, v);\n replacedValue := oldValue;\n leaf(kvs2, bitpos)\n }\n };\n let newTrie = recursiveReplace(t, 0);\n //assert(isValid<K, V>(newTrie, false));\n (newTrie, replacedValue)\n };\n\n /// Put the given key's value in the trie; return the new trie, and the previous value associated with the key, if any.\n ///\n /// For a more detailed overview of how to use a `Trie`,\n /// see the [User's Overview](#overview).\n ///\n /// Example:\n /// ```motoko include=initialize\n /// trie := Trie.put(trie, key \"hello\", Text.equal, 42).0;\n /// let previousValue = Trie.put(trie, key \"hello\", Text.equal, 33).1; // Returns ?42\n /// assert(previousValue == ?42);\n /// ```\n public func put<K, V>(t : Trie<K, V>, k : Key<K>, k_eq : (K, K) -> Bool, v : V) : (Trie<K, V>, ?V) =\n replace(t, k, k_eq, ?v);\n\n /// Get the value of the given key in the trie, or return null if nonexistent.\n ///\n /// For a more detailed overview of how to use a Trie,\n /// see the [User's Overview](#overview).\n ///\n /// Example:\n /// ```motoko include=initialize\n /// trie := Trie.put(trie, key \"hello\", Text.equal, 42).0;\n /// var value = Trie.get(trie, key \"hello\", Text.equal); // Returns `?42`\n /// assert(value == ?42);\n /// value := Trie.get(trie, key \"world\", Text.equal); // Returns `null`\n /// assert(value == null);\n /// ```\n public func get<K, V>(t : Trie<K, V>, k : Key<K>, k_eq : (K, K) -> Bool) : ?V = find(t, k, k_eq);\n\n /// Find the given key's value in the trie, or return `null` if nonexistent\n ///\n /// For a more detailed overview of how to use a `Trie`,\n /// see the [User's Overview](#overview).\n ///\n /// Example:\n /// ```motoko include=initialize\n /// trie := Trie.put(trie, key \"hello\", Text.equal, 42).0;\n /// var value = Trie.find(trie, key \"hello\", Text.equal); // Returns `?42`\n /// assert(value == ?42);\n /// value := Trie.find(trie, key \"world\", Text.equal); // Returns `null`\n /// assert(value == null);\n /// ```\n public func find<K, V>(t : Trie<K, V>, k : Key<K>, k_eq : (K, K) -> Bool) : ?V {\n let key_eq = equalKey(k_eq);\n func rec(t : Trie<K, V>, bitpos : Nat) : ?V =\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 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 = not Hash.bit(k.hash, bitpos)\n );\n\n func splitList<K, V>(l : AssocList<Key<K>, V>, bitpos : Nat) : (Nat, AssocList<Key<K>, V>, Nat, AssocList<Key<K>, V>) {\n func rec(l : AssocList<Key<K>, V>) : (Nat, AssocList<Key<K>, V>, Nat, AssocList<Key<K>, V>) =\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 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 ///\n /// For a more detailed overview of how to use a `Trie`,\n /// see the [User's Overview](#overview).\n ///\n /// Example:\n /// ```motoko include=initialize\n /// trie := Trie.put(trie, key \"hello\", Text.equal, 42).0;\n /// trie := Trie.put(trie, key \"bye\", Text.equal, 42).0;\n /// // trie2 is a copy of trie\n /// var trie2 = Trie.clone(trie);\n /// // trie2 has a different value for \"hello\"\n /// trie2 := Trie.put(trie2, key \"hello\", Text.equal, 33).0;\n /// // mergedTrie has the value 42 for \"hello\", as the left trie is preferred\n /// // in the case of a collision\n /// var mergedTrie = Trie.merge(trie, trie2, Text.equal);\n /// var value = Trie.get(mergedTrie, key \"hello\", Text.equal);\n /// assert(value == ?42);\n /// ```\n public func merge<K, V>(tl : Trie<K, V>, tr : Trie<K, V>, k_eq : (K, K) -> Bool) : Trie<K, V> {\n let key_eq = equalKey(k_eq);\n func rec(bitpos : Nat, tl : Trie<K, V>, tr : Trie<K, V>) : Trie<K, V> =\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 bitpos\n )\n };\n case (#leaf l, _) {\n let (ll, lr) = splitAssocList(l.keyvals, bitpos);\n rec(bitpos, branch(leaf(ll, bitpos), leaf(lr, bitpos)), tr)\n };\n case (_, #leaf l) {\n let (ll, lr) = splitAssocList(l.keyvals, bitpos);\n rec(bitpos, tl, branch(leaf(ll, bitpos), leaf(lr, bitpos)))\n };\n case (#branch b1, #branch b2) {\n branch(\n rec(bitpos + 1, b1.left, b2.left),\n rec(bitpos + 1, b1.right, b2.right)\n )\n }\n };\n rec(0, tl, tr)\n };\n\n /// <a name=\"mergedisjoint\"></a>\n ///\n /// Merge tries like `merge`, but traps if there are collisions in common keys between the\n /// left and right inputs.\n ///\n /// For a more detailed overview of how to use a `Trie`,\n /// see the [User's Overview](#overview).\n ///\n /// Example:\n /// ```motoko include=initialize\n /// trie := Trie.put(trie, key \"hello\", Text.equal, 42).0;\n /// trie := Trie.put(trie, key \"bye\", Text.equal, 42).0;\n /// // trie2 is a copy of trie\n /// var trie2 = Trie.clone(trie);\n /// // trie2 has a different value for \"hello\"\n /// trie2 := Trie.put(trie2, key \"hello\", Text.equal, 33).0;\n /// // `mergeDisjoint` signals a dynamic errror\n /// // in the case of a collision\n /// var mergedTrie = Trie.mergeDisjoint(trie, trie2, Text.equal);\n /// ```\n public func mergeDisjoint<K, V>(tl : Trie<K, V>, tr : Trie<K, V>, k_eq : (K, K) -> Bool) : Trie<K, V> {\n func rec(bitpos : Nat, tl : Trie<K, V>, tr : Trie<K, V>) : Trie<K, V> =\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 equalKey(k_eq),\n func(x : ?V, y : ?V) : V =\n switch (x, y) {\n case (null, ?v) { v };\n case (?v, null) { v };\n case (_, _) { Debug.trap \"Trie.mergeDisjoint\" }\n }\n ),\n bitpos\n )\n };\n case (#leaf l, _) {\n let (ll, lr) = splitAssocList(l.keyvals, bitpos);\n rec(bitpos, branch(leaf(ll, bitpos), leaf(lr, bitpos)), tr)\n };\n case (_, #leaf l) {\n let (ll, lr) = splitAssocList(l.keyvals, bitpos);\n rec(bitpos, tl, branch(leaf(ll, bitpos), leaf(lr, bitpos)))\n };\n case (#branch b1, #branch b2) {\n branch(\n rec(bitpos + 1, b1.left, b2.left),\n rec(bitpos + 1, b1.right, b2.right)\n )\n }\n };\n rec(0, tl, tr)\n };\n\n /// Difference of tries. The output consists of pairs of\n /// the left trie whose keys are not present in the right trie; the\n /// values of the right trie are irrelevant.\n ///\n /// For a more detailed overview of how to use a `Trie`,\n /// see the [User's Overview](#overview).\n ///\n /// Example:\n /// ```motoko include=initialize\n /// trie := Trie.put(trie, key \"hello\", Text.equal, 42).0;\n /// trie := Trie.put(trie, key \"bye\", Text.equal, 42).0;\n /// // trie2 is a copy of trie\n /// var trie2 = Trie.clone(trie);\n /// // trie2 now has an additional key\n /// trie2 := Trie.put(trie2, key \"ciao\", Text.equal, 33).0;\n /// // `diff` returns a trie with the key \"ciao\",\n /// // as this key is not present in `trie`\n /// // (note that we pass `trie2` as the left trie)\n /// Trie.diff(trie2, trie, Text.equal);\n /// ```\n public func diff<K, V, W>(tl : Trie<K, V>, tr : Trie<K, W>, k_eq : (K, K) -> Bool) : Trie<K, V> {\n let key_eq = equalKey(k_eq);\n\n func rec(bitpos : Nat, tl : Trie<K, V>, tr : Trie<K, W>) : Trie<K, V> =\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 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 /* 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 /* 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 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 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 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 #empty\n ),\n #empty\n )\n };\n\n /// Returns an iterator of type `Iter` over the key-value entries of the trie.\n ///\n /// Each iterator gets a _persistent view_ of the mapping, independent of concurrent updates to the iterated map.\n ///\n /// For a more detailed overview of how to use a `Trie`,\n /// see the [User's Overview](#overview).\n ///\n /// Example:\n /// ```motoko include=initialize\n /// trie := Trie.put(trie, key \"hello\", Text.equal, 42).0;\n /// trie := Trie.put(trie, key \"bye\", Text.equal, 32).0;\n /// // create an Iterator over key-value pairs of trie\n /// let iter = Trie.iter(trie);\n /// // add another key-value pair to `trie`.\n /// // because we created our iterator before\n /// // this update, it will not contain this new key-value pair\n /// trie := Trie.put(trie, key \"ciao\", Text.equal, 3).0;\n /// var sum : Nat = 0;\n /// for ((k,v) in iter) {\n /// sum += v;\n /// };\n /// assert(sum == 74);\n /// ```\n public func iter<K, V>(t : Trie<K, V>) : I.Iter<(K, V)> =\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 /// 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 /// Build sequence of two sub-builds\n public func seq<K, V>(l : Build<K, V>, r : Build<K, V>) : Build<K, V> {\n let sum = size(l) + size(r);\n #seq { size = sum; left = l; right = r }\n };\n\n /// Like [`prod`](#prod), except do not actually do the put calls, just\n /// record them, as a (binary tree) data structure, isomorphic to the\n /// recursion of this function (which is balanced, in expectation).\n public func prod<K1, V1, K2, V2, K3, V3>(\n tl : Trie<K1, V1>,\n tr : Trie<K2, V2>,\n op : (K1, V1, K2, V2) -> ?(K3, V3),\n _k3_eq : (K3, K3) -> Bool\n ) : Build<K3, V3> {\n\n func bin(a : Build<K3, V3>, b : Build<K3, V3>) : Build<K3, V3> = seq(a, b);\n\n /// double-nested folds\n foldUp(\n tl,\n bin,\n func(k1 : K1, v1 : V1) : Build<K3, V3> =\n foldUp(\n tr,\n 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 #skip\n ),\n #skip\n )\n };\n\n /// Project the nth key-value pair from the trie build.\n ///\n /// This position is meaningful only when the build contains multiple uses of one or more keys, otherwise it is not.\n public func nth<K, V>(tb : Build<K, V>, i : Nat) : ?(K, ?Hash.Hash, V) {\n func rec(tb : Build<K, V>, i : Nat) : ?(K, ?Hash.Hash, V) =\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 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> = seq(t1, t2),\n func(_ : K1, t : Build<K2, V>) : Build<K2, V> = t,\n #skip\n );\n\n /// Gather the collection of key-value pairs into an array of a (possibly-distinct) type.\n public func toArray<K, V, W>(tb : Build<K, V>, f : (K, V) -> W) : [W] {\n let c = size(tb);\n let a = A.init<?W>(c, null);\n var i = 0;\n func rec(tb : Build<K, V>) =\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 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 /// Fold over the key-value pairs of the trie, using an accumulator.\n /// The key-value pairs have no reliable or meaningful ordering.\n ///\n /// For a more detailed overview of how to use a `Trie`,\n /// see the [User's Overview](#overview).\n ///\n /// Example:\n /// ```motoko include=initialize\n /// trie := Trie.put(trie, key \"hello\", Text.equal, 42).0;\n /// trie := Trie.put(trie, key \"bye\", Text.equal, 32).0;\n /// trie := Trie.put(trie, key \"ciao\", Text.equal, 3).0;\n /// // create an accumulator, in our case the sum of all values\n /// func calculateSum(k : Text, v : Nat, acc : Nat) : Nat = acc + v;\n /// // Fold over the trie using the accumulator.\n /// // Note that 0 is the initial value of the accumulator.\n /// let sum = Trie.fold(trie, calculateSum, 0);\n /// assert(sum == 77);\n /// ```\n public func fold<K, V, X>(t : Trie<K, V>, f : (K, V, X) -> X, x : X) : X {\n func rec(t : Trie<K, V>, x : X) : X =\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 rec(t, x)\n };\n\n /// Test whether a given key-value pair is present, or not.\n ///\n /// For a more detailed overview of how to use a `Trie`,\n /// see the [User's Overview](#overview).\n ///\n /// Example:\n /// ```motoko include=initialize\n /// trie := Trie.put(trie, key \"hello\", Text.equal, 42).0;\n /// trie := Trie.put(trie, key \"bye\", Text.equal, 32).0;\n /// trie := Trie.put(trie, key \"ciao\", Text.equal, 3).0;\n /// // `some` takes a function that returns a Boolean indicating whether\n /// // the key-value pair is present or not\n /// var isPresent = Trie.some(\n /// trie,\n /// func(k : Text, v : Nat) : Bool = k == \"bye\" and v == 32,\n /// );\n /// assert(isPresent == true);\n /// isPresent := Trie.some(\n /// trie,\n /// func(k : Text, v : Nat) : Bool = k == \"hello\" and v == 32,\n /// );\n /// assert(isPresent == false);\n /// ```\n public func some<K, V>(t : Trie<K, V>, f : (K, V) -> Bool) : Bool {\n func rec(t : Trie<K, V>) : Bool =\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 rec(t)\n };\n\n /// Test whether all key-value pairs have a given property.\n ///\n /// For a more detailed overview of how to use a `Trie`,\n /// see the [User's Overview](#overview).\n ///\n /// Example:\n /// ```motoko include=initialize\n /// trie := Trie.put(trie, key \"hello\", Text.equal, 42).0;\n /// trie := Trie.put(trie, key \"bye\", Text.equal, 32).0;\n /// trie := Trie.put(trie, key \"ciao\", Text.equal, 10).0;\n /// // `all` takes a function that returns a boolean indicating whether\n /// // the key-value pairs all have a given property, in our case that\n /// // all values are greater than 9\n /// var hasProperty = Trie.all(\n /// trie,\n /// func(k : Text, v : Nat) : Bool = v > 9,\n /// );\n /// assert(hasProperty == true);\n /// // now we check if all values are greater than 100\n /// hasProperty := Trie.all(\n /// trie,\n /// func(k : Text, v : Nat) : Bool = v > 100,\n /// );\n /// assert(hasProperty == false);\n /// ```\n public func all<K, V>(t : Trie<K, V>, f : (K, V) -> Bool) : Bool {\n func rec(t : Trie<K, V>) : Bool =\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 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 ///\n /// For a more detailed overview of how to use a `Trie`,\n /// see the [User's Overview](#overview).\n ///\n /// Example:\n /// ```motoko include=initialize\n /// import Array \"mo:base/Array\";\n /// trie := Trie.put(trie, key \"hello\", Text.equal, 42).0;\n /// trie := Trie.put(trie, key \"bye\", Text.equal, 32).0;\n /// trie := Trie.put(trie, key \"ciao\", Text.equal, 10).0;\n /// // `tabulate` takes a size parameter, so we check the size of\n /// // the trie first\n /// let size = Trie.size(trie);\n /// // Now we can create an array of the same size passing `nth` as\n /// // the generator used to fill the array.\n /// // Note that `toArray` is a convenience function that does the\n /// // same thing without you having to check whether the tuple is\n /// // `null` or not, which we're not doing in this example\n /// let array = Array.tabulate<?(Key<Text>, Nat)>(\n /// size,\n /// func n = Trie.nth(trie, n)\n /// );\n /// ```\n public func nth<K, V>(t : Trie<K, V>, i : Nat) : ?(Key<K>, V) {\n func rec(t : Trie<K, V>, i : Nat) : ?(Key<K>, V) =\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 if (i >= size(t)) {\n return null\n };\n rec(t, i)\n };\n\n /// Gather the collection of key-value pairs into an array of a (possibly-distinct) type.\n ///\n /// For a more detailed overview of how to use a `Trie`,\n /// see the [User's Overview](#overview).\n ///\n /// Example:\n /// ```motoko include=initialize\n /// trie := Trie.put(trie, key \"hello\", Text.equal, 42).0;\n /// trie := Trie.put(trie, key \"bye\", Text.equal, 32).0;\n /// trie := Trie.put(trie, key \"ciao\", Text.equal, 10).0;\n /// // `toArray` takes a function that takes a key-value tuple\n /// // and returns a value of the type you want to use to fill\n /// // the array.\n /// // In our case we just return the value\n /// let array = Trie.toArray<Text, Nat, Nat>(\n /// trie,\n /// func (k, v) = v\n /// );\n /// ```\n public func toArray<K, V, W>(t : Trie<K, V>, f : (K, V) -> W) : [W] =\n A.tabulate<W>(\n size(t),\n func(i : Nat) : W {\n let (k, v) = switch (nth(t, i)) {\n case null { P.unreachable() };\n case (?x) { x }\n };\n f(k.key, v)\n }\n );\n\n /// Test for \"deep emptiness\": subtrees that have branching structure,\n /// but no leaves. These can result from naive filtering operations;\n /// filter uses this function to avoid creating such subtrees.\n public func isEmpty<K, V>(t : Trie<K, V>) : Bool = size(t) == 0;\n\n /// Filter the key-value pairs by a given predicate.\n ///\n /// For a more detailed overview of how to use a `Trie`,\n /// see the [User's Overview](#overview).\n ///\n /// Example:\n /// ```motoko include=initialize\n /// trie := Trie.put(trie, key \"hello\", Text.equal, 42).0;\n /// trie := Trie.put(trie, key \"bye\", Text.equal, 32).0;\n /// trie := Trie.put(trie, key \"ciao\", Text.equal, 10).0;\n /// // `filter` takes a function that takes a key-value tuple\n /// // and returns true if the key-value pair should be included.\n /// // In our case those are pairs with a value greater than 20\n /// let filteredTrie = Trie.filter<Text, Nat>(\n /// trie,\n /// func (k, v) = v > 20\n /// );\n /// assert (Trie.all<Text, Nat>(filteredTrie, func(k, v) = v > 20) == true);\n /// ```\n public func filter<K, V>(t : Trie<K, V>, f : (K, V) -> Bool) : Trie<K, V> {\n func rec(t : Trie<K, V>, bitpos : Nat) : Trie<K, V> =\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 combineReducedNodes(fl, fr)\n }\n };\n rec(t, 0)\n };\n\n /// Map and filter the key-value pairs by a given predicate.\n ///\n /// For a more detailed overview of how to use a `Trie`,\n /// see the [User's Overview](#overview).\n ///\n /// Example:\n /// ```motoko include=initialize\n /// trie := Trie.put(trie, key \"hello\", Text.equal, 42).0;\n /// trie := Trie.put(trie, key \"bye\", Text.equal, 32).0;\n /// trie := Trie.put(trie, key \"ciao\", Text.equal, 10).0;\n /// // `mapFilter` takes a function that takes a key-value tuple\n /// // and returns a possibly-distinct value if the key-value pair should be included.\n /// // In our case, we filter for values greater than 20 and map them to their square.\n /// let filteredTrie = Trie.mapFilter<Text, Nat, Nat>(\n /// trie,\n /// func (k, v) = if (v > 20) return ?(v**2) else return null\n /// );\n /// assert (Trie.all<Text, Nat>(filteredTrie, func(k, v) = v > 60) == true);\n /// ```\n public func mapFilter<K, V, W>(t : Trie<K, V>, f : (K, V) -> ?W) : Trie<K, W> {\n func rec(t : Trie<K, V>, bitpos : Nat) : Trie<K, W> =\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 bitpos\n )\n };\n case (#branch b) {\n let fl = rec(b.left, bitpos + 1);\n let fr = rec(b.right, bitpos + 1);\n combineReducedNodes(fl, fr)\n }\n };\n\n rec(t, 0)\n };\n\n /// Test for equality, but naively, based on structure.\n /// Does not attempt to remove \"junk\" in the tree;\n /// For instance, a \"smarter\" approach would equate\n /// `#bin {left = #empty; right = #empty}`\n /// with\n /// `#empty`.\n /// We do not observe that equality here.\n public func equalStructure<K, V>(\n tl : Trie<K, V>,\n tr : Trie<K, V>,\n keq : (K, K) -> Bool,\n veq : (V, V) -> Bool\n ) : Bool {\n func rec(tl : Trie<K, V>, tr : Trie<K, V>) : Bool =\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 rec(tl, tr)\n };\n\n /// Replace the given key's value in the trie,\n /// and only if successful, do the success continuation,\n /// otherwise, return the failure value\n ///\n /// For a more detailed overview of how to use a Trie,\n /// see the [User's Overview](#overview).\n ///\n /// Example:\n /// ```motoko include=initialize\n /// trie := Trie.put(trie, key \"hello\", Text.equal, 42).0;\n /// trie := Trie.put(trie, key \"bye\", Text.equal, 32).0;\n /// trie := Trie.put(trie, key \"ciao\", Text.equal, 10).0;\n /// // `replaceThen` takes the same arguments as `replace` but also a success continuation\n /// // and a failure connection that are called in the respective scenarios.\n /// // if the replace fails, that is the key is not present in the trie, the failure continuation is called.\n /// // if the replace succeeds, that is the key is present in the trie, the success continuation is called.\n /// // in this example we are simply returning the Text values `success` and `fail` respectively.\n /// var continuation = Trie.replaceThen<Text, Nat, Text>(\n /// trie,\n /// key \"hello\",\n /// Text.equal,\n /// 12,\n /// func (t, v) = \"success\",\n /// func () = \"fail\"\n /// );\n /// assert (continuation == \"success\");\n /// continuation := Trie.replaceThen<Text, Nat, Text>(\n /// trie,\n /// key \"shalom\",\n /// Text.equal,\n /// 12,\n /// func (t, v) = \"success\",\n /// func () = \"fail\"\n /// );\n /// assert (continuation == \"fail\");\n /// ```\n public func replaceThen<K, V, X>(\n t : Trie<K, V>,\n k : Key<K>,\n k_eq : (K, K) -> Bool,\n v2 : V,\n success : (Trie<K, V>, V) -> X,\n fail : () -> X\n ) : X {\n let (t2, ov) = replace(t, k, k_eq, ?v2);\n switch ov {\n case null { /* no prior value; failure to remove */ fail() };\n case (?v1) { success(t2, v1) }\n }\n };\n\n /// Put the given key's value in the trie; return the new trie; assert that no prior value is associated with the key\n ///\n /// For a more detailed overview of how to use a `Trie`,\n /// see the [User's Overview](#overview).\n ///\n /// Example:\n /// ```motoko include=initialize\n /// // note that compared to `put`, `putFresh` does not return a tuple\n /// trie := Trie.putFresh(trie, key \"hello\", Text.equal, 42);\n /// trie := Trie.putFresh(trie, key \"bye\", Text.equal, 32);\n /// // this will fail as \"hello\" is already present in the trie\n /// trie := Trie.putFresh(trie, key \"hello\", Text.equal, 10);\n /// ```\n public func putFresh<K, V>(t : Trie<K, V>, k : Key<K>, k_eq : (K, K) -> Bool, v : V) : Trie<K, V> {\n let (t2, none) = replace(t, k, k_eq, ?v);\n switch none {\n case null {};\n case (?_) assert false\n };\n t2\n };\n\n /// Put the given key's value in the 2D trie; return the new 2D trie.\n public func put2D<K1, K2, V>(\n t : Trie2D<K1, K2, V>,\n k1 : Key<K1>,\n k1_eq : (K1, K1) -> Bool,\n k2 : Key<K2>,\n k2_eq : (K2, K2) -> Bool,\n v : V\n ) : Trie2D<K1, K2, V> {\n let inner = find(t, k1, k1_eq);\n let (updated_inner, _) = switch inner {\n case null { put(#empty, k2, k2_eq, v) };\n case (?inner) { put(inner, k2, k2_eq, v) }\n };\n let (updated_outer, _) = put(t, k1, k1_eq, updated_inner);\n updated_outer\n };\n\n /// Put the given key's value in the trie; return the new trie;\n public func put3D<K1, K2, K3, V>(\n t : Trie3D<K1, K2, K3, V>,\n k1 : Key<K1>,\n k1_eq : (K1, K1) -> Bool,\n k2 : Key<K2>,\n k2_eq : (K2, K2) -> Bool,\n k3 : Key<K3>,\n k3_eq : (K3, K3) -> Bool,\n v : V\n ) : Trie3D<K1, K2, K3, V> {\n let inner1 = find(t, k1, k1_eq);\n let (updated_inner1, _) = switch inner1 {\n case null {\n put(\n #empty,\n k2,\n k2_eq,\n (put(#empty, k3, k3_eq, v)).0\n )\n };\n case (?inner1) {\n let inner2 = find(inner1, k2, k2_eq);\n let (updated_inner2, _) = switch inner2 {\n case null { put(#empty, k3, k3_eq, v) };\n case (?inner2) { put(inner2, k3, k3_eq, v) }\n };\n put(inner1, k2, k2_eq, updated_inner2)\n }\n };\n let (updated_outer, _) = put(t, k1, k1_eq, updated_inner1);\n updated_outer\n };\n\n /// Remove the entry for the given key from the trie, by returning the reduced trie.\n /// Also returns the removed value if the key existed and `null` otherwise.\n /// Compares keys using the provided function `k_eq`.\n ///\n /// Note: The removal of an existing key shrinks the trie.\n ///\n /// For a more detailed overview of how to use a `Trie`,\n /// see the [User's Overview](#overview).\n ///\n /// Example:\n /// ```motoko include=initialize\n /// trie := Trie.put(trie, key \"hello\", Text.equal, 42).0;\n /// trie := Trie.put(trie, key \"bye\", Text.equal, 32).0;\n /// // remove the entry associated with \"hello\"\n /// trie := Trie.remove(trie, key \"hello\", Text.equal).0;\n /// assert (Trie.get(trie, key \"hello\", Text.equal) == null);\n /// ```\n public func remove<K, V>(t : Trie<K, V>, k : Key<K>, k_eq : (K, K) -> Bool) : (Trie<K, V>, ?V) =\n replace(t, k, k_eq, null);\n\n /// Remove the given key's value in the trie,\n /// and only if successful, do the success continuation,\n /// otherwise, return the failure value\n public func removeThen<K, V, X>(\n t : Trie<K, V>,\n k : Key<K>,\n k_eq : (K, K) -> Bool,\n success : (Trie<K, V>, V) -> X,\n fail : () -> X\n ) : X {\n let (t2, ov) = replace(t, k, k_eq, null);\n switch ov {\n case null { /* no prior value; failure to remove */ fail() };\n case (?v) { success(t2, v) }\n }\n };\n\n /// remove the given key-key pair's value in the 2D trie; return the\n /// new trie, and the prior value, if any.\n public func remove2D<K1, K2, V>(\n t : Trie2D<K1, K2, V>,\n k1 : Key<K1>,\n k1_eq : (K1, K1) -> Bool,\n k2 : Key<K2>,\n k2_eq : (K2, K2) -> Bool\n ) : (Trie2D<K1, K2, V>, ?V) =\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 /// 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 /// 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> = mergeDisjoint(t1, t2, k2_eq),\n func(_ : K1, t : Trie<K2, V>) : Trie<K2, V> = t,\n #empty\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 = 1;\n while (i < size) {\n array[i] := generator i;\n i += 1\n };\n array\n };\n\n /// Transforms a mutable array into an immutable array.\n ///\n /// ```motoko include=import\n ///\n /// let varArray = [var 0, 1, 2];\n /// varArray[2] := 3;\n /// let array = Array.freeze<Nat>(varArray);\n /// ```\n ///\n /// Runtime: 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 /// Note that `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 (x, i) = 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\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 arrays = Prim.Array_tabulate<[Y]>(\n array.size(),\n func i {\n let subArray = k(array[i]);\n flatSize += subArray.size();\n subArray\n }\n );\n\n // could replace with a call to flatten,\n // but it would require an extra pass (to compute `flatSize`)\n var outer = 0;\n var inner = 0;\n Prim.Array_tabulate<Y>(\n flatSize,\n func _ {\n while (inner == arrays[outer].size()) {\n inner := 0;\n outer += 1\n };\n let element = arrays[outer][inner];\n inner += 1;\n element\n }\n )\n };\n\n /// Collapses the elements in `array` into a single value by starting with `base`\n /// and progessively combining elements into `base` with `combine`. Iteration runs\n /// left to right.\n ///\n /// ```motoko include=import\n /// import {add} \"mo:base/Nat\";\n ///\n /// let array = [4, 2, 0, 1];\n /// let sum =\n /// Array.foldLeft<Nat, Nat>(\n /// array,\n /// 0, // start the sum at 0\n /// func(sumSoFar, x) = sumSoFar + x // this entire function can be replaced with `add`!\n /// );\n /// ```\n ///\n /// Runtime: 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 /// Returns a new subarray from the given array provided the start index and length of elements in the subarray\n ///\n /// Limitations: Traps if the start index + length is greater than the size of the array\n ///\n /// ```motoko include=import\n ///\n /// let array = [1,2,3,4,5];\n /// let subArray = Array.subArray<Nat>(array, 2, 3);\n /// ```\n /// Runtime: O(length);\n /// Space: O(length);\n public func subArray<X>(array : [X], start : Nat, length : Nat) : [X] {\n if (start + length > array.size()) { Prim.trap(\"Array.subArray\") };\n tabulate<X>(\n length,\n func(i) {\n array[start + i]\n }\n )\n };\n\n /// Returns the index of the first `element` in the `array`.\n ///\n /// ```motoko include=import\n /// import Char \"mo:base/Char\";\n /// let array = ['c', 'o', 'f', 'f', 'e', 'e'];\n /// assert Array.indexOf<Char>('c', array, Char.equal) == ?0;\n /// assert Array.indexOf<Char>('f', array, Char.equal) == ?2;\n /// assert Array.indexOf<Char>('g', array, Char.equal) == null;\n /// ```\n ///\n /// Runtime: O(array.size());\n /// Space: O(1);\n public func indexOf<X>(element : X, array : [X], equal : (X, X) -> Bool) : ?Nat = nextIndexOf<X>(element, array, 0, equal);\n\n /// Returns the index of the next occurence of `element` in the `array` starting from the `from` index (inclusive).\n ///\n /// ```motoko include=import\n /// import Char \"mo:base/Char\";\n /// let array = ['c', 'o', 'f', 'f', 'e', 'e'];\n /// assert Array.nextIndexOf<Char>('c', array, 0, Char.equal) == ?0;\n /// assert Array.nextIndexOf<Char>('f', array, 0, Char.equal) == ?2;\n /// assert Array.nextIndexOf<Char>('f', array, 2, Char.equal) == ?2;\n /// assert Array.nextIndexOf<Char>('f', array, 3, Char.equal) == ?3;\n /// assert Array.nextIndexOf<Char>('f', array, 4, Char.equal) == null;\n /// ```\n ///\n /// Runtime: O(array.size());\n /// Space: O(1);\n public func nextIndexOf<X>(element : X, array : [X], fromInclusive : Nat, equal : (X, X) -> Bool) : ?Nat {\n var i = fromInclusive;\n let n = array.size();\n while (i < n) {\n if (equal(array[i], element)) {\n return ?i\n } else {\n i += 1\n }\n };\n null\n };\n\n /// Returns the index of the last `element` in the `array`.\n ///\n /// ```motoko include=import\n /// import Char \"mo:base/Char\";\n /// let array = ['c', 'o', 'f', 'f', 'e', 'e'];\n /// assert Array.lastIndexOf<Char>('c', array, Char.equal) == ?0;\n /// assert Array.lastIndexOf<Char>('f', array, Char.equal) == ?3;\n /// assert Array.lastIndexOf<Char>('e', array, Char.equal) == ?5;\n /// assert Array.lastIndexOf<Char>('g', array, Char.equal) == null;\n /// ```\n ///\n /// Runtime: O(array.size());\n /// Space: O(1);\n public func lastIndexOf<X>(element : X, array : [X], equal : (X, X) -> Bool) : ?Nat = prevIndexOf<X>(element, array, array.size(), equal);\n\n /// Returns the index of the previous occurance of `element` in the `array` starting from the `from` index (exclusive).\n ///\n /// ```motoko include=import\n /// import Char \"mo:base/Char\";\n /// let array = ['c', 'o', 'f', 'f', 'e', 'e'];\n /// assert Array.prevIndexOf<Char>('c', array, array.size(), Char.equal) == ?0;\n /// assert Array.prevIndexOf<Char>('e', array, array.size(), Char.equal) == ?5;\n /// assert Array.prevIndexOf<Char>('e', array, 5, Char.equal) == ?4;\n /// assert Array.prevIndexOf<Char>('e', array, 4, Char.equal) == null;\n /// ```\n ///\n /// Runtime: O(array.size());\n /// Space: O(1);\n public func prevIndexOf<T>(element : T, array : [T], fromExclusive : Nat, equal : (T, T) -> Bool) : ?Nat {\n var i = fromExclusive;\n while (i > 0) {\n i -= 1;\n if (equal(array[i], element)) {\n return ?i\n }\n };\n null\n };\n\n /// Returns an iterator over a slice of the given array.\n ///\n /// ```motoko include=import\n /// let array = [1, 2, 3, 4, 5];\n /// let s = Array.slice<Nat>(array, 3, array.size());\n /// assert s.next() == ?4;\n /// assert s.next() == ?5;\n /// assert s.next() == null;\n ///\n /// let s = Array.slice<Nat>(array, 0, 0);\n /// assert s.next() == null;\n /// ```\n ///\n /// Runtime: O(1)\n /// Space: O(1)\n public func slice<X>(array : [X], fromInclusive : Nat, toExclusive : Nat) : I.Iter<X> = object {\n var i = fromInclusive;\n\n public func next() : ?X {\n if (i >= toExclusive) {\n return null\n };\n let result = array[i];\n i += 1;\n return ?result\n }\n };\n\n /// Returns a new subarray of given length from the beginning or end of the given array\n ///\n /// Returns the entire array if the length is greater than the size of the array\n ///\n /// ```motoko include=import\n /// let array = [1, 2, 3, 4, 5];\n /// assert Array.take(array, 2) == [1, 2];\n /// assert Array.take(array, -2) == [4, 5];\n /// assert Array.take(array, 10) == [1, 2, 3, 4, 5];\n /// assert Array.take(array, -99) == [1, 2, 3, 4, 5];\n /// ```\n /// Runtime: O(length);\n /// Space: O(length);\n public func take<T>(array : [T], length : Int) : [T] {\n let len = Prim.abs(length);\n let size = array.size();\n let resSize = if (len < size) { len } else { size };\n let start : Nat = if (length > 0) 0 else size - resSize;\n subArray(array, start, resSize)\n }\n}\n"},"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 switch (map) {\n case (?((hd_k, hd_v), tl)) {\n if (equal(key, hd_k)) {\n ?hd_v\n } else {\n find(tl, key, equal)\n }\n };\n case (null) { null }\n }\n };\n\n /// Maps `key` to `value` in `map`, and overwrites the old entry if the key\n /// was already present. Returns the old value in an option if it existed and\n /// `null` otherwise, as well as the new map. Compares keys using the provided\n /// function `equal`.\n ///\n /// Example:\n /// ```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 var prev : ?V = null;\n func del(al : AssocList<K, V>) : AssocList<K, V> {\n switch (al) {\n case (?(kv, tl)) {\n if (equal(key, kv.0)) {\n prev := ?kv.1;\n tl\n } else {\n let tl1 = del(tl);\n switch (prev) {\n case null { al };\n case (?_) { ?(kv, tl1) }\n }\n }\n };\n case null {\n null\n }\n }\n };\n let map1 = del(map);\n switch value {\n case (?value) {\n (?((key, value), map1), prev)\n };\n case null {\n (map1, prev)\n };\n };\n };\n\n /// Produces a new map containing all entries from `map1` whose keys are not\n /// contained in `map2`. The \"extra\" entries in `map2` are ignored. Compares\n /// keys using the provided function `equal`.\n ///\n /// Example:\n /// ```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> {\n func rec(al1 : AssocList<K, V>, al2 : AssocList<K, W>) : AssocList<K, X> {\n switch (al1, al2) {\n case (null, null) { null };\n case (?((k, v), al1_), _) { ?((k, f(?v, null)), rec(al1_, al2)) };\n case (null, ?((k, v), al2_)) { ?((k, f(null, ?v)), rec(null, al2_)) }\n }\n };\n rec(map1, map2)\n };\n\n /// Produces a new map by mapping entries in `map1` and `map2` using `f` and\n /// concatenating the results. Assumes that there are no collisions between\n /// keys in `map1` and `map2`.\n ///\n /// Example:\n /// ```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> {\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"}}}
1
+ {"name":"base","version":"moc-0.14.12","files":{"Int8.mo":{"content":"/// Provides utility functions on 8-bit signed integers.\n/// \n/// :::info Function form for higher-order use\n/// \n/// Several arithmetic and comparison functions (e.g. `add`, `sub`, `bitor`, `bitand`, `pow`) are defined in this module to enable their use as first-class function values, which is not possible with operators like `+`, `-`, `==`, etc., in Motoko. This allows you to pass these operations to higher-order functions such as `map`, `foldLeft`, or `sort`.\n/// :::\n/// \n/// :::note\n/// Most operations are available as built-in operators (e.g. `1 + 1`).\n/// :::\n/// Import from the base library to use this module.\n/// \n/// ```motoko name=import\n/// import Int8 \"mo:base/Int8\";\n/// ```\nimport Int \"Int\";\nimport Prim \"mo:⛔\";\n\nmodule {\n\n /// 8-bit signed integers.\n public type Int8 = Prim.Types.Int8;\n\n /// Minimum 8-bit integer value, `-2 ** 7`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int8.minimumValue // => -128\n /// ```\n public let minimumValue = -128 : Int8;\n\n /// Maximum 8-bit integer value, `+2 ** 7 - 1`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int8.maximumValue // => +127\n /// ```\n public let maximumValue = 127 : Int8;\n\n /// Converts an 8-bit signed integer to a signed integer with infinite precision.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int8.toInt(123) // => 123 : Int\n /// ```\n public let toInt : Int8 -> Int = Prim.int8ToInt;\n\n /// Converts a signed integer with infinite precision to an 8-bit signed integer.\n /// \n /// Traps on overflow/underflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int8.fromInt(123) // => +123 : Int8\n /// ```\n public let fromInt : Int -> Int8 = Prim.intToInt8;\n\n /// Converts a signed integer with infinite precision to an 8-bit signed integer.\n /// \n /// Wraps on overflow/underflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int8.fromIntWrap(-123) // => -123 : Int\n /// ```\n public let fromIntWrap : Int -> Int8 = Prim.intToInt8Wrap;\n\n /// Converts a 16-bit signed integer to an 8-bit signed integer.\n /// \n /// Traps on overflow/underflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int8.fromInt16(123) // => +123 : Int8\n /// ```\n public let fromInt16 : Int16 -> Int8 = Prim.int16ToInt8;\n\n /// Converts an 8-bit signed integer to a 16-bit signed integer.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int8.toInt16(123) // => +123 : Int16\n /// ```\n public let toInt16 : Int8 -> Int16 = Prim.int8ToInt16;\n\n /// Converts an unsigned 8-bit integer to a signed 8-bit integer.\n /// \n /// Wraps on overflow/underflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int8.fromNat8(123) // => +123 : Int8\n /// ```\n public let fromNat8 : Nat8 -> Int8 = Prim.nat8ToInt8;\n\n /// Converts a signed 8-bit integer to an unsigned 8-bit integer.\n /// \n /// Wraps on overflow/underflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int8.toNat8(-1) // => 255 : Nat8 // underflow\n /// ```\n public let toNat8 : Int8 -> Nat8 = Prim.int8ToNat8;\n\n /// Converts an integer number to its textual representation.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int8.toText(-123) // => \"-123\"\n /// ```\n public func toText(x : Int8) : Text {\n Int.toText(toInt(x))\n };\n\n /// Returns the absolute value of `x`.\n /// \n /// Traps when `x == -2 ** 7` (the minimum `Int8` value).\n /// \n /// Example:\n /// ```motoko include=import\n /// Int8.abs(-123) // => +123\n /// ```\n public func abs(x : Int8) : Int8 {\n fromInt(Int.abs(toInt(x)))\n };\n\n /// Returns the minimum of `x` and `y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int8.min(+2, -3) // => -3\n /// ```\n public func min(x : Int8, y : Int8) : Int8 {\n if (x < y) { x } else { y }\n };\n\n /// Returns the maximum of `x` and `y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int8.max(+2, -3) // => +2\n /// ```\n public func max(x : Int8, y : Int8) : Int8 {\n if (x < y) { y } else { x }\n };\n\n /// Equality function for Int8 types.\n /// This is equivalent to `x == y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int8.equal(-1, -1); // => true\n /// ```\n /// \n\n /// \n /// Example:\n /// ```motoko include=import\n /// import Buffer \"mo:base/Buffer\";\n /// \n /// let buffer1 = Buffer.Buffer<Int8>(1);\n /// buffer1.add(-3);\n /// let buffer2 = Buffer.Buffer<Int8>(1);\n /// buffer2.add(-3);\n /// Buffer.equal(buffer1, buffer2, Int8.equal) // => true\n /// ```\n public func equal(x : Int8, y : Int8) : Bool { x == y };\n\n /// Inequality function for Int8 types.\n /// This is equivalent to `x != y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int8.notEqual(-1, -2); // => true\n /// ```\n /// \n\n public func notEqual(x : Int8, y : Int8) : Bool { x != y };\n\n /// \"Less than\" function for Int8 types.\n /// This is equivalent to `x < y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int8.less(-2, 1); // => true\n /// ```\n /// \n\n public func less(x : Int8, y : Int8) : Bool { x < y };\n\n /// \"Less than or equal\" function for Int8 types.\n /// This is equivalent to `x <= y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int8.lessOrEqual(-2, -2); // => true\n /// ```\n /// \n\n public func lessOrEqual(x : Int8, y : Int8) : Bool { x <= y };\n\n /// \"Greater than\" function for Int8 types.\n /// This is equivalent to `x > y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int8.greater(-2, -3); // => true\n /// ```\n /// \n\n public func greater(x : Int8, y : Int8) : Bool { x > y };\n\n /// \"Greater than or equal\" function for Int8 types.\n /// This is equivalent to `x >= y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int8.greaterOrEqual(-2, -2); // => true\n /// ```\n /// \n\n public func greaterOrEqual(x : Int8, y : Int8) : Bool { x >= y };\n\n /// General-purpose comparison function for `Int8`. Returns the `Order` (\n /// either `#less`, `#equal`, or `#greater`) of comparing `x` with `y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int8.compare(-3, 2) // => #less\n /// ```\n /// \n /// This function can be used as value for a high order function, such as a sort function.\n /// \n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.sort([1, -2, -3] : [Int8], Int8.compare) // => [-3, -2, 1]\n /// ```\n public func compare(x : Int8, y : Int8) : { #less; #equal; #greater } {\n if (x < y) { #less } else if (x == y) { #equal } else { #greater }\n };\n\n /// Returns the negation of `x`, `-x`.\n /// \n /// Traps on overflow, i.e. for `neg(-2 ** 7)`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int8.neg(123) // => -123\n /// ```\n /// \n\n public func neg(x : Int8) : Int8 { -x };\n\n /// Returns the sum of `x` and `y`, `x + y`.\n /// \n /// Traps on overflow/underflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int8.add(100, 23) // => +123\n /// ```\n /// \n\n /// \n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.foldLeft<Int8, Int8>([1, -2, -3], 0, Int8.add) // => -4\n /// ```\n public func add(x : Int8, y : Int8) : Int8 { x + y };\n\n /// Returns the difference of `x` and `y`, `x - y`.\n /// \n /// Traps on overflow/underflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int8.sub(123, 23) // => +100\n /// ```\n /// \n\n /// \n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.foldLeft<Int8, Int8>([1, -2, -3], 0, Int8.sub) // => 4\n /// ```\n public func sub(x : Int8, y : Int8) : Int8 { x - y };\n\n /// Returns the product of `x` and `y`, `x * y`.\n /// \n /// Traps on overflow/underflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int8.mul(12, 10) // => +120\n /// ```\n /// \n\n /// \n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.foldLeft<Int8, Int8>([1, -2, -3], 1, Int8.mul) // => 6\n /// ```\n public func mul(x : Int8, y : Int8) : Int8 { x * y };\n\n /// Returns the signed integer division of `x` by `y`, `x / y`.\n /// Rounds the quotient towards zero, which is the same as truncating the decimal places of the quotient.\n /// \n /// Traps when `y` is zero.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int8.div(123, 10) // => +12\n /// ```\n /// \n\n public func div(x : Int8, y : Int8) : Int8 { x / y };\n\n /// Returns the remainder of the signed integer division of `x` by `y`, `x % y`,\n /// which is defined as `x - x / y * y`.\n /// \n /// Traps when `y` is zero.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int8.rem(123, 10) // => +3\n /// ```\n /// \n\n public func rem(x : Int8, y : Int8) : Int8 { x % y };\n\n /// Returns `x` to the power of `y`, `x ** y`.\n /// \n /// Traps on overflow/underflow and when `y < 0 or y >= 8`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int8.pow(2, 6) // => +64\n /// ```\n /// \n\n public func pow(x : Int8, y : Int8) : Int8 { x ** y };\n\n /// Returns the bitwise negation of `x`, `^x`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int8.bitnot(-16 /* 0xf0 */) // => +15 // 0x0f\n /// ```\n /// \n\n public func bitnot(x : Int8) : Int8 { ^x };\n\n /// Returns the bitwise \"and\" of `x` and `y`, `x & y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int8.bitand(0x1f, 0x70) // => +16 // 0x10\n /// ```\n /// \n\n public func bitand(x : Int8, y : Int8) : Int8 { x & y };\n\n /// Returns the bitwise \"or\" of `x` and `y`, `x | y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int8.bitor(0x0f, 0x70) // => +127 // 0x7f\n /// ```\n /// \n\n public func bitor(x : Int8, y : Int8) : Int8 { x | y };\n\n /// Returns the bitwise \"exclusive or\" of `x` and `y`, `x ^ y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int8.bitxor(0x70, 0x7f) // => +15 // 0x0f\n /// ```\n /// \n\n public func bitxor(x : Int8, y : Int8) : Int8 { x ^ y };\n\n /// Returns the bitwise left shift of `x` by `y`, `x << y`.\n /// The right bits of the shift filled with zeros.\n /// Left-overflowing bits, including the sign bit, are discarded.\n /// \n /// For `y >= 8`, the semantics is the same as for `bitshiftLeft(x, y % 8)`.\n /// For `y < 0`, the semantics is the same as for `bitshiftLeft(x, y + y % 8)`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int8.bitshiftLeft(1, 4) // => +16 // 0x10 equivalent to `2 ** 4`.\n /// ```\n /// \n\n public func bitshiftLeft(x : Int8, y : Int8) : Int8 { x << y };\n\n /// Returns the signed bitwise right shift of `x` by `y`, `x >> y`.\n /// The sign bit is retained and the left side is filled with the sign bit.\n /// Right-underflowing bits are discarded, i.e. not rotated to the left side.\n /// \n /// For `y >= 8`, the semantics is the same as for `bitshiftRight(x, y % 8)`.\n /// For `y < 0`, the semantics is the same as for `bitshiftRight (x, y + y % 8)`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int8.bitshiftRight(64, 4) // => +4 // equivalent to `64 / (2 ** 4)`\n /// ```\n /// \n\n public func bitshiftRight(x : Int8, y : Int8) : Int8 { x >> y };\n\n /// Returns the bitwise left rotatation of `x` by `y`, `x <<> y`.\n /// Each left-overflowing bit is inserted again on the right side.\n /// The sign bit is rotated like other bits, i.e. the rotation interprets the number as unsigned.\n /// \n /// Changes the direction of rotation for negative `y`.\n /// For `y >= 8`, the semantics is the same as for `bitrotLeft(x, y % 8)`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int8.bitrotLeft(0x11 /* 0b0001_0001 */, 2) // => +68 // 0b0100_0100 == 0x44.\n /// ```\n /// \n\n public func bitrotLeft(x : Int8, y : Int8) : Int8 { x <<> y };\n\n /// Returns the bitwise right rotation of `x` by `y`, `x <>> y`.\n /// Each right-underflowing bit is inserted again on the right side.\n /// The sign bit is rotated like other bits, i.e. the rotation interprets the number as unsigned.\n /// \n /// Changes the direction of rotation for negative `y`.\n /// For `y >= 8`, the semantics is the same as for `bitrotRight(x, y % 8)`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int8.bitrotRight(0x11 /* 0b0001_0001 */, 1) // => -120 // 0b1000_1000 == 0x88.\n /// ```\n /// \n\n public func bitrotRight(x : Int8, y : Int8) : Int8 { x <>> y };\n\n /// Returns the value of bit `p` in `x`, `x & 2**p == 2**p`.\n /// If `p >= 8`, the semantics is the same as for `bittest(x, p % 8)`.\n /// This is equivalent to checking if the `p`-th bit is set in `x`, using 0 indexing.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int8.bittest(64, 6) // => true\n /// ```\n public func bittest(x : Int8, p : Nat) : Bool {\n Prim.btstInt8(x, Prim.intToInt8(p))\n };\n\n /// Returns the value of setting bit `p` in `x` to `1`.\n /// If `p >= 8`, the semantics is the same as for `bitset(x, p % 8)`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int8.bitset(0, 6) // => +64\n /// ```\n public func bitset(x : Int8, p : Nat) : Int8 {\n x | (1 << Prim.intToInt8(p))\n };\n\n /// Returns the value of clearing bit `p` in `x` to `0`.\n /// If `p >= 8`, the semantics is the same as for `bitclear(x, p % 8)`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int8.bitclear(-1, 6) // => -65\n /// ```\n public func bitclear(x : Int8, p : Nat) : Int8 {\n x & ^(1 << Prim.intToInt8(p))\n };\n\n /// Returns the value of flipping bit `p` in `x`.\n /// If `p >= 8`, the semantics is the same as for `bitclear(x, p % 8)`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int8.bitflip(127, 6) // => +63\n /// ```\n public func bitflip(x : Int8, p : Nat) : Int8 {\n x ^ (1 << Prim.intToInt8(p))\n };\n\n /// Returns the count of non-zero bits in `x`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int8.bitcountNonZero(0x0f) // => +4\n /// ```\n public let bitcountNonZero : (x : Int8) -> Int8 = Prim.popcntInt8;\n\n /// Returns the count of leading zero bits in `x`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int8.bitcountLeadingZero(0x08) // => +4\n /// ```\n public let bitcountLeadingZero : (x : Int8) -> Int8 = Prim.clzInt8;\n\n /// Returns the count of trailing zero bits in `x`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int8.bitcountTrailingZero(0x10) // => +4\n /// ```\n public let bitcountTrailingZero : (x : Int8) -> Int8 = Prim.ctzInt8;\n\n /// Returns the sum of `x` and `y`, `x +% y`.\n /// \n /// Wraps on overflow/underflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int8.addWrap(2 ** 6, 2 ** 6) // => -128 // overflow\n /// ```\n /// \n\n public func addWrap(x : Int8, y : Int8) : Int8 { x +% y };\n\n /// Returns the difference of `x` and `y`, `x -% y`.\n /// \n /// Wraps on overflow/underflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int8.subWrap(-2 ** 7, 1) // => +127 // underflow\n /// ```\n /// \n\n public func subWrap(x : Int8, y : Int8) : Int8 { x -% y };\n\n /// Returns the product of `x` and `y`, `x *% y`. Wraps on overflow.\n /// \n /// Wraps on overflow/underflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int8.mulWrap(2 ** 4, 2 ** 4) // => 0 // overflow\n /// ```\n /// \n\n public func mulWrap(x : Int8, y : Int8) : Int8 { x *% y };\n\n /// Returns `x` to the power of `y`, `x **% y`.\n /// \n /// Wraps on overflow/underflow.\n /// Traps if `y < 0 or y >= 8`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int8.powWrap(2, 7) // => -128 // overflow\n /// ```\n /// \n\n public func powWrap(x : Int8, y : Int8) : Int8 { x **% y };\n\n}\n"},"Nat64.mo":{"content":"/// Provides utility functions on 64-bit unsigned integers.\n/// \n/// :::note\n/// Most operations on integer numbers (e.g. addition) are available as built-in operators (e.g. `1 + 1`).\n/// This module provides equivalent functions and `Text` conversion.\n/// :::\n/// \n/// :::info Function form for higher-order use\n/// \n/// Several arithmetic and comparison functions (e.g. `add`, `sub`, `equal`, `less`, `pow`) are defined in this module to enable their use as first-class function values, which is not possible with operators like `+`, `-`, `==`, etc., in Motoko. This allows you to pass these operations to higher-order functions such as `map`, `foldLeft`, or `sort`.\n/// :::\n/// \n/// Import from the base library to use this module.\n/// \n/// ```motoko name=import\n/// import Nat64 \"mo:base/Nat64\";\n/// ```\n/// \nimport Nat \"Nat\";\nimport Prim \"mo:⛔\";\n\nmodule {\n\n /// 64-bit natural numbers.\n public type Nat64 = Prim.Types.Nat64;\n\n /// Maximum 64-bit natural number. `2 ** 64 - 1`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat64.maximumValue; // => 18446744073709551615 : Nat64\n /// ```\n\n public let maximumValue = 18446744073709551615 : Nat64;\n\n /// Converts a 64-bit unsigned integer to an unsigned integer with infinite precision.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat64.toNat(123); // => 123 : Nat\n /// ```\n public let toNat : Nat64 -> Nat = Prim.nat64ToNat;\n\n /// Converts an unsigned integer with infinite precision to a 64-bit unsigned integer.\n /// \n /// Traps on overflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat64.fromNat(123); // => 123 : Nat64\n /// ```\n public let fromNat : Nat -> Nat64 = Prim.natToNat64;\n\n /// Converts a 32-bit unsigned integer to a 64-bit unsigned integer.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat64.fromNat32(123); // => 123 : Nat64\n /// ```\n public func fromNat32(x : Nat32) : Nat64 {\n Prim.nat32ToNat64(x)\n };\n\n /// Converts a 64-bit unsigned integer to a 32-bit unsigned integer.\n /// \n /// Traps on overflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat64.toNat32(123); // => 123 : Nat32\n /// ```\n public func toNat32(x : Nat64) : Nat32 {\n Prim.nat64ToNat32(x)\n };\n\n /// Converts a signed integer with infinite precision to a 64-bit unsigned integer.\n /// \n /// Traps on overflow/underflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat64.fromIntWrap(123); // => 123 : Nat64\n /// ```\n public let fromIntWrap : Int -> Nat64 = Prim.intToNat64Wrap;\n\n /// Converts `x` to its textual representation. Textual representation _do not_\n /// contain underscores to represent commas.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat64.toText(1234); // => \"1234\" : Text\n /// ```\n public func toText(x : Nat64) : Text {\n Nat.toText(toNat(x))\n };\n\n /// Returns the minimum of `x` and `y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat64.min(123, 456); // => 123 : Nat64\n /// ```\n public func min(x : Nat64, y : Nat64) : Nat64 {\n if (x < y) { x } else { y }\n };\n\n /// Returns the maximum of `x` and `y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat64.max(123, 456); // => 456 : Nat64\n /// ```\n public func max(x : Nat64, y : Nat64) : Nat64 {\n if (x < y) { y } else { x }\n };\n\n /// Equality function for Nat64 types.\n /// This is equivalent to `x == y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat64.equal(1, 1); // => true\n /// (1 : Nat64) == (1 : Nat64) // => true\n /// ```\n /// \n\n /// \n /// Example:\n /// ```motoko include=import\n /// import Buffer \"mo:base/Buffer\";\n /// \n /// let buffer1 = Buffer.Buffer<Nat64>(3);\n /// let buffer2 = Buffer.Buffer<Nat64>(3);\n /// Buffer.equal(buffer1, buffer2, Nat64.equal) // => true\n /// ```\n public func equal(x : Nat64, y : Nat64) : Bool { x == y };\n\n /// Inequality function for Nat64 types.\n /// This is equivalent to `x != y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat64.notEqual(1, 2); // => true\n /// (1 : Nat64) != (2 : Nat64) // => true\n /// ```\n /// \n\n public func notEqual(x : Nat64, y : Nat64) : Bool { x != y };\n\n /// \"Less than\" function for Nat64 types.\n /// This is equivalent to `x < y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat64.less(1, 2); // => true\n /// (1 : Nat64) < (2 : Nat64) // => true\n /// ```\n /// \n\n public func less(x : Nat64, y : Nat64) : Bool { x < y };\n\n /// \"Less than or equal\" function for Nat64 types.\n /// This is equivalent to `x <= y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat64.lessOrEqual(1, 2); // => true\n /// (1 : Nat64) <= (2 : Nat64) // => true\n /// ```\n /// \n\n public func lessOrEqual(x : Nat64, y : Nat64) : Bool { x <= y };\n\n /// \"Greater than\" function for Nat64 types.\n /// This is equivalent to `x > y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat64.greater(2, 1); // => true\n /// (2 : Nat64) > (1 : Nat64) // => true\n /// ```\n /// \n\n public func greater(x : Nat64, y : Nat64) : Bool { x > y };\n\n /// \"Greater than or equal\" function for Nat64 types.\n /// This is equivalent to `x >= y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat64.greaterOrEqual(2, 1); // => true\n /// (2 : Nat64) >= (1 : Nat64) // => true\n /// ```\n /// \n\n public func greaterOrEqual(x : Nat64, y : Nat64) : Bool { x >= y };\n\n /// General purpose comparison function for `Nat64`. Returns the `Order` (\n /// either `#less`, `#equal`, or `#greater`) of comparing `x` with `y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat64.compare(2, 3) // => #less\n /// ```\n /// \n /// This function can be used as value for a high order function, such as a sort function.\n /// \n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.sort([2, 3, 1] : [Nat64], Nat64.compare) // => [1, 2, 3]\n /// ```\n public func compare(x : Nat64, y : Nat64) : { #less; #equal; #greater } {\n if (x < y) { #less } else if (x == y) { #equal } else { #greater }\n };\n\n /// Returns the sum of `x` and `y`, `x + y`.\n /// Traps on overflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat64.add(1, 2); // => 3\n /// (1 : Nat64) + (2 : Nat64) // => 3\n /// ```\n /// \n\n /// \n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.foldLeft<Nat64, Nat64>([2, 3, 1], 0, Nat64.add) // => 6\n /// ```\n public func add(x : Nat64, y : Nat64) : Nat64 { x + y };\n\n /// Returns the difference of `x` and `y`, `x - y`.\n /// Traps on underflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat64.sub(3, 1); // => 2\n /// (3 : Nat64) - (1 : Nat64) // => 2\n /// ```\n /// \n\n /// \n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.foldLeft<Nat64, Nat64>([2, 3, 1], 10, Nat64.sub) // => 4\n /// ```\n public func sub(x : Nat64, y : Nat64) : Nat64 { x - y };\n\n /// Returns the product of `x` and `y`, `x * y`.\n /// Traps on overflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat64.mul(2, 3); // => 6\n /// (2 : Nat64) * (3 : Nat64) // => 6\n /// ```\n /// \n\n /// \n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.foldLeft<Nat64, Nat64>([2, 3, 1], 1, Nat64.mul) // => 6\n /// ```\n public func mul(x : Nat64, y : Nat64) : Nat64 { x * y };\n\n /// Returns the quotient of `x` divided by `y`, `x / y`.\n /// Traps when `y` is zero.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat64.div(6, 2); // => 3\n /// (6 : Nat64) / (2 : Nat64) // => 3\n /// ```\n /// \n\n public func div(x : Nat64, y : Nat64) : Nat64 { x / y };\n\n /// Returns the remainder of `x` divided by `y`, `x % y`.\n /// Traps when `y` is zero.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat64.rem(6, 4); // => 2\n /// (6 : Nat64) % (4 : Nat64) // => 2\n /// ```\n /// \n\n public func rem(x : Nat64, y : Nat64) : Nat64 { x % y };\n\n /// Returns `x` to the power of `y`, `x ** y`. Traps on overflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat64.pow(2, 3); // => 8\n /// (2 : Nat64) ** (3 : Nat64) // => 8\n /// ```\n /// \n\n public func pow(x : Nat64, y : Nat64) : Nat64 { x ** y };\n\n /// Returns the bitwise negation of `x`, `^x`.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat64.bitnot(0); // => 18446744073709551615\n /// ^(0 : Nat64) // => 18446744073709551615\n /// ```\n /// \n\n public func bitnot(x : Nat64) : Nat64 { ^x };\n\n /// Returns the bitwise and of `x` and `y`, `x & y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat64.bitand(1, 3); // => 1\n /// (1 : Nat64) & (3 : Nat64) // => 1\n /// ```\n /// \n\n public func bitand(x : Nat64, y : Nat64) : Nat64 { x & y };\n\n /// Returns the bitwise or of `x` and `y`, `x | y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat64.bitor(1, 3); // => 3\n /// (1 : Nat64) | (3 : Nat64) // => 3\n /// ```\n /// \n\n public func bitor(x : Nat64, y : Nat64) : Nat64 { x | y };\n\n /// Returns the bitwise exclusive or of `x` and `y`, `x ^ y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat64.bitxor(1, 3); // => 2\n /// (1 : Nat64) ^ (3 : Nat64) // => 2\n /// ```\n /// \n\n public func bitxor(x : Nat64, y : Nat64) : Nat64 { x ^ y };\n\n /// Returns the bitwise shift left of `x` by `y`, `x << y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat64.bitshiftLeft(1, 3); // => 8\n /// (1 : Nat64) << (3 : Nat64) // => 8\n /// ```\n /// \n\n public func bitshiftLeft(x : Nat64, y : Nat64) : Nat64 { x << y };\n\n /// Returns the bitwise shift right of `x` by `y`, `x >> y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat64.bitshiftRight(8, 3); // => 1\n /// (8 : Nat64) >> (3 : Nat64) // => 1\n /// ```\n /// \n\n public func bitshiftRight(x : Nat64, y : Nat64) : Nat64 { x >> y };\n\n /// Returns the bitwise rotate left of `x` by `y`, `x <<> y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat64.bitrotLeft(1, 3); // => 8\n /// (1 : Nat64) <<> (3 : Nat64) // => 8\n /// ```\n /// \n\n public func bitrotLeft(x : Nat64, y : Nat64) : Nat64 { x <<> y };\n\n /// Returns the bitwise rotate right of `x` by `y`, `x <>> y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat64.bitrotRight(8, 3); // => 1\n /// (8 : Nat64) <>> (3 : Nat64) // => 1\n /// ```\n /// \n\n public func bitrotRight(x : Nat64, y : Nat64) : Nat64 { x <>> y };\n\n /// Returns the value of bit `p mod 64` in `x`, `(x & 2^(p mod 64)) == 2^(p mod 64)`.\n /// This is equivalent to checking if the `p`-th bit is set in `x`, using 0 indexing.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat64.bittest(5, 2); // => true\n /// ```\n public func bittest(x : Nat64, p : Nat) : Bool {\n Prim.btstNat64(x, Prim.natToNat64(p))\n };\n\n /// Returns the value of setting bit `p mod 64` in `x` to `1`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat64.bitset(5, 1); // => 7\n /// ```\n public func bitset(x : Nat64, p : Nat) : Nat64 {\n x | (1 << Prim.natToNat64(p))\n };\n\n /// Returns the value of clearing bit `p mod 64` in `x` to `0`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat64.bitclear(5, 2); // => 1\n /// ```\n public func bitclear(x : Nat64, p : Nat) : Nat64 {\n x & ^(1 << Prim.natToNat64(p))\n };\n\n /// Returns the value of flipping bit `p mod 64` in `x`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat64.bitflip(5, 2); // => 1\n /// ```\n public func bitflip(x : Nat64, p : Nat) : Nat64 {\n x ^ (1 << Prim.natToNat64(p))\n };\n\n /// Returns the count of non-zero bits in `x`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat64.bitcountNonZero(5); // => 2\n /// ```\n public let bitcountNonZero : (x : Nat64) -> Nat64 = Prim.popcntNat64;\n\n /// Returns the count of leading zero bits in `x`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat64.bitcountLeadingZero(5); // => 61\n /// ```\n public let bitcountLeadingZero : (x : Nat64) -> Nat64 = Prim.clzNat64;\n\n /// Returns the count of trailing zero bits in `x`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat64.bitcountTrailingZero(16); // => 4\n /// ```\n public let bitcountTrailingZero : (x : Nat64) -> Nat64 = Prim.ctzNat64;\n\n /// Returns the upper (i.e. most significant), lower (least significant)\n /// and in-between bytes of `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat64.explode 0xbb772266aa885511 // => (187, 119, 34, 102, 170, 136, 85, 17)\n /// ```\n public let explode : (x : Nat64) -> (msb : Nat8, Nat8, Nat8, Nat8, Nat8, Nat8, Nat8, lsb : Nat8) = Prim.explodeNat64;\n\n /// Returns the sum of `x` and `y`, `x +% y`. Wraps on overflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat64.addWrap(Nat64.maximumValue, 1); // => 0\n /// Nat64.maximumValue +% (1 : Nat64) // => 0\n /// ```\n ///\n /// :::info \n /// The reason why this function is defined in this library (in addition\n /// to the existing `+%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `+%`\n /// as a function value at the moment.\n /// :::\n public func addWrap(x : Nat64, y : Nat64) : Nat64 { x +% y };\n\n /// Returns the difference of `x` and `y`, `x -% y`. Wraps on underflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat64.subWrap(0, 1); // => 18446744073709551615\n /// (0 : Nat64) -% (1 : Nat64) // => 18446744073709551615\n /// ```\n /// \n\n public func subWrap(x : Nat64, y : Nat64) : Nat64 { x -% y };\n\n /// Returns the product of `x` and `y`, `x *% y`. Wraps on overflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat64.mulWrap(4294967296, 4294967296); // => 0\n /// (4294967296 : Nat64) *% (4294967296 : Nat64) // => 0\n /// ```\n /// \n\n public func mulWrap(x : Nat64, y : Nat64) : Nat64 { x *% y };\n\n /// Returns `x` to the power of `y`, `x **% y`. Wraps on overflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat64.powWrap(2, 64); // => 0\n /// (2 : Nat64) **% (64 : Nat64) // => 0\n /// ```\n /// \n\n public func powWrap(x : Nat64, y : Nat64) : Nat64 { x **% y };\n\n}\n"},"Stack.mo":{"content":"/// Class `Stack<X>` provides a minimal LIFO stack of elements of type `X`.\n/// \n/// See library `Deque` for mixed LIFO/FIFO behavior.\n/// \n/// Example:\n/// ```motoko name=initialize\n/// import Stack \"mo:base/Stack\";\n/// \n/// let stack = Stack.Stack<Nat>(); // create a stack\n/// ```\n/// | Runtime | Space |\n/// |-----------|-----------|\n/// | `O(1)` | `O(1)` |\n\nimport List \"List\";\n\nmodule {\n\n public class Stack<T>() {\n\n var stack : List.List<T> = List.nil<T>();\n\n /// Push an element on the top of the stack.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// stack.push(1);\n /// stack.push(2);\n /// stack.push(3);\n /// stack.peek(); // examine the top most element\n /// ```\n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(1)` | `O(1)` |\n public func push(x : T) {\n stack := ?(x, stack)\n };\n\n /// True when the stack is empty and false otherwise.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// stack.isEmpty();\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(1)` | `O(1)` |\n public func isEmpty() : Bool {\n List.isNil<T>(stack)\n };\n\n /// Return (without removing) the top element, or return null if the stack is empty.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// stack.push(1);\n /// stack.push(2);\n /// stack.push(3);\n /// stack.peek();\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(1)` | `O(1)` |\n public func peek() : ?T {\n switch stack {\n case null { null };\n case (?(h, _)) { ?h }\n }\n };\n\n /// Remove and return the top element, or return null if the stack is empty.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// stack.push(1);\n /// ignore stack.pop();\n /// stack.isEmpty();\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(1)` | `O(1)` |\n public func pop() : ?T {\n switch stack {\n case null { null };\n case (?(h, t)) { stack := t; ?h }\n }\n }\n }\n}\n"},"Nat16.mo":{"content":"/// Provides utility functions on 16-bit unsigned integers.\n/// \n/// :::note\n/// Most operations on integer numbers (e.g. addition) are available as built-in operators (e.g. `1 + 1`).\n/// This module provides equivalent functions and `Text` conversion.\n/// :::\n/// \n/// :::info Function form for higher-order use\n/// \n/// Several arithmetic and comparison functions (e.g. `add`, `sub`, `equal`, `less`, `pow`) are defined in this module to enable their use as first-class function values, which is not possible with operators like `+`, `-`, `==`, etc., in Motoko. This allows you to pass these operations to higher-order functions such as `map`, `foldLeft`, or `sort`.\n/// :::\n/// \n/// Import from the base library to use this module.\n/// \n/// ```motoko name=import\n/// import Nat16 \"mo:base/Nat16\";\n/// ```\nimport Nat \"Nat\";\nimport Prim \"mo:⛔\";\n\nmodule {\n\n /// 16-bit natural numbers.\n public type Nat16 = Prim.Types.Nat16;\n\n /// Maximum 16-bit natural number. `2 ** 16 - 1`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat16.maximumValue; // => 65536 : Nat16\n /// ```\n public let maximumValue = 65535 : Nat16;\n\n /// Converts a 16-bit unsigned integer to an unsigned integer with infinite precision.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat16.toNat(123); // => 123 : Nat\n /// ```\n public let toNat : Nat16 -> Nat = Prim.nat16ToNat;\n\n /// Converts an unsigned integer with infinite precision to a 16-bit unsigned integer.\n /// \n /// Traps on overflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat16.fromNat(123); // => 123 : Nat16\n /// ```\n public let fromNat : Nat -> Nat16 = Prim.natToNat16;\n\n /// Converts an 8-bit unsigned integer to a 16-bit unsigned integer.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat16.fromNat8(123); // => 123 : Nat16\n /// ```\n public func fromNat8(x : Nat8) : Nat16 {\n Prim.nat8ToNat16(x)\n };\n\n /// Converts a 16-bit unsigned integer to an 8-bit unsigned integer.\n /// \n /// Traps on overflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat16.toNat8(123); // => 123 : Nat8\n /// ```\n public func toNat8(x : Nat16) : Nat8 {\n Prim.nat16ToNat8(x)\n };\n\n /// Converts a 32-bit unsigned integer to a 16-bit unsigned integer.\n /// \n /// Traps on overflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat16.fromNat32(123); // => 123 : Nat16\n /// ```\n public func fromNat32(x : Nat32) : Nat16 {\n Prim.nat32ToNat16(x)\n };\n\n /// Converts a 16-bit unsigned integer to a 32-bit unsigned integer.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat16.toNat32(123); // => 123 : Nat32\n /// ```\n public func toNat32(x : Nat16) : Nat32 {\n Prim.nat16ToNat32(x)\n };\n\n /// Converts a signed integer with infinite precision to a 16-bit unsigned integer.\n /// \n /// Wraps on overflow/underflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat16.fromIntWrap(123 : Int); // => 123 : Nat16\n /// ```\n public let fromIntWrap : Int -> Nat16 = Prim.intToNat16Wrap;\n\n /// Converts `x` to its textual representation. Textual representation _do not_\n /// contain underscores to represent commas.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat16.toText(1234); // => \"1234\" : Text\n /// ```\n public func toText(x : Nat16) : Text {\n Nat.toText(toNat(x))\n };\n\n /// Returns the minimum of `x` and `y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat16.min(123, 200); // => 123 : Nat16\n /// ```\n public func min(x : Nat16, y : Nat16) : Nat16 {\n if (x < y) { x } else { y }\n };\n\n /// Returns the maximum of `x` and `y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat16.max(123, 200); // => 200 : Nat16\n /// ```\n public func max(x : Nat16, y : Nat16) : Nat16 {\n if (x < y) { y } else { x }\n };\n\n /// Equality function for Nat16 types.\n /// This is equivalent to `x == y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat16.equal(1, 1); // => true\n /// (1 : Nat16) == (1 : Nat16) // => true\n /// ```\n /// \n\n /// \n /// Example:\n /// ```motoko include=import\n /// import Buffer \"mo:base/Buffer\";\n /// \n /// let buffer1 = Buffer.Buffer<Nat16>(3);\n /// let buffer2 = Buffer.Buffer<Nat16>(3);\n /// Buffer.equal(buffer1, buffer2, Nat16.equal) // => true\n /// ```\n public func equal(x : Nat16, y : Nat16) : Bool { x == y };\n\n /// Inequality function for Nat16 types.\n /// This is equivalent to `x != y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat16.notEqual(1, 2); // => true\n /// (1 : Nat16) != (2 : Nat16) // => true\n /// ```\n /// \n\n public func notEqual(x : Nat16, y : Nat16) : Bool { x != y };\n\n /// \"Less than\" function for Nat16 types.\n /// This is equivalent to `x < y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat16.less(1, 2); // => true\n /// (1 : Nat16) < (2 : Nat16) // => true\n /// ```\n /// \n\n public func less(x : Nat16, y : Nat16) : Bool { x < y };\n\n /// \"Less than or equal\" function for Nat16 types.\n /// This is equivalent to `x <= y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat16.lessOrEqual(1, 2); // => true\n /// (1 : Nat16) <= (2 : Nat16) // => true\n /// ```\n /// \n\n public func lessOrEqual(x : Nat16, y : Nat16) : Bool { x <= y };\n\n /// \"Greater than\" function for Nat16 types.\n /// This is equivalent to `x > y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat16.greater(2, 1); // => true\n /// (2 : Nat16) > (1 : Nat16) // => true\n /// ```\n /// \n\n public func greater(x : Nat16, y : Nat16) : Bool { x > y };\n\n /// \"Greater than or equal\" function for Nat16 types.\n /// This is equivalent to `x >= y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat16.greaterOrEqual(2, 1); // => true\n /// (2 : Nat16) >= (1 : Nat16) // => true\n /// ```\n /// \n\n public func greaterOrEqual(x : Nat16, y : Nat16) : Bool { x >= y };\n\n /// General purpose comparison function for `Nat16`. Returns the `Order` (\n /// either `#less`, `#equal`, or `#greater`) of comparing `x` with `y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat16.compare(2, 3) // => #less\n /// ```\n /// \n /// This function can be used as value for a high order function, such as a sort function.\n /// \n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.sort([2, 3, 1] : [Nat16], Nat16.compare) // => [1, 2, 3]\n /// ```\n public func compare(x : Nat16, y : Nat16) : { #less; #equal; #greater } {\n if (x < y) { #less } else if (x == y) { #equal } else { #greater }\n };\n\n /// Returns the sum of `x` and `y`, `x + y`.\n /// Traps on overflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat16.add(1, 2); // => 3\n /// (1 : Nat16) + (2 : Nat16) // => 3\n /// ```\n /// \n\n /// \n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.foldLeft<Nat16, Nat16>([2, 3, 1], 0, Nat16.add) // => 6\n /// ```\n public func add(x : Nat16, y : Nat16) : Nat16 { x + y };\n\n /// Returns the difference of `x` and `y`, `x - y`.\n /// Traps on underflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat16.sub(2, 1); // => 1\n /// (2 : Nat16) - (1 : Nat16) // => 1\n /// ```\n /// \n\n /// \n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.foldLeft<Nat16, Nat16>([2, 3, 1], 20, Nat16.sub) // => 14\n /// ```\n public func sub(x : Nat16, y : Nat16) : Nat16 { x - y };\n\n /// Returns the product of `x` and `y`, `x * y`.\n /// Traps on overflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat16.mul(2, 3); // => 6\n /// (2 : Nat16) * (3 : Nat16) // => 6\n /// ```\n /// \n\n /// \n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.foldLeft<Nat16, Nat16>([2, 3, 1], 1, Nat16.mul) // => 6\n /// ```\n public func mul(x : Nat16, y : Nat16) : Nat16 { x * y };\n\n /// Returns the quotient of `x` divided by `y`, `x / y`.\n /// Traps when `y` is zero.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat16.div(6, 2); // => 3\n /// (6 : Nat16) / (2 : Nat16) // => 3\n /// ```\n /// \n\n public func div(x : Nat16, y : Nat16) : Nat16 { x / y };\n\n /// Returns the remainder of `x` divided by `y`, `x % y`.\n /// Traps when `y` is zero.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat16.rem(6, 4); // => 2\n /// (6 : Nat16) % (4 : Nat16) // => 2\n /// ```\n /// \n\n public func rem(x : Nat16, y : Nat16) : Nat16 { x % y };\n\n /// Returns the power of `x` to `y`, `x ** y`.\n /// Traps on overflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat16.pow(2, 3); // => 8\n /// (2 : Nat16) ** (3 : Nat16) // => 8\n /// ```\n /// \n\n public func pow(x : Nat16, y : Nat16) : Nat16 { x ** y };\n\n /// Returns the bitwise negation of `x`, `^x`.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat16.bitnot(0); // => 65535\n /// ^(0 : Nat16) // => 65535\n /// ```\n /// \n\n public func bitnot(x : Nat16) : Nat16 { ^x };\n\n /// Returns the bitwise and of `x` and `y`, `x & y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat16.bitand(0, 1); // => 0\n /// (0 : Nat16) & (1 : Nat16) // => 0\n /// ```\n /// \n\n public func bitand(x : Nat16, y : Nat16) : Nat16 { x & y };\n\n /// Returns the bitwise or of `x` and `y`, `x | y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat16.bitor(0, 1); // => 1\n /// (0 : Nat16) | (1 : Nat16) // => 1\n /// ```\n public func bitor(x : Nat16, y : Nat16) : Nat16 { x | y };\n\n /// Returns the bitwise exclusive or of `x` and `y`, `x ^ y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat16.bitxor(0, 1); // => 1\n /// (0 : Nat16) ^ (1 : Nat16) // => 1\n /// ```\n public func bitxor(x : Nat16, y : Nat16) : Nat16 { x ^ y };\n\n /// Returns the bitwise shift left of `x` by `y`, `x << y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat16.bitshiftLeft(1, 3); // => 8\n /// (1 : Nat16) << (3 : Nat16) // => 8\n /// ```\n /// \n\n public func bitshiftLeft(x : Nat16, y : Nat16) : Nat16 { x << y };\n\n /// Returns the bitwise shift right of `x` by `y`, `x >> y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat16.bitshiftRight(8, 3); // => 1\n /// (8 : Nat16) >> (3 : Nat16) // => 1\n /// ```\n /// \n\n public func bitshiftRight(x : Nat16, y : Nat16) : Nat16 { x >> y };\n\n /// Returns the bitwise rotate left of `x` by `y`, `x <<> y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat16.bitrotLeft(2, 1); // => 4\n /// (2 : Nat16) <<> (1 : Nat16) // => 4\n /// ```\n /// \n\n public func bitrotLeft(x : Nat16, y : Nat16) : Nat16 { x <<> y };\n\n /// Returns the bitwise rotate right of `x` by `y`, `x <>> y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat16.bitrotRight(1, 1); // => 32768\n /// (1 : Nat16) <>> (1 : Nat16) // => 32768\n /// ```\n /// \n\n public func bitrotRight(x : Nat16, y : Nat16) : Nat16 { x <>> y };\n\n /// Returns the value of bit `p mod 16` in `x`, `(x & 2^(p mod 16)) == 2^(p mod 16)`.\n /// This is equivalent to checking if the `p`-th bit is set in `x`, using 0 indexing.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat16.bittest(5, 2); // => true\n /// ```\n public func bittest(x : Nat16, p : Nat) : Bool {\n Prim.btstNat16(x, Prim.natToNat16(p))\n };\n\n /// Returns the value of setting bit `p mod 16` in `x` to `1`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat16.bitset(0, 2); // => 4\n /// ```\n public func bitset(x : Nat16, p : Nat) : Nat16 {\n x | (1 << Prim.natToNat16(p))\n };\n\n /// Returns the value of clearing bit `p mod 16` in `x` to `0`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat16.bitclear(5, 2); // => 1\n /// ```\n public func bitclear(x : Nat16, p : Nat) : Nat16 {\n x & ^(1 << Prim.natToNat16(p))\n };\n\n /// Returns the value of flipping bit `p mod 16` in `x`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat16.bitflip(5, 2); // => 1\n /// ```\n public func bitflip(x : Nat16, p : Nat) : Nat16 {\n x ^ (1 << Prim.natToNat16(p))\n };\n\n /// Returns the count of non-zero bits in `x`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat16.bitcountNonZero(5); // => 2\n /// ```\n public let bitcountNonZero : (x : Nat16) -> Nat16 = Prim.popcntNat16;\n\n /// Returns the count of leading zero bits in `x`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat16.bitcountLeadingZero(5); // => 13\n /// ```\n public let bitcountLeadingZero : (x : Nat16) -> Nat16 = Prim.clzNat16;\n\n /// Returns the count of trailing zero bits in `x`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat16.bitcountTrailingZero(5); // => 0\n /// ```\n public let bitcountTrailingZero : (x : Nat16) -> Nat16 = Prim.ctzNat16;\n\n /// Returns the upper (i.e. most significant) and lower (least significant) byte of `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat16.explode 0xaa88 // => (170, 136)\n /// ```\n public let explode : (x : Nat16) -> (msb : Nat8, lsb : Nat8) = Prim.explodeNat16;\n\n /// Returns the sum of `x` and `y`, `x +% y`. Wraps on overflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat16.addWrap(65532, 5); // => 1\n /// (65532 : Nat16) +% (5 : Nat16) // => 1\n /// ```\n ///\n /// :::info \n /// The reason why this function is defined in this library (in addition\n /// to the existing `+%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `+%`\n /// as a function value at the moment.\n /// :::\n public func addWrap(x : Nat16, y : Nat16) : Nat16 { x +% y };\n\n /// Returns the difference of `x` and `y`, `x -% y`. Wraps on underflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat16.subWrap(1, 2); // => 65535\n /// (1 : Nat16) -% (2 : Nat16) // => 65535\n /// ```\n /// \n\n public func subWrap(x : Nat16, y : Nat16) : Nat16 { x -% y };\n\n /// Returns the product of `x` and `y`, `x *% y`. Wraps on overflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat16.mulWrap(655, 101); // => 619\n /// (655 : Nat16) *% (101 : Nat16) // => 619\n /// ```\n /// \n\n public func mulWrap(x : Nat16, y : Nat16) : Nat16 { x *% y };\n\n /// Returns `x` to the power of `y`, `x **% y`. Wraps on overflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat16.powWrap(2, 16); // => 0\n /// (2 : Nat16) **% (16 : Nat16) // => 0\n /// ```\n /// \n\n public func powWrap(x : Nat16, y : Nat16) : Nat16 { x **% y };\n\n}\n"},"List.mo":{"content":"/// Purely-functional, singly-linked lists.\n/// A list of type `List<T>` is either `null` or an optional pair of a value of type `T` and a tail, itself of type `List<T>`.\n/// \n/// :::note Assumptions\n/// \n/// Runtime and space complexity assumes that `equal`, and other functions execute in `O(1)` time and space.\n/// :::\n/// \n/// To use this library, import it using:\n/// \n/// ```motoko name=initialize\n/// import List \"mo:base/List\";\n/// ```\n\nimport Array \"Array\";\nimport Iter \"IterType\";\nimport Option \"Option\";\nimport Order \"Order\";\nimport Result \"Result\";\n\nmodule {\n\n // A singly-linked list consists of zero or more _cons cells_, wherein\n // each cell contains a single list element (the cell's _head_), and a pointer to the\n // remainder of the list (the cell's _tail_).\n public type List<T> = ?(T, List<T>);\n\n /// Create an empty list.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// List.nil<Nat>() // => null\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(1)` | `O(1)` |\n public func nil<T>() : List<T> = null;\n\n /// Check whether a list is empty and return true if the list is empty.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// List.isNil<Nat>(null) // => true\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(1)` | `O(1)` |\n public func isNil<T>(l : List<T>) : Bool {\n switch l {\n case null { true };\n case _ { false }\n }\n };\n\n /// Add `x` to the head of `list`, and return the new list.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// List.push<Nat>(0, null) // => ?(0, null);\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(1)` | `O(1)` |\n public func push<T>(x : T, l : List<T>) : List<T> = ?(x, l);\n\n /// Return the last element of the list, if present.\n /// Example:\n /// ```motoko include=initialize\n /// List.last<Nat>(?(0, ?(1, null))) // => ?1\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size)` | `O(1)` |\n public func last<T>(l : List<T>) : ?T {\n switch l {\n case null { null };\n case (?(x, null)) { ?x };\n case (?(_, t)) { last<T>(t) }\n }\n };\n\n /// Remove the head of the list, returning the optioned head and the tail of the list in a pair.\n /// Returns `(null, null)` if the list is empty.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// List.pop<Nat>(?(0, ?(1, null))) // => (?0, ?(1, null))\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(1)` | `O(1)` |\n public func pop<T>(l : List<T>) : (?T, List<T>) {\n switch l {\n case null { (null, null) };\n case (?(h, t)) { (?h, t) }\n }\n };\n\n /// Return the length of the list.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// List.size<Nat>(?(0, ?(1, null))) // => 2\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size)` | `O(1)` |\n public func size<T>(l : List<T>) : Nat {\n func rec(l : List<T>, n : Nat) : Nat {\n switch l {\n case null { n };\n case (?(_, t)) { rec(t, n + 1) }\n }\n };\n rec(l, 0)\n };\n /// Access any item in a list, zero-based.\n /// \n /// :::note Consideration\n /// Indexing into a list is a linear operation, and usually an\n /// indication that a list might not be the best data structure\n /// to use.\n /// :::\n /// \n /// Example:\n /// \n /// ```motoko include=initialize\n /// List.get<Nat>(?(0, ?(1, null)), 1) // => ?1\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size)` | `O(1)` |\n public func get<T>(l : List<T>, n : Nat) : ?T {\n switch (n, l) {\n case (_, null) { null };\n case (0, (?(h, _))) { ?h };\n case (_, (?(_, t))) { get<T>(t, n - 1) }\n }\n };\n\n /// Reverses the list.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// List.reverse<Nat>(?(0, ?(1, ?(2, null)))) // => ?(2, ?(1, ?(0, null)))\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size)` | `O(size)` |\n public func reverse<T>(l : List<T>) : List<T> {\n func rec(l : List<T>, r : List<T>) : List<T> {\n switch l {\n case null { r };\n case (?(h, t)) { rec(t, ?(h, r)) }\n }\n };\n rec(l, null)\n };\n\n /// Call the given function for its side effect, with each list element in turn.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// var sum = 0;\n /// List.iterate<Nat>(?(0, ?(1, ?(2, null))), func n { sum += n });\n /// sum // => 3\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size)` | `O(size)` |\n /// \n public func iterate<T>(l : List<T>, f : T -> ()) {\n switch l {\n case null { () };\n case (?(h, t)) { f(h); iterate<T>(t, f) }\n }\n };\n\n /// Call the given function `f` on each list element and collect the results\n /// in a new list.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// import Nat = \"mo:base/Nat\"\n /// List.map<Nat, Text>(?(0, ?(1, ?(2, null))), Nat.toText) // => ?(\"0\", ?(\"1\", ?(\"2\", null))\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size)` | `O(size)` |\n\n public func map<T, U>(l : List<T>, f : T -> U) : List<U> {\n switch l {\n case null { null };\n case (?(h, t)) { ?(f(h), map<T, U>(t, f)) }\n }\n };\n\n /// Create a new list with only those elements of the original list for which\n /// the given function (often called the _predicate_) returns true.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// List.filter<Nat>(?(0, ?(1, ?(2, null))), func n { n != 1 }) // => ?(0, ?(2, null))\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size)` | `O(size)` |\n public func filter<T>(l : List<T>, f : T -> Bool) : List<T> {\n switch l {\n case null { null };\n case (?(h, t)) {\n if (f(h)) {\n ?(h, filter<T>(t, f))\n } else {\n filter<T>(t, f)\n }\n }\n }\n };\n\n /// Create two new lists from the results of a given function (`f`).\n /// The first list only includes the elements for which the given\n /// function `f` returns true and the second list only includes\n /// the elements for which the function returns false.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// List.partition<Nat>(?(0, ?(1, ?(2, null))), func n { n != 1 }) // => (?(0, ?(2, null)), ?(1, null))\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size)` | `O(size)` |\n /// \n public func partition<T>(l : List<T>, f : T -> Bool) : (List<T>, List<T>) {\n switch l {\n case null { (null, null) };\n case (?(h, t)) {\n if (f(h)) {\n // call f in-order\n let (l, r) = partition<T>(t, f);\n (?(h, l), r)\n } else {\n let (l, r) = partition<T>(t, f);\n (l, ?(h, r))\n }\n }\n }\n };\n\n /// Call the given function on each list element, and collect the non-null results\n /// in a new list.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// List.mapFilter<Nat, Nat>(\n /// ?(1, ?(2, ?(3, null))),\n /// func n {\n /// if (n > 1) {\n /// ?(n * 2);\n /// } else {\n /// null\n /// }\n /// }\n /// ) // => ?(4, ?(6, null))\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size)` | `O(size)` |\n /// \n public func mapFilter<T, U>(l : List<T>, f : T -> ?U) : List<U> {\n switch l {\n case null { null };\n case (?(h, t)) {\n switch (f(h)) {\n case null { mapFilter<T, U>(t, f) };\n case (?h_) { ?(h_, mapFilter<T, U>(t, f)) }\n }\n }\n }\n };\n\n /// Maps a Result-returning function `f` over a List and returns either\n /// the first error or a list of successful values.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// List.mapResult<Nat, Nat, Text>(\n /// ?(1, ?(2, ?(3, null))),\n /// func n {\n /// if (n > 0) {\n /// #ok(n * 2);\n /// } else {\n /// #err(\"Some element is zero\")\n /// }\n /// }\n /// ); // => #ok ?(2, ?(4, ?(6, null))\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size)` | `O(size)` |\n /// \n public func mapResult<T, R, E>(xs : List<T>, f : T -> Result.Result<R, E>) : Result.Result<List<R>, E> {\n func go(xs : List<T>, acc : List<R>) : Result.Result<List<R>, E> {\n switch xs {\n case null { #ok(acc) };\n case (?(head, tail)) {\n switch (f(head)) {\n case (#err(err)) { #err(err) };\n case (#ok(ok)) { go(tail, ?(ok, acc)) }\n }\n }\n }\n };\n Result.mapOk(go(xs, null), func(xs : List<R>) : List<R> = reverse(xs))\n };\n\n /// Append the elements from the reverse of one list, 'l', to another list, 'm'.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// List.revAppend<Nat>(\n /// ?(2, ?(1, ?(0, null))),\n /// ?(3, ?(4, ?(5, null)))\n /// ); // => ?(0, ?(1, ?(2, ?(3, ?(4, ?(5, null))))))\n /// ```\n /// \n /// | Runtime | Space |\n /// |-------------|-------------|\n /// | `O(size(l))` | `O(size(l))` |\n func revAppend<T>(l : List<T>, m : List<T>) : List<T> {\n switch l {\n case null { m };\n case (?(h, t)) { revAppend(t, ?(h, m)) }\n }\n };\n\n /// Append the elements from one list to another list.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// List.append<Nat>(\n /// ?(0, ?(1, ?(2, null))),\n /// ?(3, ?(4, ?(5, null)))\n /// ) // => ?(0, ?(1, ?(2, ?(3, ?(4, ?(5, null))))))\n /// ```\n /// \n /// | Runtime | Space |\n /// |-------------|-------------|\n /// | `O(size(l))` | `O(size(l))` |\n public func append<T>(l : List<T>, m : List<T>) : List<T> {\n revAppend(reverse(l), m)\n };\n\n /// Flatten, or concatenate, a list of lists as a list.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// List.flatten<Nat>(\n /// ?(?(0, ?(1, ?(2, null))),\n /// ?(?(3, ?(4, ?(5, null))),\n /// null))\n /// ); // => ?(0, ?(1, ?(2, ?(3, ?(4, ?(5, null))))))\n /// ```\n /// \n /// | Runtime | Space |\n /// |-------------|-------------|\n /// | `O(size*size)` | `O(size*size)` |\n public func flatten<T>(l : List<List<T>>) : List<T> {\n //FIXME: this is quadratic, not linear https://github.com/dfinity/motoko-base/issues/459\n foldLeft<List<T>, List<T>>(l, null, func(a, b) { append<T>(a, b) })\n };\n\n /// Returns the first `n` elements of the given list.\n /// If the given list has fewer than `n` elements, this function returns\n /// a copy of the full input list.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// List.take<Nat>(\n /// ?(0, ?(1, ?(2, null))),\n /// 2\n /// ); // => ?(0, ?(1, null))\n /// ```\n /// \n /// | Runtime | Space |\n /// |-------------|-------------|\n /// | `O(n)` | `O(n)` |\n public func take<T>(l : List<T>, n : Nat) : List<T> {\n switch (l, n) {\n case (_, 0) { null };\n case (null, _) { null };\n case (?(h, t), m) { ?(h, take<T>(t, m - 1)) }\n }\n };\n\n /// Drop the first `n` elements from the given list.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// List.drop<Nat>(\n /// ?(0, ?(1, ?(2, null))),\n /// 2\n /// ); // => ?(2, null)\n /// ```\n /// \n /// | Runtime | Space |\n /// |-------------|-------------|\n /// | `O(n)` | `O(1)` |\n public func drop<T>(l : List<T>, n : Nat) : List<T> {\n switch (l, n) {\n case (l_, 0) { l_ };\n case (null, _) { null };\n case ((?(_, t)), m) { drop<T>(t, m - 1) }\n }\n };\n\n /// Collapses the elements in `list` into a single value by starting with `base`\n /// and progessively combining elements into `base` with `combine`. Iteration runs\n /// left to right.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n /// List.foldLeft<Nat, Text>(\n /// ?(1, ?(2, ?(3, null))),\n /// \"\",\n /// func (acc, x) { acc # Nat.toText(x)}\n /// ) // => \"123\"\n /// ```\n /// \n /// | Runtime | Space (Heap) | Space (Stack) |\n /// |----------------|--------------|----------------|\n /// | `O(size(list))` | `O(1)` | `O(1)` |\n /// \n\n public func foldLeft<T, S>(list : List<T>, base : S, combine : (S, T) -> S) : S {\n switch list {\n case null { base };\n case (?(h, t)) { foldLeft(t, combine(base, h), combine) }\n }\n };\n\n /// Collapses the elements in `buffer` into a single value by starting with `base`\n /// and progessively combining elements into `base` with `combine`. Iteration runs\n /// right to left.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n /// List.foldRight<Nat, Text>(\n /// ?(1, ?(2, ?(3, null))),\n /// \"\",\n /// func (x, acc) { Nat.toText(x) # acc}\n /// ) // => \"123\"\n /// ```\n /// \n /// | Runtime | Space (Heap) | Space (Stack) |\n /// |---------------|--------------|-------------------|\n /// | `O(size(list))` | `O(1)` | `O(size(list))` |\n /// \n public func foldRight<T, S>(list : List<T>, base : S, combine : (T, S) -> S) : S {\n switch list {\n case null { base };\n case (?(h, t)) { combine(h, foldRight<T, S>(t, base, combine)) }\n }\n };\n\n /// Return the first element for which the given predicate `f` is true,\n /// if such an element exists.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// List.find<Nat>(\n /// ?(1, ?(2, ?(3, null))),\n /// func n { n > 1 }\n /// ); // => ?2\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size)` | `O(1)` |\n /// \n\n public func find<T>(l : List<T>, f : T -> Bool) : ?T {\n switch l {\n case null { null };\n case (?(h, t)) { if (f(h)) { ?h } else { find<T>(t, f) } }\n }\n };\n\n /// Return true if there exists a list element for which\n /// the given predicate `f` is true.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// List.some<Nat>(\n /// ?(1, ?(2, ?(3, null))),\n /// func n { n > 1 }\n /// ) // => true\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size)` | `O(1)` |\n /// \n\n public func some<T>(l : List<T>, f : T -> Bool) : Bool {\n switch l {\n case null { false };\n case (?(h, t)) { f(h) or some<T>(t, f) }\n }\n };\n\n /// Return true if the given predicate `f` is true for all list\n /// elements.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// List.all<Nat>(\n /// ?(1, ?(2, ?(3, null))),\n /// func n { n > 1 }\n /// ); // => false\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size)` | `O(1)` |\n /// \n\n public func all<T>(l : List<T>, f : T -> Bool) : Bool {\n switch l {\n case null { true };\n case (?(h, t)) { f(h) and all<T>(t, f) }\n }\n };\n\n /// Merge two ordered lists into a single ordered list.\n /// This function requires both list to be ordered as specified\n /// by the given relation `lessThanOrEqual`.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// List.merge<Nat>(\n /// ?(1, ?(2, ?(4, null))),\n /// ?(2, ?(4, ?(6, null))),\n /// func (n1, n2) { n1 <= n2 }\n /// ); // => ?(1, ?(2, ?(2, ?(4, ?(4, ?(6, null))))))),\n /// ```\n /// \n /// | Runtime | Space |\n /// |----------------------------|------------------------|\n /// | `O(size(l1) + size(l2))` | `O(size(l1) + size(l2))` |\n /// \n\n // TODO: replace by merge taking a compare : (T, T) -> Order.Order function?\n public func merge<T>(l1 : List<T>, l2 : List<T>, lessThanOrEqual : (T, T) -> Bool) : List<T> {\n switch (l1, l2) {\n case (null, _) { l2 };\n case (_, null) { l1 };\n case (?(h1, t1), ?(h2, t2)) {\n if (lessThanOrEqual(h1, h2)) {\n ?(h1, merge<T>(t1, l2, lessThanOrEqual))\n } else {\n ?(h2, merge<T>(l1, t2, lessThanOrEqual))\n }\n }\n }\n };\n\n private func compareAux<T>(l1 : List<T>, l2 : List<T>, compare : (T, T) -> Order.Order) : Order.Order {\n switch (l1, l2) {\n case (null, null) { #equal };\n case (null, _) { #less };\n case (_, null) { #greater };\n case (?(h1, t1), ?(h2, t2)) {\n switch (compare(h1, h2)) {\n case (#equal) { compareAux<T>(t1, t2, compare) };\n case other { other }\n }\n }\n }\n };\n\n /// Compare two lists using lexicographic ordering specified by argument function `compare`.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n /// \n /// List.compare<Nat>(\n /// ?(1, ?(2, null)),\n /// ?(3, ?(4, null)),\n /// Nat.compare\n /// ) // => #less\n /// ```\n /// \n /// | Runtime | Space |\n /// |----------------------------|------------------------|\n /// | `O(size(l1))` | `O(1)` |\n /// \n\n public func compare<T>(l1 : List<T>, l2 : List<T>, compare : (T, T) -> Order.Order) : Order.Order {\n compareAux<T>(l1, l2, compare)\n };\n\n private func equalAux<T>(l1 : List<T>, l2 : List<T>, equal : (T, T) -> Bool) : Bool {\n switch (l1, l2) {\n case (?(h1, t1), ?(h2, t2)) {\n equal(h1, h2) and equalAux<T>(t1, t2, equal)\n };\n case (null, null) { true };\n case _ { false }\n }\n };\n /// Compare two lists for equality using the argument function `equal` to determine equality of their elements.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n /// \n /// List.equal<Nat>(\n /// ?(1, ?(2, null)),\n /// ?(3, ?(4, null)),\n /// Nat.equal\n /// ); // => false\n /// ```\n /// \n /// | Runtime | Space |\n /// |----------------------------|------------------------|\n /// | `O(size(l1))` | `O(1)` |\n /// \n public func equal<T>(l1 : List<T>, l2 : List<T>, equal : (T, T) -> Bool) : Bool {\n equalAux<T>(l1, l2, equal)\n };\n\n /// Generate a list based on a length and a function that maps from\n /// a list index to a list element.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// List.tabulate<Nat>(\n /// 3,\n /// func n { n * 2 }\n /// ) // => ?(0, ?(2, (?4, null)))\n /// ```\n /// \n /// | Runtime | Space |\n /// |----------------------------|------------------------|\n /// | `O(n)` | `O(n)` |\n /// \n\n public func tabulate<T>(n : Nat, f : Nat -> T) : List<T> {\n var i = 0;\n var l : List<T> = null;\n while (i < n) {\n l := ?(f(i), l);\n i += 1\n };\n reverse(l)\n };\n\n /// Create a list with exactly one element.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// List.make<Nat>(\n /// 0\n /// ) // => ?(0, null)\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(1)` | `O(1)` |\n public func make<T>(x : T) : List<T> = ?(x, null);\n\n /// Create a list of the given length with the same value in each position.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// List.replicate<Nat>(\n /// 3,\n /// 0\n /// ) // => ?(0, ?(0, ?(0, null)))\n /// ```\n /// \n /// | Runtime | Space |\n /// |----------------------------|------------------------|\n /// | `O(n)` | `O(n)` |\n public func replicate<T>(n : Nat, x : T) : List<T> {\n var i = 0;\n var l : List<T> = null;\n while (i < n) {\n l := ?(x, l);\n i += 1\n };\n l\n };\n\n /// Create a list of pairs from a pair of lists.\n /// \n /// If the given lists have different lengths, then the created list will have a\n /// length equal to the length of the smaller list.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// List.zip<Nat, Text>(\n /// ?(0, ?(1, ?(2, null))),\n /// ?(\"0\", ?(\"1\", null)),\n /// ) // => ?((0, \"0\"), ?((1, \"1\"), null))\n /// ```\n /// \n /// | Runtime | Space |\n /// |----------------------------|------------------------|\n /// | `O(min(size(xs), size(ys)))` | `O(min(size(xs), size(ys)))` |\n public func zip<T, U>(xs : List<T>, ys : List<U>) : List<(T, U)> = zipWith<T, U, (T, U)>(xs, ys, func(x, y) { (x, y) });\n\n /// Create a list in which elements are created by applying function `f` to each pair `(x, y)` of elements\n /// occuring at the same position in list `xs` and list `ys`.\n /// \n /// If the given lists have different lengths, then the created list will have a\n /// length equal to the length of the smaller list.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// import Nat = \"mo:base/Nat\";\n /// import Char = \"mo:base/Char\";\n /// \n /// List.zipWith<Nat, Char, Text>(\n /// ?(0, ?(1, ?(2, null))),\n /// ?('a', ?('b', null)),\n /// func (n, c) { Nat.toText(n) # Char.toText(c) }\n /// ) // => ?(\"0a\", ?(\"1b\", null))\n /// ```\n /// \n /// | Runtime | Space |\n /// |----------------------------|------------------------|\n /// | `O(min(size(xs), size(ys)))` | `O(min(size(xs), size(ys)))` |\n /// \n\n public func zipWith<T, U, V>(\n xs : List<T>,\n ys : List<U>,\n f : (T, U) -> V\n ) : List<V> {\n switch (pop<T>(xs)) {\n case (null, _) { null };\n case (?x, xt) {\n switch (pop<U>(ys)) {\n case (null, _) { null };\n case (?y, yt) {\n push<V>(f(x, y), zipWith<T, U, V>(xt, yt, f))\n }\n }\n }\n }\n };\n\n /// Split the given list at the given zero-based index.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// List.split<Nat>(\n /// 2,\n /// ?(0, ?(1, ?(2, null)))\n /// ) // => (?(0, ?(1, null)), ?(2, null))\n /// ```\n /// \n /// | Runtime | Space |\n /// |-------------|-------------|\n /// | `O(n)` | `O(n)` |\n public func split<T>(n : Nat, xs : List<T>) : (List<T>, List<T>) {\n if (n == 0) { (null, xs) } else {\n func rec(n : Nat, xs : List<T>) : (List<T>, List<T>) {\n switch (pop<T>(xs)) {\n case (null, _) { (null, null) };\n case (?h, t) {\n if (n == 1) { (make<T>(h), t) } else {\n let (l, r) = rec(n - 1, t);\n (push<T>(h, l), r)\n }\n }\n }\n };\n rec(n, xs)\n }\n };\n\n /// Split the given list into chunks of length `n`.\n /// The last chunk will be shorter if the length of the given list\n /// does not divide by `n` evenly.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// List.chunks<Nat>(\n /// 2,\n /// ?(0, ?(1, ?(2, ?(3, ?(4, null)))))\n /// )\n /// /* => ?(?(0, ?(1, null)),\n /// ?(?(2, ?(3, null)),\n /// ?(?(4, null),\n /// null)))\n /// */\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size)` | `O(size)` |\n public func chunks<T>(n : Nat, xs : List<T>) : List<List<T>> {\n let (l, r) = split<T>(n, xs);\n if (isNil<T>(l)) {\n null\n } else {\n push<List<T>>(l, chunks<T>(n, r))\n }\n };\n\n /// Convert an array into a list.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// List.fromArray<Nat>([ 0, 1, 2, 3, 4])\n /// // => ?(0, ?(1, ?(2, ?(3, ?(4, null)))))\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size)` | `O(size)` |\n public func fromArray<T>(xs : [T]) : List<T> {\n Array.foldRight<T, List<T>>(\n xs,\n null,\n func(x : T, ys : List<T>) : List<T> {\n push<T>(x, ys)\n }\n )\n };\n\n /// Convert a mutable array into a list.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// List.fromVarArray<Nat>([var 0, 1, 2, 3, 4])\n /// // => ?(0, ?(1, ?(2, ?(3, ?(4, null)))))\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size)` | `O(size)` |\n public func fromVarArray<T>(xs : [var T]) : List<T> = fromArray<T>(Array.freeze<T>(xs));\n\n /// Create an array from a list.\n /// Example:\n /// ```motoko include=initialize\n /// List.toArray<Nat>(?(0, ?(1, ?(2, ?(3, ?(4, null))))))\n /// // => [0, 1, 2, 3, 4]\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size)` | `O(size)` |\n public func toArray<T>(xs : List<T>) : [T] {\n let length = size<T>(xs);\n var list = xs;\n Array.tabulate<T>(\n length,\n func(i) {\n let popped = pop<T>(list);\n list := popped.1;\n switch (popped.0) {\n case null { loop { assert false } };\n case (?x) x\n }\n }\n )\n };\n\n /// Create a mutable array from a list.\n /// Example:\n /// ```motoko include=initialize\n /// List.toVarArray<Nat>(?(0, ?(1, ?(2, ?(3, ?(4, null))))))\n /// // => [var 0, 1, 2, 3, 4]\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size)` | `O(size)` |\n public func toVarArray<T>(xs : List<T>) : [var T] = Array.thaw<T>(toArray<T>(xs));\n\n /// Create an iterator from a list.\n /// Example:\n /// ```motoko include=initialize\n /// var sum = 0;\n /// for (n in List.toIter<Nat>(?(0, ?(1, ?(2, ?(3, ?(4, null))))))) {\n /// sum += n;\n /// };\n /// sum\n /// // => 10\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(1)` | `O(1)` |\n public func toIter<T>(xs : List<T>) : Iter.Iter<T> {\n var state = xs;\n object {\n public func next() : ?T = switch state {\n case (?(hd, tl)) { state := tl; ?hd };\n case _ null\n }\n }\n }\n\n}\n"},"Iter.mo":{"content":"\nimport Array \"Array\";\nimport Buffer \"Buffer\";\nimport List \"List\";\nimport Order \"Order\";\n\nmodule {\n\n /// An iterator that produces values of type `T`. Calling `next` returns\n /// `null` when iteration is finished.\n /// \n /// Iterators are inherently stateful. Calling `next` \"consumes\" a value from\n /// the Iterator that cannot be put back, so keep that in mind when sharing\n /// iterators between consumers.\n /// \n /// An iterater `i` can be iterated over using\n /// ```\n /// for (x in i) {\n /// …do something with x…\n /// }\n /// ```\n public type Iter<T> = { next : () -> ?T };\n\n /// Creates an iterator that produces all `Nat`s from `x` to `y` including\n /// both of the bounds.\n /// ```motoko\n /// import Iter \"mo:base/Iter\";\n /// let iter = Iter.range(1, 3);\n /// assert(?1 == iter.next());\n /// assert(?2 == iter.next());\n /// assert(?3 == iter.next());\n /// assert(null == iter.next());\n /// ```\n public class range(x : Nat, y : Int) {\n var i = x;\n public func next() : ?Nat {\n if (i > y) { null } else { let j = i; i += 1; ?j }\n }\n };\n\n /// Like `range` but produces the values in the opposite\n /// order.\n public class revRange(x : Int, y : Int) {\n var i = x;\n public func next() : ?Int {\n if (i < y) { null } else { let j = i; i -= 1; ?j }\n }\n };\n\n /// Calls a function `f` on every value produced by an iterator and discards\n /// the results. If you're looking to keep these results use `map` instead.\n /// \n /// ```motoko\n /// import Iter \"mo:base/Iter\";\n /// var sum = 0;\n /// Iter.iterate<Nat>(Iter.range(1, 3), func(x, _index) {\n /// sum += x;\n /// });\n /// assert(6 == sum)\n /// ```\n public func iterate<A>(\n xs : Iter<A>,\n f : (A, Nat) -> ()\n ) {\n var i = 0;\n label l loop {\n switch (xs.next()) {\n case (?next) {\n f(next, i)\n };\n case (null) {\n break l\n }\n };\n i += 1;\n continue l\n }\n };\n\n /// Consumes an iterator and counts how many elements were produced\n /// (discarding them in the process).\n public func size<A>(xs : Iter<A>) : Nat {\n var len = 0;\n iterate<A>(xs, func(x, i) { len += 1 });\n len\n };\n\n /// Takes a function and an iterator and returns a new iterator that lazily applies\n /// the function to every element produced by the argument iterator.\n /// ```motoko\n /// import Iter \"mo:base/Iter\";\n /// let iter = Iter.range(1, 3);\n /// let mappedIter = Iter.map(iter, func (x : Nat) : Nat { x * 2 });\n /// assert(?2 == mappedIter.next());\n /// assert(?4 == mappedIter.next());\n /// assert(?6 == mappedIter.next());\n /// assert(null == mappedIter.next());\n /// ```\n public func map<A, B>(xs : Iter<A>, f : A -> B) : Iter<B> = object {\n public func next() : ?B {\n switch (xs.next()) {\n case (?next) {\n ?f(next)\n };\n case (null) {\n null\n }\n }\n }\n };\n\n /// Takes a function and an iterator and returns a new iterator that produces\n /// elements from the original iterator if and only if the predicate is true.\n /// ```motoko\n /// import Iter \"mo:base/Iter\";\n /// let iter = Iter.range(1, 3);\n /// let mappedIter = Iter.filter(iter, func (x : Nat) : Bool { x % 2 == 1 });\n /// assert(?1 == mappedIter.next());\n /// assert(?3 == mappedIter.next());\n /// assert(null == mappedIter.next());\n /// ```\n public func filter<A>(xs : Iter<A>, f : A -> Bool) : Iter<A> = object {\n public func next() : ?A {\n loop {\n switch (xs.next()) {\n case (null) {\n return null\n };\n case (?x) {\n if (f(x)) {\n return ?x\n }\n }\n }\n };\n null\n }\n };\n\n /// Creates an iterator that produces an infinite sequence of `x`.\n /// ```motoko\n /// import Iter \"mo:base/Iter\";\n /// let iter = Iter.make(10);\n /// assert(?10 == iter.next());\n /// assert(?10 == iter.next());\n /// assert(?10 == iter.next());\n /// // ...\n /// ```\n public func make<A>(x : A) : Iter<A> = object {\n public func next() : ?A {\n ?x\n }\n };\n\n /// Takes two iterators and returns a new iterator that produces\n /// elements from the original iterators sequentally.\n /// ```motoko\n /// import Iter \"mo:base/Iter\";\n /// let iter1 = Iter.range(1, 2);\n /// let iter2 = Iter.range(5, 6);\n /// let concatenatedIter = Iter.concat(iter1, iter2);\n /// assert(?1 == concatenatedIter.next());\n /// assert(?2 == concatenatedIter.next());\n /// assert(?5 == concatenatedIter.next());\n /// assert(?6 == concatenatedIter.next());\n /// assert(null == concatenatedIter.next());\n /// ```\n public func concat<A>(a : Iter<A>, b : Iter<A>) : Iter<A> {\n var aEnded : Bool = false;\n object {\n public func next() : ?A {\n if (aEnded) {\n return b.next()\n };\n switch (a.next()) {\n case (?x) ?x;\n case (null) {\n aEnded := true;\n b.next()\n }\n }\n }\n }\n };\n\n /// Creates an iterator that produces the elements of an `Array` in ascending index order.\n /// ```motoko\n /// import Iter \"mo:base/Iter\";\n /// let iter = Iter.fromArray([1, 2, 3]);\n /// assert(?1 == iter.next());\n /// assert(?2 == iter.next());\n /// assert(?3 == iter.next());\n /// assert(null == iter.next());\n /// ```\n public func fromArray<A>(xs : [A]) : Iter<A> {\n var ix : Nat = 0;\n let size = xs.size();\n object {\n public func next() : ?A {\n if (ix >= size) {\n return null\n } else {\n let res = ?(xs[ix]);\n ix += 1;\n return res\n }\n }\n }\n };\n\n /// Like `fromArray` but for `Array`s with mutable elements. Captures\n /// the elements of the `Array` at the time the iterator is created, so\n /// further modifications won't be reflected in the iterator.\n public func fromArrayMut<A>(xs : [var A]) : Iter<A> {\n fromArray<A>(Array.freeze<A>(xs))\n };\n\n /// Like `fromArray` but for Lists.\n public let fromList = List.toIter;\n\n /// Consumes an iterator and collects its produced elements in an `Array`.\n /// ```motoko\n /// import Iter \"mo:base/Iter\";\n /// let iter = Iter.range(1, 3);\n /// assert([1, 2, 3] == Iter.toArray(iter));\n /// ```\n public func toArray<A>(xs : Iter<A>) : [A] {\n let buffer = Buffer.Buffer<A>(8);\n iterate(xs, func(x : A, _ : Nat) { buffer.add(x) });\n return Buffer.toArray(buffer)\n };\n\n /// Like `toArray` but for `Array`s with mutable elements.\n public func toArrayMut<A>(xs : Iter<A>) : [var A] {\n Array.thaw<A>(toArray<A>(xs))\n };\n\n /// Like `toArray` but for Lists.\n public func toList<A>(xs : Iter<A>) : List.List<A> {\n var result = List.nil<A>();\n iterate<A>(\n xs,\n func(x, _i) {\n result := List.push<A>(x, result)\n }\n );\n List.reverse<A>(result)\n };\n\n /// Sorted iterator. Will iterate over *all* elements to sort them, necessarily.\n public func sort<A>(xs : Iter<A>, compare : (A, A) -> Order.Order) : Iter<A> {\n let a = toArrayMut<A>(xs);\n Array.sortInPlace<A>(a, compare);\n fromArrayMut<A>(a)\n };\n\n}\n"},"Trie.mo":{"content":"/// Functional key-value hash map.\n/// \n/// Provides an applicative (purely functional) hash map, called a *trie*, where each operation returns a new version of the structure without mutating the original.\n/// \n/// Operations use `Key` records that group the key value with its precomputed hash.\n/// \n/// For imperative or object-oriented alternatives, see [`TrieMap`](../TrieMap) or [`HashMap`](../HashMap).\n/// \n/// :::warning Hash collision limit\n/// Each trie node supports at most 8 distinct keys with the same hash (`MAX_LEAF_SIZE = 8`). Exceeding this will cause a trap.\n/// :::\n/// \n/// :::info Credits\n/// Based on Section 6 of [\"Incremental computation via function caching\", Pugh & Teitelbaum](https://dl.acm.org/citation.cfm?id=75305).\n/// :::\n/// \n/// Example:\n/// \n/// ```motoko\n/// import Trie \"mo:base/Trie\";\n/// import Text \"mo:base/Text\";\n/// \n/// // we do this to have shorter type names and thus\n/// // better readability\n/// type Trie<K, V> = Trie.Trie<K, V>;\n/// type Key<K> = Trie.Key<K>;\n/// \n/// // we have to provide `put`, `get` and `remove` with\n/// // a record of type `Key<K> = { hash : Hash.Hash; key : K }`;\n/// // thus we define the following function that takes a value of type `K`\n/// // (in this case `Text`) and returns a `Key<K>` record.\n/// func key(t: Text) : Key<Text> { { hash = Text.hash t; key = t } };\n/// \n/// // we start off by creating an empty `Trie`\n/// let t0 : Trie<Text, Nat> = Trie.empty();\n/// \n/// // `put` requires 4 arguments:\n/// // - the trie we want to insert the value into,\n/// // - the key of the value we want to insert (note that we use the `key` function defined above),\n/// // - a function that checks for equality of keys, and\n/// // - the value we want to insert.\n/// //\n/// // When inserting a value, `put` returns a tuple of type `(Trie<K, V>, ?V)`.\n/// // to get the new trie that contains the value, we use the `0` projection\n/// // and assign it to `t1` and `t2` respectively.\n/// let t1 : Trie<Text, Nat> = Trie.put(t0, key \"hello\", Text.equal, 42).0;\n/// let t2 : Trie<Text, Nat> = Trie.put(t1, key \"world\", Text.equal, 24).0;\n/// \n/// // If for a given key there already was a value in the trie, `put` returns\n/// // that previous value as the second element of the tuple.\n/// // in our case we have already inserted the value 42 for the key \"hello\", so\n/// // `put` returns 42 as the second element of the tuple.\n/// let (t3, n) : (Trie<Text, Nat>, ?Nat) = Trie.put(\n/// t2,\n/// key \"hello\",\n/// Text.equal,\n/// 0,\n/// );\n/// assert (n == ?42);\n/// \n/// // `get` requires 3 arguments:\n/// // - the trie we want to get the value from\n/// // - the key of the value we want to get (note that we use the `key` function defined above)\n/// // - a function that checks for equality of keys\n/// //\n/// // If the given key is nonexistent in the trie, `get` returns `null`.\n/// var value = Trie.get(t3, key \"hello\", Text.equal); // Returns `?42`\n/// assert(value == ?0);\n/// value := Trie.get(t3, key \"universe\", Text.equal); // Returns `null`\n/// assert(value == null);\n/// \n/// // `remove` requires 3 arguments:\n/// // - the trie we want to remove the value from,\n/// // - the key of the value we want to remove (note that we use the `key` function defined above), and\n/// // - a function that checks for equality of keys.\n/// //\n/// // In the case of keys of type `Text`, we can use `Text.equal`\n/// // to check for equality of keys. Function `remove` returns a tuple of type `(Trie<K, V>, ?V)`.\n/// // where the second element of the tuple is the value that was removed, or `null` if\n/// // there was no value for the given key.\n/// let removedValue : ?Nat = Trie.remove(\n/// t3,\n/// key \"hello\",\n/// Text.equal,\n/// ).1;\n/// assert (removedValue == ?0);\n/// \n/// // To iterate over the Trie, we use the `iter` function that takes a trie\n/// // of type `Trie<K,V>` and returns an iterator of type `Iter<(K,V)>`:\n/// var sum : Nat = 0;\n/// for (kv in Trie.iter(t3)) {\n/// sum += kv.1;\n/// };\n/// assert(sum == 24);\n/// ```\n\nimport Debug \"Debug\";\n\nimport Prim \"mo:⛔\";\nimport P \"Prelude\";\nimport Option \"Option\";\nimport Hash \"Hash\";\nimport A \"Array\";\n\nimport List \"List\";\nimport AssocList \"AssocList\";\nimport I \"Iter\";\n\nmodule {\n\n let MAX_LEAF_SIZE = 8; // to do -- further profiling and tuning\n\n /// Binary hash tries: either empty, a leaf node, or a branch node.\n public type Trie<K, V> = {\n #empty;\n #leaf : Leaf<K, V>;\n #branch : Branch<K, V>\n };\n\n /// Leaf nodes of trie consist of key-value pairs as a list.\n public type Leaf<K, V> = {\n size : Nat;\n keyvals : AssocList<Key<K>, V>\n };\n\n /// Branch nodes of the trie discriminate on a bit position of the keys' hashes.\n /// This bit position is not stored in the branch but determined from\n /// the context of the branch.\n public type Branch<K, V> = {\n size : Nat;\n left : Trie<K, V>;\n right : Trie<K, V>\n };\n\n public type AssocList<K, V> = AssocList.AssocList<K, V>;\n\n /// A `Key` for the trie has an associated hash value:\n /// - `hash` permits fast inequality checks, and permits collisions.\n /// - `key` permits precise equality checks, but is only used on values with equal hashes.\n public type Key<K> = {\n hash : Hash.Hash;\n key : K\n };\n\n type List<T> = List.List<T>;\n\n /// Equality function for two `Key<K>`s, in terms of equality of `K`'s.\n public func equalKey<K>(keq : (K, K) -> Bool) : ((Key<K>, Key<K>) -> Bool) = func(key1 : Key<K>, key2 : Key<K>) : Bool = Hash.equal(key1.hash, key2.hash) and keq(key1.key, key2.key);\n\n /// :::warning Deprecated function\n /// `isValid` is an internal predicate and will be removed in future.\n /// :::\n public func isValid<K, V>(t : Trie<K, V>, _enforceNormal : Bool) : Bool {\n func rec(t : Trie<K, V>, bitpos : ?Hash.Hash, bits : Hash.Hash, mask : Hash.Hash) : Bool = switch t {\n case (#empty) {\n true\n };\n case (#leaf l) {\n let len = List.size(l.keyvals);\n len <= MAX_LEAF_SIZE and len == l.size and List.all(\n l.keyvals,\n func((k : Key<K>, _v : V)) : Bool { ((k.hash & mask) == bits) }\n )\n };\n case (#branch b) {\n let bitpos1 = switch bitpos {\n case null { Prim.natToNat32(0) };\n case (?bp) { Prim.natToNat32(Prim.nat32ToNat(bp) + 1) }\n };\n let mask1 = mask | (Prim.natToNat32(1) << bitpos1);\n let bits1 = bits | (Prim.natToNat32(1) << bitpos1);\n let sum = size(b.left) + size(b.right);\n (b.size == sum) and rec(b.left, ?bitpos1, bits, mask1) and rec(b.right, ?bitpos1, bits1, mask1)\n }\n };\n rec(t, null, 0, 0)\n };\n\n /// A 2D trie maps dimension-1 keys to another\n /// layer of tries, each keyed on the dimension-2 keys.\n public type Trie2D<K1, K2, V> = Trie<K1, Trie<K2, V>>;\n\n /// A 3D trie maps dimension-1 keys to another\n /// Composition of 2D tries, each keyed on the dimension-2 and dimension-3 keys.\n public type Trie3D<K1, K2, K3, V> = Trie<K1, Trie2D<K2, K3, V>>;\n\n /// An empty trie. This is usually the starting point for building a trie.\n /// \n /// Example:\n /// ```motoko name=initialize\n /// import { print } \"mo:base/Debug\";\n /// import Trie \"mo:base/Trie\";\n /// import Text \"mo:base/Text\";\n /// \n /// // we do this to have shorter type names and thus\n /// // better readibility\n /// type Trie<K, V> = Trie.Trie<K, V>;\n /// type Key<K> = Trie.Key<K>;\n /// \n /// // We have to provide `put`, `get` and `remove` with\n /// // a function of return type `Key<K> = { hash : Hash.Hash; key : K }`\n /// func key(t: Text) : Key<Text> { { hash = Text.hash t; key = t } };\n /// // We start off by creating an empty `Trie`\n /// var trie : Trie<Text, Nat> = Trie.empty();\n /// ```\n public func empty<K, V>() : Trie<K, V> = #empty;\n\n /// Get the size in O(1) time.\n /// \n /// \n /// Example:\n /// ```motoko include=initialize\n /// var size = Trie.size(trie); // Returns 0, as `trie` is empty\n /// assert(size == 0);\n /// trie := Trie.put(trie, key \"hello\", Text.equal, 42).0;\n /// size := Trie.size(trie); // Returns 1, as we just added a new entry\n /// assert(size == 1);\n /// ```\n\n public func size<K, V>(t : Trie<K, V>) : Nat = switch t {\n case (#empty) { 0 };\n case (#leaf l) { l.size };\n case (#branch b) { b.size }\n };\n\n /// Construct a branch node, computing the size stored there.\n public func branch<K, V>(l : Trie<K, V>, r : Trie<K, V>) : Trie<K, V> =\n #branch {\n size = size l + size r;\n left = l;\n right = r\n };\n\n /// Construct a leaf node, computing the size stored there.\n /// \n /// This helper function automatically enforces the MAX_LEAF_SIZE\n /// by constructing branches as necessary; to do so, it also needs the bitpos\n /// of the leaf.\n public func leaf<K, V>(kvs : AssocList<Key<K>, V>, bitpos : Nat) : Trie<K, V> = fromList(null, kvs, bitpos);\n\n module ListUtil {\n /* Deprecated: List.lenClamp */\n /// Return the list length unless the number of items in the list exceeds\n /// a maximum value. If the list length exceed the maximum, the function\n /// returns `null`.\n public func lenClamp<T>(l : List<T>, max : Nat) : ?Nat {\n func rec(l : List<T>, max : Nat, i : Nat) : ?Nat = switch l {\n case null { ?i };\n case (?(_, t)) {\n if (i >= max) { null } else { rec(t, max, i + 1) }\n }\n };\n rec(l, max, 0)\n }\n };\n\n /// Transform a list into a trie, splitting input list into small (leaf) lists, if necessary.\n public func fromList<K, V>(kvc : ?Nat, kvs : AssocList<Key<K>, V>, bitpos : Nat) : Trie<K, V> {\n func rec(kvc : ?Nat, kvs : AssocList<Key<K>, V>, bitpos : Nat) : Trie<K, V> {\n switch kvc {\n case null {\n switch (ListUtil.lenClamp(kvs, MAX_LEAF_SIZE)) {\n case null {} /* fall through to branch case. */;\n case (?len) {\n return #leaf { size = len; keyvals = kvs }\n }\n }\n };\n case (?c) {\n if (c == 0) {\n return #empty\n } else if (c <= MAX_LEAF_SIZE) {\n return #leaf { size = c; keyvals = kvs }\n } else {\n\n //fall through to branch case\n }\n }\n };\n let (ls, l, rs, r) = splitList(kvs, bitpos);\n if (ls == 0 and rs == 0) {\n #empty\n } else if (rs == 0 and ls <= MAX_LEAF_SIZE) {\n #leaf { size = ls; keyvals = l }\n } else if (ls == 0 and rs <= MAX_LEAF_SIZE) {\n #leaf { size = rs; keyvals = r }\n } else {\n branch(rec(?ls, l, bitpos + 1), rec(?rs, r, bitpos + 1))\n }\n };\n rec(kvc, kvs, bitpos)\n };\n\n /// Clone the trie efficiently, via sharing.\n /// \n /// Purely-functional representation permits _O(1)_ copy, via persistent sharing.\n public func clone<K, V>(t : Trie<K, V>) : Trie<K, V> = t;\n\n /// Combine two nodes that may have a reduced size after an entry deletion.\n func combineReducedNodes<K, V>(left : Trie<K, V>, right : Trie<K, V>) : Trie<K, V> = switch (left, right) {\n case (#empty, #empty) {\n #empty\n };\n case (#leaf _, #empty) {\n left\n };\n case (#empty, #leaf _) {\n right\n };\n case (#leaf leftLeaf, #leaf rightLeaf) {\n let size = leftLeaf.size + rightLeaf.size;\n if (size <= MAX_LEAF_SIZE) {\n let union = List.append(leftLeaf.keyvals, rightLeaf.keyvals);\n #leaf { size; keyvals = union }\n } else {\n branch(left, right)\n }\n };\n case (left, right) {\n branch(left, right)\n }\n };\n\n /// Replace the given key's value option with the given value, returning the modified trie.\n /// Also returns the replaced value if the key existed and `null` otherwise.\n /// Compares keys using the provided function `k_eq`.\n /// \n /// :::note\n /// Replacing a key's value by `null` removes the key and also shrinks the trie.\n /// :::\n /// \n /// Example:\n /// ```motoko include=initialize\n /// trie := Trie.put(trie, key \"test\", Text.equal, 1).0;\n /// trie := Trie.replace(trie, key \"test\", Text.equal, 42).0;\n /// assert (Trie.get(trie, key \"hello\", Text.equal) == ?42);\n /// ```\n public func replace<K, V>(t : Trie<K, V>, k : Key<K>, k_eq : (K, K) -> Bool, v : ?V) : (Trie<K, V>, ?V) {\n let key_eq = equalKey(k_eq);\n var replacedValue : ?V = null;\n\n func recursiveReplace(t : Trie<K, V>, bitpos : Nat) : Trie<K, V> = switch t {\n case (#empty) {\n let (kvs, _) = AssocList.replace(null, k, key_eq, v);\n leaf(kvs, bitpos)\n };\n case (#branch b) {\n let bit = Hash.bit(k.hash, bitpos);\n // rebuild either the left or right path with the (k, v) pair\n if (not bit) {\n let l = recursiveReplace(b.left, bitpos + 1);\n combineReducedNodes(l, b.right)\n } else {\n let r = recursiveReplace(b.right, bitpos + 1);\n combineReducedNodes(b.left, r)\n }\n };\n case (#leaf l) {\n let (kvs2, oldValue) = AssocList.replace(l.keyvals, k, key_eq, v);\n replacedValue := oldValue;\n leaf(kvs2, bitpos)\n }\n };\n let newTrie = recursiveReplace(t, 0);\n //assert(isValid<K, V>(newTrie, false));\n (newTrie, replacedValue)\n };\n\n /// Put the given key's value in the trie; return the new trie, and the previous value associated with the key, if any.\n /// \n /// \n /// Example:\n /// ```motoko include=initialize\n /// trie := Trie.put(trie, key \"hello\", Text.equal, 42).0;\n /// let previousValue = Trie.put(trie, key \"hello\", Text.equal, 33).1; // Returns ?42\n /// assert(previousValue == ?42);\n /// ```\n public func put<K, V>(t : Trie<K, V>, k : Key<K>, k_eq : (K, K) -> Bool, v : V) : (Trie<K, V>, ?V) = replace(t, k, k_eq, ?v);\n\n /// Get the value of the given key in the trie, or return null if nonexistent.\n /// \n /// \n /// Example:\n /// ```motoko include=initialize\n /// trie := Trie.put(trie, key \"hello\", Text.equal, 42).0;\n /// var value = Trie.get(trie, key \"hello\", Text.equal); // Returns `?42`\n /// assert(value == ?42);\n /// value := Trie.get(trie, key \"world\", Text.equal); // Returns `null`\n /// assert(value == null);\n /// ```\n public func get<K, V>(t : Trie<K, V>, k : Key<K>, k_eq : (K, K) -> Bool) : ?V = find(t, k, k_eq);\n\n /// Find the given key's value in the trie, or return `null` if nonexistent\n /// \n /// \n /// Example:\n /// ```motoko include=initialize\n /// trie := Trie.put(trie, key \"hello\", Text.equal, 42).0;\n /// var value = Trie.find(trie, key \"hello\", Text.equal); // Returns `?42`\n /// assert(value == ?42);\n /// value := Trie.find(trie, key \"world\", Text.equal); // Returns `null`\n /// assert(value == null);\n /// ```\n public func find<K, V>(t : Trie<K, V>, k : Key<K>, k_eq : (K, K) -> Bool) : ?V {\n let key_eq = equalKey(k_eq);\n func rec(t : Trie<K, V>, bitpos : Nat) : ?V = switch t {\n case (#empty) { null };\n case (#leaf l) {\n AssocList.find(l.keyvals, k, key_eq)\n };\n case (#branch b) {\n let bit = Hash.bit(k.hash, bitpos);\n if (not bit) {\n rec(b.left, bitpos + 1)\n } else {\n rec(b.right, bitpos + 1)\n }\n }\n };\n rec(t, 0)\n };\n\n func splitAssocList<K, V>(al : AssocList<Key<K>, V>, bitpos : Nat) : (AssocList<Key<K>, V>, AssocList<Key<K>, V>) = List.partition(\n al,\n func((k : Key<K>, _v : V)) : Bool = not Hash.bit(k.hash, bitpos)\n );\n\n func splitList<K, V>(l : AssocList<Key<K>, V>, bitpos : Nat) : (Nat, AssocList<Key<K>, V>, Nat, AssocList<Key<K>, V>) {\n func rec(l : AssocList<Key<K>, V>) : (Nat, AssocList<Key<K>, V>, Nat, AssocList<Key<K>, V>) = switch l {\n case null { (0, null, 0, null) };\n case (?((k, v), t)) {\n let (cl, l, cr, r) = rec(t);\n if (not Hash.bit(k.hash, bitpos)) { (cl + 1, ?((k, v), l), cr, r) } else {\n (cl, l, cr + 1, ?((k, v), r))\n }\n }\n };\n rec(l)\n };\n\n /// Merge tries, preferring the left trie where there are collisions\n /// in common keys.\n /// \n /// :::note\n /// The `disj` operation generalizes this `merge`\n /// operation in various ways, and does not (in general) lose\n /// information; this operation is a simpler, special case.\n /// :::\n /// \n /// Example:\n /// ```motoko include=initialize\n /// trie := Trie.put(trie, key \"hello\", Text.equal, 42).0;\n /// trie := Trie.put(trie, key \"bye\", Text.equal, 42).0;\n /// // trie2 is a copy of trie\n /// var trie2 = Trie.clone(trie);\n /// // trie2 has a different value for \"hello\"\n /// trie2 := Trie.put(trie2, key \"hello\", Text.equal, 33).0;\n /// // mergedTrie has the value 42 for \"hello\", as the left trie is preferred\n /// // in the case of a collision\n /// var mergedTrie = Trie.merge(trie, trie2, Text.equal);\n /// var value = Trie.get(mergedTrie, key \"hello\", Text.equal);\n /// assert(value == ?42);\n /// ```\n public func merge<K, V>(tl : Trie<K, V>, tr : Trie<K, V>, k_eq : (K, K) -> Bool) : Trie<K, V> {\n let key_eq = equalKey(k_eq);\n func rec(bitpos : Nat, tl : Trie<K, V>, tr : Trie<K, V>) : Trie<K, V> = switch (tl, tr) {\n case (#empty, _) { return tr };\n case (_, #empty) { return tl };\n case (#leaf l1, #leaf l2) {\n leaf(\n AssocList.disj(\n l1.keyvals,\n l2.keyvals,\n key_eq,\n func(x : ?V, y : ?V) : V = switch (x, y) {\n case (null, null) { P.unreachable() };\n case (null, ?v) { v };\n case (?v, _) { v }\n }\n ),\n bitpos\n )\n };\n case (#leaf l, _) {\n let (ll, lr) = splitAssocList(l.keyvals, bitpos);\n rec(bitpos, branch(leaf(ll, bitpos), leaf(lr, bitpos)), tr)\n };\n case (_, #leaf l) {\n let (ll, lr) = splitAssocList(l.keyvals, bitpos);\n rec(bitpos, tl, branch(leaf(ll, bitpos), leaf(lr, bitpos)))\n };\n case (#branch b1, #branch b2) {\n branch(\n rec(bitpos + 1, b1.left, b2.left),\n rec(bitpos + 1, b1.right, b2.right)\n )\n }\n };\n rec(0, tl, tr)\n };\n\n /// <a name=\"mergedisjoint\"></a>\n /// \n /// Merge tries like `merge`, but traps if there are collisions in common keys between the\n /// left and right inputs.\n /// \n /// \n /// Example:\n /// ```motoko include=initialize\n /// trie := Trie.put(trie, key \"hello\", Text.equal, 42).0;\n /// trie := Trie.put(trie, key \"bye\", Text.equal, 42).0;\n /// // trie2 is a copy of trie\n /// var trie2 = Trie.clone(trie);\n /// // trie2 has a different value for \"hello\"\n /// trie2 := Trie.put(trie2, key \"hello\", Text.equal, 33).0;\n /// // `mergeDisjoint` signals a dynamic errror\n /// // in the case of a collision\n /// var mergedTrie = Trie.mergeDisjoint(trie, trie2, Text.equal);\n /// ```\n public func mergeDisjoint<K, V>(tl : Trie<K, V>, tr : Trie<K, V>, k_eq : (K, K) -> Bool) : Trie<K, V> {\n func rec(bitpos : Nat, tl : Trie<K, V>, tr : Trie<K, V>) : Trie<K, V> = switch (tl, tr) {\n case (#empty, _) { return tr };\n case (_, #empty) { return tl };\n case (#leaf l1, #leaf l2) {\n leaf(\n AssocList.disj(\n l1.keyvals,\n l2.keyvals,\n equalKey(k_eq),\n func(x : ?V, y : ?V) : V = switch (x, y) {\n case (null, ?v) { v };\n case (?v, null) { v };\n case (_, _) { Debug.trap \"Trie.mergeDisjoint\" }\n }\n ),\n bitpos\n )\n };\n case (#leaf l, _) {\n let (ll, lr) = splitAssocList(l.keyvals, bitpos);\n rec(bitpos, branch(leaf(ll, bitpos), leaf(lr, bitpos)), tr)\n };\n case (_, #leaf l) {\n let (ll, lr) = splitAssocList(l.keyvals, bitpos);\n rec(bitpos, tl, branch(leaf(ll, bitpos), leaf(lr, bitpos)))\n };\n case (#branch b1, #branch b2) {\n branch(\n rec(bitpos + 1, b1.left, b2.left),\n rec(bitpos + 1, b1.right, b2.right)\n )\n }\n };\n rec(0, tl, tr)\n };\n\n /// Difference of tries. The output consists of pairs of\n /// the left trie whose keys are not present in the right trie; the\n /// values of the right trie are irrelevant.\n /// \n /// \n /// Example:\n /// ```motoko include=initialize\n /// trie := Trie.put(trie, key \"hello\", Text.equal, 42).0;\n /// trie := Trie.put(trie, key \"bye\", Text.equal, 42).0;\n /// // trie2 is a copy of trie\n /// var trie2 = Trie.clone(trie);\n /// // trie2 now has an additional key\n /// trie2 := Trie.put(trie2, key \"ciao\", Text.equal, 33).0;\n /// // `diff` returns a trie with the key \"ciao\",\n /// // as this key is not present in `trie`\n /// // (note that we pass `trie2` as the left trie)\n /// Trie.diff(trie2, trie, Text.equal);\n /// ```\n public func diff<K, V, W>(tl : Trie<K, V>, tr : Trie<K, W>, k_eq : (K, K) -> Bool) : Trie<K, V> {\n let key_eq = equalKey(k_eq);\n\n func rec(bitpos : Nat, tl : Trie<K, V>, tr : Trie<K, W>) : Trie<K, V> = switch (tl, tr) {\n case (#empty, _) { return #empty };\n case (_, #empty) { return tl };\n case (#leaf l1, #leaf l2) {\n leaf(\n AssocList.diff(\n l1.keyvals,\n l2.keyvals,\n key_eq\n ),\n bitpos\n )\n };\n case (#leaf l, _) {\n let (ll, lr) = splitAssocList(l.keyvals, bitpos);\n rec(bitpos, branch(leaf(ll, bitpos), leaf(lr, bitpos)), tr)\n };\n case (_, #leaf l) {\n let (ll, lr) = splitAssocList(l.keyvals, bitpos);\n rec(bitpos, tl, branch(leaf(ll, bitpos), leaf(lr, bitpos)))\n };\n case (#branch b1, #branch b2) {\n branch(\n rec(bitpos + 1, b1.left, b2.left),\n rec(bitpos + 1, b1.right, b2.right)\n )\n }\n };\n rec(0, tl, tr)\n };\n\n /// Map disjunction.\n /// \n /// This operation generalizes the notion of \"set union\" to finite maps.\n /// \n /// Produces a \"disjunctive image\" of the two tries, where the values of\n /// matching keys are combined with the given binary operator.\n /// \n /// For unmatched key-value pairs, the operator is still applied to\n /// create the value in the image. To accomodate these various\n /// situations, the operator accepts optional values, but is never\n /// applied to (null, null).\n /// \n /// Implements the database idea of an [\"outer join\"](https://stackoverflow.com/questions/38549/what-is-the-difference-between-inner-join-and-outer-join).\n /// \n public func disj<K, V, W, X>(\n tl : Trie<K, V>,\n tr : Trie<K, W>,\n k_eq : (K, K) -> Bool,\n vbin : (?V, ?W) -> X\n ) : Trie<K, X> {\n let key_eq = equalKey(k_eq);\n\n /* empty right case; build from left only: */\n func recL(t : Trie<K, V>, bitpos : Nat) : Trie<K, X> = switch t {\n case (#empty) { #empty };\n case (#leaf l) {\n leaf(AssocList.disj(l.keyvals, null, key_eq, vbin), bitpos)\n };\n case (#branch b) {\n branch(\n recL(b.left, bitpos + 1),\n recL(b.right, bitpos + 1)\n )\n }\n };\n\n /* empty left case; build from right only: */\n func recR(t : Trie<K, W>, bitpos : Nat) : Trie<K, X> = switch t {\n case (#empty) { #empty };\n case (#leaf l) {\n leaf(AssocList.disj(null, l.keyvals, key_eq, vbin), bitpos)\n };\n case (#branch b) {\n branch(\n recR(b.left, bitpos + 1),\n recR(b.right, bitpos + 1)\n )\n }\n };\n\n /* main recursion */\n func rec(bitpos : Nat, tl : Trie<K, V>, tr : Trie<K, W>) : Trie<K, X> = switch (tl, tr) {\n case (#empty, #empty) { #empty };\n case (#empty, _) { recR(tr, bitpos) };\n case (_, #empty) { recL(tl, bitpos) };\n case (#leaf l1, #leaf l2) {\n leaf(AssocList.disj(l1.keyvals, l2.keyvals, key_eq, vbin), bitpos)\n };\n case (#leaf l, _) {\n let (ll, lr) = splitAssocList(l.keyvals, bitpos);\n rec(bitpos, branch(leaf(ll, bitpos), leaf(lr, bitpos)), tr)\n };\n case (_, #leaf l) {\n let (ll, lr) = splitAssocList(l.keyvals, bitpos);\n rec(bitpos, tl, branch(leaf(ll, bitpos), leaf(lr, bitpos)))\n };\n case (#branch b1, #branch b2) {\n branch(\n rec(bitpos + 1, b1.left, b2.left),\n rec(bitpos + 1, b1.right, b2.right)\n )\n }\n };\n\n rec(0, tl, tr)\n };\n\n /// Map join.\n /// \n /// Implements the database idea of an [\"inner join\"](https://stackoverflow.com/questions/38549/what-is-the-difference-between-inner-join-and-outer-join).\n /// \n /// This operation generalizes the notion of \"set intersection\" to\n /// finite maps. The values of matching keys are combined with the given binary\n /// operator, and unmatched key-value pairs are not present in the output.\n /// \n public func join<K, V, W, X>(\n tl : Trie<K, V>,\n tr : Trie<K, W>,\n k_eq : (K, K) -> Bool,\n vbin : (V, W) -> X\n ) : Trie<K, X> {\n let key_eq = equalKey(k_eq);\n\n func rec(bitpos : Nat, tl : Trie<K, V>, tr : Trie<K, W>) : Trie<K, X> = switch (tl, tr) {\n case (#empty, _) { #empty };\n case (_, #empty) { #empty };\n case (#leaf l1, #leaf l2) {\n leaf(AssocList.join(l1.keyvals, l2.keyvals, key_eq, vbin), bitpos)\n };\n case (#leaf l, _) {\n let (ll, lr) = splitAssocList(l.keyvals, bitpos);\n rec(bitpos, branch(leaf(ll, bitpos), leaf(lr, bitpos)), tr)\n };\n case (_, #leaf l) {\n let (ll, lr) = splitAssocList(l.keyvals, bitpos);\n rec(bitpos, tl, branch(leaf(ll, bitpos), leaf(lr, bitpos)))\n };\n case (#branch b1, #branch b2) {\n branch(\n rec(bitpos + 1, b1.left, b2.left),\n rec(bitpos + 1, b1.right, b2.right)\n )\n }\n };\n\n rec(0, tl, tr)\n };\n\n /// This operation gives a recursor for the internal structure of\n /// tries. Many common operations are instantiations of this function,\n /// either as clients, or as hand-specialized versions (e.g., see , map,\n /// mapFilter, some and all below).\n public func foldUp<K, V, X>(t : Trie<K, V>, bin : (X, X) -> X, leaf : (K, V) -> X, empty : X) : X {\n func rec(t : Trie<K, V>) : X = switch t {\n case (#empty) { empty };\n case (#leaf l) {\n AssocList.fold(\n l.keyvals,\n empty,\n func(k : Key<K>, v : V, x : X) : X = bin(leaf(k.key, v), x)\n )\n };\n case (#branch b) { bin(rec(b.left), rec(b.right)) }\n };\n rec(t)\n };\n\n /// Map product.\n /// \n /// Conditional _catesian product_, where the given\n /// operation `op` _conditionally_ creates output elements in the\n /// resulting trie.\n /// \n /// The keyed structure of the input tries are not relevant for this\n /// operation: all pairs are considered, regardless of keys matching or\n /// not. Moreover, the resulting trie may use keys that are unrelated to\n /// these input keys.\n /// \n public func prod<K1, V1, K2, V2, K3, V3>(\n tl : Trie<K1, V1>,\n tr : Trie<K2, V2>,\n op : (K1, V1, K2, V2) -> ?(Key<K3>, V3),\n k3_eq : (K3, K3) -> Bool\n ) : Trie<K3, V3> {\n\n /*- binary case: merge disjoint results: */\n func merge(a : Trie<K3, V3>, b : Trie<K3, V3>) : Trie<K3, V3> = mergeDisjoint(a, b, k3_eq);\n\n /*- \"`foldUp` squared\" (imagine two nested loops): */\n foldUp(\n tl,\n merge,\n func(k1 : K1, v1 : V1) : Trie<K3, V3> = foldUp(\n tr,\n merge,\n func(k2 : K2, v2 : V2) : Trie<K3, V3> = switch (op(k1, v1, k2, v2)) {\n case null { #empty };\n case (?(k3, v3)) { put(#empty, k3, k3_eq, v3).0 }\n },\n #empty\n ),\n #empty\n )\n };\n\n /// Returns an iterator of type `Iter` over the key-value entries of the trie.\n /// \n /// Each iterator gets a _persistent view_ of the mapping, independent of concurrent updates to the iterated map.\n /// \n /// \n /// Example:\n /// ```motoko include=initialize\n /// trie := Trie.put(trie, key \"hello\", Text.equal, 42).0;\n /// trie := Trie.put(trie, key \"bye\", Text.equal, 32).0;\n /// // create an Iterator over key-value pairs of trie\n /// let iter = Trie.iter(trie);\n /// // add another key-value pair to `trie`.\n /// // because we created our iterator before\n /// // this update, it will not contain this new key-value pair\n /// trie := Trie.put(trie, key \"ciao\", Text.equal, 3).0;\n /// var sum : Nat = 0;\n /// for ((k,v) in iter) {\n /// sum += v;\n /// };\n /// assert(sum == 74);\n /// ```\n public func iter<K, V>(t : Trie<K, V>) : I.Iter<(K, V)> = object {\n var stack = ?(t, null) : List.List<Trie<K, V>>;\n public func next() : ?(K, V) = switch stack {\n case null { null };\n case (?(trie, stack2)) {\n switch trie {\n case (#empty) {\n stack := stack2;\n next()\n };\n case (#leaf { keyvals = null }) {\n stack := stack2;\n next()\n };\n case (#leaf { size = c; keyvals = ?((k, v), kvs) }) {\n stack := ?(#leaf { size = c - 1; keyvals = kvs }, stack2);\n ?(k.key, v)\n };\n case (#branch br) {\n stack := ?(br.left, ?(br.right, stack2));\n next()\n }\n }\n }\n }\n };\n\n /// Represent the construction of tries as data.\n /// \n /// This module provides optimized variants of normal tries, for\n /// more efficient join queries.\n /// \n /// The central insight is that for (unmaterialized) join query results, we\n /// do not need to actually build any resulting trie of the resulting\n /// data, but rather, just need a collection of what would be in that\n /// trie. Since query results can be large (quadratic in the DB size),\n /// avoiding the construction of this trie provides a considerable savings.\n /// \n /// To get this savings, we use an ADT for the operations that _would_ build this trie,\n /// if evaluated. This structure specializes a rope: a balanced tree representing a\n /// sequence. It is only as balanced as the tries from which we generate\n /// these build ASTs. They have no intrinsic balance properties of their\n /// own.\n /// \n public module Build {\n /// The build of a trie, as an AST for a simple DSL.\n public type Build<K, V> = {\n #skip;\n #put : (K, ?Hash.Hash, V);\n #seq : {\n size : Nat;\n left : Build<K, V>;\n right : Build<K, V>\n }\n };\n\n /// Size of the build, measured in `#put` operations\n public func size<K, V>(tb : Build<K, V>) : Nat = switch tb {\n case (#skip) { 0 };\n case (#put(_, _, _)) { 1 };\n case (#seq(seq)) { seq.size }\n };\n\n /// Build sequence of two sub-builds\n public func seq<K, V>(l : Build<K, V>, r : Build<K, V>) : Build<K, V> {\n let sum = size(l) + size(r);\n #seq { size = sum; left = l; right = r }\n };\n\n /// Like [`prod`](#prod), except do not actually do the put calls, just\n /// record them, as a (binary tree) data structure, isomorphic to the\n /// recursion of this function (which is balanced, in expectation).\n public func prod<K1, V1, K2, V2, K3, V3>(\n tl : Trie<K1, V1>,\n tr : Trie<K2, V2>,\n op : (K1, V1, K2, V2) -> ?(K3, V3),\n _k3_eq : (K3, K3) -> Bool\n ) : Build<K3, V3> {\n\n func bin(a : Build<K3, V3>, b : Build<K3, V3>) : Build<K3, V3> = seq(a, b);\n\n /// double-nested folds\n foldUp(\n tl,\n bin,\n func(k1 : K1, v1 : V1) : Build<K3, V3> = foldUp(\n tr,\n bin,\n func(k2 : K2, v2 : V2) : Build<K3, V3> = switch (op(k1, v1, k2, v2)) {\n case null { #skip };\n case (?(k3, v3)) { #put(k3, null, v3) }\n },\n #skip\n ),\n #skip\n )\n };\n\n /// Project the nth key-value pair from the trie build.\n /// \n /// This position is meaningful only when the build contains multiple uses of one or more keys, otherwise it is not.\n public func nth<K, V>(tb : Build<K, V>, i : Nat) : ?(K, ?Hash.Hash, V) {\n func rec(tb : Build<K, V>, i : Nat) : ?(K, ?Hash.Hash, V) = switch tb {\n case (#skip) { P.unreachable() };\n case (#put(k, h, v)) {\n assert (i == 0);\n ?(k, h, v)\n };\n case (#seq(s)) {\n let size_left = size(s.left);\n if (i < size_left) { rec(s.left, i) } else {\n rec(s.right, i - size_left)\n }\n }\n };\n\n if (i >= size(tb)) {\n return null\n };\n rec(tb, i)\n };\n\n /// Like [`mergeDisjoint`](#mergedisjoint), except that it avoids the\n /// work of actually merging any tries; rather, just record the work for\n /// latter (if ever).\n public func projectInner<K1, K2, V>(t : Trie<K1, Build<K2, V>>) : Build<K2, V> = foldUp(\n t,\n func(t1 : Build<K2, V>, t2 : Build<K2, V>) : Build<K2, V> = seq(t1, t2),\n func(_ : K1, t : Build<K2, V>) : Build<K2, V> = t,\n #skip\n );\n\n /// Gather the collection of key-value pairs into an array of a (possibly-distinct) type.\n public func toArray<K, V, W>(tb : Build<K, V>, f : (K, V) -> W) : [W] {\n let c = size(tb);\n let a = A.init<?W>(c, null);\n var i = 0;\n func rec(tb : Build<K, V>) = switch tb {\n case (#skip) {};\n case (#put(k, _, v)) { a[i] := ?f(k, v); i := i + 1 };\n case (#seq(s)) { rec(s.left); rec(s.right) }\n };\n rec(tb);\n A.tabulate(\n c,\n func(i : Nat) : W = switch (a[i]) {\n case null { P.unreachable() };\n case (?x) { x }\n }\n )\n };\n\n };\n\n /// Fold over the key-value pairs of the trie, using an accumulator.\n /// The key-value pairs have no reliable or meaningful ordering.\n /// \n /// \n /// Example:\n /// ```motoko include=initialize\n /// trie := Trie.put(trie, key \"hello\", Text.equal, 42).0;\n /// trie := Trie.put(trie, key \"bye\", Text.equal, 32).0;\n /// trie := Trie.put(trie, key \"ciao\", Text.equal, 3).0;\n /// // create an accumulator, in our case the sum of all values\n /// func calculateSum(k : Text, v : Nat, acc : Nat) : Nat = acc + v;\n /// // Fold over the trie using the accumulator.\n /// // Note that 0 is the initial value of the accumulator.\n /// let sum = Trie.fold(trie, calculateSum, 0);\n /// assert(sum == 77);\n /// ```\n public func fold<K, V, X>(t : Trie<K, V>, f : (K, V, X) -> X, x : X) : X {\n func rec(t : Trie<K, V>, x : X) : X = switch t {\n case (#empty) { x };\n case (#leaf l) {\n AssocList.fold(\n l.keyvals,\n x,\n func(k : Key<K>, v : V, x : X) : X = f(k.key, v, x)\n )\n };\n case (#branch b) { rec(b.left, rec(b.right, x)) }\n };\n rec(t, x)\n };\n\n /// Test whether a given key-value pair is present, or not.\n /// \n /// \n /// Example:\n /// ```motoko include=initialize\n /// trie := Trie.put(trie, key \"hello\", Text.equal, 42).0;\n /// trie := Trie.put(trie, key \"bye\", Text.equal, 32).0;\n /// trie := Trie.put(trie, key \"ciao\", Text.equal, 3).0;\n /// // `some` takes a function that returns a Boolean indicating whether\n /// // the key-value pair is present or not\n /// var isPresent = Trie.some(\n /// trie,\n /// func(k : Text, v : Nat) : Bool = k == \"bye\" and v == 32,\n /// );\n /// assert(isPresent == true);\n /// isPresent := Trie.some(\n /// trie,\n /// func(k : Text, v : Nat) : Bool = k == \"hello\" and v == 32,\n /// );\n /// assert(isPresent == false);\n /// ```\n public func some<K, V>(t : Trie<K, V>, f : (K, V) -> Bool) : Bool {\n func rec(t : Trie<K, V>) : Bool = switch t {\n case (#empty) { false };\n case (#leaf l) {\n List.some(\n l.keyvals,\n func((k : Key<K>, v : V)) : Bool = f(k.key, v)\n )\n };\n case (#branch b) { rec(b.left) or rec(b.right) }\n };\n rec(t)\n };\n\n /// Test whether all key-value pairs have a given property.\n /// \n /// \n /// Example:\n /// ```motoko include=initialize\n /// trie := Trie.put(trie, key \"hello\", Text.equal, 42).0;\n /// trie := Trie.put(trie, key \"bye\", Text.equal, 32).0;\n /// trie := Trie.put(trie, key \"ciao\", Text.equal, 10).0;\n /// // `all` takes a function that returns a boolean indicating whether\n /// // the key-value pairs all have a given property, in our case that\n /// // all values are greater than 9\n /// var hasProperty = Trie.all(\n /// trie,\n /// func(k : Text, v : Nat) : Bool = v > 9,\n /// );\n /// assert(hasProperty == true);\n /// // now we check if all values are greater than 100\n /// hasProperty := Trie.all(\n /// trie,\n /// func(k : Text, v : Nat) : Bool = v > 100,\n /// );\n /// assert(hasProperty == false);\n /// ```\n public func all<K, V>(t : Trie<K, V>, f : (K, V) -> Bool) : Bool {\n func rec(t : Trie<K, V>) : Bool = switch t {\n case (#empty) { true };\n case (#leaf l) {\n List.all(\n l.keyvals,\n func((k : Key<K>, v : V)) : Bool = f(k.key, v)\n )\n };\n case (#branch b) { rec(b.left) and rec(b.right) }\n };\n rec(t)\n };\n\n /// Project the nth key-value pair from the trie.\n /// \n /// :::note\n /// This position is not meaningful; it's only here so that we\n /// can inject tries into arrays using functions like `Array.tabulate`.\n /// :::\n /// \n /// Example:\n /// ```motoko include=initialize\n /// import Array \"mo:base/Array\";\n /// trie := Trie.put(trie, key \"hello\", Text.equal, 42).0;\n /// trie := Trie.put(trie, key \"bye\", Text.equal, 32).0;\n /// trie := Trie.put(trie, key \"ciao\", Text.equal, 10).0;\n /// // `tabulate` takes a size parameter, so we check the size of\n /// // the trie first\n /// let size = Trie.size(trie);\n /// // Now we can create an array of the same size passing `nth` as\n /// // the generator used to fill the array.\n /// // Note that `toArray` is a convenience function that does the\n /// // same thing without you having to check whether the tuple is\n /// // `null` or not, which we're not doing in this example\n /// let array = Array.tabulate<?(Key<Text>, Nat)>(\n /// size,\n /// func n = Trie.nth(trie, n)\n /// );\n /// ```\n public func nth<K, V>(t : Trie<K, V>, i : Nat) : ?(Key<K>, V) {\n func rec(t : Trie<K, V>, i : Nat) : ?(Key<K>, V) = switch t {\n case (#empty) { P.unreachable() };\n case (#leaf l) { List.get(l.keyvals, i) };\n case (#branch b) {\n let size_left = size(b.left);\n if (i < size_left) { rec(b.left, i) } else {\n rec(b.right, i - size_left)\n }\n }\n };\n if (i >= size(t)) {\n return null\n };\n rec(t, i)\n };\n\n /// Gather the collection of key-value pairs into an array of a (possibly-distinct) type.\n /// \n /// \n /// Example:\n /// ```motoko include=initialize\n /// trie := Trie.put(trie, key \"hello\", Text.equal, 42).0;\n /// trie := Trie.put(trie, key \"bye\", Text.equal, 32).0;\n /// trie := Trie.put(trie, key \"ciao\", Text.equal, 10).0;\n /// // `toArray` takes a function that takes a key-value tuple\n /// // and returns a value of the type you want to use to fill\n /// // the array.\n /// // In our case we just return the value\n /// let array = Trie.toArray<Text, Nat, Nat>(\n /// trie,\n /// func (k, v) = v\n /// );\n /// ```\n public func toArray<K, V, W>(t : Trie<K, V>, f : (K, V) -> W) : [W] = A.tabulate<W>(\n size(t),\n func(i : Nat) : W {\n let (k, v) = switch (nth(t, i)) {\n case null { P.unreachable() };\n case (?x) { x }\n };\n f(k.key, v)\n }\n );\n\n /// Test for \"deep emptiness\": subtrees that have branching structure,\n /// but no leaves. These can result from naive filtering operations;\n /// filter uses this function to avoid creating such subtrees.\n public func isEmpty<K, V>(t : Trie<K, V>) : Bool = size(t) == 0;\n\n /// Filter the key-value pairs by a given predicate.\n /// \n /// \n /// Example:\n /// ```motoko include=initialize\n /// trie := Trie.put(trie, key \"hello\", Text.equal, 42).0;\n /// trie := Trie.put(trie, key \"bye\", Text.equal, 32).0;\n /// trie := Trie.put(trie, key \"ciao\", Text.equal, 10).0;\n /// // `filter` takes a function that takes a key-value tuple\n /// // and returns true if the key-value pair should be included.\n /// // In our case those are pairs with a value greater than 20\n /// let filteredTrie = Trie.filter<Text, Nat>(\n /// trie,\n /// func (k, v) = v > 20\n /// );\n /// assert (Trie.all<Text, Nat>(filteredTrie, func(k, v) = v > 20) == true);\n /// ```\n public func filter<K, V>(t : Trie<K, V>, f : (K, V) -> Bool) : Trie<K, V> {\n func rec(t : Trie<K, V>, bitpos : Nat) : Trie<K, V> = switch t {\n case (#empty) { #empty };\n case (#leaf l) {\n leaf(\n List.filter(\n l.keyvals,\n func((k : Key<K>, v : V)) : Bool = f(k.key, v)\n ),\n bitpos\n )\n };\n case (#branch b) {\n let fl = rec(b.left, bitpos + 1);\n let fr = rec(b.right, bitpos + 1);\n combineReducedNodes(fl, fr)\n }\n };\n rec(t, 0)\n };\n\n /// Map and filter the key-value pairs by a given predicate.\n /// \n /// \n /// Example:\n /// ```motoko include=initialize\n /// trie := Trie.put(trie, key \"hello\", Text.equal, 42).0;\n /// trie := Trie.put(trie, key \"bye\", Text.equal, 32).0;\n /// trie := Trie.put(trie, key \"ciao\", Text.equal, 10).0;\n /// // `mapFilter` takes a function that takes a key-value tuple\n /// // and returns a possibly-distinct value if the key-value pair should be included.\n /// // In our case, we filter for values greater than 20 and map them to their square.\n /// let filteredTrie = Trie.mapFilter<Text, Nat, Nat>(\n /// trie,\n /// func (k, v) = if (v > 20) return ?(v**2) else return null\n /// );\n /// assert (Trie.all<Text, Nat>(filteredTrie, func(k, v) = v > 60) == true);\n /// ```\n public func mapFilter<K, V, W>(t : Trie<K, V>, f : (K, V) -> ?W) : Trie<K, W> {\n func rec(t : Trie<K, V>, bitpos : Nat) : Trie<K, W> = switch t {\n case (#empty) { #empty };\n case (#leaf l) {\n leaf(\n List.mapFilter(\n l.keyvals,\n // retain key and hash, but update key's value using f:\n func((k : Key<K>, v : V)) : ?(Key<K>, W) = switch (f(k.key, v)) {\n case null { null };\n case (?w) { ?({ key = k.key; hash = k.hash }, w) }\n }\n ),\n bitpos\n )\n };\n case (#branch b) {\n let fl = rec(b.left, bitpos + 1);\n let fr = rec(b.right, bitpos + 1);\n combineReducedNodes(fl, fr)\n }\n };\n\n rec(t, 0)\n };\n\n /// Test for equality, but naively, based on structure.\n /// Does not attempt to remove \"junk\" in the tree;\n /// For instance, a \"smarter\" approach would equate\n /// `#bin {left = #empty; right = #empty}`\n /// with\n /// `#empty`.\n /// We do not observe that equality here.\n public func equalStructure<K, V>(\n tl : Trie<K, V>,\n tr : Trie<K, V>,\n keq : (K, K) -> Bool,\n veq : (V, V) -> Bool\n ) : Bool {\n func rec(tl : Trie<K, V>, tr : Trie<K, V>) : Bool = switch (tl, tr) {\n case (#empty, #empty) { true };\n case (#leaf l1, #leaf l2) {\n List.equal(\n l1.keyvals,\n l2.keyvals,\n func((k1 : Key<K>, v1 : V), (k2 : Key<K>, v2 : V)) : Bool = keq(k1.key, k2.key) and veq(v1, v2)\n )\n };\n case (#branch b1, #branch b2) {\n rec(b1.left, b2.left) and rec(b2.right, b2.right)\n };\n case _ { false }\n };\n rec(tl, tr)\n };\n\n /// Replace the given key's value in the trie,\n /// and only if successful, do the success continuation,\n /// otherwise, return the failure value\n /// \n /// \n /// Example:\n /// ```motoko include=initialize\n /// trie := Trie.put(trie, key \"hello\", Text.equal, 42).0;\n /// trie := Trie.put(trie, key \"bye\", Text.equal, 32).0;\n /// trie := Trie.put(trie, key \"ciao\", Text.equal, 10).0;\n /// // `replaceThen` takes the same arguments as `replace` but also a success continuation\n /// // and a failure connection that are called in the respective scenarios.\n /// // if the replace fails, that is the key is not present in the trie, the failure continuation is called.\n /// // if the replace succeeds, that is the key is present in the trie, the success continuation is called.\n /// // in this example we are simply returning the Text values `success` and `fail` respectively.\n /// var continuation = Trie.replaceThen<Text, Nat, Text>(\n /// trie,\n /// key \"hello\",\n /// Text.equal,\n /// 12,\n /// func (t, v) = \"success\",\n /// func () = \"fail\"\n /// );\n /// assert (continuation == \"success\");\n /// continuation := Trie.replaceThen<Text, Nat, Text>(\n /// trie,\n /// key \"shalom\",\n /// Text.equal,\n /// 12,\n /// func (t, v) = \"success\",\n /// func () = \"fail\"\n /// );\n /// assert (continuation == \"fail\");\n /// ```\n public func replaceThen<K, V, X>(\n t : Trie<K, V>,\n k : Key<K>,\n k_eq : (K, K) -> Bool,\n v2 : V,\n success : (Trie<K, V>, V) -> X,\n fail : () -> X\n ) : X {\n let (t2, ov) = replace(t, k, k_eq, ?v2);\n switch ov {\n case null { /* no prior value; failure to remove */ fail() };\n case (?v1) { success(t2, v1) }\n }\n };\n\n /// Put the given key's value in the trie; return the new trie; assert that no prior value is associated with the key.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// // note that compared to `put`, `putFresh` does not return a tuple\n /// trie := Trie.putFresh(trie, key \"hello\", Text.equal, 42);\n /// trie := Trie.putFresh(trie, key \"bye\", Text.equal, 32);\n /// // this will fail as \"hello\" is already present in the trie\n /// trie := Trie.putFresh(trie, key \"hello\", Text.equal, 10);\n /// ```\n public func putFresh<K, V>(t : Trie<K, V>, k : Key<K>, k_eq : (K, K) -> Bool, v : V) : Trie<K, V> {\n let (t2, none) = replace(t, k, k_eq, ?v);\n switch none {\n case null {};\n case (?_) assert false\n };\n t2\n };\n\n /// Put the given key's value in the 2D trie; return the new 2D trie.\n public func put2D<K1, K2, V>(\n t : Trie2D<K1, K2, V>,\n k1 : Key<K1>,\n k1_eq : (K1, K1) -> Bool,\n k2 : Key<K2>,\n k2_eq : (K2, K2) -> Bool,\n v : V\n ) : Trie2D<K1, K2, V> {\n let inner = find(t, k1, k1_eq);\n let (updated_inner, _) = switch inner {\n case null { put(#empty, k2, k2_eq, v) };\n case (?inner) { put(inner, k2, k2_eq, v) }\n };\n let (updated_outer, _) = put(t, k1, k1_eq, updated_inner);\n updated_outer\n };\n\n /// Put the given key's value in the trie; return the new trie;\n public func put3D<K1, K2, K3, V>(\n t : Trie3D<K1, K2, K3, V>,\n k1 : Key<K1>,\n k1_eq : (K1, K1) -> Bool,\n k2 : Key<K2>,\n k2_eq : (K2, K2) -> Bool,\n k3 : Key<K3>,\n k3_eq : (K3, K3) -> Bool,\n v : V\n ) : Trie3D<K1, K2, K3, V> {\n let inner1 = find(t, k1, k1_eq);\n let (updated_inner1, _) = switch inner1 {\n case null {\n put(\n #empty,\n k2,\n k2_eq,\n (put(#empty, k3, k3_eq, v)).0\n )\n };\n case (?inner1) {\n let inner2 = find(inner1, k2, k2_eq);\n let (updated_inner2, _) = switch inner2 {\n case null { put(#empty, k3, k3_eq, v) };\n case (?inner2) { put(inner2, k3, k3_eq, v) }\n };\n put(inner1, k2, k2_eq, updated_inner2)\n }\n };\n let (updated_outer, _) = put(t, k1, k1_eq, updated_inner1);\n updated_outer\n };\n\n /// Remove the entry for the given key from the trie, by returning the reduced trie.\n /// Also returns the removed value if the key existed and `null` otherwise.\n /// Compares keys using the provided function `k_eq`.\n /// \n /// :::note \n /// The removal of an existing key shrinks the trie.\n /// :::\n /// \n /// Example:\n /// ```motoko include=initialize\n /// trie := Trie.put(trie, key \"hello\", Text.equal, 42).0;\n /// trie := Trie.put(trie, key \"bye\", Text.equal, 32).0;\n /// // remove the entry associated with \"hello\"\n /// trie := Trie.remove(trie, key \"hello\", Text.equal).0;\n /// assert (Trie.get(trie, key \"hello\", Text.equal) == null);\n /// ```\n public func remove<K, V>(t : Trie<K, V>, k : Key<K>, k_eq : (K, K) -> Bool) : (Trie<K, V>, ?V) = replace(t, k, k_eq, null);\n\n /// Remove the given key's value in the trie,\n /// and only if successful, do the success continuation,\n /// otherwise, return the failure value.\n public func removeThen<K, V, X>(\n t : Trie<K, V>,\n k : Key<K>,\n k_eq : (K, K) -> Bool,\n success : (Trie<K, V>, V) -> X,\n fail : () -> X\n ) : X {\n let (t2, ov) = replace(t, k, k_eq, null);\n switch ov {\n case null { /* no prior value; failure to remove */ fail() };\n case (?v) { success(t2, v) }\n }\n };\n\n /// remove the given key-key pair's value in the 2D trie; return the\n /// new trie, and the prior value, if any.\n public func remove2D<K1, K2, V>(\n t : Trie2D<K1, K2, V>,\n k1 : Key<K1>,\n k1_eq : (K1, K1) -> Bool,\n k2 : Key<K2>,\n k2_eq : (K2, K2) -> Bool\n ) : (Trie2D<K1, K2, V>, ?V) = switch (find(t, k1, k1_eq)) {\n case null { (t, null) };\n case (?inner) {\n let (updated_inner, ov) = remove(inner, k2, k2_eq);\n let (updated_outer, _) = put(t, k1, k1_eq, updated_inner);\n (updated_outer, ov)\n }\n };\n\n /// Remove the given key-key pair's value in the 3D trie; return the\n /// new trie, and the prior value, if any.\n public func remove3D<K1, K2, K3, V>(\n t : Trie3D<K1, K2, K3, V>,\n k1 : Key<K1>,\n k1_eq : (K1, K1) -> Bool,\n k2 : Key<K2>,\n k2_eq : (K2, K2) -> Bool,\n k3 : Key<K3>,\n k3_eq : (K3, K3) -> Bool\n ) : (Trie3D<K1, K2, K3, V>, ?V) = switch (find(t, k1, k1_eq)) {\n case null { (t, null) };\n case (?inner) {\n let (updated_inner, ov) = remove2D(inner, k2, k2_eq, k3, k3_eq);\n let (updated_outer, _) = put(t, k1, k1_eq, updated_inner);\n (updated_outer, ov)\n }\n };\n\n /// Like [`mergeDisjoint`](#mergedisjoint), except instead of merging a\n /// pair, it merges the collection of dimension-2 sub-trees of a 2D\n /// trie.\n public func mergeDisjoint2D<K1, K2, V>(\n t : Trie2D<K1, K2, V>,\n _k1_eq : (K1, K1) -> Bool,\n k2_eq : (K2, K2) -> Bool\n ) : Trie<K2, V> = foldUp(\n t,\n func(t1 : Trie<K2, V>, t2 : Trie<K2, V>) : Trie<K2, V> = mergeDisjoint(t1, t2, k2_eq),\n func(_ : K1, t : Trie<K2, V>) : Trie<K2, V> = t,\n #empty\n );\n\n}\n"},"ExperimentalCycles.mo":{"content":"/// Managing cycles within actors on the Internet Computer (ICP).\n/// \n/// The usage of the Internet Computer is measured, and paid for, in _cycles_.\n/// This library provides imperative operations for observing cycles, transferring cycles, and observing refunds of cycles.\n/// \n/// :::warning Experimental API\n/// \n/// This low-level API is experimental and may change or be removed in the future.\n/// Dedicated syntactic support for manipulating cycles may be added to the language, which would make this library obsolete.\n/// :::\n/// \n/// :::note Volatile cycle balance\n/// \n/// Since cycles measure computational resources, the value of `balance()` can change from one call to the next.\n/// :::\n/// \n/// Example:\n/// \n/// ```motoko no-repl\n/// import Cycles \"mo:base/ExperimentalCycles\";\n/// import Debug \"mo:base/Debug\";\n/// \n/// actor {\n/// public func main() : async() {\n/// Debug.print(\"Main balance: \" # debug_show(Cycles.balance()));\n/// Cycles.add<system>(15_000_000);\n/// await operation(); // accepts 10_000_000 cycles\n/// Debug.print(\"Main refunded: \" # debug_show(Cycles.refunded())); // 5_000_000\n/// Debug.print(\"Main balance: \" # debug_show(Cycles.balance())); // decreased by around 10_000_000\n/// };\n/// \n/// func operation() : async() {\n/// Debug.print(\"Operation balance: \" # debug_show(Cycles.balance()));\n/// Debug.print(\"Operation available: \" # debug_show(Cycles.available()));\n/// let obtained = Cycles.accept<system>(10_000_000);\n/// Debug.print(\"Operation obtained: \" # debug_show(obtained)); // => 10_000_000\n/// Debug.print(\"Operation balance: \" # debug_show(Cycles.balance())); // increased by 10_000_000\n/// Debug.print(\"Operation available: \" # debug_show(Cycles.available())); // decreased by 10_000_000\n/// }\n/// }\n/// ```\nimport Prim \"mo:⛔\";\nmodule {\n\n /// Returns the actor's current balance of cycles as `amount`.\n /// \n /// Example:\n /// ```motoko no-repl\n /// import Cycles \"mo:base/ExperimentalCycles\";\n /// import Debug \"mo:base/Debug\";\n /// \n /// actor {\n /// public func main() : async() {\n /// let balance = Cycles.balance();\n /// Debug.print(\"Balance: \" # debug_show(balance));\n /// }\n /// }\n /// ```\n public let balance : () -> (amount : Nat) = Prim.cyclesBalance;\n\n /// Returns the currently available `amount` of cycles.\n /// The amount available is the amount received in the current call,\n /// minus the cumulative amount `accept`ed by this call.\n /// On exit from the current shared function or async expression via `return` or `throw`,\n /// any remaining available amount is automatically refunded to the caller/context.\n /// \n /// Example:\n /// ```motoko no-repl\n /// import Cycles \"mo:base/ExperimentalCycles\";\n /// import Debug \"mo:base/Debug\";\n /// \n /// actor {\n /// public func main() : async() {\n /// let available = Cycles.available();\n /// Debug.print(\"Available: \" # debug_show(available));\n /// }\n /// }\n /// ```\n public let available : () -> (amount : Nat) = Prim.cyclesAvailable;\n\n /// Transfers up to `amount` from `available()` to `balance()`.\n /// Returns the amount actually transferred, which may be less than\n /// requested, for example, if less is available, or if canister balance limits are reached.\n /// \n /// Example (for simplicity, only transferring cycles to itself):\n /// ```motoko no-repl\n /// import Cycles \"mo:base/ExperimentalCycles\";\n /// import Debug \"mo:base/Debug\";\n /// \n /// actor {\n /// public func main() : async() {\n /// Cycles.add<system>(15_000_000);\n /// await operation(); // accepts 10_000_000 cycles\n /// };\n /// \n /// func operation() : async() {\n /// let obtained = Cycles.accept<system>(10_000_000);\n /// Debug.print(\"Obtained: \" # debug_show(obtained)); // => 10_000_000\n /// }\n /// }\n /// ```\n public let accept : <system>(amount : Nat) -> (accepted : Nat) = Prim.cyclesAccept;\n\n /// Indicates additional `amount` of cycles to be transferred in\n /// the next call, that is, evaluation of a shared function call or\n /// async expression.\n /// Traps if the current total would exceed `2 ** 128` cycles.\n /// Upon the call, but not before, the total amount of cycles ``add``ed since\n /// the last call is deducted from `balance()`.\n /// If this total exceeds `balance()`, the caller traps, aborting the call.\n /// \n /// :::note Reset behavior\n /// \n /// The implicit register of added amounts is reset to zero on entry to a shared function and after each shared function call or resume from an await.\n /// :::\n /// \n /// Example (for simplicity, only transferring cycles to itself):\n /// ```motoko no-repl\n /// import Cycles \"mo:base/ExperimentalCycles\";\n /// \n /// actor {\n /// func operation() : async() {\n /// ignore Cycles.accept<system>(10_000_000);\n /// };\n /// \n /// public func main() : async() {\n /// Cycles.add<system>(15_000_000);\n /// await operation();\n /// }\n /// }\n /// ```\n /// @deprecated This function will be removed in future. Use the parenthetical syntax on message sends and `async` expressions to attach cycles: `(with cycles = <amount>) C.send(...)`.\n public let add : <system>(amount : Nat) -> () = Prim.cyclesAdd;\n\n /// Reports `amount` of cycles refunded in the last `await` of the current\n /// context, or zero if no await has occurred yet.\n /// Calling `refunded()` is solely informational and does not affect `balance()`.\n /// Instead, refunds are automatically added to the current balance,\n /// whether or not `refunded` is used to observe them.\n /// \n /// Example (for simplicity, only transferring cycles to itself):\n /// ```motoko no-repl\n /// import Cycles \"mo:base/ExperimentalCycles\";\n /// import Debug \"mo:base/Debug\";\n /// \n /// actor {\n /// func operation() : async() {\n /// ignore Cycles.accept<system>(10_000_000);\n /// };\n /// \n /// public func main() : async() {\n /// Cycles.add<system>(15_000_000);\n /// await operation(); // accepts 10_000_000 cycles\n /// Debug.print(\"Refunded: \" # debug_show(Cycles.refunded())); // 5_000_000\n /// }\n /// }\n /// ```\n public let refunded : () -> (amount : Nat) = Prim.cyclesRefunded;\n\n /// Attempts to burn `amount` of cycles, deducting `burned` from the canister's\n /// cycle balance. The burned cycles are irrevocably lost and not available to any\n /// other principal either.\n /// \n /// Example:\n /// ```motoko no-repl\n /// import Cycles \"mo:base/ExperimentalCycles\";\n /// import Debug \"mo:base/Debug\";\n /// \n /// actor {\n /// public func main() : async() {\n /// let burnt = Cycles.burn<system>(10_000_000);\n /// Debug.print(\"Burned: \" # debug_show burnt); // 10_000_000\n /// }\n /// }\n /// ```\n public let burn : <system>(amount : Nat) -> (burned : Nat) = Prim.cyclesBurn;\n\n}\n"},"Prelude.mo":{"content":"/// This prelude file proposes standard library features that _may_\n/// belong in the _language_ (compiler-internal) prelude sometime, after\n/// some further experience and discussion. Until then, they live here.\n\nimport Debug \"Debug\";\n\nmodule {\n\n /// :::warning\n /// Not yet implemented\n /// :::\n /// \n /// Mark incomplete code with the `nyi` and `xxx` functions.\n /// \n /// Each have calls that are well-typed in all typing contexts, which\n /// trap in all execution contexts.\n public func nyi() : None {\n Debug.trap(\"Prelude.nyi()\")\n };\n\n public func xxx() : None {\n Debug.trap(\"Prelude.xxx()\")\n };\n\n /// Mark unreachable code with the `unreachable` function.\n /// \n /// Calls are well-typed in all typing contexts, and they\n /// trap in all execution contexts.\n public func unreachable() : None {\n Debug.trap(\"Prelude.unreachable()\")\n };\n\n}\n"},"CertifiedData.mo":{"content":"/// The Internet Computer allows canister smart contracts to store a small amount of data during\n/// update method processing so that during query call processing, the canister can obtain\n/// a certificate about that data.\n/// \n/// :::info Intended audience\n/// \n/// This module provides a _low-level_ interface to this API, aimed at advanced\n/// users and library implementors. See the Internet Computer interface\n/// specification and corresponding documentation for how to use this to make query\n/// calls to your canister tamperproof.\n/// :::\n/// \n\nimport Prim \"mo:⛔\";\n\nmodule {\n\n /// Set the certified data.\n /// \n /// :::note Usage constraints\n ///\n /// Must be called from an update method, else traps.\n /// Must be passed a blob of at most 32 bytes, else traps.\n /// :::\n ///\n /// Example:\n ///\n /// ```motoko no-repl\n /// import CertifiedData \"mo:base/CertifiedData\";\n /// import Blob \"mo:base/Blob\";\n ///\n /// // Must be in an update call\n ///\n /// let array : [Nat8] = [1, 2, 3];\n /// let blob = Blob.fromArray(array);\n /// CertifiedData.set(blob);\n /// ```\n /// \n /// :::info\n /// [See a full example on how to use certified variables](https://github.com/dfinity/examples/tree/master/motoko/cert-var).\n /// :::\n /// \n public let set : (data : Blob) -> () = Prim.setCertifiedData;\n\n /// Gets a certificate.\n /// \n /// :::note When available\n ///\n /// Returns `null` if no certificate is available, e.g. when processing an\n /// update call or inter-canister call. This returns a non-`null` value only\n /// when processing a query call.\n /// :::\n ///\n /// Example:\n ///\n /// ```motoko no-repl\n /// import CertifiedData \"mo:base/CertifiedData\";\n /// // Must be in a query call\n ///\n /// CertifiedData.getCertificate();\n /// ```\n ///\n /// :::info\n /// [See a full example on how to use certified variables](https://github.com/dfinity/examples/tree/master/motoko/cert-var).\n /// :::\n public let getCertificate : () -> ?Blob = Prim.getCertificate\n}\n"},"None.mo":{"content":"/// The `None` type represents a type with _no_ value.\n/// \n/// It is often used to type code that fails to return control (e.g. an infinite loop)\n/// or to designate impossible values (e.g. the type `?None` only contains `null`).\n\nimport Prim \"mo:⛔\";\n\nmodule {\n\n /// The empty type. A subtype of all types.\n public type None = Prim.Types.None;\n\n /// Turns an absurd value into an arbitrary type.\n public let impossible : <A> None -> A = func<A>(x : None) : A {\n switch (x) {}\n }\n}\n"},"Region.mo":{"content":"/// Byte-level access to isolated, (virtual) stable memory _regions_.\n/// \n/// This is a moderately lightweight abstraction over IC _stable memory_ and supports persisting\n/// regions of binary data across Motoko upgrades.\n/// Use of this module is fully compatible with Motoko's use of\n/// _stable variables_, whose persistence mechanism also uses (real) IC stable memory internally, but does not interfere with this API.\n/// It is also fully compatible with existing uses of the `ExperimentalStableMemory` library, which has a similar interface, but,\n/// only supported a single memory region, without isolation between different applications.\n/// \n/// The `Region` type is stable and can be used in stable data structures.\n/// \n/// A new, empty `Region` is allocated using function `new()`.\n/// \n/// Regions are stateful objects and can be distinguished by the numeric identifier returned by function `id(region)`.\n/// Every region owns an initially empty, but growable sequence of virtual IC stable memory pages.\n/// The current size, in pages, of a region is returned by function `size(region)`.\n/// The size of a region determines the range, [ 0, ..., size(region)*2^16 ), of valid byte-offsets into the region; these offsets are used as the source and destination of `load`/`store` operations on the region.\n/// \n/// Memory is allocated to a region, using function `grow(region, pages)`, sequentially and on demand, in units of 64KiB logical pages, starting with 0 allocated pages.\n/// A call to `grow` may succeed, returning the previous size of the region, or fail, returning a sentinel value. New pages are zero initialized.\n/// \n/// A size of a region can only grow and never shrink.\n/// In addition, the stable memory pages allocated to a region will *not* be reclaimed by garbage collection, even\n/// if the region object itself becomes unreachable.\n/// \n/// Growth is capped by a soft limit on physical page count controlled by compile-time flag\n/// `--max-stable-pages <n>` (the default is 65536, or 4GiB).\n/// \n/// Each `load` operation loads from region relative byte address `offset` in little-endian\n/// format using the natural bit-width of the type in question.\n/// The operation traps if attempting to read beyond the current region size.\n/// \n/// Each `store` operation stores to region relative byte address `offset` in little-endian format using the natural bit-width of the type in question.\n/// The operation traps if attempting to write beyond the current region size.\n/// \n/// Text values can be handled by using `Text.decodeUtf8` and `Text.encodeUtf8`, in conjunction with `loadBlob` and `storeBlob`.\n/// \n/// The current region allocation and region contents are preserved across upgrades.\n/// \n/// NB: The IC's actual stable memory size (`ic0.stable_size`) may exceed the\n/// total page size reported by summing all regions sizes.\n/// This (and the cap on growth) are to accommodate Motoko's stable variables and bookkeeping for regions.\n/// Applications that plan to use Motoko stable variables sparingly or not at all can\n/// increase `--max-stable-pages` as desired, approaching the IC maximum (initially 8GiB, then 32Gib, currently 64Gib).\n/// All applications should reserve at least one page for stable variable data, even when no stable variables are used.\n/// \n/// Usage:\n/// ```motoko no-repl\n/// import Region \"mo:base/Region\";\n/// ```\n\nimport Prim \"mo:⛔\";\n\nmodule {\n\n /// A stateful handle to an isolated region of IC stable memory.\n /// `Region` is a stable type and regions can be stored in stable variables.\n public type Region = Prim.Types.Region;\n\n /// Allocate a new, isolated Region of size 0.\n /// \n /// Example:\n /// \n /// ```motoko no-repl\n /// let region = Region.new();\n /// assert Region.size(region) == 0;\n /// ```\n public let new : () -> Region = Prim.regionNew;\n\n /// Return a Nat identifying the given region.\n /// Maybe be used for equality, comparison and hashing.\n /// NB: Regions returned by `new()` are numbered from 16\n /// (regions 0..15 are currently reserved for internal use).\n /// Allocate a new, isolated Region of size 0.\n /// \n /// Example:\n /// \n /// ```motoko no-repl\n /// let region = Region.new();\n /// assert Region.id(region) == 16;\n /// ```\n public let id : Region -> Nat = Prim.regionId;\n\n /// Current size of `region`, in pages.\n /// Each page is 64KiB (65536 bytes).\n /// Initially `0`.\n /// Preserved across upgrades, together with contents of allocated\n /// stable memory.\n /// \n /// Example:\n /// ```motoko no-repl\n /// let region = Region.new();\n /// let beforeSize = Region.size(region);\n /// ignore Region.grow(region, 10);\n /// let afterSize = Region.size(region);\n /// afterSize - beforeSize // => 10\n /// ```\n public let size : (region : Region) -> (pages : Nat64) = Prim.regionSize;\n\n /// Grow current `size` of `region` by the given number of pages.\n /// Each page is 64KiB (65536 bytes).\n /// Returns the previous `size` when able to grow.\n /// Returns `0xFFFF_FFFF_FFFF_FFFF` if remaining pages insufficient.\n /// Every new page is zero-initialized, containing byte 0x00 at every offset.\n /// Function `grow` is capped by a soft limit on `size` controlled by compile-time flag\n /// `--max-stable-pages <n>` (the default is 65536, or 4GiB).\n /// \n /// Example:\n /// ```motoko no-repl\n /// import Error \"mo:base/Error\";\n /// \n /// let region = Region.new();\n /// let beforeSize = Region.grow(region, 10);\n /// if (beforeSize == 0xFFFF_FFFF_FFFF_FFFF) {\n /// throw Error.reject(\"Out of memory\");\n /// };\n /// let afterSize = Region.size(region);\n /// afterSize - beforeSize // => 10\n /// ```\n public let grow : (region : Region, newPages : Nat64) -> (oldPages : Nat64) = Prim.regionGrow;\n\n /// Within `region`, load a `Nat8` value from `offset`.\n /// Traps on an out-of-bounds access.\n /// \n /// Example:\n /// ```motoko no-repl\n /// let region = Region.new();\n /// let offset = 0;\n /// let value = 123;\n /// Region.storeNat8(region, offset, value);\n /// Region.loadNat8(region, offset) // => 123\n /// ```\n public let loadNat8 : (region : Region, offset : Nat64) -> Nat8 = Prim.regionLoadNat8;\n\n /// Within `region`, store a `Nat8` value at `offset`.\n /// Traps on an out-of-bounds access.\n /// \n /// Example:\n /// ```motoko no-repl\n /// let region = Region.new();\n /// let offset = 0;\n /// let value = 123;\n /// Region.storeNat8(region, offset, value);\n /// Region.loadNat8(region, offset) // => 123\n /// ```\n public let storeNat8 : (region : Region, offset : Nat64, value : Nat8) -> () = Prim.regionStoreNat8;\n\n /// Within `region`, load a `Nat16` value from `offset`.\n /// Traps on an out-of-bounds access.\n /// \n /// Example:\n /// ```motoko no-repl\n /// let region = Region.new();\n /// let offset = 0;\n /// let value = 123;\n /// Region.storeNat16(region, offset, value);\n /// Region.loadNat16(region, offset) // => 123\n /// ```\n public let loadNat16 : (region : Region, offset : Nat64) -> Nat16 = Prim.regionLoadNat16;\n\n /// Within `region`, store a `Nat16` value at `offset`.\n /// Traps on an out-of-bounds access.\n /// \n /// Example:\n /// ```motoko no-repl\n /// let region = Region.new();\n /// let offset = 0;\n /// let value = 123;\n /// Region.storeNat16(region, offset, value);\n /// Region.loadNat16(region, offset) // => 123\n /// ```\n public let storeNat16 : (region : Region, offset : Nat64, value : Nat16) -> () = Prim.regionStoreNat16;\n\n /// Within `region`, load a `Nat32` value from `offset`.\n /// Traps on an out-of-bounds access.\n /// \n /// Example:\n /// ```motoko no-repl\n /// let region = Region.new();\n /// let offset = 0;\n /// let value = 123;\n /// Region.storeNat32(region, offset, value);\n /// Region.loadNat32(region, offset) // => 123\n /// ```\n public let loadNat32 : (region : Region, offset : Nat64) -> Nat32 = Prim.regionLoadNat32;\n\n /// Within `region`, store a `Nat32` value at `offset`.\n /// Traps on an out-of-bounds access.\n /// \n /// Example:\n /// ```motoko no-repl\n /// let region = Region.new();\n /// let offset = 0;\n /// let value = 123;\n /// Region.storeNat32(region, offset, value);\n /// Region.loadNat32(region, offset) // => 123\n /// ```\n public let storeNat32 : (region : Region, offset : Nat64, value : Nat32) -> () = Prim.regionStoreNat32;\n\n /// Within `region`, load a `Nat64` value from `offset`.\n /// Traps on an out-of-bounds access.\n /// \n /// Example:\n /// ```motoko no-repl\n /// let region = Region.new();\n /// let offset = 0;\n /// let value = 123;\n /// Region.storeNat64(region, offset, value);\n /// Region.loadNat64(region, offset) // => 123\n /// ```\n public let loadNat64 : (region : Region, offset : Nat64) -> Nat64 = Prim.regionLoadNat64;\n\n /// Within `region`, store a `Nat64` value at `offset`.\n /// Traps on an out-of-bounds access.\n /// \n /// Example:\n /// ```motoko no-repl\n /// let region = Region.new();\n /// let offset = 0;\n /// let value = 123;\n /// Region.storeNat64(region, offset, value);\n /// Region.loadNat64(region, offset) // => 123\n /// ```\n public let storeNat64 : (region : Region, offset : Nat64, value : Nat64) -> () = Prim.regionStoreNat64;\n\n /// Within `region`, load a `Int8` value from `offset`.\n /// Traps on an out-of-bounds access.\n /// \n /// Example:\n /// ```motoko no-repl\n /// let region = Region.new();\n /// let offset = 0;\n /// let value = 123;\n /// Region.storeInt8(region, offset, value);\n /// Region.loadInt8(region, offset) // => 123\n /// ```\n public let loadInt8 : (region : Region, offset : Nat64) -> Int8 = Prim.regionLoadInt8;\n\n /// Within `region`, store a `Int8` value at `offset`.\n /// Traps on an out-of-bounds access.\n /// \n /// Example:\n /// ```motoko no-repl\n /// let region = Region.new();\n /// let offset = 0;\n /// let value = 123;\n /// Region.storeInt8(region, offset, value);\n /// Region.loadInt8(region, offset) // => 123\n /// ```\n public let storeInt8 : (region : Region, offset : Nat64, value : Int8) -> () = Prim.regionStoreInt8;\n\n /// Within `region`, load a `Int16` value from `offset`.\n /// Traps on an out-of-bounds access.\n /// \n /// Example:\n /// ```motoko no-repl\n /// let region = Region.new();\n /// let offset = 0;\n /// let value = 123;\n /// Region.storeInt16(region, offset, value);\n /// Region.loadInt16(region, offset) // => 123\n /// ```\n public let loadInt16 : (region : Region, offset : Nat64) -> Int16 = Prim.regionLoadInt16;\n\n /// Within `region`, store a `Int16` value at `offset`.\n /// Traps on an out-of-bounds access.\n /// \n /// Example:\n /// ```motoko no-repl\n /// let region = Region.new();\n /// let offset = 0;\n /// let value = 123;\n /// Region.storeInt16(region, offset, value);\n /// Region.loadInt16(region, offset) // => 123\n /// ```\n public let storeInt16 : (region : Region, offset : Nat64, value : Int16) -> () = Prim.regionStoreInt16;\n\n /// Within `region`, load a `Int32` value from `offset`.\n /// Traps on an out-of-bounds access.\n /// \n /// Example:\n /// ```motoko no-repl\n /// let region = Region.new();\n /// let offset = 0;\n /// let value = 123;\n /// Region.storeInt32(region, offset, value);\n /// Region.loadInt32(region, offset) // => 123\n /// ```\n public let loadInt32 : (region : Region, offset : Nat64) -> Int32 = Prim.regionLoadInt32;\n\n /// Within `region`, store a `Int32` value at `offset`.\n /// Traps on an out-of-bounds access.\n /// \n /// Example:\n /// ```motoko no-repl\n /// let region = Region.new();\n /// let offset = 0;\n /// let value = 123;\n /// Region.storeInt32(region, offset, value);\n /// Region.loadInt32(region, offset) // => 123\n /// ```\n public let storeInt32 : (region : Region, offset : Nat64, value : Int32) -> () = Prim.regionStoreInt32;\n\n /// Within `region`, load a `Int64` value from `offset`.\n /// Traps on an out-of-bounds access.\n /// \n /// Example:\n /// ```motoko no-repl\n /// let region = Region.new();\n /// let offset = 0;\n /// let value = 123;\n /// Region.storeInt64(region, offset, value);\n /// Region.loadInt64(region, offset) // => 123\n /// ```\n public let loadInt64 : (region : Region, offset : Nat64) -> Int64 = Prim.regionLoadInt64;\n\n /// Within `region`, store a `Int64` value at `offset`.\n /// Traps on an out-of-bounds access.\n /// \n /// Example:\n /// ```motoko no-repl\n /// let region = Region.new();\n /// let offset = 0;\n /// let value = 123;\n /// Region.storeInt64(region, offset, value);\n /// Region.loadInt64(region, offset) // => 123\n /// ```\n public let storeInt64 : (region : Region, offset : Nat64, value : Int64) -> () = Prim.regionStoreInt64;\n\n /// Within `region`, loads a `Float` value from the given `offset`.\n /// Traps on an out-of-bounds access.\n /// \n /// Example:\n /// ```motoko no-repl\n /// let region = Region.new();\n /// let offset = 0;\n /// let value = 1.25;\n /// Region.storeFloat(region, offset, value);\n /// Region.loadFloat(region, offset) // => 1.25\n /// ```\n public let loadFloat : (region : Region, offset : Nat64) -> Float = Prim.regionLoadFloat;\n\n /// Within `region`, store float `value` at the given `offset`.\n /// Traps on an out-of-bounds access.\n /// \n /// Example:\n /// ```motoko no-repl\n /// let region = Region.new();\n /// let offset = 0;\n /// let value = 1.25;\n /// Region.storeFloat(region, offset, value);\n /// Region.loadFloat(region, offset) // => 1.25\n /// ```\n public let storeFloat : (region : Region, offset : Nat64, value : Float) -> () = Prim.regionStoreFloat;\n\n /// Within `region,` load `size` bytes starting from `offset` as a `Blob`.\n /// Traps on an out-of-bounds access.\n /// \n /// Example:\n /// ```motoko no-repl\n /// import Blob \"mo:base/Blob\";\n /// \n /// let region = Region.new();\n /// let offset = 0;\n /// let value = Blob.fromArray([1, 2, 3]);\n /// let size = value.size();\n /// Region.storeBlob(region, offset, value);\n /// Blob.toArray(Region.loadBlob(region, offset, size)) // => [1, 2, 3]\n /// ```\n public let loadBlob : (region : Region, offset : Nat64, size : Nat) -> Blob = Prim.regionLoadBlob;\n\n /// Within `region, write `blob.size()` bytes of `blob` beginning at `offset`.\n /// Traps on an out-of-bounds access.\n /// \n /// Example:\n /// ```motoko no-repl\n /// import Blob \"mo:base/Blob\";\n /// \n /// let region = Region.new();\n /// let offset = 0;\n /// let value = Blob.fromArray([1, 2, 3]);\n /// let size = value.size();\n /// Region.storeBlob(region, offset, value);\n /// Blob.toArray(Region.loadBlob(region, offset, size)) // => [1, 2, 3]\n /// ```\n public let storeBlob : (region : Region, offset : Nat64, value : Blob) -> () = Prim.regionStoreBlob;\n\n}\n"},"Nat.mo":{"content":"/// Natural numbers with infinite precision.\n/// \n/// :::note\n/// Most operations on integer numbers (e.g. addition) are available as built-in operators (e.g. `1 + 1`).\n/// This module provides equivalent functions and `Text` conversion.\n/// :::\n/// \n/// :::info Function form for higher-order use\n/// \n/// Several arithmetic and comparison functions (e.g. `add`, `sub`, `equal`, `less`, `pow`) are defined in this module to enable their use as first-class function values, which is not possible with operators like `+`, `-`, `==`, etc., in Motoko. This allows you to pass these operations to higher-order functions such as `map`, `foldLeft`, or `sort`.\n/// :::\n/// \n/// Import from the base library to use this module.\n/// \n/// ```motoko name=import\n/// import Nat \"mo:base/Nat\";\n/// ```\n\nimport Int \"Int\";\nimport Order \"Order\";\nimport Prim \"mo:⛔\";\nimport Char \"Char\";\n\nmodule {\n\n /// Infinite precision natural numbers.\n public type Nat = Prim.Types.Nat;\n\n /// Converts a natural number to its textual representation. Textual\n /// representation _does not_ contain underscores to represent commas.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat.toText 1234 // => \"1234\"\n /// ```\n public func toText(n : Nat) : Text = Int.toText n;\n\n /// Creates a natural number from its textual representation. Returns `null`\n /// if the input is not a valid natural number.\n /// \n /// :::note\n /// The textual representation _must not_ contain underscores.\n /// :::\n /// Example:\n /// ```motoko include=import\n /// Nat.fromText \"1234\" // => ?1234\n /// ```\n public func fromText(text : Text) : ?Nat {\n if (text == \"\") {\n return null\n };\n var n = 0;\n for (c in text.chars()) {\n if (Char.isDigit(c)) {\n let charAsNat = Prim.nat32ToNat(Prim.charToNat32(c) -% Prim.charToNat32('0'));\n n := n * 10 + charAsNat\n } else {\n return null\n }\n };\n ?n\n };\n\n /// Returns the minimum of `x` and `y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat.min(1, 2) // => 1\n /// ```\n public func min(x : Nat, y : Nat) : Nat {\n if (x < y) { x } else { y }\n };\n\n /// Returns the maximum of `x` and `y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat.max(1, 2) // => 2\n /// ```\n public func max(x : Nat, y : Nat) : Nat {\n if (x < y) { y } else { x }\n };\n\n /// Equality function for Nat types.\n /// This is equivalent to `x == y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat.equal(1, 1); // => true\n /// 1 == 1 // => true\n /// ```\n /// \n\n /// \n /// Example:\n /// ```motoko include=import\n /// import Buffer \"mo:base/Buffer\";\n /// \n /// let buffer1 = Buffer.Buffer<Nat>(3);\n /// let buffer2 = Buffer.Buffer<Nat>(3);\n /// Buffer.equal(buffer1, buffer2, Nat.equal) // => true\n /// ```\n public func equal(x : Nat, y : Nat) : Bool { x == y };\n\n /// Inequality function for Nat types.\n /// This is equivalent to `x != y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat.notEqual(1, 2); // => true\n /// 1 != 2 // => true\n /// ```\n /// \n\n public func notEqual(x : Nat, y : Nat) : Bool { x != y };\n\n /// \"Less than\" function for Nat types.\n /// This is equivalent to `x < y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat.less(1, 2); // => true\n /// 1 < 2 // => true\n /// ```\n /// \n\n public func less(x : Nat, y : Nat) : Bool { x < y };\n\n /// \"Less than or equal\" function for Nat types.\n /// This is equivalent to `x <= y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat.lessOrEqual(1, 2); // => true\n /// 1 <= 2 // => true\n /// ```\n /// \n\n public func lessOrEqual(x : Nat, y : Nat) : Bool { x <= y };\n\n /// \"Greater than\" function for Nat types.\n /// This is equivalent to `x > y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat.greater(2, 1); // => true\n /// 2 > 1 // => true\n /// ```\n /// \n\n public func greater(x : Nat, y : Nat) : Bool { x > y };\n\n /// \"Greater than or equal\" function for Nat types.\n /// This is equivalent to `x >= y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat.greaterOrEqual(2, 1); // => true\n /// 2 >= 1 // => true\n /// ```\n /// \n\n public func greaterOrEqual(x : Nat, y : Nat) : Bool { x >= y };\n\n /// General purpose comparison function for `Nat`. Returns the `Order` (\n /// either `#less`, `#equal`, or `#greater`) of comparing `x` with `y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat.compare(2, 3) // => #less\n /// ```\n /// \n /// This function can be used as value for a high order function, such as a sort function.\n /// \n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.sort([2, 3, 1], Nat.compare) // => [1, 2, 3]\n /// ```\n public func compare(x : Nat, y : Nat) : { #less; #equal; #greater } {\n if (x < y) { #less } else if (x == y) { #equal } else { #greater }\n };\n\n /// Returns the sum of `x` and `y`, `x + y`. This operator will never overflow\n /// because `Nat` is infinite precision.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat.add(1, 2); // => 3\n /// 1 + 2 // => 3\n /// ```\n /// \n\n /// \n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.foldLeft([2, 3, 1], 0, Nat.add) // => 6\n /// ```\n public func add(x : Nat, y : Nat) : Nat { x + y };\n\n /// Returns the difference of `x` and `y`, `x - y`.\n /// Traps on underflow below `0`.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat.sub(2, 1); // => 1\n /// // Add a type annotation to avoid a warning about the subtraction\n /// 2 - 1 : Nat // => 1\n /// ```\n /// \n\n /// \n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.foldLeft([2, 3, 1], 10, Nat.sub) // => 4\n /// ```\n public func sub(x : Nat, y : Nat) : Nat { x - y };\n\n /// Returns the product of `x` and `y`, `x * y`. This operator will never\n /// overflow because `Nat` is infinite precision.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat.mul(2, 3); // => 6\n /// 2 * 3 // => 6\n /// ```\n /// \n\n /// \n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.foldLeft([2, 3, 1], 1, Nat.mul) // => 6\n /// ```\n public func mul(x : Nat, y : Nat) : Nat { x * y };\n\n /// Returns the unsigned integer division of `x` by `y`, `x / y`.\n /// Traps when `y` is zero.\n /// \n /// The quotient is rounded down, which is equivalent to truncating the\n /// decimal places of the quotient.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat.div(6, 2); // => 3\n /// 6 / 2 // => 3\n /// ```\n /// \n\n public func div(x : Nat, y : Nat) : Nat { x / y };\n\n /// Returns the remainder of unsigned integer division of `x` by `y`, `x % y`.\n /// Traps when `y` is zero.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat.rem(6, 4); // => 2\n /// 6 % 4 // => 2\n /// ```\n /// \n\n public func rem(x : Nat, y : Nat) : Nat { x % y };\n\n /// Returns `x` to the power of `y`, `x ** y`. Traps when `y > 2^32`. This operator\n /// will never overflow because `Nat` is infinite precision.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat.pow(2, 3); // => 8\n /// 2 ** 3 // => 8\n /// ```\n /// \n\n public func pow(x : Nat, y : Nat) : Nat { x ** y };\n\n /// Returns the (conceptual) bitwise shift left of `x` by `y`, `x * (2 ** y)`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat.bitshiftLeft(1, 3); // => 8\n /// ```\n /// \n\n public func bitshiftLeft(x : Nat, y : Nat32) : Nat { Prim.shiftLeft(x, y) };\n\n /// Returns the (conceptual) bitwise shift right of `x` by `y`, `x / (2 ** y)`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat.bitshiftRight(8, 3); // => 1\n /// ```\n /// \n\n public func bitshiftRight(x : Nat, y : Nat32) : Nat { Prim.shiftRight(x, y) };\n\n}\n"},"Int.mo":{"content":"/// Signed integer numbers with infinite precision (also called big integers).\n/// \n/// :::note\n/// Most operations on integer numbers (e.g. addition) are available as built-in operators (e.g. `-1 + 1`).\n/// This module provides equivalent functions and `Text` conversion.\n/// :::\n/// \n/// :::info Function form for higher-order use\n/// \n/// Several arithmetic and comparison functions (e.g. `add`, `sub`, `equal`, `less`, `pow`) are defined in this module to enable their use as first-class function values, which is not possible with operators like `+`, `-`, `==`, etc., in Motoko. This allows you to pass these operations to higher-order functions such as `map`, `foldLeft`, or `sort`.\n/// :::\n/// \n/// Import from the base library to use this module.\n/// \n/// ```motoko name=import\n/// import Int \"mo:base/Int\";\n/// ```\n/// \n\nimport Prim \"mo:⛔\";\nimport Prelude \"Prelude\";\nimport Hash \"Hash\";\n\nmodule {\n\n /// Infinite precision signed integers.\n public type Int = Prim.Types.Int;\n\n /// Returns the absolute value of `x`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int.abs(-12) // => 12\n /// ```\n public func abs(x : Int) : Nat {\n Prim.abs(x)\n };\n\n /// Converts an integer number to its textual representation. Textual\n /// representation _do not_ contain underscores to represent commas.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int.toText(-1234) // => \"-1234\"\n /// ```\n public func toText(x : Int) : Text {\n if (x == 0) {\n return \"0\"\n };\n\n let isNegative = x < 0;\n var int = if isNegative { -x } else { x };\n\n var text = \"\";\n let base = 10;\n\n while (int > 0) {\n let rem = int % base;\n text := (\n switch (rem) {\n case 0 { \"0\" };\n case 1 { \"1\" };\n case 2 { \"2\" };\n case 3 { \"3\" };\n case 4 { \"4\" };\n case 5 { \"5\" };\n case 6 { \"6\" };\n case 7 { \"7\" };\n case 8 { \"8\" };\n case 9 { \"9\" };\n case _ { Prelude.unreachable() }\n }\n ) # text;\n int := int / base\n };\n\n return if isNegative { \"-\" # text } else { text }\n };\n\n /// Returns the minimum of `x` and `y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int.min(2, -3) // => -3\n /// ```\n public func min(x : Int, y : Int) : Int {\n if (x < y) { x } else { y }\n };\n\n /// Returns the maximum of `x` and `y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int.max(2, -3) // => 2\n /// ```\n public func max(x : Int, y : Int) : Int {\n if (x < y) { y } else { x }\n };\n\n // this is a local copy of deprecated Hash.hashNat8 (redefined to suppress the warning)\n private func hashNat8(key : [Nat32]) : Hash.Hash {\n var hash : Nat32 = 0;\n for (natOfKey in key.vals()) {\n hash := hash +% natOfKey;\n hash := hash +% hash << 10;\n hash := hash ^ (hash >> 6)\n };\n hash := hash +% hash << 3;\n hash := hash ^ (hash >> 11);\n hash := hash +% hash << 15;\n return hash\n };\n\n /// :::warning Deprecated function\n /// \n /// The function `hash` is deprecated. It computes a hash using only the least significant 32 bits of the `Int`, ignoring the rest.\n /// For large integers, this may lead to hash collisions. Use a bespoke hash function that considers all bits of the value instead.\n /// :::\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 /// :::warning Deprecated function\n /// \n /// The function `hashAcc` is deprecated. It accumulates a hash using only the least significant 32 bits of the `Int`, ignoring other bits.\n /// This limits its effectiveness for large integers. Prefer using a custom hash function that processes the full integer input.\n /// :::\n public func hashAcc(h1 : Hash.Hash, i : Int) : Hash.Hash {\n // CAUTION: This removes the high bits!\n let j = Prim.int32ToNat32(Prim.intToInt32Wrap(i));\n hashNat8([\n h1,\n j & (255 << 0),\n j & (255 << 8),\n j & (255 << 16),\n j & (255 << 24)\n ])\n };\n\n /// Equality function for Int types.\n /// This is equivalent to `x == y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int.equal(-1, -1); // => true\n /// ```\n /// \n /// \n /// Example:\n /// ```motoko include=import\n /// import Buffer \"mo:base/Buffer\";\n /// \n /// let buffer1 = Buffer.Buffer<Int>(1);\n /// buffer1.add(-3);\n /// let buffer2 = Buffer.Buffer<Int>(1);\n /// buffer2.add(-3);\n /// Buffer.equal(buffer1, buffer2, Int.equal) // => true\n /// ```\n public func equal(x : Int, y : Int) : Bool { x == y };\n\n /// Inequality function for Int types.\n /// This is equivalent to `x != y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int.notEqual(-1, -2); // => true\n /// ```\n /// \n\n public func notEqual(x : Int, y : Int) : Bool { x != y };\n\n /// \"Less than\" function for Int types.\n /// This is equivalent to `x < y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int.less(-2, 1); // => true\n /// ```\n /// \n\n public func less(x : Int, y : Int) : Bool { x < y };\n\n /// \"Less than or equal\" function for Int types.\n /// This is equivalent to `x <= y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int.lessOrEqual(-2, 1); // => true\n /// ```\n /// \n\n public func lessOrEqual(x : Int, y : Int) : Bool { x <= y };\n\n /// \"Greater than\" function for Int types.\n /// This is equivalent to `x > y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int.greater(1, -2); // => true\n /// ```\n /// \n\n public func greater(x : Int, y : Int) : Bool { x > y };\n\n /// \"Greater than or equal\" function for Int types.\n /// This is equivalent to `x >= y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int.greaterOrEqual(1, -2); // => true\n /// ```\n /// \n\n public func greaterOrEqual(x : Int, y : Int) : Bool { x >= y };\n\n /// General-purpose comparison function for `Int`. Returns the `Order` (\n /// either `#less`, `#equal`, or `#greater`) of comparing `x` with `y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int.compare(-3, 2) // => #less\n /// ```\n /// \n /// This function can be used as value for a high order function, such as a sort function.\n /// \n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.sort([1, -2, -3], Int.compare) // => [-3, -2, 1]\n /// ```\n public func compare(x : Int, y : Int) : { #less; #equal; #greater } {\n if (x < y) { #less } else if (x == y) { #equal } else { #greater }\n };\n\n /// Returns the negation of `x`, `-x` .\n /// \n /// Example:\n /// ```motoko include=import\n /// Int.neg(123) // => -123\n /// ```\n /// \n\n public func neg(x : Int) : Int { -x };\n\n /// Returns the sum of `x` and `y`, `x + y`.\n /// \n /// No overflow since `Int` has infinite precision.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int.add(1, -2); // => -1\n /// ```\n /// \n\n /// \n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.foldLeft([1, -2, -3], 0, Int.add) // => -4\n /// ```\n public func add(x : Int, y : Int) : Int { x + y };\n\n /// Returns the difference of `x` and `y`, `x - y`.\n /// \n /// No overflow since `Int` has infinite precision.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int.sub(1, 2); // => -1\n /// ```\n /// \n\n /// \n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.foldLeft([1, -2, -3], 0, Int.sub) // => 4\n /// ```\n public func sub(x : Int, y : Int) : Int { x - y };\n\n /// Returns the product of `x` and `y`, `x * y`.\n /// \n /// No overflow since `Int` has infinite precision.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int.mul(-2, 3); // => -6\n /// ```\n /// \n\n /// \n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.foldLeft([1, -2, -3], 1, Int.mul) // => 6\n /// ```\n public func mul(x : Int, y : Int) : Int { x * y };\n\n /// Returns the signed integer division of `x` by `y`, `x / y`.\n /// Rounds the quotient towards zero, which is the same as truncating the decimal places of the quotient.\n /// \n /// Traps when `y` is zero.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int.div(6, -2); // => -3\n /// ```\n /// \n\n public func div(x : Int, y : Int) : Int { x / y };\n\n /// Returns the remainder of the signed integer division of `x` by `y`, `x % y`,\n /// which is defined as `x - x / y * y`.\n /// \n /// Traps when `y` is zero.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int.rem(6, -4); // => 2\n /// ```\n /// \n\n public func rem(x : Int, y : Int) : Int { x % y };\n\n /// Returns `x` to the power of `y`, `x ** y`.\n /// \n /// Traps when `y` is negative or `y > 2 ** 32 - 1`.\n /// No overflow since `Int` has infinite precision.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int.pow(-2, 3); // => -8\n /// ```\n /// \n public func pow(x : Int, y : Int) : Int { x ** y };\n\n}\n"},"Principal.mo":{"content":"/// Module for interacting with Principals (users, canisters, or other entities).\n/// \n/// Principals are used to identify entities that can interact with the Internet\n/// Computer including users or canisters.\n/// \n/// Example textual representation of Principals:\n/// \n/// `un4fu-tqaaa-aaaab-qadjq-cai`\n/// \n/// In Motoko, there is a primitive Principal type called `Principal`. As an example\n/// of where you might see Principals, you can access the Principal of the\n/// caller of your shared function.\n/// \n/// ```motoko no-repl\n/// shared(msg) func foo() {\n/// let caller : Principal = msg.caller;\n/// };\n/// ```\n/// \n/// Then, you can use this module to work with the `Principal`.\n/// \n/// :::note Comparison usage\n/// \n/// These functions are defined in this library in addition to the existing comparison operators so that they can be passed as function values to higher-order functions. It is currently not possible to use operators such as `==`, `!=`, `<`, `<=`, `>`, or `>=` as function values directly.\n/// :::\n/// \n/// Import from the base library to use this module.\n/// \n/// ```motoko name=import\n/// import Principal \"mo:base/Principal\";\n/// ```\n/// \n\nimport Prim \"mo:⛔\";\nimport Blob \"Blob\";\nimport Hash \"Hash\";\nimport Array \"Array\";\nimport Nat8 \"Nat8\";\nimport Nat32 \"Nat32\";\nimport Nat64 \"Nat64\";\nimport Text \"Text\";\n\nmodule {\n\n public type Principal = Prim.Types.Principal;\n\n /// Get the `Principal` identifier of an actor.\n /// \n /// Example:\n /// ```motoko include=import no-repl\n /// actor MyCanister {\n /// func getPrincipal() : Principal {\n /// let principal = Principal.fromActor(MyCanister);\n /// }\n /// }\n /// ```\n public func fromActor(a : actor {}) : Principal = Prim.principalOfActor a;\n\n /// Compute the Ledger account identifier of a principal. Optionally specify a sub-account.\n /// \n /// Example:\n /// ```motoko include=import\n /// let principal = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n /// let subAccount : Blob = \"\\4A\\8D\\3F\\2B\\6E\\01\\C8\\7D\\9E\\03\\B4\\56\\7C\\F8\\9A\\01\\D2\\34\\56\\78\\9A\\BC\\DE\\F0\\12\\34\\56\\78\\9A\\BC\\DE\\F0\";\n /// let account = Principal.toLedgerAccount(principal, ?subAccount); // => \\8C\\5C\\20\\C6\\15\\3F\\7F\\51\\E2\\0D\\0F\\0F\\B5\\08\\51\\5B\\47\\65\\63\\A9\\62\\B4\\A9\\91\\5F\\4F\\02\\70\\8A\\ED\\4F\\82\n /// ```\n public func toLedgerAccount(principal : Principal, subAccount : ?Blob) : Blob {\n let sha224 = SHA224();\n let accountSeparator : Blob = \"\\0Aaccount-id\";\n sha224.writeBlob(accountSeparator);\n sha224.writeBlob(toBlob(principal));\n switch subAccount {\n case (?subAccount) {\n sha224.writeBlob(subAccount)\n };\n case (null) {\n let defaultSubAccount = Array.tabulate<Nat8>(32, func _ = 0);\n sha224.writeArray(defaultSubAccount)\n }\n };\n\n let hashSum = sha224.sum();\n\n // hashBlob is a CRC32 implementation\n let crc32Bytes = nat32ToByteArray(Prim.hashBlob hashSum);\n\n Blob.fromArray(Array.append(crc32Bytes, Blob.toArray(hashSum)))\n };\n\n /// Convert a `Principal` to its `Blob` (bytes) representation.\n /// \n /// Example:\n /// ```motoko include=import\n /// let principal = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n /// let blob = Principal.toBlob(principal); // => \\00\\00\\00\\00\\00\\30\\00\\D3\\01\\01\n /// ```\n public func toBlob(p : Principal) : Blob = Prim.blobOfPrincipal p;\n\n /// Converts a `Blob` (bytes) representation of a `Principal` to a `Principal` value.\n /// \n /// Example:\n /// ```motoko include=import\n /// let blob = \"\\00\\00\\00\\00\\00\\30\\00\\D3\\01\\01\" : Blob;\n /// let principal = Principal.fromBlob(blob);\n /// Principal.toText(principal) // => \"un4fu-tqaaa-aaaab-qadjq-cai\"\n /// ```\n public func fromBlob(b : Blob) : Principal = Prim.principalOfBlob b;\n\n /// Converts a `Principal` to its `Text` representation.\n /// \n /// Example:\n /// ```motoko include=import\n /// let principal = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n /// Principal.toText(principal) // => \"un4fu-tqaaa-aaaab-qadjq-cai\"\n /// ```\n public func toText(p : Principal) : Text = debug_show (p);\n\n /// Converts a `Text` representation of a `Principal` to a `Principal` value.\n /// \n /// Example:\n /// ```motoko include=import\n /// let principal = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n /// Principal.toText(principal) // => \"un4fu-tqaaa-aaaab-qadjq-cai\"\n /// ```\n public func fromText(t : Text) : Principal = fromActor(actor (t));\n\n private let anonymousPrincipal : Blob = \"\\04\";\n\n /// Checks if the given principal represents an anonymous user.\n /// \n /// Example:\n /// ```motoko include=import\n /// let principal = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n /// Principal.isAnonymous(principal) // => false\n /// ```\n public func isAnonymous(p : Principal) : Bool = Prim.blobOfPrincipal p == anonymousPrincipal;\n\n /// Checks if the given principal can control this canister.\n /// \n /// Example:\n /// ```motoko include=import\n /// let principal = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n /// Principal.isController(principal) // => false\n /// ```\n public func isController(p : Principal) : Bool = Prim.isController p;\n\n /// Hashes the given principal by hashing its `Blob` representation.\n /// \n /// Example:\n /// ```motoko include=import\n /// let principal = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n /// Principal.hash(principal) // => 2_742_573_646\n /// ```\n public func hash(principal : Principal) : Hash.Hash = Blob.hash(Prim.blobOfPrincipal(principal));\n\n /// General purpose comparison function for `Principal`. Returns the `Order` (\n /// either `#less`, `#equal`, or `#greater`) of comparing `principal1` with\n /// `principal2`.\n /// \n /// Example:\n /// ```motoko include=import\n /// let principal1 = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n /// let principal2 = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n /// Principal.compare(principal1, principal2) // => #equal\n /// ```\n public func compare(principal1 : Principal, principal2 : Principal) : {\n #less;\n #equal;\n #greater\n } {\n if (principal1 < principal2) {\n #less\n } else if (principal1 == principal2) {\n #equal\n } else {\n #greater\n }\n };\n\n /// Equality function for Principal types.\n /// This is equivalent to `principal1 == principal2`.\n /// \n /// Example:\n /// ```motoko include=import\n /// let principal1 = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n /// let principal2 = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n /// ignore Principal.equal(principal1, principal2);\n /// principal1 == principal2 // => true\n /// ```\n /// \n\n /// \n /// Example:\n /// ```motoko include=import\n /// import Buffer \"mo:base/Buffer\";\n /// \n /// let buffer1 = Buffer.Buffer<Principal>(3);\n /// let buffer2 = Buffer.Buffer<Principal>(3);\n /// Buffer.equal(buffer1, buffer2, Principal.equal) // => true\n /// ```\n public func equal(principal1 : Principal, principal2 : Principal) : Bool {\n principal1 == principal2\n };\n\n /// Inequality function for Principal types.\n /// This is equivalent to `principal1 != principal2`.\n /// \n /// Example:\n /// ```motoko include=import\n /// let principal1 = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n /// let principal2 = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n /// ignore Principal.notEqual(principal1, principal2);\n /// principal1 != principal2 // => false\n /// ```\n /// \n\n public func notEqual(principal1 : Principal, principal2 : Principal) : Bool {\n principal1 != principal2\n };\n\n /// \"Less than\" function for Principal types.\n /// This is equivalent to `principal1 < principal2`.\n /// \n /// Example:\n /// ```motoko include=import\n /// let principal1 = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n /// let principal2 = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n /// ignore Principal.less(principal1, principal2);\n /// principal1 < principal2 // => false\n /// ```\n /// \n\n public func less(principal1 : Principal, principal2 : Principal) : Bool {\n principal1 < principal2\n };\n\n /// \"Less than or equal to\" function for Principal types.\n /// This is equivalent to `principal1 <= principal2`.\n /// \n /// Example:\n /// ```motoko include=import\n /// let principal1 = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n /// let principal2 = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n /// ignore Principal.lessOrEqual(principal1, principal2);\n /// principal1 <= principal2 // => true\n /// ```\n /// \n\n public func lessOrEqual(principal1 : Principal, principal2 : Principal) : Bool {\n principal1 <= principal2\n };\n\n /// \"Greater than\" function for Principal types.\n /// This is equivalent to `principal1 > principal2`.\n /// \n /// Example:\n /// ```motoko include=import\n /// let principal1 = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n /// let principal2 = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n /// ignore Principal.greater(principal1, principal2);\n /// principal1 > principal2 // => false\n /// ```\n /// \n\n public func greater(principal1 : Principal, principal2 : Principal) : Bool {\n principal1 > principal2\n };\n\n /// \"Greater than or equal to\" function for Principal types.\n /// This is equivalent to `principal1 >= principal2`.\n /// \n /// Example:\n /// ```motoko include=import\n /// let principal1 = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n /// let principal2 = Principal.fromText(\"un4fu-tqaaa-aaaab-qadjq-cai\");\n /// ignore Principal.greaterOrEqual(principal1, principal2);\n /// principal1 >= principal2 // => true\n /// ```\n /// \n\n public func greaterOrEqual(principal1 : Principal, principal2 : Principal) : Bool {\n principal1 >= principal2\n };\n\n /**\n * SHA224 Utilities used in toAccount().\n * Utilities are not exposed as public functions.\n * Taken with permission from https://github.com/research-ag/sha2\n **/\n let K00 : Nat32 = 0x428a2f98;\n let K01 : Nat32 = 0x71374491;\n let K02 : Nat32 = 0xb5c0fbcf;\n let K03 : Nat32 = 0xe9b5dba5;\n let K04 : Nat32 = 0x3956c25b;\n let K05 : Nat32 = 0x59f111f1;\n let K06 : Nat32 = 0x923f82a4;\n let K07 : Nat32 = 0xab1c5ed5;\n let K08 : Nat32 = 0xd807aa98;\n let K09 : Nat32 = 0x12835b01;\n let K10 : Nat32 = 0x243185be;\n let K11 : Nat32 = 0x550c7dc3;\n let K12 : Nat32 = 0x72be5d74;\n let K13 : Nat32 = 0x80deb1fe;\n let K14 : Nat32 = 0x9bdc06a7;\n let K15 : Nat32 = 0xc19bf174;\n let K16 : Nat32 = 0xe49b69c1;\n let K17 : Nat32 = 0xefbe4786;\n let K18 : Nat32 = 0x0fc19dc6;\n let K19 : Nat32 = 0x240ca1cc;\n let K20 : Nat32 = 0x2de92c6f;\n let K21 : Nat32 = 0x4a7484aa;\n let K22 : Nat32 = 0x5cb0a9dc;\n let K23 : Nat32 = 0x76f988da;\n let K24 : Nat32 = 0x983e5152;\n let K25 : Nat32 = 0xa831c66d;\n let K26 : Nat32 = 0xb00327c8;\n let K27 : Nat32 = 0xbf597fc7;\n let K28 : Nat32 = 0xc6e00bf3;\n let K29 : Nat32 = 0xd5a79147;\n let K30 : Nat32 = 0x06ca6351;\n let K31 : Nat32 = 0x14292967;\n let K32 : Nat32 = 0x27b70a85;\n let K33 : Nat32 = 0x2e1b2138;\n let K34 : Nat32 = 0x4d2c6dfc;\n let K35 : Nat32 = 0x53380d13;\n let K36 : Nat32 = 0x650a7354;\n let K37 : Nat32 = 0x766a0abb;\n let K38 : Nat32 = 0x81c2c92e;\n let K39 : Nat32 = 0x92722c85;\n let K40 : Nat32 = 0xa2bfe8a1;\n let K41 : Nat32 = 0xa81a664b;\n let K42 : Nat32 = 0xc24b8b70;\n let K43 : Nat32 = 0xc76c51a3;\n let K44 : Nat32 = 0xd192e819;\n let K45 : Nat32 = 0xd6990624;\n let K46 : Nat32 = 0xf40e3585;\n let K47 : Nat32 = 0x106aa070;\n let K48 : Nat32 = 0x19a4c116;\n let K49 : Nat32 = 0x1e376c08;\n let K50 : Nat32 = 0x2748774c;\n let K51 : Nat32 = 0x34b0bcb5;\n let K52 : Nat32 = 0x391c0cb3;\n let K53 : Nat32 = 0x4ed8aa4a;\n let K54 : Nat32 = 0x5b9cca4f;\n let K55 : Nat32 = 0x682e6ff3;\n let K56 : Nat32 = 0x748f82ee;\n let K57 : Nat32 = 0x78a5636f;\n let K58 : Nat32 = 0x84c87814;\n let K59 : Nat32 = 0x8cc70208;\n let K60 : Nat32 = 0x90befffa;\n let K61 : Nat32 = 0xa4506ceb;\n let K62 : Nat32 = 0xbef9a3f7;\n let K63 : Nat32 = 0xc67178f2;\n\n let ivs : [[Nat32]] = [\n [\n // 224\n 0xc1059ed8,\n 0x367cd507,\n 0x3070dd17,\n 0xf70e5939,\n 0xffc00b31,\n 0x68581511,\n 0x64f98fa7,\n 0xbefa4fa4\n ],\n [\n // 256\n 0x6a09e667,\n 0xbb67ae85,\n 0x3c6ef372,\n 0xa54ff53a,\n 0x510e527f,\n 0x9b05688c,\n 0x1f83d9ab,\n 0x5be0cd19\n ]\n ];\n\n let rot = Nat32.bitrotRight;\n\n class SHA224() {\n let (sum_bytes, iv) = (28, 0);\n\n var s0 : Nat32 = 0;\n var s1 : Nat32 = 0;\n var s2 : Nat32 = 0;\n var s3 : Nat32 = 0;\n var s4 : Nat32 = 0;\n var s5 : Nat32 = 0;\n var s6 : Nat32 = 0;\n var s7 : Nat32 = 0;\n\n let msg : [var Nat32] = Array.init<Nat32>(16, 0);\n let digest = Array.init<Nat8>(sum_bytes, 0);\n var word : Nat32 = 0;\n\n var i_msg : Nat8 = 0;\n var i_byte : Nat8 = 4;\n var i_block : Nat64 = 0;\n\n public func reset() {\n i_msg := 0;\n i_byte := 4;\n i_block := 0;\n s0 := ivs[iv][0];\n s1 := ivs[iv][1];\n s2 := ivs[iv][2];\n s3 := ivs[iv][3];\n s4 := ivs[iv][4];\n s5 := ivs[iv][5];\n s6 := ivs[iv][6];\n s7 := ivs[iv][7]\n };\n\n reset();\n\n private func writeByte(val : Nat8) : () {\n word := (word << 8) ^ Nat32.fromIntWrap(Nat8.toNat(val));\n i_byte -%= 1;\n if (i_byte == 0) {\n msg[Nat8.toNat(i_msg)] := word;\n word := 0;\n i_byte := 4;\n i_msg +%= 1;\n if (i_msg == 16) {\n process_block();\n i_msg := 0;\n i_block +%= 1\n }\n }\n };\n\n private func process_block() : () {\n let w00 = msg[0];\n let w01 = msg[1];\n let w02 = msg[2];\n let w03 = msg[3];\n let w04 = msg[4];\n let w05 = msg[5];\n let w06 = msg[6];\n let w07 = msg[7];\n let w08 = msg[8];\n let w09 = msg[9];\n let w10 = msg[10];\n let w11 = msg[11];\n let w12 = msg[12];\n let w13 = msg[13];\n let w14 = msg[14];\n let w15 = msg[15];\n let w16 = w00 +% rot(w01, 07) ^ rot(w01, 18) ^ (w01 >> 03) +% w09 +% rot(w14, 17) ^ rot(w14, 19) ^ (w14 >> 10);\n let w17 = w01 +% rot(w02, 07) ^ rot(w02, 18) ^ (w02 >> 03) +% w10 +% rot(w15, 17) ^ rot(w15, 19) ^ (w15 >> 10);\n let w18 = w02 +% rot(w03, 07) ^ rot(w03, 18) ^ (w03 >> 03) +% w11 +% rot(w16, 17) ^ rot(w16, 19) ^ (w16 >> 10);\n let w19 = w03 +% rot(w04, 07) ^ rot(w04, 18) ^ (w04 >> 03) +% w12 +% rot(w17, 17) ^ rot(w17, 19) ^ (w17 >> 10);\n let w20 = w04 +% rot(w05, 07) ^ rot(w05, 18) ^ (w05 >> 03) +% w13 +% rot(w18, 17) ^ rot(w18, 19) ^ (w18 >> 10);\n let w21 = w05 +% rot(w06, 07) ^ rot(w06, 18) ^ (w06 >> 03) +% w14 +% rot(w19, 17) ^ rot(w19, 19) ^ (w19 >> 10);\n let w22 = w06 +% rot(w07, 07) ^ rot(w07, 18) ^ (w07 >> 03) +% w15 +% rot(w20, 17) ^ rot(w20, 19) ^ (w20 >> 10);\n let w23 = w07 +% rot(w08, 07) ^ rot(w08, 18) ^ (w08 >> 03) +% w16 +% rot(w21, 17) ^ rot(w21, 19) ^ (w21 >> 10);\n let w24 = w08 +% rot(w09, 07) ^ rot(w09, 18) ^ (w09 >> 03) +% w17 +% rot(w22, 17) ^ rot(w22, 19) ^ (w22 >> 10);\n let w25 = w09 +% rot(w10, 07) ^ rot(w10, 18) ^ (w10 >> 03) +% w18 +% rot(w23, 17) ^ rot(w23, 19) ^ (w23 >> 10);\n let w26 = w10 +% rot(w11, 07) ^ rot(w11, 18) ^ (w11 >> 03) +% w19 +% rot(w24, 17) ^ rot(w24, 19) ^ (w24 >> 10);\n let w27 = w11 +% rot(w12, 07) ^ rot(w12, 18) ^ (w12 >> 03) +% w20 +% rot(w25, 17) ^ rot(w25, 19) ^ (w25 >> 10);\n let w28 = w12 +% rot(w13, 07) ^ rot(w13, 18) ^ (w13 >> 03) +% w21 +% rot(w26, 17) ^ rot(w26, 19) ^ (w26 >> 10);\n let w29 = w13 +% rot(w14, 07) ^ rot(w14, 18) ^ (w14 >> 03) +% w22 +% rot(w27, 17) ^ rot(w27, 19) ^ (w27 >> 10);\n let w30 = w14 +% rot(w15, 07) ^ rot(w15, 18) ^ (w15 >> 03) +% w23 +% rot(w28, 17) ^ rot(w28, 19) ^ (w28 >> 10);\n let w31 = w15 +% rot(w16, 07) ^ rot(w16, 18) ^ (w16 >> 03) +% w24 +% rot(w29, 17) ^ rot(w29, 19) ^ (w29 >> 10);\n let w32 = w16 +% rot(w17, 07) ^ rot(w17, 18) ^ (w17 >> 03) +% w25 +% rot(w30, 17) ^ rot(w30, 19) ^ (w30 >> 10);\n let w33 = w17 +% rot(w18, 07) ^ rot(w18, 18) ^ (w18 >> 03) +% w26 +% rot(w31, 17) ^ rot(w31, 19) ^ (w31 >> 10);\n let w34 = w18 +% rot(w19, 07) ^ rot(w19, 18) ^ (w19 >> 03) +% w27 +% rot(w32, 17) ^ rot(w32, 19) ^ (w32 >> 10);\n let w35 = w19 +% rot(w20, 07) ^ rot(w20, 18) ^ (w20 >> 03) +% w28 +% rot(w33, 17) ^ rot(w33, 19) ^ (w33 >> 10);\n let w36 = w20 +% rot(w21, 07) ^ rot(w21, 18) ^ (w21 >> 03) +% w29 +% rot(w34, 17) ^ rot(w34, 19) ^ (w34 >> 10);\n let w37 = w21 +% rot(w22, 07) ^ rot(w22, 18) ^ (w22 >> 03) +% w30 +% rot(w35, 17) ^ rot(w35, 19) ^ (w35 >> 10);\n let w38 = w22 +% rot(w23, 07) ^ rot(w23, 18) ^ (w23 >> 03) +% w31 +% rot(w36, 17) ^ rot(w36, 19) ^ (w36 >> 10);\n let w39 = w23 +% rot(w24, 07) ^ rot(w24, 18) ^ (w24 >> 03) +% w32 +% rot(w37, 17) ^ rot(w37, 19) ^ (w37 >> 10);\n let w40 = w24 +% rot(w25, 07) ^ rot(w25, 18) ^ (w25 >> 03) +% w33 +% rot(w38, 17) ^ rot(w38, 19) ^ (w38 >> 10);\n let w41 = w25 +% rot(w26, 07) ^ rot(w26, 18) ^ (w26 >> 03) +% w34 +% rot(w39, 17) ^ rot(w39, 19) ^ (w39 >> 10);\n let w42 = w26 +% rot(w27, 07) ^ rot(w27, 18) ^ (w27 >> 03) +% w35 +% rot(w40, 17) ^ rot(w40, 19) ^ (w40 >> 10);\n let w43 = w27 +% rot(w28, 07) ^ rot(w28, 18) ^ (w28 >> 03) +% w36 +% rot(w41, 17) ^ rot(w41, 19) ^ (w41 >> 10);\n let w44 = w28 +% rot(w29, 07) ^ rot(w29, 18) ^ (w29 >> 03) +% w37 +% rot(w42, 17) ^ rot(w42, 19) ^ (w42 >> 10);\n let w45 = w29 +% rot(w30, 07) ^ rot(w30, 18) ^ (w30 >> 03) +% w38 +% rot(w43, 17) ^ rot(w43, 19) ^ (w43 >> 10);\n let w46 = w30 +% rot(w31, 07) ^ rot(w31, 18) ^ (w31 >> 03) +% w39 +% rot(w44, 17) ^ rot(w44, 19) ^ (w44 >> 10);\n let w47 = w31 +% rot(w32, 07) ^ rot(w32, 18) ^ (w32 >> 03) +% w40 +% rot(w45, 17) ^ rot(w45, 19) ^ (w45 >> 10);\n let w48 = w32 +% rot(w33, 07) ^ rot(w33, 18) ^ (w33 >> 03) +% w41 +% rot(w46, 17) ^ rot(w46, 19) ^ (w46 >> 10);\n let w49 = w33 +% rot(w34, 07) ^ rot(w34, 18) ^ (w34 >> 03) +% w42 +% rot(w47, 17) ^ rot(w47, 19) ^ (w47 >> 10);\n let w50 = w34 +% rot(w35, 07) ^ rot(w35, 18) ^ (w35 >> 03) +% w43 +% rot(w48, 17) ^ rot(w48, 19) ^ (w48 >> 10);\n let w51 = w35 +% rot(w36, 07) ^ rot(w36, 18) ^ (w36 >> 03) +% w44 +% rot(w49, 17) ^ rot(w49, 19) ^ (w49 >> 10);\n let w52 = w36 +% rot(w37, 07) ^ rot(w37, 18) ^ (w37 >> 03) +% w45 +% rot(w50, 17) ^ rot(w50, 19) ^ (w50 >> 10);\n let w53 = w37 +% rot(w38, 07) ^ rot(w38, 18) ^ (w38 >> 03) +% w46 +% rot(w51, 17) ^ rot(w51, 19) ^ (w51 >> 10);\n let w54 = w38 +% rot(w39, 07) ^ rot(w39, 18) ^ (w39 >> 03) +% w47 +% rot(w52, 17) ^ rot(w52, 19) ^ (w52 >> 10);\n let w55 = w39 +% rot(w40, 07) ^ rot(w40, 18) ^ (w40 >> 03) +% w48 +% rot(w53, 17) ^ rot(w53, 19) ^ (w53 >> 10);\n let w56 = w40 +% rot(w41, 07) ^ rot(w41, 18) ^ (w41 >> 03) +% w49 +% rot(w54, 17) ^ rot(w54, 19) ^ (w54 >> 10);\n let w57 = w41 +% rot(w42, 07) ^ rot(w42, 18) ^ (w42 >> 03) +% w50 +% rot(w55, 17) ^ rot(w55, 19) ^ (w55 >> 10);\n let w58 = w42 +% rot(w43, 07) ^ rot(w43, 18) ^ (w43 >> 03) +% w51 +% rot(w56, 17) ^ rot(w56, 19) ^ (w56 >> 10);\n let w59 = w43 +% rot(w44, 07) ^ rot(w44, 18) ^ (w44 >> 03) +% w52 +% rot(w57, 17) ^ rot(w57, 19) ^ (w57 >> 10);\n let w60 = w44 +% rot(w45, 07) ^ rot(w45, 18) ^ (w45 >> 03) +% w53 +% rot(w58, 17) ^ rot(w58, 19) ^ (w58 >> 10);\n let w61 = w45 +% rot(w46, 07) ^ rot(w46, 18) ^ (w46 >> 03) +% w54 +% rot(w59, 17) ^ rot(w59, 19) ^ (w59 >> 10);\n let w62 = w46 +% rot(w47, 07) ^ rot(w47, 18) ^ (w47 >> 03) +% w55 +% rot(w60, 17) ^ rot(w60, 19) ^ (w60 >> 10);\n let w63 = w47 +% rot(w48, 07) ^ rot(w48, 18) ^ (w48 >> 03) +% w56 +% rot(w61, 17) ^ rot(w61, 19) ^ (w61 >> 10);\n\n /*\n for ((i, j, k, l, m) in expansion_rounds.vals()) {\n // (j,k,l,m) = (i+1,i+9,i+14,i+16)\n let (v0, v1) = (msg[j], msg[l]);\n let s0 = rot(v0, 07) ^ rot(v0, 18) ^ (v0 >> 03);\n let s1 = rot(v1, 17) ^ rot(v1, 19) ^ (v1 >> 10);\n msg[m] := msg[i] +% s0 +% msg[k] +% s1;\n };\n */\n // compress\n var a = s0;\n var b = s1;\n var c = s2;\n var d = s3;\n var e = s4;\n var f = s5;\n var g = s6;\n var h = s7;\n var t = 0 : Nat32;\n\n t := h +% K00 +% w00 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K01 +% w01 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K02 +% w02 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K03 +% w03 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K04 +% w04 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K05 +% w05 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K06 +% w06 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K07 +% w07 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K08 +% w08 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K09 +% w09 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K10 +% w10 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K11 +% w11 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K12 +% w12 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K13 +% w13 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K14 +% w14 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K15 +% w15 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K16 +% w16 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K17 +% w17 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K18 +% w18 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K19 +% w19 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K20 +% w20 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K21 +% w21 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K22 +% w22 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K23 +% w23 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K24 +% w24 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K25 +% w25 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K26 +% w26 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K27 +% w27 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K28 +% w28 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K29 +% w29 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K30 +% w30 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K31 +% w31 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K32 +% w32 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K33 +% w33 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K34 +% w34 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K35 +% w35 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K36 +% w36 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K37 +% w37 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K38 +% w38 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K39 +% w39 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K40 +% w40 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K41 +% w41 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K42 +% w42 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K43 +% w43 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K44 +% w44 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K45 +% w45 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K46 +% w46 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K47 +% w47 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K48 +% w48 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K49 +% w49 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K50 +% w50 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K51 +% w51 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K52 +% w52 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K53 +% w53 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K54 +% w54 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K55 +% w55 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K56 +% w56 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K57 +% w57 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K58 +% w58 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K59 +% w59 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K60 +% w60 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K61 +% w61 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K62 +% w62 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n t := h +% K63 +% w63 +% (e & f) ^ (^ e & g) +% rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% (b & c) ^ (b & d) ^ (c & d) +% rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n\n /*\n for (i in compression_rounds.keys()) {\n let ch = (e & f) ^ (^ e & g);\n let maj = (a & b) ^ (a & c) ^ (b & c);\n let sigma0 = rot(a, 02) ^ rot(a, 13) ^ rot(a, 22);\n let sigma1 = rot(e, 06) ^ rot(e, 11) ^ rot(e, 25);\n let t = h +% K[i] +% msg[i] +% ch +% sigma1;\n h := g;\n g := f;\n f := e;\n e := d +% t;\n d := c;\n c := b;\n b := a;\n a := t +% maj +% sigma0;\n };\n */\n // final addition\n s0 +%= a;\n s1 +%= b;\n s2 +%= c;\n s3 +%= d;\n s4 +%= e;\n s5 +%= f;\n s6 +%= g;\n s7 +%= h\n };\n\n public func writeIter(iter : { next() : ?Nat8 }) : () {\n label reading loop {\n switch (iter.next()) {\n case (?val) {\n writeByte(val);\n continue reading\n };\n case (null) {\n break reading\n }\n }\n }\n };\n\n public func writeArray(arr : [Nat8]) : () = writeIter(arr.vals());\n public func writeBlob(blob : Blob) : () = writeIter(blob.vals());\n\n public func sum() : Blob {\n // calculate padding\n // t = bytes in the last incomplete block (0-63)\n let t : Nat8 = (i_msg << 2) +% 4 -% i_byte;\n // p = length of padding (1-64)\n var p : Nat8 = if (t < 56) (56 -% t) else (120 -% t);\n // n_bits = length of message in bits\n let n_bits : Nat64 = ((i_block << 6) +% Nat64.fromIntWrap(Nat8.toNat(t))) << 3;\n\n // write padding\n writeByte(0x80);\n p -%= 1;\n while (p != 0) {\n writeByte(0x00);\n p -%= 1\n };\n\n // write length (8 bytes)\n // Note: this exactly fills the block buffer, hence process_block will get\n // triggered by the last writeByte\n writeByte(Nat8.fromIntWrap(Nat64.toNat((n_bits >> 56) & 0xff)));\n writeByte(Nat8.fromIntWrap(Nat64.toNat((n_bits >> 48) & 0xff)));\n writeByte(Nat8.fromIntWrap(Nat64.toNat((n_bits >> 40) & 0xff)));\n writeByte(Nat8.fromIntWrap(Nat64.toNat((n_bits >> 32) & 0xff)));\n writeByte(Nat8.fromIntWrap(Nat64.toNat((n_bits >> 24) & 0xff)));\n writeByte(Nat8.fromIntWrap(Nat64.toNat((n_bits >> 16) & 0xff)));\n writeByte(Nat8.fromIntWrap(Nat64.toNat((n_bits >> 8) & 0xff)));\n writeByte(Nat8.fromIntWrap(Nat64.toNat(n_bits & 0xff)));\n\n // retrieve sum\n digest[0] := Nat8.fromIntWrap(Nat32.toNat((s0 >> 24) & 0xff));\n digest[1] := Nat8.fromIntWrap(Nat32.toNat((s0 >> 16) & 0xff));\n digest[2] := Nat8.fromIntWrap(Nat32.toNat((s0 >> 8) & 0xff));\n digest[3] := Nat8.fromIntWrap(Nat32.toNat(s0 & 0xff));\n digest[4] := Nat8.fromIntWrap(Nat32.toNat((s1 >> 24) & 0xff));\n digest[5] := Nat8.fromIntWrap(Nat32.toNat((s1 >> 16) & 0xff));\n digest[6] := Nat8.fromIntWrap(Nat32.toNat((s1 >> 8) & 0xff));\n digest[7] := Nat8.fromIntWrap(Nat32.toNat(s1 & 0xff));\n digest[8] := Nat8.fromIntWrap(Nat32.toNat((s2 >> 24) & 0xff));\n digest[9] := Nat8.fromIntWrap(Nat32.toNat((s2 >> 16) & 0xff));\n digest[10] := Nat8.fromIntWrap(Nat32.toNat((s2 >> 8) & 0xff));\n digest[11] := Nat8.fromIntWrap(Nat32.toNat(s2 & 0xff));\n digest[12] := Nat8.fromIntWrap(Nat32.toNat((s3 >> 24) & 0xff));\n digest[13] := Nat8.fromIntWrap(Nat32.toNat((s3 >> 16) & 0xff));\n digest[14] := Nat8.fromIntWrap(Nat32.toNat((s3 >> 8) & 0xff));\n digest[15] := Nat8.fromIntWrap(Nat32.toNat(s3 & 0xff));\n digest[16] := Nat8.fromIntWrap(Nat32.toNat((s4 >> 24) & 0xff));\n digest[17] := Nat8.fromIntWrap(Nat32.toNat((s4 >> 16) & 0xff));\n digest[18] := Nat8.fromIntWrap(Nat32.toNat((s4 >> 8) & 0xff));\n digest[19] := Nat8.fromIntWrap(Nat32.toNat(s4 & 0xff));\n digest[20] := Nat8.fromIntWrap(Nat32.toNat((s5 >> 24) & 0xff));\n digest[21] := Nat8.fromIntWrap(Nat32.toNat((s5 >> 16) & 0xff));\n digest[22] := Nat8.fromIntWrap(Nat32.toNat((s5 >> 8) & 0xff));\n digest[23] := Nat8.fromIntWrap(Nat32.toNat(s5 & 0xff));\n digest[24] := Nat8.fromIntWrap(Nat32.toNat((s6 >> 24) & 0xff));\n digest[25] := Nat8.fromIntWrap(Nat32.toNat((s6 >> 16) & 0xff));\n digest[26] := Nat8.fromIntWrap(Nat32.toNat((s6 >> 8) & 0xff));\n digest[27] := Nat8.fromIntWrap(Nat32.toNat(s6 & 0xff));\n\n return Blob.fromArrayMut(digest)\n }\n }; // class SHA224\n\n func nat32ToByteArray(n : Nat32) : [Nat8] {\n func byte(n : Nat32) : Nat8 {\n Nat8.fromNat(Nat32.toNat(n & 0xff))\n };\n [byte(n >> 24), byte(n >> 16), byte(n >> 8), byte(n)]\n }\n}\n"},"Debug.mo":{"content":"/// Utility functions for debugging.\n/// \n/// Import from the base library to use this module.\n/// ```motoko name=import\n/// import Debug \"mo:base/Debug\";\n/// ```\n\nimport Prim \"mo:⛔\";\nmodule {\n /// Prints `text` to output stream.\n /// \n /// :::note\n /// When running on ICP, all output is written to the [canister log](https://internetcomputer.org/docs/current/developer-docs/smart-contracts/maintain/logs) with the exclusion of any output\n /// produced during the execution of non-replicated queries and composite queries.\n /// In other environments, like the interpreter and stand-alone Wasm engines, the output is written to standard out.\n /// :::\n /// \n /// ```motoko include=import\n /// Debug.print \"Hello New World!\";\n /// Debug.print(debug_show(4)) // Often used with `debug_show` to convert values to Text\n /// ```\n public func print(text : Text) {\n Prim.debugPrint text\n };\n\n /// `trap(t)` traps execution with a user-provided diagnostic message.\n /// \n /// The caller of a future whose execution called `trap(t)` will\n /// observe the trap as an `Error` value, thrown at `await`, with code\n /// `#canister_error` and message `m`. Here `m` is a more descriptive `Text`\n /// message derived from the provided `t`. See example for more details.\n /// \n /// :::note\n\n /// Other execution environments that cannot handle traps may only\n /// propagate the trap and terminate execution, with or without some\n /// descriptive message.\n /// :::\n /// \n /// ```motoko\n /// import Debug \"mo:base/Debug\";\n /// import Error \"mo:base/Error\";\n /// \n /// actor {\n /// func fail() : async () {\n /// Debug.trap(\"user provided error message\");\n /// };\n /// \n /// public func foo() : async () {\n /// try {\n /// await fail();\n /// } catch e {\n /// let code = Error.code(e); // evaluates to #canister_error\n /// let message = Error.message(e); // contains user provided error message\n /// }\n /// };\n /// }\n /// ```\n public func trap(errorMessage : Text) : None {\n Prim.trap errorMessage\n }\n}\n"},"Option.mo":{"content":"/// Optional values can be seen as a typesafe `null`. A value of type `?Int` can\n/// be constructed with either `null` or `?42`. The simplest way to get at the\n/// contents of an optional is to use pattern matching:\n/// \n/// ```motoko\n/// let optionalInt1 : ?Int = ?42;\n/// let optionalInt2 : ?Int = null;\n/// \n/// let int1orZero : Int = switch optionalInt1 {\n/// case null 0;\n/// case (?int) int;\n/// };\n/// assert int1orZero == 42;\n/// \n/// let int2orZero : Int = switch optionalInt2 {\n/// case null 0;\n/// case (?int) int;\n/// };\n/// assert int2orZero == 0;\n/// ```\n/// \n/// The functions in this module capture some common operations when working\n/// with optionals that can be more succinct than using pattern matching.\n\nimport P \"Prelude\";\n\nmodule {\n\n /// Unwraps an optional value, with a default value, i.e. `get(?x, d) = x` and\n /// `get(null, d) = d`.\n public func get<T>(x : ?T, default : T) : T = switch x {\n case null { default };\n case (?x_) { x_ }\n };\n\n /// Unwraps an optional value using a function, or returns the default, i.e.\n /// `option(?x, f, d) = f x` and `option(null, f, d) = d`.\n public func getMapped<A, B>(x : ?A, f : A -> B, default : B) : B = switch x {\n case null { default };\n case (?x_) { f(x_) }\n };\n\n /// Applies a function to the wrapped value. `null`'s are left untouched.\n /// ```motoko\n /// import Option \"mo:base/Option\";\n /// assert Option.map<Nat, Nat>(?42, func x = x + 1) == ?43;\n /// assert Option.map<Nat, Nat>(null, func x = x + 1) == null;\n /// ```\n public func map<A, B>(x : ?A, f : A -> B) : ?B = switch x {\n case null { null };\n case (?x_) { ?f(x_) }\n };\n\n /// Applies a function to the wrapped value, but discards the result. Use\n /// `iterate` if you're only interested in the side effect `f` produces.\n /// \n /// ```motoko\n /// import Option \"mo:base/Option\";\n /// var counter : Nat = 0;\n /// Option.iterate(?5, func (x : Nat) { counter += x });\n /// assert counter == 5;\n /// Option.iterate(null, func (x : Nat) { counter += x });\n /// assert counter == 5;\n /// ```\n public func iterate<A>(x : ?A, f : A -> ()) = switch x {\n case null {};\n case (?x_) { f(x_) }\n };\n\n /// Applies an optional function to an optional value. Returns `null` if at\n /// least one of the arguments is `null`.\n public func apply<A, B>(x : ?A, f : ?(A -> B)) : ?B {\n switch (f, x) {\n case (?f_, ?x_) {\n ?f_(x_)\n };\n case (_, _) {\n null\n }\n }\n };\n\n /// Applies a function to an optional value. Returns `null` if the argument is\n /// `null`, or the function returns `null`.\n public func chain<A, B>(x : ?A, f : A -> ?B) : ?B {\n switch (x) {\n case (?x_) {\n f(x_)\n };\n case (null) {\n null\n }\n }\n };\n\n /// Given an optional optional value, removes one layer of optionality.\n /// ```motoko\n /// import Option \"mo:base/Option\";\n /// assert Option.flatten(?(?(42))) == ?42;\n /// assert Option.flatten(?(null)) == null;\n /// assert Option.flatten(null) == null;\n /// ```\n public func flatten<A>(x : ??A) : ?A {\n chain<?A, A>(\n x,\n func(x_ : ?A) : ?A {\n x_\n }\n )\n };\n\n /// Creates an optional value from a definite value.\n /// ```motoko\n /// import Option \"mo:base/Option\";\n /// assert Option.make(42) == ?42;\n /// ```\n public func make<A>(x : A) : ?A = ?x;\n\n /// Returns true if the argument is not `null`, otherwise returns false.\n public func isSome(x : ?Any) : Bool = switch x {\n case null { false };\n case _ { true }\n };\n\n /// Returns true if the argument is `null`, otherwise returns false.\n public func isNull(x : ?Any) : Bool = switch x {\n case null { true };\n case _ { false }\n };\n\n /// Returns true if the optional arguments are equal according to the equality function provided, otherwise returns false.\n public func equal<A>(x : ?A, y : ?A, eq : (A, A) -> Bool) : Bool = switch (x, y) {\n case (null, null) { true };\n case (?x_, ?y_) { eq(x_, y_) };\n case (_, _) { false }\n };\n\n /// :::warning Deprecated function\n ///\n /// `Option.assertSome` will be removed soon. Use an `assert` expression instead.\n ///\n /// :::\n public func assertSome(x : ?Any) = switch x {\n case null { P.unreachable() };\n case _ {}\n };\n\n /// :::warning Deprecated function\n /// \n /// `Option.assertNull` will be removed soon. Use an `assert` expression instead.\n /// :::\n public func assertNull(x : ?Any) = switch x {\n case null {};\n case _ { P.unreachable() }\n };\n\n /// :::warning Deprecated function\n /// \n /// `Option.unwrap` is unsafe and will be removed soon. Use a `switch` or `do?` expression instead.\n /// :::\n public func unwrap<T>(x : ?T) : T = switch x {\n case null { P.unreachable() };\n case (?x_) { x_ }\n }\n}\n"},"Heap.mo":{"content":"/// Class `Heap<X>` provides a priority queue of elements of type `X`.\n/// \n/// The class wraps a purely-functional implementation based on a leftist heap.\n/// \n/// :::note Constructor details\n/// The constructor takes in a comparison function `compare` that defines the ordering between elements of type `X`. Most primitive types have a default version of this comparison function defined in their modules (e.g. `Nat.compare`). The runtime analysis in this documentation assumes that the `compare` function runs in `O(1)` time and space.\n/// :::\n/// \n/// Example:\n/// \n/// ```motoko name=initialize\n/// import Heap \"mo:base/Heap\";\n/// import Text \"mo:base/Text\";\n/// \n/// let heap = Heap.Heap<Text>(Text.compare);\n/// ```\n/// \n/// | Runtime | Space |\n/// |-----------|-----------|\n/// | `O(1)` | `O(1)` |\n\nimport O \"Order\";\nimport P \"Prelude\";\nimport L \"List\";\nimport I \"Iter\";\n\nmodule {\n\n public type Tree<X> = ?(Int, X, Tree<X>, Tree<X>);\n\n public class Heap<X>(compare : (X, X) -> O.Order) {\n var heap : Tree<X> = null;\n\n /// Inserts an element into the heap.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// heap.put(\"apple\");\n /// heap.peekMin() // => ?\"apple\"\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(1)` | `O(1)` |\n public func put(x : X) {\n heap := merge(heap, ?(1, x, null, null), compare)\n };\n\n /// Return the minimal element in the heap, or `null` if the heap is empty.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// heap.put(\"apple\");\n /// heap.put(\"banana\");\n /// heap.put(\"cantaloupe\");\n /// heap.peekMin() // => ?\"apple\"\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(1)` | `O(1)` |\n public func peekMin() : ?X {\n switch heap {\n case (null) { null };\n case (?(_, x, _, _)) { ?x }\n }\n };\n\n /// Delete the minimal element in the heap, if it exists.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// heap.put(\"apple\");\n /// heap.put(\"banana\");\n /// heap.put(\"cantaloupe\");\n /// heap.deleteMin();\n /// heap.peekMin(); // => ?\"banana\"\n /// ```\n /// \n /// | Runtime | Space |\n /// |--------------|-------------|\n /// | `O(log(n))` | `O(log(n))` |\n public func deleteMin() {\n switch heap {\n case null {};\n case (?(_, _, a, b)) { heap := merge(a, b, compare) }\n }\n };\n\n /// Delete and return the minimal element in the heap, if it exists.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// heap.put(\"apple\");\n /// heap.put(\"banana\");\n /// heap.put(\"cantaloupe\");\n /// heap.removeMin(); // => ?\"apple\"\n /// ```\n /// \n /// | Runtime | Space |\n /// |--------------|-------------|\n /// | `O(log(n))` | `O(log(n))` |\n public func removeMin() : (minElement : ?X) {\n switch heap {\n case null { null };\n case (?(_, x, a, b)) {\n heap := merge(a, b, compare);\n ?x\n }\n }\n };\n\n /// Return a snapshot of the internal functional tree representation as sharable data.\n /// The returned tree representation is not affected by subsequent changes of the `Heap` instance.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// heap.put(\"banana\");\n /// heap.share();\n /// ```\n /// \n /// Useful for storing the heap as a stable variable, pretty-printing, and sharing it across async function calls,\n /// i.e. passing it in async arguments or async results.\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(1)` | `O(1)` |\n public func share() : Tree<X> {\n heap\n };\n\n /// Rewraps a snapshot of a heap (obtained by `share()`) in a `Heap` instance.\n /// The wrapping instance must be initialized with the same `compare`\n /// function that created the snapshot.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// heap.put(\"apple\");\n /// heap.put(\"banana\");\n /// let snapshot = heap.share();\n /// let heapCopy = Heap.Heap<Text>(Text.compare);\n /// heapCopy.unsafeUnshare(snapshot);\n /// heapCopy.peekMin() // => ?\"apple\"\n /// ```\n /// \n /// Useful for loading a stored heap from a stable variable or accesing a heap\n /// snapshot passed from an async function call.\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(1)` | `O(1)` |\n public func unsafeUnshare(tree : Tree<X>) {\n heap := tree\n };\n\n };\n\n func rank<X>(heap : Tree<X>) : Int {\n switch heap {\n case null { 0 };\n case (?(r, _, _, _)) { r }\n }\n };\n\n func makeT<X>(x : X, a : Tree<X>, b : Tree<X>) : Tree<X> {\n if (rank(a) >= rank(b)) {\n ?(rank(b) + 1, x, a, b)\n } else {\n ?(rank(a) + 1, x, b, a)\n }\n };\n\n func merge<X>(h1 : Tree<X>, h2 : Tree<X>, compare : (X, X) -> O.Order) : Tree<X> {\n switch (h1, h2) {\n case (null, h) { h };\n case (h, null) { h };\n case (?(_, x, a, b), ?(_, y, c, d)) {\n switch (compare(x, y)) {\n case (#less) { makeT(x, a, merge(b, h2, compare)) };\n case _ { makeT(y, c, merge(d, h1, compare)) }\n }\n }\n }\n };\n\n /// Returns a new `Heap`, containing all entries given by the iterator `iter`.\n /// The new map is initialized with the provided `compare` function.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// let entries = [\"banana\", \"apple\", \"cantaloupe\"];\n /// let iter = entries.vals();\n /// \n /// let newHeap = Heap.fromIter<Text>(iter, Text.compare);\n /// newHeap.peekMin() // => ?\"apple\"\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size)` | `O(size)` |\n public func fromIter<X>(iter : I.Iter<X>, compare : (X, X) -> O.Order) : Heap<X> {\n let heap = Heap<X>(compare);\n func build(xs : L.List<Tree<X>>) : Tree<X> {\n func join(xs : L.List<Tree<X>>) : L.List<Tree<X>> {\n switch (xs) {\n case (null) { null };\n case (?(hd, null)) { ?(hd, null) };\n case (?(h1, ?(h2, tl))) { ?(merge(h1, h2, compare), join(tl)) }\n }\n };\n switch (xs) {\n case null { P.unreachable() };\n case (?(hd, null)) { hd };\n case _ { build(join(xs)) }\n }\n };\n let list = I.toList(I.map(iter, func(x : X) : Tree<X> { ?(1, x, null, null) }));\n if (not L.isNil(list)) {\n let t = build(list);\n heap.unsafeUnshare(t)\n };\n heap\n };\n\n}\n"},"IterType.mo":{"content":"\n// Just here to break cyclic module definitions\n\nmodule {\n public type Iter<T> = { next : () -> ?T }\n}\n"},"Blob.mo":{"content":"/// `Blob` is an immutable, iterable sequence of bytes. Unlike `[Nat8]`, which is less compact (using 4 bytes per logical byte), `Blob` provides a more efficient representation.\n/// \n/// Blobs are not indexable and can be empty. To manipulate a `Blob`, convert it to `[var Nat8]` or `Buffer<Nat8>`, perform your changes, then convert it back.\n/// \n/// Import from the base library to use this module.\n/// \n/// ```motoko name=import\n/// import Blob \"mo:base/Blob\";\n/// ```\n/// \n/// :::note Additional features\n/// \n/// Some built-in features are not listed in this module:\n/// \n/// - You can create a `Blob` literal from a `Text` literal, provided the context expects an expression of type `Blob`.\n/// - `b.size() : Nat` returns the number of bytes in the blob `b`.\n/// - `b.vals() : Iter.Iter<Nat8>` returns an iterator to enumerate the bytes of the blob `b`.\n/// :::\n/// \n/// For example:\n/// \n/// ```motoko include=import\n/// import Debug \"mo:base/Debug\";\n/// import Nat8 \"mo:base/Nat8\";\n/// \n/// let blob = \"\\00\\00\\00\\ff\" : Blob; // blob literals, where each byte is delimited by a back-slash and represented in hex\n/// let blob2 = \"charsもあり\" : Blob; // you can also use characters in the literals\n/// let numBytes = blob.size(); // => 4 (returns the number of bytes in the Blob)\n/// for (byte : Nat8 in blob.vals()) { // iterator over the Blob\n/// Debug.print(Nat8.toText(byte))\n/// }\n/// ```\n/// :::note Operator limitation\n/// \n/// Comparison functions (`equal`, `notEqual`, `less`, `lessOrEqual`, `greater`, `greaterOrEqual`) are defined in this library to allow their use as function values in higher-order functions.\n/// Operators like `==`, `!=`, `<`, `<=`, `>`, and `>=` cannot currently be passed as function values.\n/// :::\nimport Prim \"mo:⛔\";\nmodule {\n public type Blob = Prim.Types.Blob;\n /// Creates a `Blob` from an array of bytes (`[Nat8]`) by copying each element.\n /// \n /// Example:\n /// ```motoko include=import\n /// let bytes : [Nat8] = [0, 255, 0];\n /// let blob = Blob.fromArray(bytes); // => \"\\00\\FF\\00\"\n /// ```\n public func fromArray(bytes : [Nat8]) : Blob = Prim.arrayToBlob bytes;\n\n /// Creates a `Blob` from a mutable array of bytes (`[var Nat8]`) by copying each element.\n /// \n /// Example:\n /// ```motoko include=import\n /// let bytes : [var Nat8] = [var 0, 255, 0];\n /// let blob = Blob.fromArrayMut(bytes); // => \"\\00\\FF\\00\"\n /// ```\n public func fromArrayMut(bytes : [var Nat8]) : Blob = Prim.arrayMutToBlob bytes;\n\n /// Converts a `Blob` to an array of bytes (`[Nat8]`) by copying each element.\n /// \n /// Example:\n /// ```motoko include=import\n /// let blob = \"\\00\\FF\\00\" : Blob;\n /// let bytes = Blob.toArray(blob); // => [0, 255, 0]\n /// ```\n public func toArray(blob : Blob) : [Nat8] = Prim.blobToArray blob;\n\n /// Converts a `Blob` to a mutable array of bytes (`[var Nat8]`) by copying each element.\n /// \n /// Example:\n /// ```motoko include=import\n /// let blob = \"\\00\\FF\\00\" : Blob;\n /// let bytes = Blob.toArrayMut(blob); // => [var 0, 255, 0]\n /// ```\n public func toArrayMut(blob : Blob) : [var Nat8] = Prim.blobToArrayMut blob;\n\n /// Returns the (non-cryptographic) hash of `blob`.\n /// \n /// Example:\n /// ```motoko include=import\n /// let blob = \"\\00\\FF\\00\" : Blob;\n /// Blob.hash(blob) // => 1_818_567_776\n /// ```\n public func hash(blob : Blob) : Nat32 = Prim.hashBlob blob;\n\n /// General purpose comparison function for `Blob` by comparing the value of\n /// the bytes. Returns the `Order` (either `#less`, `#equal`, or `#greater`)\n /// by comparing `blob1` with `blob2`.\n /// \n /// Example:\n /// ```motoko include=import\n /// let blob1 = \"\\00\\00\\00\" : Blob;\n /// let blob2 = \"\\00\\FF\\00\" : Blob;\n /// Blob.compare(blob1, blob2) // => #less\n /// ```\n public func compare(b1 : Blob, b2 : Blob) : { #less; #equal; #greater } {\n let c = Prim.blobCompare(b1, b2);\n if (c < 0) #less else if (c == 0) #equal else #greater\n };\n\n /// Equality function for `Blob` types.\n /// This is equivalent to `blob1 == blob2`.\n /// \n /// Example:\n /// ```motoko include=import\n /// let blob1 = \"\\00\\FF\\00\" : Blob;\n /// let blob2 = \"\\00\\FF\\00\" : Blob;\n /// ignore Blob.equal(blob1, blob2);\n /// blob1 == blob2 // => true\n /// ```\n /// \n public func equal(blob1 : Blob, blob2 : Blob) : Bool { blob1 == blob2 };\n\n /// Inequality function for `Blob` types.\n /// This is equivalent to `blob1 != blob2`.\n /// \n /// Example:\n /// ```motoko include=import\n /// let blob1 = \"\\00\\AA\\AA\" : Blob;\n /// let blob2 = \"\\00\\FF\\00\" : Blob;\n /// ignore Blob.notEqual(blob1, blob2);\n /// blob1 != blob2 // => true\n /// ```\n\n public func notEqual(blob1 : Blob, blob2 : Blob) : Bool { blob1 != blob2 };\n\n /// \"Less than\" function for `Blob` types.\n /// This is equivalent to `blob1 < blob2`.\n /// \n /// Example:\n /// ```motoko include=import\n /// let blob1 = \"\\00\\AA\\AA\" : Blob;\n /// let blob2 = \"\\00\\FF\\00\" : Blob;\n /// ignore Blob.less(blob1, blob2);\n /// blob1 < blob2 // => true\n /// ```\n\n public func less(blob1 : Blob, blob2 : Blob) : Bool { blob1 < blob2 };\n\n /// \"Less than or equal to\" function for `Blob` types.\n /// This is equivalent to `blob1 <= blob2`.\n /// \n /// Example:\n /// ```motoko include=import\n /// let blob1 = \"\\00\\AA\\AA\" : Blob;\n /// let blob2 = \"\\00\\FF\\00\" : Blob;\n /// ignore Blob.lessOrEqual(blob1, blob2);\n /// blob1 <= blob2 // => true\n /// ```\n public func lessOrEqual(blob1 : Blob, blob2 : Blob) : Bool { blob1 <= blob2 };\n\n /// \"Greater than\" function for `Blob` types.\n /// This is equivalent to `blob1 > blob2`.\n /// \n /// Example:\n /// ```motoko include=import\n /// let blob1 = \"\\BB\\AA\\AA\" : Blob;\n /// let blob2 = \"\\00\\00\\00\" : Blob;\n /// ignore Blob.greater(blob1, blob2);\n /// blob1 > blob2 // => true\n /// ```\n public func greater(blob1 : Blob, blob2 : Blob) : Bool { blob1 > blob2 };\n\n /// \"Greater than or equal to\" function for `Blob` types.\n /// This is equivalent to `blob1 >= blob2`.\n /// \n /// Example:\n /// ```motoko include=import\n /// let blob1 = \"\\BB\\AA\\AA\" : Blob;\n /// let blob2 = \"\\00\\00\\00\" : Blob;\n /// ignore Blob.greaterOrEqual(blob1, blob2);\n /// blob1 >= blob2 // => true\n /// ```\n public func greaterOrEqual(blob1 : Blob, blob2 : Blob) : Bool {\n blob1 >= blob2\n }\n}\n"},"Int16.mo":{"content":"/// Provides utility functions on 16-bit signed integers.\n/// \n/// :::note\n/// Most operations are available as built-in operators (e.g. `1 + 1`).\n/// :::\n/// \n/// :::info Function form for higher-order use\n/// \n/// Several arithmetic and comparison functions (e.g. `add`, `sub`, `bitor`, `bitand`, `pow`) are defined in this module to enable their use as first-class function values, which is not possible with operators like `+`, `-`, `==`, etc., in Motoko. This allows you to pass these operations to higher-order functions such as `map`, `foldLeft`, or `sort`.\n/// :::\n/// \n/// Import from the base library to use this module.\n/// \n/// ```motoko name=import\n/// import Int16 \"mo:base/Int16\";\n/// ```\nimport Int \"Int\";\nimport Prim \"mo:⛔\";\n\nmodule {\n\n /// 16-bit signed integers.\n public type Int16 = Prim.Types.Int16;\n\n /// Minimum 16-bit integer value, `-2 ** 15`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int16.minimumValue // => -32_768 : Int16\n /// ```\n public let minimumValue = -32_768 : Int16;\n\n /// Maximum 16-bit integer value, `+2 ** 15 - 1`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int16.maximumValue // => +32_767 : Int16\n /// ```\n public let maximumValue = 32_767 : Int16;\n\n /// Converts a 16-bit signed integer to a signed integer with infinite precision.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int16.toInt(12_345) // => 12_345 : Int\n /// ```\n public let toInt : Int16 -> Int = Prim.int16ToInt;\n\n /// Converts a signed integer with infinite precision to a 16-bit signed integer.\n /// \n /// Traps on overflow/underflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int16.fromInt(12_345) // => +12_345 : Int16\n /// ```\n public let fromInt : Int -> Int16 = Prim.intToInt16;\n\n /// Converts a signed integer with infinite precision to a 16-bit signed integer.\n /// \n /// Wraps on overflow/underflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int16.fromIntWrap(-12_345) // => -12_345 : Int\n /// ```\n public let fromIntWrap : Int -> Int16 = Prim.intToInt16Wrap;\n\n /// Converts a 8-bit signed integer to a 16-bit signed integer.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int16.fromInt8(-123) // => -123 : Int16\n /// ```\n public let fromInt8 : Int8 -> Int16 = Prim.int8ToInt16;\n\n /// Converts a 16-bit signed integer to a 8-bit signed integer.\n /// \n /// Traps on overflow/underflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int16.toInt8(-123) // => -123 : Int8\n /// ```\n public let toInt8 : Int16 -> Int8 = Prim.int16ToInt8;\n\n /// Converts a 32-bit signed integer to a 16-bit signed integer.\n /// \n /// Traps on overflow/underflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int16.fromInt32(-12_345) // => -12_345 : Int16\n /// ```\n public let fromInt32 : Int32 -> Int16 = Prim.int32ToInt16;\n\n /// Converts a 16-bit signed integer to a 32-bit signed integer.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int16.toInt32(-12_345) // => -12_345 : Int32\n /// ```\n public let toInt32 : Int16 -> Int32 = Prim.int16ToInt32;\n\n /// Converts an unsigned 16-bit integer to a signed 16-bit integer.\n /// \n /// Wraps on overflow/underflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int16.fromNat16(12_345) // => +12_345 : Int16\n /// ```\n public let fromNat16 : Nat16 -> Int16 = Prim.nat16ToInt16;\n\n /// Converts a signed 16-bit integer to an unsigned 16-bit integer.\n /// \n /// Wraps on overflow/underflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int16.toNat16(-1) // => 65_535 : Nat16 // underflow\n /// ```\n public let toNat16 : Int16 -> Nat16 = Prim.int16ToNat16;\n\n /// Returns the Text representation of `x`. Textual representation _do not_\n /// contain underscores to represent commas.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int16.toText(-12345) // => \"-12345\"\n /// ```\n public func toText(x : Int16) : Text {\n Int.toText(toInt(x))\n };\n\n /// Returns the absolute value of `x`.\n /// \n /// Traps when `x == -2 ** 15` (the minimum `Int16` value).\n /// \n /// Example:\n /// ```motoko include=import\n /// Int16.abs(-12345) // => +12_345\n /// ```\n public func abs(x : Int16) : Int16 {\n fromInt(Int.abs(toInt(x)))\n };\n\n /// Returns the minimum of `x` and `y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int16.min(+2, -3) // => -3\n /// ```\n public func min(x : Int16, y : Int16) : Int16 {\n if (x < y) { x } else { y }\n };\n\n /// Returns the maximum of `x` and `y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int16.max(+2, -3) // => +2\n /// ```\n public func max(x : Int16, y : Int16) : Int16 {\n if (x < y) { y } else { x }\n };\n\n /// Equality function for Int16 types.\n /// This is equivalent to `x == y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int16.equal(-1, -1); // => true\n /// ```\n /// \n\n /// \n /// Example:\n /// ```motoko include=import\n /// import Buffer \"mo:base/Buffer\";\n /// \n /// let buffer1 = Buffer.Buffer<Int16>(1);\n /// buffer1.add(-3);\n /// let buffer2 = Buffer.Buffer<Int16>(1);\n /// buffer2.add(-3);\n /// Buffer.equal(buffer1, buffer2, Int16.equal) // => true\n /// ```\n public func equal(x : Int16, y : Int16) : Bool { x == y };\n\n /// Inequality function for Int16 types.\n /// This is equivalent to `x != y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int16.notEqual(-1, -2); // => true\n /// ```\n /// \n\n public func notEqual(x : Int16, y : Int16) : Bool { x != y };\n\n /// \"Less than\" function for Int16 types.\n /// This is equivalent to `x < y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int16.less(-2, 1); // => true\n /// ```\n /// \n\n public func less(x : Int16, y : Int16) : Bool { x < y };\n\n /// \"Less than or equal\" function for Int16 types.\n /// This is equivalent to `x <= y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int16.lessOrEqual(-2, -2); // => true\n /// ```\n /// \n\n public func lessOrEqual(x : Int16, y : Int16) : Bool { x <= y };\n\n /// \"Greater than\" function for Int16 types.\n /// This is equivalent to `x > y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int16.greater(-2, 1); // => false\n /// ```\n public func greater(x : Int16, y : Int16) : Bool { x > y };\n\n /// \"Greater than or equal\" function for Int16 types.\n /// This is equivalent to `x >= y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int16.greaterOrEqual(-2, -2); // => true\n /// ```\n public func greaterOrEqual(x : Int16, y : Int16) : Bool { x >= y };\n\n /// General-purpose comparison function for `Int16`. Returns the `Order` (\n /// either `#less`, `#equal`, or `#greater`) of comparing `x` with `y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int16.compare(-3, 2) // => #less\n /// ```\n /// \n /// This function can be used as value for a high order function, such as a sort function.\n /// \n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.sort([1, -2, -3] : [Int16], Int16.compare) // => [-3, -2, 1]\n /// ```\n public func compare(x : Int16, y : Int16) : { #less; #equal; #greater } {\n if (x < y) { #less } else if (x == y) { #equal } else { #greater }\n };\n\n /// Returns the negation of `x`, `-x`.\n /// \n /// Traps on overflow, i.e. for `neg(-2 ** 15)`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int16.neg(123) // => -123\n /// ```\n /// \n\n public func neg(x : Int16) : Int16 { -x };\n\n /// Returns the sum of `x` and `y`, `x + y`.\n /// \n /// Traps on overflow/underflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int16.add(100, 23) // => +123\n /// ```\n /// \n\n /// \n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.foldLeft<Int16, Int16>([1, -2, -3], 0, Int16.add) // => -4\n /// ```\n public func add(x : Int16, y : Int16) : Int16 { x + y };\n\n /// Returns the difference of `x` and `y`, `x - y`.\n /// \n /// Traps on overflow/underflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int16.sub(123, 100) // => +23\n /// ```\n /// \n\n /// \n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.foldLeft<Int16, Int16>([1, -2, -3], 0, Int16.sub) // => 4\n /// ```\n public func sub(x : Int16, y : Int16) : Int16 { x - y };\n\n /// Returns the product of `x` and `y`, `x * y`.\n /// \n /// Traps on overflow/underflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int16.mul(12, 10) // => +120\n /// ```\n /// \n\n /// \n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.foldLeft<Int16, Int16>([1, -2, -3], 1, Int16.mul) // => 6\n /// ```\n public func mul(x : Int16, y : Int16) : Int16 { x * y };\n\n /// Returns the signed integer division of `x` by `y`, `x / y`.\n /// Rounds the quotient towards zero, which is the same as truncating the decimal places of the quotient.\n /// \n /// Traps when `y` is zero.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int16.div(123, 10) // => +12\n /// ```\n /// \n\n public func div(x : Int16, y : Int16) : Int16 { x / y };\n\n /// Returns the remainder of the signed integer division of `x` by `y`, `x % y`,\n /// which is defined as `x - x / y * y`.\n /// \n /// Traps when `y` is zero.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int16.rem(123, 10) // => +3\n /// ```\n /// \n\n public func rem(x : Int16, y : Int16) : Int16 { x % y };\n\n /// Returns `x` to the power of `y`, `x ** y`.\n /// \n /// Traps on overflow/underflow and when `y < 0 or y >= 16`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int16.pow(2, 10) // => +1_024\n /// ```\n /// \n\n public func pow(x : Int16, y : Int16) : Int16 { x ** y };\n\n /// Returns the bitwise negation of `x`, `^x`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int16.bitnot(-256 /* 0xff00 */) // => +255 // 0xff\n /// ```\n /// \n\n public func bitnot(x : Int16) : Int16 { ^x };\n\n /// Returns the bitwise \"and\" of `x` and `y`, `x & y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int16.bitand(0x0fff, 0x00f0) // => +240 // 0xf0\n /// ```\n /// \n\n public func bitand(x : Int16, y : Int16) : Int16 { x & y };\n\n /// Returns the bitwise \"or\" of `x` and `y`, `x | y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int16.bitor(0x0f0f, 0x00f0) // => +4_095 // 0x0fff\n /// ```\n\n public func bitor(x : Int16, y : Int16) : Int16 { x | y };\n\n /// Returns the bitwise \"exclusive or\" of `x` and `y`, `x ^ y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int16.bitxor(0x0fff, 0x00f0) // => +3_855 // 0x0f0f\n /// ```\n\n public func bitxor(x : Int16, y : Int16) : Int16 { x ^ y };\n\n /// Returns the bitwise left shift of `x` by `y`, `x << y`.\n /// The right bits of the shift filled with zeros.\n /// Left-overflowing bits, including the sign bit, are discarded.\n /// \n /// For `y >= 16`, the semantics is the same as for `bitshiftLeft(x, y % 16)`.\n /// For `y < 0`, the semantics is the same as for `bitshiftLeft(x, y + y % 16)`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int16.bitshiftLeft(1, 8) // => +256 // 0x100 equivalent to `2 ** 8`.\n /// ```\n /// \n\n public func bitshiftLeft(x : Int16, y : Int16) : Int16 { x << y };\n\n /// Returns the signed bitwise right shift of `x` by `y`, `x >> y`.\n /// The sign bit is retained and the left side is filled with the sign bit.\n /// Right-underflowing bits are discarded, i.e. not rotated to the left side.\n /// \n /// For `y >= 16`, the semantics is the same as for `bitshiftRight(x, y % 16)`.\n /// For `y < 0`, the semantics is the same as for `bitshiftRight (x, y + y % 16)`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int16.bitshiftRight(1024, 8) // => +4 // equivalent to `1024 / (2 ** 8)`\n /// ```\n /// \n\n public func bitshiftRight(x : Int16, y : Int16) : Int16 { x >> y };\n\n /// Returns the bitwise left rotatation of `x` by `y`, `x <<> y`.\n /// Each left-overflowing bit is inserted again on the right side.\n /// The sign bit is rotated like other bits, i.e. the rotation interprets the number as unsigned.\n /// \n /// Changes the direction of rotation for negative `y`.\n /// For `y >= 16`, the semantics is the same as for `bitrotLeft(x, y % 16)`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int16.bitrotLeft(0x2001, 4) // => +18 // 0x12.\n /// ```\n /// \n\n public func bitrotLeft(x : Int16, y : Int16) : Int16 { x <<> y };\n\n /// Returns the bitwise right rotation of `x` by `y`, `x <>> y`.\n /// Each right-underflowing bit is inserted again on the right side.\n /// The sign bit is rotated like other bits, i.e. the rotation interprets the number as unsigned.\n /// \n /// Changes the direction of rotation for negative `y`.\n /// For `y >= 16`, the semantics is the same as for `bitrotRight(x, y % 16)`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int16.bitrotRight(0x2010, 8) // => +4_128 // 0x01020.\n /// ```\n /// \n\n public func bitrotRight(x : Int16, y : Int16) : Int16 { x <>> y };\n\n /// Returns the value of bit `p` in `x`, `x & 2**p == 2**p`.\n /// If `p >= 16`, the semantics is the same as for `bittest(x, p % 16)`.\n /// This is equivalent to checking if the `p`-th bit is set in `x`, using 0 indexing.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int16.bittest(128, 7) // => true\n /// ```\n public func bittest(x : Int16, p : Nat) : Bool {\n Prim.btstInt16(x, Prim.intToInt16(p))\n };\n\n /// Returns the value of setting bit `p` in `x` to `1`.\n /// If `p >= 16`, the semantics is the same as for `bitset(x, p % 16)`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int16.bitset(0, 7) // => +128\n /// ```\n public func bitset(x : Int16, p : Nat) : Int16 {\n x | (1 << Prim.intToInt16(p))\n };\n\n /// Returns the value of clearing bit `p` in `x` to `0`.\n /// If `p >= 16`, the semantics is the same as for `bitclear(x, p % 16)`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int16.bitclear(-1, 7) // => -129\n /// ```\n public func bitclear(x : Int16, p : Nat) : Int16 {\n x & ^(1 << Prim.intToInt16(p))\n };\n\n /// Returns the value of flipping bit `p` in `x`.\n /// If `p >= 16`, the semantics is the same as for `bitclear(x, p % 16)`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int16.bitflip(255, 7) // => +127\n /// ```\n public func bitflip(x : Int16, p : Nat) : Int16 {\n x ^ (1 << Prim.intToInt16(p))\n };\n\n /// Returns the count of non-zero bits in `x`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int16.bitcountNonZero(0xff) // => +8\n /// ```\n public let bitcountNonZero : (x : Int16) -> Int16 = Prim.popcntInt16;\n\n /// Returns the count of leading zero bits in `x`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int16.bitcountLeadingZero(0x80) // => +8\n /// ```\n public let bitcountLeadingZero : (x : Int16) -> Int16 = Prim.clzInt16;\n\n /// Returns the count of trailing zero bits in `x`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int16.bitcountTrailingZero(0x0100) // => +8\n /// ```\n public let bitcountTrailingZero : (x : Int16) -> Int16 = Prim.ctzInt16;\n\n /// Returns the upper (i.e. most significant) and lower (least significant) byte of `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int16.explode 0x77ee // => (119, 238)\n /// ```\n public let explode : (x : Int16) -> (msb : Nat8, lsb : Nat8) = Prim.explodeInt16;\n\n /// Returns the sum of `x` and `y`, `x +% y`.\n ///\n /// Wraps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int16.addWrap(2 ** 14, 2 ** 14) // => -32_768 // overflow\n /// ```\n ///\n /// :::info \n /// The reason why this function is defined in this library (in addition\n /// to the existing `+%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `+%`\n /// as a function value at the moment.\n /// :::\n public func addWrap(x : Int16, y : Int16) : Int16 { x +% y };\n\n /// Returns the difference of `x` and `y`, `x -% y`.\n /// \n /// Wraps on overflow/underflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int16.subWrap(-2 ** 15, 1) // => +32_767 // underflow\n /// ```\n /// \n\n public func subWrap(x : Int16, y : Int16) : Int16 { x -% y };\n\n /// Returns the product of `x` and `y`, `x *% y`. Wraps on overflow.\n /// \n /// Wraps on overflow/underflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int16.mulWrap(2 ** 8, 2 ** 8) // => 0 // overflow\n /// ```\n /// \n\n public func mulWrap(x : Int16, y : Int16) : Int16 { x *% y };\n\n /// Returns `x` to the power of `y`, `x **% y`.\n /// \n /// Wraps on overflow/underflow.\n /// Traps if `y < 0 or y >= 16`.\n /// \n /// Example:\n /// ```motoko include=import\n /// \n /// Int16.powWrap(2, 15) // => -32_768 // overflow\n /// ```\n /// \n\n public func powWrap(x : Int16, y : Int16) : Int16 { x **% y }\n}\n"},"Array.mo":{"content":"/// Provides extended utility functions on Arrays.\n/// \n/// :::warning\n/// \n/// If you are looking for a list that can grow and shrink in size,\n/// it is recommended you use either the `Buffer` or `List` data structure for\n/// those purposes.\n/// \n/// :::\n/// \n/// :::note Assumptions\n/// \n/// Runtime and space complexity assumes that `generator`, `equal`, and other functions execute in `O(1)` time and space.\n/// :::\n/// \n/// Import from the base library to use this module.\n/// \n/// ```motoko name=import\n/// import Array \"mo:base/Array\";\n/// ```\n/// \n\nimport I \"IterType\";\nimport Option \"Option\";\nimport Order \"Order\";\nimport Prim \"mo:⛔\";\nimport Result \"Result\";\n\nmodule {\n /// Create a mutable array with `size` copies of the initial value.\n ///\n /// ```motoko include=import\n /// let array = Array.init<Nat>(4, 2);\n /// ```\n ///\n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size)` | `O(size)` |\n public func init<X>(size : Nat, initValue : X) : [var X] = Prim.Array_init<X>(size, initValue);\n\n /// Create an immutable array of size `size`. Each element at index i\n /// is created by applying `generator` to i.\n ///\n /// ```motoko include=import\n /// let array : [Nat] = Array.tabulate<Nat>(4, func i = i * 2);\n /// ```\n ///\n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size)` | `O(size)` |\n public func tabulate<X>(size : Nat, generator : Nat -> X) : [X] = Prim.Array_tabulate<X>(size, generator);\n\n /// Create a mutable array of size `size`. Each element at index i\n /// is created by applying `generator` to i.\n ///\n /// ```motoko include=import\n /// let array : [var Nat] = Array.tabulateVar<Nat>(4, func i = i * 2);\n /// array[2] := 0;\n /// array\n /// ```\n ///\n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size)` | `O(size)` |\n public func tabulateVar<X>(size : Nat, generator : Nat -> X) : [var X] {\n // FIXME add this as a primitive in the RTS\n if (size == 0) { return [var] };\n let array = Prim.Array_init<X>(size, generator 0);\n var i = 1;\n while (i < size) {\n array[i] := generator i;\n i += 1\n };\n array\n };\n\n /// Transforms a mutable array into an immutable array.\n ///\n /// ```motoko include=import\n ///\n /// let varArray = [var 0, 1, 2];\n /// varArray[2] := 3;\n /// let array = Array.freeze<Nat>(varArray);\n /// ```\n ///\n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size)` | `O(1)` |\n public func freeze<X>(varArray : [var X]) : [X] = Prim.Array_tabulate<X>(varArray.size(), func i = varArray[i]);\n\n /// Transforms an immutable array into a mutable array.\n ///\n /// ```motoko include=import\n ///\n /// let array = [0, 1, 2];\n /// let varArray = Array.thaw<Nat>(array);\n /// varArray[2] := 3;\n /// varArray\n /// ```\n ///\n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size)` | `O(1)` |\n public func thaw<A>(array : [A]) : [var A] {\n let size = array.size();\n if (size == 0) {\n return [var]\n };\n let newArray = Prim.Array_init<A>(size, array[0]);\n var i = 0;\n while (i < size) {\n newArray[i] := array[i];\n i += 1\n };\n newArray\n };\n\n /// Tests if two arrays contain equal values (i.e. they represent the same\n /// list of elements). Uses `equal` to compare elements in the arrays.\n ///\n /// ```motoko include=import\n /// // Use the equal function from the Nat module to compare Nats\n /// import {equal} \"mo:base/Nat\";\n ///\n /// let array1 = [0, 1, 2, 3];\n /// let array2 = [0, 1, 2, 3];\n /// Array.equal(array1, array2, equal)\n /// ```\n ///\n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size1 + size2)` | `O(size1 + size2)` |\n public func equal<X>(array1 : [X], array2 : [X], equal : (X, X) -> Bool) : Bool {\n let size1 = array1.size();\n let size2 = array2.size();\n if (size1 != size2) {\n return false\n };\n var i = 0;\n while (i < size1) {\n if (not equal(array1[i], array2[i])) {\n return false\n };\n i += 1\n };\n return true\n };\n\n /// Returns the first value in `array` for which `predicate` returns true.\n /// If no element satisfies the predicate, returns null.\n ///\n /// ```motoko include=import\n /// let array = [1, 9, 4, 8];\n /// Array.find<Nat>(array, func x = x > 8)\n /// ```\n ///\n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size)` | `O(1)` |\n ///\n public func find<X>(array : [X], predicate : X -> Bool) : ?X {\n for (element in array.vals()) {\n if (predicate element) {\n return ?element\n }\n };\n return null\n };\n\n /// Create a new array by appending the values of `array1` and `array2`.\n ///\n /// :::note Efficient appending\n ///\n /// `Array.append` copies its arguments and runs in linear time.\n /// For better performance in loops, consider using `Buffer` and `Buffer.append` instead.\n ///\n /// :::\n ///\n /// ```motoko include=import\n /// let array1 = [1, 2, 3];\n /// let array2 = [4, 5, 6];\n /// Array.append<Nat>(array1, array2)\n /// ```\n ///\n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size1 + size2)` | `O(size1 + size2)` |\n public func append<X>(array1 : [X], array2 : [X]) : [X] {\n let size1 = array1.size();\n let size2 = array2.size();\n Prim.Array_tabulate<X>(\n size1 + size2,\n func i {\n if (i < size1) {\n array1[i]\n } else {\n array2[i - size1]\n }\n }\n )\n };\n\n /// Sorts the elements in the array according to `compare`.\n /// Sort is deterministic and stable.\n ///\n /// ```motoko include=import\n /// import Nat \"mo:base/Nat\";\n ///\n /// let array = [4, 2, 6];\n /// Array.sort(array, Nat.compare).\n /// ```\n ///\n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size * log(size))` | `O(size)` |\n public func sort<X>(array : [X], compare : (X, X) -> Order.Order) : [X] {\n let temp : [var X] = thaw(array);\n sortInPlace(temp, compare);\n freeze(temp)\n };\n\n /// Sorts the elements in the array, __in place__, according to `compare`.\n /// Sort is deterministic, stable, and in-place.\n ///\n /// ```motoko include=import\n /// import {compare} \"mo:base/Nat\";\n /// let array = [var 4, 2, 6];\n /// Array.sortInPlace(array, compare);\n /// array\n /// ```\n ///\n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size * log(size))` | `O(size)` |\n ///\n public func sortInPlace<X>(array : [var X], compare : (X, X) -> Order.Order) {\n // Stable merge sort in a bottom-up iterative style. Same algorithm as the sort in Buffer.\n let size = array.size();\n if (size == 0) {\n return\n };\n let scratchSpace = Prim.Array_init<X>(size, array[0]);\n\n let sizeDec = size - 1 : Nat;\n var currSize = 1; // current size of the subarrays being merged\n // when the current size == size, the array has been merged into a single sorted array\n while (currSize < size) {\n var leftStart = 0; // selects the current left subarray being merged\n while (leftStart < sizeDec) {\n let mid : Nat = if (leftStart + currSize - 1 : Nat < sizeDec) {\n leftStart + currSize - 1\n } else { sizeDec };\n let rightEnd : Nat = if (leftStart + (2 * currSize) - 1 : Nat < sizeDec) {\n leftStart + (2 * currSize) - 1\n } else { sizeDec };\n\n // Merge subarrays elements[leftStart...mid] and elements[mid+1...rightEnd]\n var left = leftStart;\n var right = mid + 1;\n var nextSorted = leftStart;\n while (left < mid + 1 and right < rightEnd + 1) {\n let leftElement = array[left];\n let rightElement = array[right];\n switch (compare(leftElement, rightElement)) {\n case (#less or #equal) {\n scratchSpace[nextSorted] := leftElement;\n left += 1\n };\n case (#greater) {\n scratchSpace[nextSorted] := rightElement;\n right += 1\n }\n };\n nextSorted += 1\n };\n while (left < mid + 1) {\n scratchSpace[nextSorted] := array[left];\n nextSorted += 1;\n left += 1\n };\n while (right < rightEnd + 1) {\n scratchSpace[nextSorted] := array[right];\n nextSorted += 1;\n right += 1\n };\n\n // Copy over merged elements\n var i = leftStart;\n while (i < rightEnd + 1) {\n array[i] := scratchSpace[i];\n i += 1\n };\n\n leftStart += 2 * currSize\n };\n currSize *= 2\n }\n };\n\n /// Creates a new array by reversing the order of elements in `array`.\n /// \n /// ```motoko include=import\n /// let array = [10, 11, 12];\n /// Array.reverse(array)\n /// ```\n ///\n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size)` | `O(1)` |\n public func reverse<X>(array : [X]) : [X] {\n let size = array.size();\n Prim.Array_tabulate<X>(size, func i = array[size - i - 1])\n };\n\n /// Creates a new array by applying `f` to each element in `array`. `f` \"maps\"\n /// each element it is applied to of type `X` to an element of type `Y`.\n /// Retains original ordering of elements.\n /// \n /// ```motoko include=import\n /// let array = [0, 1, 2, 3];\n /// Array.map<Nat, Nat>(array, func x = x * 3)\n /// ```\n ///\n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size)` | `O(size)` |\n ///\n public func map<X, Y>(array : [X], f : X -> Y) : [Y] = Prim.Array_tabulate<Y>(array.size(), func i = f(array[i]));\n\n /// Creates a new array by applying `predicate` to every element\n /// in `array`, retaining the elements for which `predicate` returns true.\n ///\n /// ```motoko include=import\n /// let array = [4, 2, 6, 1, 5];\n /// let evenElements = Array.filter<Nat>(array, func x = x % 2 == 0);\n /// ```\n ///\n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size)` | `O(size)` |\n public func filter<X>(array : [X], predicate : X -> Bool) : [X] {\n var count = 0;\n let keep = Prim.Array_tabulate<Bool>(\n array.size(),\n func i {\n if (predicate(array[i])) {\n count += 1;\n true\n } else {\n false\n }\n }\n );\n var nextKeep = 0;\n Prim.Array_tabulate<X>(\n count,\n func _ {\n while (not keep[nextKeep]) {\n nextKeep += 1\n };\n nextKeep += 1;\n array[nextKeep - 1]\n }\n )\n };\n\n /// Creates a new array by applying `f` to each element in `array` and its index.\n /// Retains original ordering of elements.\n ///\n /// ```motoko include=import\n /// let array = [10, 10, 10, 10];\n /// Array.mapEntries<Nat, Nat>(array, func (x, i) = i * x)\n /// ```\n ///\n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size)` | `O(size)` |\n public func mapEntries<X, Y>(array : [X], f : (X, Nat) -> Y) : [Y] = Prim.Array_tabulate<Y>(array.size(), func i = f(array[i], i));\n\n /// Creates a new array by applying `f` to each element in `array`,\n /// and keeping all non-null elements. The ordering is retained.\n ///\n /// ```motoko include=import\n /// import {toText} \"mo:base/Nat\";\n ///\n /// let array = [4, 2, 0, 1];\n /// let newArray =\n /// Array.mapFilter<Nat, Text>( // mapping from Nat to Text values\n /// array,\n /// func x = if (x == 0) { null } else { ?toText(100 / x) } // can't divide by 0, so return null\n /// );\n /// ```\n ///\n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size)` | `O(size)` |\n ///\n public func mapFilter<X, Y>(array : [X], f : X -> ?Y) : [Y] {\n var count = 0;\n let options = Prim.Array_tabulate<?Y>(\n array.size(),\n func i {\n let result = f(array[i]);\n switch (result) {\n case (?element) {\n count += 1;\n result\n };\n case null {\n null\n }\n }\n }\n );\n\n var nextSome = 0;\n Prim.Array_tabulate<Y>(\n count,\n func _ {\n while (Option.isNull(options[nextSome])) {\n nextSome += 1\n };\n nextSome += 1;\n switch (options[nextSome - 1]) {\n case (?element) element;\n case null {\n Prim.trap \"Malformed array in mapFilter\"\n }\n }\n }\n )\n };\n\n /// Creates a new array by applying `f` to each element in `array`.\n /// If any invocation of `f` produces an `#err`, returns an `#err`. Otherwise\n /// returns an `#ok` containing the new array.\n ///\n /// ```motoko include=import\n /// let array = [4, 3, 2, 1, 0];\n /// // divide 100 by every element in the array\n /// Array.mapResult<Nat, Nat, Text>(array, func x {\n /// if (x > 0) {\n /// #ok(100 / x)\n /// } else {\n /// #err \"Cannot divide by zero\"\n /// }\n /// })\n /// ```\n ///\n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size)` | `O(size)` |\n public func mapResult<X, Y, E>(array : [X], f : X -> Result.Result<Y, E>) : Result.Result<[Y], E> {\n let size = array.size();\n\n var error : ?Result.Result<[Y], E> = null;\n let results = Prim.Array_tabulate<?Y>(\n size,\n func i {\n switch (f(array[i])) {\n case (#ok element) {\n ?element\n };\n case (#err e) {\n switch (error) {\n case null {\n // only take the first error\n error := ?(#err e)\n };\n case _ {}\n };\n null\n }\n }\n }\n );\n\n switch error {\n case null {\n // unpack the option\n #ok(\n map<?Y, Y>(\n results,\n func element {\n switch element {\n case (?element) {\n element\n };\n case null {\n Prim.trap \"Malformed array in mapResults\"\n }\n }\n }\n )\n )\n };\n case (?error) {\n error\n }\n }\n };\n\n /// Creates a new array by applying `k` to each element in `array`,\n /// and concatenating the resulting arrays in order. This operation\n /// is similar to what in other functional languages is known as monadic bind.\n ///\n /// ```motoko include=import\n /// import Nat \"mo:base/Nat\";\n ///\n /// let array = [1, 2, 3, 4];\n /// Array.chain<Nat, Int>(array, func x = [x, -x])\n ///\n /// ```\n ///\n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size)` | `O(size)` |\n public func chain<X, Y>(array : [X], k : X -> [Y]) : [Y] {\n var flatSize = 0;\n let arrays = Prim.Array_tabulate<[Y]>(\n array.size(),\n func i {\n let subArray = k(array[i]);\n flatSize += subArray.size();\n subArray\n }\n );\n\n // could replace with a call to flatten,\n // but it would require an extra pass (to compute `flatSize`)\n var outer = 0;\n var inner = 0;\n Prim.Array_tabulate<Y>(\n flatSize,\n func _ {\n while (inner == arrays[outer].size()) {\n inner := 0;\n outer += 1\n };\n let element = arrays[outer][inner];\n inner += 1;\n element\n }\n )\n };\n\n /// Collapses the elements in `array` into a single value by starting with `base`\n /// and progessively combining elements into `base` with `combine`. Iteration runs\n /// left to right.\n ///\n /// ```motoko include=import\n /// import {add} \"mo:base/Nat\";\n ///\n /// let array = [4, 2, 0, 1];\n /// let sum =\n /// Array.foldLeft<Nat, Nat>(\n /// array,\n /// 0, // start the sum at 0\n /// func(sumSoFar, x) = sumSoFar + x // this entire function can be replaced with `add`!\n /// );\n /// ```\n ///\n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size)` | `O(1)` |\n public func foldLeft<X, A>(array : [X], base : A, combine : (A, X) -> A) : A {\n var accumulation = base;\n\n for (element in array.vals()) {\n accumulation := combine(accumulation, element)\n };\n\n accumulation\n };\n\n /// Collapses the elements in `array` into a single value by starting with `base`\n /// and progessively combining elements into `base` with `combine`. Iteration runs\n /// right to left.\n ///\n /// ```motoko include=import\n /// import {toText} \"mo:base/Nat\";\n ///\n /// let array = [1, 9, 4, 8];\n /// let bookTitle = Array.foldRight<Nat, Text>(array, \"\", func(x, acc) = toText(x) # acc);\n /// ```\n ///\n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size)` | `O(1)` |\n public func foldRight<X, A>(array : [X], base : A, combine : (X, A) -> A) : A {\n var accumulation = base;\n let size = array.size();\n\n var i = size;\n while (i > 0) {\n i -= 1;\n accumulation := combine(array[i], accumulation)\n };\n\n accumulation\n };\n\n /// Flattens the array of arrays into a single array. Retains the original\n /// ordering of the elements.\n ///\n /// ```motoko include=import\n /// let arrays = [[0, 1, 2], [2, 3], [], [4]];\n /// Array.flatten<Nat>(arrays)\n /// ```\n ///\n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(n)` | `O(n)` |\n public func flatten<X>(arrays : [[X]]) : [X] {\n var flatSize = 0;\n for (subArray in arrays.vals()) {\n flatSize += subArray.size()\n };\n\n var outer = 0;\n var inner = 0;\n Prim.Array_tabulate<X>(\n flatSize,\n func _ {\n while (inner == arrays[outer].size()) {\n inner := 0;\n outer += 1\n };\n let element = arrays[outer][inner];\n inner += 1;\n element\n }\n )\n };\n\n /// Create an array containing a single value.\n ///\n /// ```motoko include=import\n /// Array.make(2)\n /// ```\n ///\n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(1)` | `O(1)` |\n public func make<X>(element : X) : [X] = [element];\n\n /// Returns an Iterator (`Iter`) over the elements of `array`.\n /// Iterator provides a single method `next()`, which returns\n /// elements in order, or `null` when out of elements to iterate over.\n ///\n /// :::note Alternative approach\n ///\n /// Alternatively, you can use `array.size()` to achieve the same result. See the example below.\n /// :::\n /// \n /// ```motoko include=import\n /// let array = [10, 11, 12];\n /// var sum = 0;\n /// for (element in array.vals()) {\n /// sum += element;\n /// };\n /// sum\n /// ```\n ///\n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(1)` | `O(1)` |\n public func vals<X>(array : [X]) : I.Iter<X> = array.vals();\n\n /// Returns an Iterator (`Iter`) over the indices of `array`.\n /// Iterator provides a single method `next()`, which returns\n /// indices in order, or `null` when out of index to iterate over.\n ///\n /// :::note Alternative approach\n /// You can also use `array.keys()` instead of this function. See example\n /// below.\n ///\n /// :::\n ///\n /// ```motoko include=import\n /// let array = [10, 11, 12];\n /// var sum = 0;\n /// for (element in array.keys()) {\n /// sum += element;\n /// };\n /// sum\n /// ```\n ///\n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(1)` | `O(1)` |\n public func keys<X>(array : [X]) : I.Iter<Nat> = array.keys();\n\n /// Returns the size of `array`.\n ///\n /// :::note Alternative approach\n ///\n /// Alternatively, you can use `array.size()` to achieve the same result. See the example below.\n /// :::\n ///\n /// ```motoko include=import\n /// let array = [10, 11, 12];\n /// let size = Array.size(array);\n /// ```\n ///\n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(1)` | `O(1)` |\n public func size<X>(array : [X]) : Nat = array.size();\n\n /// Returns a new subarray from the given array provided the start index and length of elements in the subarray.\n ///\n /// :::note Limitations\n /// Traps if the start index + length is greater than the size of the array.\n /// :::\n ///\n /// ```motoko include=import\n /// let array = [1,2,3,4,5];\n /// let subArray = Array.subArray<Nat>(array, 2, 3);\n /// ```\n ///\n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(length)` | `O(length)` |\n public func subArray<X>(array : [X], start : Nat, length : Nat) : [X] {\n if (start + length > array.size()) { Prim.trap(\"Array.subArray\") };\n tabulate<X>(\n length,\n func(i) {\n array[start + i]\n }\n )\n };\n\n /// Returns the index of the first `element` in the `array`.\n /// \n /// ```motoko include=import\n /// import Char \"mo:base/Char\";\n /// let array = ['c', 'o', 'f', 'f', 'e', 'e'];\n /// assert Array.indexOf<Char>('c', array, Char.equal) == ?0;\n /// assert Array.indexOf<Char>('f', array, Char.equal) == ?2;\n /// assert Array.indexOf<Char>('g', array, Char.equal) == null;\n /// ```\n ///\n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(array.size())` | `O(1)` |\n public func indexOf<X>(element : X, array : [X], equal : (X, X) -> Bool) : ?Nat = nextIndexOf<X>(element, array, 0, equal);\n\n /// Returns the index of the next occurrence of `element` in the `array` starting from the `from` index (inclusive).\n ///\n /// ```motoko include=import\n /// import Char \"mo:base/Char\";\n /// let array = ['c', 'o', 'f', 'f', 'e', 'e'];\n /// assert Array.nextIndexOf<Char>('c', array, 0, Char.equal) == ?0;\n /// assert Array.nextIndexOf<Char>('f', array, 0, Char.equal) == ?2;\n /// assert Array.nextIndexOf<Char>('f', array, 2, Char.equal) == ?2;\n /// assert Array.nextIndexOf<Char>('f', array, 3, Char.equal) == ?3;\n /// assert Array.nextIndexOf<Char>('f', array, 4, Char.equal) == null;\n /// ```\n ///\n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(array.size())` | `O(1)` |\n public func nextIndexOf<X>(element : X, array : [X], fromInclusive : Nat, equal : (X, X) -> Bool) : ?Nat {\n var i = fromInclusive;\n let n = array.size();\n while (i < n) {\n if (equal(array[i], element)) {\n return ?i\n } else {\n i += 1\n }\n };\n null\n };\n\n /// Returns the index of the last `element` in the `array`.\n ///\n /// ```motoko include=import\n /// import Char \"mo:base/Char\";\n /// let array = ['c', 'o', 'f', 'f', 'e', 'e'];\n /// assert Array.lastIndexOf<Char>('c', array, Char.equal) == ?0;\n /// assert Array.lastIndexOf<Char>('f', array, Char.equal) == ?3;\n /// assert Array.lastIndexOf<Char>('e', array, Char.equal) == ?5;\n /// assert Array.lastIndexOf<Char>('g', array, Char.equal) == null;\n /// ```\n ///\n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(array.size())` | `O(1)` |\n public func lastIndexOf<X>(element : X, array : [X], equal : (X, X) -> Bool) : ?Nat = prevIndexOf<X>(element, array, array.size(), equal);\n\n /// Returns the index of the previous occurrence of `element` in the `array` starting from the `from` index (exclusive).\n ///\n /// ```motoko include=import\n /// import Char \"mo:base/Char\";\n /// let array = ['c', 'o', 'f', 'f', 'e', 'e'];\n /// assert Array.prevIndexOf<Char>('c', array, array.size(), Char.equal) == ?0;\n /// assert Array.prevIndexOf<Char>('e', array, array.size(), Char.equal) == ?5;\n /// assert Array.prevIndexOf<Char>('e', array, 5, Char.equal) == ?4;\n /// assert Array.prevIndexOf<Char>('e', array, 4, Char.equal) == null;\n /// ```\n ///\n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(array.size())` | `O(1)` |\n public func prevIndexOf<T>(element : T, array : [T], fromExclusive : Nat, equal : (T, T) -> Bool) : ?Nat {\n var i = fromExclusive;\n while (i > 0) {\n i -= 1;\n if (equal(array[i], element)) {\n return ?i\n }\n };\n null\n };\n\n /// Returns an iterator over a slice of the given array.\n ///\n /// ```motoko include=import\n /// let array = [1, 2, 3, 4, 5];\n /// let s = Array.slice<Nat>(array, 3, array.size());\n /// assert s.next() == ?4;\n /// assert s.next() == ?5;\n /// assert s.next() == null;\n ///\n /// let s = Array.slice<Nat>(array, 0, 0);\n /// assert s.next() == null;\n /// ```\n ///\n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(1)` | `O(1)` |\n public func slice<X>(array : [X], fromInclusive : Nat, toExclusive : Nat) : I.Iter<X> = object {\n var i = fromInclusive;\n\n public func next() : ?X {\n if (i >= toExclusive) {\n return null\n };\n let result = array[i];\n i += 1;\n return ?result\n }\n };\n\n /// Returns a new subarray of given length from the beginning or end of the given array.\n ///\n /// Returns the entire array if the length is greater than the size of the array.\n ///\n /// ```motoko include=import\n /// let array = [1, 2, 3, 4, 5];\n /// assert Array.take(array, 2) == [1, 2];\n /// assert Array.take(array, -2) == [4, 5];\n /// assert Array.take(array, 10) == [1, 2, 3, 4, 5];\n /// assert Array.take(array, -99) == [1, 2, 3, 4, 5];\n /// ```\n ///\n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(length)` | `O(length)` |\n public func take<T>(array : [T], length : Int) : [T] {\n let len = Prim.abs(length);\n let size = array.size();\n let resSize = if (len < size) { len } else { size };\n let start : Nat = if (length > 0) 0 else size - resSize;\n subArray(array, start, resSize)\n }\n}\n"},"Func.mo":{"content":"/// Create functions from simpler inputs, most commonly used when programming in functional style using higher-order functions.\n\nmodule {\n /// Import from the base library to use this module.\n /// \n /// ```motoko name=import\n /// import { compose; const; identity } = \"mo:base/Func\";\n /// import Text = \"mo:base/Text\";\n /// import Char = \"mo:base/Char\";\n /// ```\n\n /// The composition of two functions `f` and `g` is a function that applies `g` and then `f`.\n /// \n /// Example:\n /// ```motoko include=import\n /// let textFromNat32 = compose(Text.fromChar, Char.fromNat32);\n /// assert textFromNat32(65) == \"A\";\n /// ```\n public func compose<A, B, C>(f : B -> C, g : A -> B) : A -> C {\n func(x : A) : C {\n f(g(x))\n }\n };\n\n /// The `identity` function returns its argument.\n /// Example:\n /// ```motoko include=import\n /// assert identity(10) == 10;\n /// assert identity(true) == true;\n /// ```\n public func identity<A>(x : A) : A = x;\n\n /// The const function is a _curried_ function that accepts an argument `x`,\n /// and then returns a function that discards its argument and always returns\n /// the `x`.\n /// \n /// Example:\n /// ```motoko include=import\n /// assert const<Nat, Text>(10)(\"hello\") == 10;\n /// assert const(true)(20) == true;\n /// ```\n public func const<A, B>(x : A) : B -> A = func _ = x\n}\n"},"Char.mo":{"content":"import Prim \"mo:⛔\";\nmodule {\n\n /// Characters represented as Unicode code points.\n public type Char = Prim.Types.Char;\n\n /// Convert character `c` to a word containing its Unicode scalar value.\n public let toNat32 : (c : Char) -> Nat32 = Prim.charToNat32;\n\n /// Convert `w` to a character.\n /// Traps if `w` is not a valid Unicode scalar value.\n /// Value `w` is valid if, and only if, `w < 0xD800 or (0xE000 <= w and w <= 0x10FFFF)`.\n public let fromNat32 : (w : Nat32) -> Char = Prim.nat32ToChar;\n\n /// Convert character `c` to single character text.\n public let toText : (c : Char) -> Text = Prim.charToText;\n\n // Not exposed pending multi-char implementation.\n private let _toUpper : (c : Char) -> Char = Prim.charToUpper;\n\n // Not exposed pending multi-char implementation.\n private let _toLower : (c : Char) -> Char = Prim.charToLower;\n\n /// Returns `true` when `c` is a decimal digit between `0` and `9`, otherwise `false`.\n public func isDigit(c : Char) : Bool {\n Prim.charToNat32(c) -% Prim.charToNat32('0') <= (9 : Nat32)\n };\n\n /// Returns the Unicode _White_Space_ property of `c`.\n public let isWhitespace : (c : Char) -> Bool = Prim.charIsWhitespace;\n\n /// Returns the Unicode _Lowercase_ property of `c`.\n public let isLowercase : (c : Char) -> Bool = Prim.charIsLowercase;\n\n /// Returns the Unicode _Uppercase_ property of `c`.\n public let isUppercase : (c : Char) -> Bool = Prim.charIsUppercase;\n\n /// Returns the Unicode _Alphabetic_ property of `c`.\n public let isAlphabetic : (c : Char) -> Bool = Prim.charIsAlphabetic;\n\n /// Returns `x == y`.\n public func equal(x : Char, y : Char) : Bool { x == y };\n\n /// Returns `x != y`.\n public func notEqual(x : Char, y : Char) : Bool { x != y };\n\n /// Returns `x < y`.\n public func less(x : Char, y : Char) : Bool { x < y };\n\n /// Returns `x <= y`.\n public func lessOrEqual(x : Char, y : Char) : Bool { x <= y };\n\n /// Returns `x > y`.\n public func greater(x : Char, y : Char) : Bool { x > y };\n\n /// Returns `x >= y`.\n public func greaterOrEqual(x : Char, y : Char) : Bool { x >= y };\n\n /// Returns the order of `x` and `y`.\n public func compare(x : Char, y : Char) : { #less; #equal; #greater } {\n if (x < y) { #less } else if (x == y) { #equal } else { #greater }\n };\n\n}\n"},"Error.mo":{"content":"/// Error values and inspection.\n/// \n/// The `Error` type is the argument to `throw`, parameter of `catch`.\n/// The `Error` type is opaque.\n\nimport Prim \"mo:⛔\";\n\nmodule {\n\n /// Error value resulting from `async` computations\n public type Error = Prim.Types.Error;\n\n /// Error code to classify different kinds of user and system errors:\n /// ```motoko\n /// type ErrorCode = {\n /// // Fatal error.\n /// #system_fatal;\n /// // Transient error.\n /// #system_transient;\n /// // Response unknown due to missed deadline.\n /// #system_unknown;\n /// // Destination invalid.\n /// #destination_invalid;\n /// // Explicit reject by canister code.\n /// #canister_reject;\n /// // Canister trapped.\n /// #canister_error;\n /// // Future error code (with unrecognized numeric code).\n /// #future : Nat32;\n /// // Error issuing inter-canister call\n /// // (indicating destination queue full or freezing threshold crossed).\n /// #call_error : { err_code : Nat32 }\n /// };\n /// ```\n public type ErrorCode = Prim.ErrorCode;\n\n /// Create an error from the message with the code `#canister_reject`.\n /// \n /// Example:\n /// ```motoko\n /// import Error \"mo:base/Error\";\n /// \n /// Error.reject(\"Example error\") // can be used as throw argument\n /// ```\n public let reject : (message : Text) -> Error = Prim.error;\n\n /// Returns the code of an error.\n /// \n /// Example:\n /// ```motoko\n /// import Error \"mo:base/Error\";\n /// \n /// let error = Error.reject(\"Example error\");\n /// Error.code(error) // #canister_reject\n /// ```\n public let code : (error : Error) -> ErrorCode = Prim.errorCode;\n\n /// Returns the message of an error.\n /// \n /// Example:\n /// ```motoko\n /// import Error \"mo:base/Error\";\n /// \n /// let error = Error.reject(\"Example error\");\n /// Error.message(error) // \"Example error\"\n /// ```\n public let message : (error : Error) -> Text = Prim.errorMessage;\n\n /// Returns whether retrying to send a message may result in success.\n /// \n /// Example:\n /// ```motoko\n /// import { message; isRetryPossible } \"mo:base/Error\";\n /// import { print } \"mo:base/Debug\";\n /// \n /// try await (with timeout = 3) Actor.call(arg)\n /// catch e { if (isRetryPossible e) print(message e) }\n /// ```\n public func isRetryPossible(error : Error) : Bool = switch (code error) {\n case (#system_unknown or #system_transient) true;\n case _ false\n };\n\n}\n"},"ExperimentalStableMemory.mo":{"content":"/// Byte-level access to (virtual) _stable memory_.\n/// \n/// :::warning Experimental module\n/// \n/// As the name suggests, this library is experimental, subject to change, and may be replaced by safer alternatives in later versions of Motoko.\n/// Use at your own risk and discretion.\n/// :::\n/// \n/// :::warning Deprecation notice\n/// \n/// Use of `ExperimentalStableMemory` may be deprecated in the future.\n/// Consider using `Region.mo` for isolated memory regions.\n/// Isolated regions ensure that writing to one region does not affect unrelated state elsewhere.\n/// :::\n/// \n/// This is a lightweight abstraction over IC _stable memory_ and supports persisting raw binary data across Motoko upgrades.\n/// It is fully compatible with Motoko's _stable variables_, which also use IC stable memory internally, but do not interfere with this API.\n/// \n/// Memory is allocated using `grow(pages)`, sequentially and on demand, in units of 64KiB pages, starting with 0 allocated pages.\n/// New pages are zero-initialized.\n/// Growth is capped by a soft page limit set with the compile-time flag `--max-stable-pages <n>` (default: 65536, or 4GiB).\n/// \n/// Each `load` reads from byte address `offset` in little-endian format using the natural bit-width of the type.\n/// Traps if reading beyond the allocated size.\n/// \n/// Each `store` writes to byte address `offset` in little-endian format using the natural bit-width of the type.\n/// Traps if writing beyond the allocated size.\n/// \n/// Text can be handled using `Text.decodeUtf8` and `Text.encodeUtf8` in combination with `loadBlob` and `storeBlob`.\n/// \n/// The current page allocation and contents are preserved across upgrades.\n/// \n/// :::note IC stable memory discrepancy\n/// \n/// The IC’s reported stable memory size (`ic0.stable_size`) may exceed what Motoko’s `size()` returns.\n/// This and the growth cap exist to protect Motoko’s internal use of stable variables.\n/// If you're not using stable variables (or using them sparingly), you may increase `--max-stable-pages` toward the IC maximum (currently 64GiB).\n/// Even if not using stable variables, always reserve at least one page.\n/// :::\n/// \n/// Usage:\n/// \n/// ```motoko no-repl\n/// import StableMemory \"mo:base/ExperimentalStableMemory\";\n/// ```\n\nimport Prim \"mo:⛔\";\n\nmodule {\n\n /// Current size of the stable memory, in pages.\n /// Each page is 64KiB (65536 bytes).\n /// Initially `0`.\n /// Preserved across upgrades, together with contents of allocated\n /// stable memory.\n /// \n /// Example:\n /// ```motoko no-repl\n /// let beforeSize = StableMemory.size();\n /// ignore StableMemory.grow(10);\n /// let afterSize = StableMemory.size();\n /// afterSize - beforeSize // => 10\n /// ```\n public let size : () -> (pages : Nat64) = Prim.stableMemorySize;\n\n /// Grow current `size` of stable memory by the given number of pages.\n /// Each page is 64KiB (65536 bytes).\n /// Returns the previous `size` when able to grow.\n /// Returns `0xFFFF_FFFF_FFFF_FFFF` if remaining pages insufficient.\n /// Every new page is zero-initialized, containing byte 0x00 at every offset.\n /// Function `grow` is capped by a soft limit on `size` controlled by compile-time flag\n /// `--max-stable-pages <n>` (the default is 65536, or 4GiB).\n /// \n /// Example:\n /// ```motoko no-repl\n /// import Error \"mo:base/Error\";\n /// \n /// let beforeSize = StableMemory.grow(10);\n /// if (beforeSize == 0xFFFF_FFFF_FFFF_FFFF) {\n /// throw Error.reject(\"Out of memory\");\n /// };\n /// let afterSize = StableMemory.size();\n /// afterSize - beforeSize // => 10\n /// ```\n public let grow : (newPages : Nat64) -> (oldPages : Nat64) = Prim.stableMemoryGrow;\n\n /// Returns a query that, when called, returns the number of bytes of (real) IC stable memory that would be\n /// occupied by persisting its current stable variables before an upgrade.\n /// This function may be used to monitor or limit real stable memory usage.\n /// The query computes the estimate by running the first half of an upgrade, including any `preupgrade` system method.\n /// Like any other query, its state changes are discarded so no actual upgrade (or other state change) takes place.\n /// The query can only be called by the enclosing actor and will trap for other callers.\n /// \n /// Example:\n /// ```motoko no-repl\n /// actor {\n /// stable var state = \"\";\n /// public func example() : async Text {\n /// let memoryUsage = StableMemory.stableVarQuery();\n /// let beforeSize = (await memoryUsage()).size;\n /// state #= \"abcdefghijklmnopqrstuvwxyz\";\n /// let afterSize = (await memoryUsage()).size;\n /// debug_show (afterSize - beforeSize)\n /// };\n /// };\n /// ```\n public let stableVarQuery : () -> (shared query () -> async { size : Nat64 }) = Prim.stableVarQuery;\n\n /// Loads a `Nat32` value from stable memory at the given `offset`.\n /// Traps on an out-of-bounds access.\n /// \n /// Example:\n /// ```motoko no-repl\n /// let offset = 0;\n /// let value = 123;\n /// StableMemory.storeNat32(offset, value);\n /// StableMemory.loadNat32(offset) // => 123\n /// ```\n public let loadNat32 : (offset : Nat64) -> Nat32 = Prim.stableMemoryLoadNat32;\n\n /// Stores a `Nat32` value in stable memory at the given `offset`.\n /// Traps on an out-of-bounds access.\n /// \n /// Example:\n /// ```motoko no-repl\n /// let offset = 0;\n /// let value = 123;\n /// StableMemory.storeNat32(offset, value);\n /// StableMemory.loadNat32(offset) // => 123\n /// ```\n public let storeNat32 : (offset : Nat64, value : Nat32) -> () = Prim.stableMemoryStoreNat32;\n\n /// Loads a `Nat8` value from stable memory at the given `offset`.\n /// Traps on an out-of-bounds access.\n /// \n /// Example:\n /// ```motoko no-repl\n /// let offset = 0;\n /// let value = 123;\n /// StableMemory.storeNat8(offset, value);\n /// StableMemory.loadNat8(offset) // => 123\n /// ```\n public let loadNat8 : (offset : Nat64) -> Nat8 = Prim.stableMemoryLoadNat8;\n\n /// Stores a `Nat8` value in stable memory at the given `offset`.\n /// Traps on an out-of-bounds access.\n /// \n /// Example:\n /// ```motoko no-repl\n /// let offset = 0;\n /// let value = 123;\n /// StableMemory.storeNat8(offset, value);\n /// StableMemory.loadNat8(offset) // => 123\n /// ```\n public let storeNat8 : (offset : Nat64, value : Nat8) -> () = Prim.stableMemoryStoreNat8;\n\n /// Loads a `Nat16` value from stable memory at the given `offset`.\n /// Traps on an out-of-bounds access.\n /// \n /// Example:\n /// ```motoko no-repl\n /// let offset = 0;\n /// let value = 123;\n /// StableMemory.storeNat16(offset, value);\n /// StableMemory.loadNat16(offset) // => 123\n /// ```\n public let loadNat16 : (offset : Nat64) -> Nat16 = Prim.stableMemoryLoadNat16;\n\n /// Stores a `Nat16` value in stable memory at the given `offset`.\n /// Traps on an out-of-bounds access.\n /// \n /// Example:\n /// ```motoko no-repl\n /// let offset = 0;\n /// let value = 123;\n /// StableMemory.storeNat16(offset, value);\n /// StableMemory.loadNat16(offset) // => 123\n /// ```\n public let storeNat16 : (offset : Nat64, value : Nat16) -> () = Prim.stableMemoryStoreNat16;\n\n /// Loads a `Nat64` value from stable memory at the given `offset`.\n /// Traps on an out-of-bounds access.\n /// \n /// Example:\n /// ```motoko no-repl\n /// let offset = 0;\n /// let value = 123;\n /// StableMemory.storeNat64(offset, value);\n /// StableMemory.loadNat64(offset) // => 123\n /// ```\n public let loadNat64 : (offset : Nat64) -> Nat64 = Prim.stableMemoryLoadNat64;\n\n /// Stores a `Nat64` value in stable memory at the given `offset`.\n /// Traps on an out-of-bounds access.\n /// \n /// Example:\n /// ```motoko no-repl\n /// let offset = 0;\n /// let value = 123;\n /// StableMemory.storeNat64(offset, value);\n /// StableMemory.loadNat64(offset) // => 123\n /// ```\n public let storeNat64 : (offset : Nat64, value : Nat64) -> () = Prim.stableMemoryStoreNat64;\n\n /// Loads an `Int32` value from stable memory at the given `offset`.\n /// Traps on an out-of-bounds access.\n /// \n /// Example:\n /// ```motoko no-repl\n /// let offset = 0;\n /// let value = 123;\n /// StableMemory.storeInt32(offset, value);\n /// StableMemory.loadInt32(offset) // => 123\n /// ```\n public let loadInt32 : (offset : Nat64) -> Int32 = Prim.stableMemoryLoadInt32;\n\n /// Stores an `Int32` value in stable memory at the given `offset`.\n /// Traps on an out-of-bounds access.\n /// \n /// Example:\n /// ```motoko no-repl\n /// let offset = 0;\n /// let value = 123;\n /// StableMemory.storeInt32(offset, value);\n /// StableMemory.loadInt32(offset) // => 123\n /// ```\n public let storeInt32 : (offset : Nat64, value : Int32) -> () = Prim.stableMemoryStoreInt32;\n\n /// Loads an `Int8` value from stable memory at the given `offset`.\n /// Traps on an out-of-bounds access.\n /// \n /// Example:\n /// ```motoko no-repl\n /// let offset = 0;\n /// let value = 123;\n /// StableMemory.storeInt8(offset, value);\n /// StableMemory.loadInt8(offset) // => 123\n /// ```\n public let loadInt8 : (offset : Nat64) -> Int8 = Prim.stableMemoryLoadInt8;\n\n /// Stores an `Int8` value in stable memory at the given `offset`.\n /// Traps on an out-of-bounds access.\n /// \n /// Example:\n /// ```motoko no-repl\n /// let offset = 0;\n /// let value = 123;\n /// StableMemory.storeInt8(offset, value);\n /// StableMemory.loadInt8(offset) // => 123\n /// ```\n public let storeInt8 : (offset : Nat64, value : Int8) -> () = Prim.stableMemoryStoreInt8;\n\n /// Loads an `Int16` value from stable memory at the given `offset`.\n /// Traps on an out-of-bounds access.\n /// \n /// Example:\n /// ```motoko no-repl\n /// let offset = 0;\n /// let value = 123;\n /// StableMemory.storeInt16(offset, value);\n /// StableMemory.loadInt16(offset) // => 123\n /// ```\n public let loadInt16 : (offset : Nat64) -> Int16 = Prim.stableMemoryLoadInt16;\n\n /// Stores an `Int16` value in stable memory at the given `offset`.\n /// Traps on an out-of-bounds access.\n /// \n /// Example:\n /// ```motoko no-repl\n /// let offset = 0;\n /// let value = 123;\n /// StableMemory.storeInt16(offset, value);\n /// StableMemory.loadInt16(offset) // => 123\n /// ```\n public let storeInt16 : (offset : Nat64, value : Int16) -> () = Prim.stableMemoryStoreInt16;\n\n /// Loads an `Int64` value from stable memory at the given `offset`.\n /// Traps on an out-of-bounds access.\n /// \n /// Example:\n /// ```motoko no-repl\n /// let offset = 0;\n /// let value = 123;\n /// StableMemory.storeInt64(offset, value);\n /// StableMemory.loadInt64(offset) // => 123\n /// ```\n public let loadInt64 : (offset : Nat64) -> Int64 = Prim.stableMemoryLoadInt64;\n\n /// Stores an `Int64` value in stable memory at the given `offset`.\n /// Traps on an out-of-bounds access.\n /// \n /// Example:\n /// ```motoko no-repl\n /// let offset = 0;\n /// let value = 123;\n /// StableMemory.storeInt64(offset, value);\n /// StableMemory.loadInt64(offset) // => 123\n /// ```\n public let storeInt64 : (offset : Nat64, value : Int64) -> () = Prim.stableMemoryStoreInt64;\n\n /// Loads a `Float` value from stable memory at the given `offset`.\n /// Traps on an out-of-bounds access.\n /// \n /// Example:\n /// ```motoko no-repl\n /// let offset = 0;\n /// let value = 1.25;\n /// StableMemory.storeFloat(offset, value);\n /// StableMemory.loadFloat(offset) // => 1.25\n /// ```\n public let loadFloat : (offset : Nat64) -> Float = Prim.stableMemoryLoadFloat;\n\n /// Stores a `Float` value in stable memory at the given `offset`.\n /// Traps on an out-of-bounds access.\n /// \n /// Example:\n /// ```motoko no-repl\n /// let offset = 0;\n /// let value = 1.25;\n /// StableMemory.storeFloat(offset, value);\n /// StableMemory.loadFloat(offset) // => 1.25\n /// ```\n public let storeFloat : (offset : Nat64, value : Float) -> () = Prim.stableMemoryStoreFloat;\n\n /// Load `size` bytes starting from `offset` as a `Blob`.\n /// Traps on an out-of-bounds access.\n /// \n /// Example:\n /// ```motoko no-repl\n /// import Blob \"mo:base/Blob\";\n /// \n /// let offset = 0;\n /// let value = Blob.fromArray([1, 2, 3]);\n /// let size = value.size();\n /// StableMemory.storeBlob(offset, value);\n /// Blob.toArray(StableMemory.loadBlob(offset, size)) // => [1, 2, 3]\n /// ```\n public let loadBlob : (offset : Nat64, size : Nat) -> Blob = Prim.stableMemoryLoadBlob;\n\n /// Write bytes of `blob` beginning at `offset`.\n /// Traps on an out-of-bounds access.\n /// \n /// Example:\n /// ```motoko no-repl\n /// import Blob \"mo:base/Blob\";\n /// \n /// let offset = 0;\n /// let value = Blob.fromArray([1, 2, 3]);\n /// let size = value.size();\n /// StableMemory.storeBlob(offset, value);\n /// Blob.toArray(StableMemory.loadBlob(offset, size)) // => [1, 2, 3]\n /// ```\n public let storeBlob : (offset : Nat64, value : Blob) -> () = Prim.stableMemoryStoreBlob;\n\n}\n"},"HashMap.mo":{"content":"/// Class `HashMap<K, V>` provides a hashmap from keys of type `K` to values of type `V`.\n/// The class is parameterized by the key's equality and hash functions, and an initial capacity.\n/// However, the underlying allocation occurs only upon the first insertion.\n/// \n/// Internally, the map is backed by an array of `AssocList` (buckets).\n/// The array doubles in size when the expected bucket list size grows beyond a fixed threshold.\n/// \n/// :::warning Performance considerations\n/// \n/// Certain operations, such as `put`, are amortized `O(1)` but can run in worst-case `O(size)` time.\n/// These worst cases may exceed the cycle limit per message on large maps.\n/// This analysis assumes that the hash function distributes keys uniformly.\n/// Use caution when growing large maps and ensure good hash functions are used.\n/// \n/// :::\n/// \n/// :::note Non-amortized alternative\n/// \n/// For maps without amortization, see `TrieMap`.\n/// :::\n/// \n/// :::info Constructor note\n/// \n/// The `initCapacity` argument sets the initial number of buckets.\n/// All runtime and space complexities assume that the equality and hash functions run in `O(1)` time and space.\n/// \n/// :::\n/// \n/// Example:\n/// \n/// ```motoko name=initialize\n/// import HashMap \"mo:base/HashMap\";\n/// import Text \"mo:base/Text\";\n/// \n/// let map = HashMap.HashMap<Text, Nat>(5, Text.equal, Text.hash);\n/// ```\n/// \n/// | Runtime | Space |\n/// |-----------|-----------|\n/// | `O(1)` | `O(1)` |\n\nimport Prim \"mo:⛔\";\nimport P \"Prelude\";\nimport A \"Array\";\nimport Hash \"Hash\";\nimport Iter \"Iter\";\nimport AssocList \"AssocList\";\nimport Nat32 \"Nat32\";\n\nmodule {\n\n // hash field avoids re-hashing the key when the array grows.\n type Key<K> = (Hash.Hash, K);\n\n // key-val list type\n type KVs<K, V> = AssocList.AssocList<Key<K>, V>;\n\n public class HashMap<K, V>(\n initCapacity : Nat,\n keyEq : (K, K) -> Bool,\n keyHash : K -> Hash.Hash\n ) {\n\n var table : [var KVs<K, V>] = [var];\n var _count : Nat = 0;\n\n /// Returns the current number of key-value entries in the map.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// map.size() // => 0\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(1)` | `O(1)` |\n public func size() : Nat = _count;\n\n /// Returns the value assocaited with key `key` if present and `null` otherwise.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// map.put(\"key\", 3);\n /// map.get(\"key\") // => ?3\n /// ```\n /// \n /// | Runtime(worst) | Runtime(amortized) | Space |\n /// |----------------------------|--------------------|---------------------------|\n /// | `O(size)` | `O(1)` | `O(1)` |\n /// \n public func get(key : K) : (value : ?V) {\n let h = Prim.nat32ToNat(keyHash(key));\n let m = table.size();\n if (m > 0) {\n AssocList.find<Key<K>, V>(table[h % m], keyHash_(key), keyHashEq)\n } else {\n null\n }\n };\n\n /// Insert the value `value` with key `key`. Overwrites any existing entry with key `key`.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// map.put(\"key\", 3);\n /// map.get(\"key\") // => ?3\n /// ```\n /// \n /// | Runtime(amortized) | Runtime(worst) | Space (amortized) | Space(worst)\n /// |----------------------------|--------------------|---------------------------|------------------|\n /// | `O(1)` | `O(size)` | `O(1)` | `O(size)` |\n /// :::note Initial allocation\n /// \n /// This operation triggers the allocation of the underlying array if it is the first entry in the map.\n /// :::\n public func put(key : K, value : V) = ignore replace(key, value);\n\n /// Insert the value `value` with key `key`. Returns the previous value\n /// associated with key `key` or `null` if no such value exists.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// map.put(\"key\", 3);\n /// ignore map.replace(\"key\", 2); // => ?3\n /// map.get(\"key\") // => ?2\n /// ```\n /// \n /// | Expected Amortized Runtime | Worst Case Runtime | Expected Amortized Space | Worst Case Space |\n /// |----------------------------|--------------------|---------------------------|------------------|\n /// | `O(1)` | `O(size)` | `O(1)` | `O(size)` |\n /// \n /// :::note Initial allocation\n /// \n /// This operation triggers the allocation of the underlying array if it is the first entry in the map.\n /// :::\n public func replace(key : K, value : V) : (oldValue : ?V) {\n if (_count >= table.size()) {\n let size = if (_count == 0) {\n if (initCapacity > 0) {\n initCapacity\n } else {\n 1\n }\n } else {\n table.size() * 2\n };\n let table2 = A.init<KVs<K, V>>(size, null);\n for (i in table.keys()) {\n var kvs = table[i];\n label moveKeyVals : () loop {\n switch kvs {\n case null { break moveKeyVals };\n case (?((k, v), kvsTail)) {\n let pos2 = Nat32.toNat(k.0) % table2.size(); // critical: uses saved hash. no re-hash.\n table2[pos2] := ?((k, v), table2[pos2]);\n kvs := kvsTail\n }\n }\n }\n };\n table := table2\n };\n let h = Prim.nat32ToNat(keyHash(key));\n let pos = h % table.size();\n let (kvs2, ov) = AssocList.replace<Key<K>, V>(table[pos], keyHash_(key), keyHashEq, ?value);\n table[pos] := kvs2;\n switch (ov) {\n case null { _count += 1 };\n case _ {}\n };\n ov\n };\n\n /// Deletes the entry with the key `key`. Has no effect if `key` is not\n /// present in the map.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// map.put(\"key\", 3);\n /// map.delete(\"key\");\n /// map.get(\"key\"); // => null\n /// ```\n /// \n /// | Expected Runtime | Worst Case Runtime | Expected Space | Worst Case Space |\n /// |------------------|--------------------|----------------|------------------|\n /// | `O(1)` | `O(size)` | `O(1)` | `O(size)` |\n /// \n public func delete(key : K) = ignore remove(key);\n\n func keyHash_(k : K) : Key<K> = (keyHash(k), k);\n\n func keyHashEq(k1 : Key<K>, k2 : Key<K>) : Bool {\n k1.0 == k2.0 and keyEq(k1.1, k2.1)\n };\n\n /// Deletes the entry with the key `key`. Returns the previous value\n /// associated with key `key` or `null` if no such value exists.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// map.put(\"key\", 3);\n /// map.remove(\"key\"); // => ?3\n /// ```\n /// \n /// | Expected Runtime | Worst Case Runtime | Expected Space | Worst Case Space |\n /// |------------------|--------------------|----------------|------------------|\n /// | `O(1)` | `O(size)` | `O(1)` | `O(size)` |\n public func remove(key : K) : (oldValue : ?V) {\n let m = table.size();\n if (m > 0) {\n let h = Prim.nat32ToNat(keyHash(key));\n let pos = h % m;\n let (kvs2, ov) = AssocList.replace<Key<K>, V>(table[pos], keyHash_(key), keyHashEq, null);\n table[pos] := kvs2;\n switch (ov) {\n case null {};\n case _ { _count -= 1 }\n };\n ov\n } else {\n null\n }\n };\n\n /// Returns an Iterator (`Iter`) over the keys of the map.\n /// Iterator provides a single method `next()`, which returns\n /// keys in no specific order, or `null` when out of keys to iterate over.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// \n /// map.put(\"key1\", 1);\n /// map.put(\"key2\", 2);\n /// map.put(\"key3\", 3);\n /// \n /// var keys = \"\";\n /// for (key in map.keys()) {\n /// keys := key # \" \" # keys\n /// };\n /// keys // => \"key3 key2 key1 \"\n /// ```\n /// \n /// Cost of iteration over all keys:\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size)` | `O(1)` |\n public func keys() : Iter.Iter<K> {\n Iter.map(entries(), func(kv : (K, V)) : K { kv.0 })\n };\n\n /// Returns an Iterator (`Iter`) over the values of the map.\n /// Iterator provides a single method `next()`, which returns\n /// values in no specific order, or `null` when out of values to iterate over.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// \n /// map.put(\"key1\", 1);\n /// map.put(\"key2\", 2);\n /// map.put(\"key3\", 3);\n /// \n /// var sum = 0;\n /// for (value in map.vals()) {\n /// sum += value;\n /// };\n /// sum // => 6\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size)` | `O(1)` |\n public func vals() : Iter.Iter<V> {\n Iter.map(entries(), func(kv : (K, V)) : V { kv.1 })\n };\n\n /// Returns an Iterator (`Iter`) over the key-value pairs in the map.\n /// Iterator provides a single method `next()`, which returns\n /// pairs in no specific order, or `null` when out of pairs to iterate over.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n /// \n /// map.put(\"key1\", 1);\n /// map.put(\"key2\", 2);\n /// map.put(\"key3\", 3);\n /// \n /// var pairs = \"\";\n /// for ((key, value) in map.entries()) {\n /// pairs := \"(\" # key # \", \" # Nat.toText(value) # \") \" # pairs\n /// };\n /// pairs // => \"(key3, 3) (key2, 2) (key1, 1)\"\n /// ```\n /// \n /// Cost of iteration over all pairs:\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size)` | `O(1)` |\n public func entries() : Iter.Iter<(K, V)> {\n if (table.size() == 0) {\n object { public func next() : ?(K, V) { null } }\n } else {\n object {\n var kvs = table[0];\n var nextTablePos = 1;\n public func next() : ?(K, V) {\n switch kvs {\n case (?(kv, kvs2)) {\n kvs := kvs2;\n ?(kv.0.1, kv.1)\n };\n case null {\n if (nextTablePos < table.size()) {\n kvs := table[nextTablePos];\n nextTablePos += 1;\n next()\n } else {\n null\n }\n }\n }\n }\n }\n }\n };\n\n };\n\n /// Returns a copy of `map`, initializing the copy with the provided equality\n /// and hash functions.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// map.put(\"key1\", 1);\n /// map.put(\"key2\", 2);\n /// map.put(\"key3\", 3);\n /// \n /// let map2 = HashMap.clone(map, Text.equal, Text.hash);\n /// map2.get(\"key1\") // => ?1\n /// ```\n /// \n /// | Runtime(expected) | Runtime(worst) | Space(expected) | Space(worst) |\n /// |------------------|--------------------|----------------|------------------|\n /// | `O(size)` | `O(size * size)` | `O(size)` | `O(size)` |\n public func clone<K, V>(\n map : HashMap<K, V>,\n keyEq : (K, K) -> Bool,\n keyHash : K -> Hash.Hash\n ) : HashMap<K, V> {\n let h2 = HashMap<K, V>(map.size(), keyEq, keyHash);\n for ((k, v) in map.entries()) {\n h2.put(k, v)\n };\n h2\n };\n\n /// Returns a new map, containing all entries given by the iterator `iter`.\n /// The new map is initialized with the provided initial capacity, equality,\n /// and hash functions.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// let entries = [(\"key3\", 3), (\"key2\", 2), (\"key1\", 1)];\n /// let iter = entries.vals();\n /// \n /// let map2 = HashMap.fromIter<Text, Nat>(iter, entries.size(), Text.equal, Text.hash);\n /// map2.get(\"key1\") // => ?1\n /// ```\n /// \n /// | Runtime(expected) | Runtime(worst) | Space(expected) | Space(worst) |\n /// |------------------|--------------------|----------------|------------------|\n /// | `O(size)` | `O(size * size)` | `O(size)` | `O(size)` |\n public func fromIter<K, V>(\n iter : Iter.Iter<(K, V)>,\n initCapacity : Nat,\n keyEq : (K, K) -> Bool,\n keyHash : K -> Hash.Hash\n ) : HashMap<K, V> {\n let h = HashMap<K, V>(initCapacity, keyEq, keyHash);\n for ((k, v) in iter) {\n h.put(k, v)\n };\n h\n };\n\n /// Creates a new map by applying `f` to each entry in `hashMap`. Each entry\n /// `(k, v)` in the old map is transformed into a new entry `(k, v2)`, where\n /// the new value `v2` is created by applying `f` to `(k, v)`.\n /// \n /// ```motoko include=initialize\n /// map.put(\"key1\", 1);\n /// map.put(\"key2\", 2);\n /// map.put(\"key3\", 3);\n /// \n /// let map2 = HashMap.map<Text, Nat, Nat>(map, Text.equal, Text.hash, func (k, v) = v * 2);\n /// map2.get(\"key2\") // => ?4\n /// ```\n /// \n /// Expected Runtime: O(size), Worst Case Runtime: O(size * size)\n /// \n /// | Runtime(expected) | Runtime(worst) | Space(expected) | Space(worst) |\n /// |------------------|--------------------|----------------|------------------|\n /// | `O(size)` | `O(size * size)` | `O(size)` | `O(size)` |\n public func map<K, V1, V2>(\n hashMap : HashMap<K, V1>,\n keyEq : (K, K) -> Bool,\n keyHash : K -> Hash.Hash,\n f : (K, V1) -> V2\n ) : HashMap<K, V2> {\n let h2 = HashMap<K, V2>(hashMap.size(), keyEq, keyHash);\n for ((k, v1) in hashMap.entries()) {\n let v2 = f(k, v1);\n h2.put(k, v2)\n };\n h2\n };\n\n /// Creates a new map by applying `f` to each entry in `hashMap`. For each entry\n /// `(k, v)` in the old map, if `f` evaluates to `null`, the entry is discarded.\n /// Otherwise, the entry is transformed into a new entry `(k, v2)`, where\n /// the new value `v2` is the result of applying `f` to `(k, v)`.\n /// \n /// ```motoko include=initialize\n /// map.put(\"key1\", 1);\n /// map.put(\"key2\", 2);\n /// map.put(\"key3\", 3);\n /// \n /// let map2 =\n /// HashMap.mapFilter<Text, Nat, Nat>(\n /// map,\n /// Text.equal,\n /// Text.hash,\n /// func (k, v) = if (v == 2) { null } else { ?(v * 2)}\n /// );\n /// map2.get(\"key3\") // => ?6\n /// ```\n /// \n /// | Runtime(expected) | Runtime(worst) | Space(expected) | Space(worst) |\n /// |------------------|--------------------|----------------|------------------|\n /// | `O(size)` | `O(size * size)` | `O(size)` | `O(size)` |\n public func mapFilter<K, V1, V2>(\n hashMap : HashMap<K, V1>,\n keyEq : (K, K) -> Bool,\n keyHash : K -> Hash.Hash,\n f : (K, V1) -> ?V2\n ) : HashMap<K, V2> {\n let h2 = HashMap<K, V2>(hashMap.size(), keyEq, keyHash);\n for ((k, v1) in hashMap.entries()) {\n switch (f(k, v1)) {\n case null {};\n case (?v2) {\n h2.put(k, v2)\n }\n }\n };\n h2\n };\n\n}\n"},"Nat8.mo":{"content":"/// Provides utility functions on 8-bit unsigned integers.\n/// \n/// :::note\n/// Most operations on integer numbers (e.g. addition) are available as built-in operators (e.g. `1 + 1`).\n/// This module provides equivalent functions and `Text` conversion.\n/// :::\n/// \n/// :::info Function form for higher-order use\n/// \n/// Several arithmetic and comparison functions (e.g. `add`, `sub`, `equal`, `less`, `pow`) are defined in this module to enable their use as first-class function values, which is not possible with operators like `+`, `-`, `==`, etc., in Motoko. This allows you to pass these operations to higher-order functions such as `map`, `foldLeft`, or `sort`.\n/// :::\n/// \n/// Import from the base library to use this module.\n/// \n/// ```motoko name=import\n/// import Nat8 \"mo:base/Nat8\";\n/// ```\nimport Nat \"Nat\";\nimport Prim \"mo:⛔\";\n\nmodule {\n\n /// 8-bit natural numbers.\n public type Nat8 = Prim.Types.Nat8;\n\n /// Maximum 8-bit natural number. `2 ** 8 - 1`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat8.maximumValue; // => 255 : Nat8\n /// ```\n public let maximumValue = 255 : Nat8;\n\n /// Converts an 8-bit unsigned integer to an unsigned integer with infinite precision.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat8.toNat(123); // => 123 : Nat\n /// ```\n public let toNat : Nat8 -> Nat = Prim.nat8ToNat;\n\n /// Converts an unsigned integer with infinite precision to an 8-bit unsigned integer.\n /// \n /// Traps on overflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat8.fromNat(123); // => 123 : Nat8\n /// ```\n public let fromNat : Nat -> Nat8 = Prim.natToNat8;\n\n /// Converts a 16-bit unsigned integer to a 8-bit unsigned integer.\n /// \n /// Traps on overflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat8.fromNat16(123); // => 123 : Nat8\n /// ```\n public let fromNat16 : Nat16 -> Nat8 = Prim.nat16ToNat8;\n\n /// Converts an 8-bit unsigned integer to a 16-bit unsigned integer.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat8.toNat16(123); // => 123 : Nat16\n /// ```\n public let toNat16 : Nat8 -> Nat16 = Prim.nat8ToNat16;\n\n /// Converts a signed integer with infinite precision to an 8-bit unsigned integer.\n /// \n /// Wraps on overflow/underflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat8.fromIntWrap(123); // => 123 : Nat8\n /// ```\n public let fromIntWrap : Int -> Nat8 = Prim.intToNat8Wrap;\n\n /// Converts `x` to its textual representation.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat8.toText(123); // => \"123\" : Text\n /// ```\n public func toText(x : Nat8) : Text {\n Nat.toText(toNat(x))\n };\n\n /// Returns the minimum of `x` and `y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat8.min(123, 200); // => 123 : Nat8\n /// ```\n public func min(x : Nat8, y : Nat8) : Nat8 {\n if (x < y) { x } else { y }\n };\n\n /// Returns the maximum of `x` and `y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat8.max(123, 200); // => 200 : Nat8\n /// ```\n public func max(x : Nat8, y : Nat8) : Nat8 {\n if (x < y) { y } else { x }\n };\n\n /// Equality function for Nat8 types.\n /// This is equivalent to `x == y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat8.equal(1, 1); // => true\n /// (1 : Nat8) == (1 : Nat8) // => true\n /// ```\n /// \n\n /// \n /// Example:\n /// ```motoko include=import\n /// import Buffer \"mo:base/Buffer\";\n /// \n /// let buffer1 = Buffer.Buffer<Nat8>(3);\n /// let buffer2 = Buffer.Buffer<Nat8>(3);\n /// Buffer.equal(buffer1, buffer2, Nat8.equal) // => true\n /// ```\n public func equal(x : Nat8, y : Nat8) : Bool { x == y };\n\n /// Inequality function for Nat8 types.\n /// This is equivalent to `x != y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat8.notEqual(1, 2); // => true\n /// (1 : Nat8) != (2 : Nat8) // => true\n /// ```\n /// \n\n public func notEqual(x : Nat8, y : Nat8) : Bool { x != y };\n\n /// \"Less than\" function for Nat8 types.\n /// This is equivalent to `x < y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat8.less(1, 2); // => true\n /// (1 : Nat8) < (2 : Nat8) // => true\n /// ```\n /// \n\n public func less(x : Nat8, y : Nat8) : Bool { x < y };\n\n /// \"Less than or equal\" function for Nat8 types.\n /// This is equivalent to `x <= y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat.lessOrEqual(1, 2); // => true\n /// 1 <= 2 // => true\n /// ```\n /// \n\n public func lessOrEqual(x : Nat8, y : Nat8) : Bool { x <= y };\n\n /// \"Greater than\" function for Nat8 types.\n /// This is equivalent to `x > y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat8.greater(2, 1); // => true\n /// (2 : Nat8) > (1 : Nat8) // => true\n /// ```\n /// \n\n public func greater(x : Nat8, y : Nat8) : Bool { x > y };\n\n /// \"Greater than or equal\" function for Nat8 types.\n /// This is equivalent to `x >= y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat8.greaterOrEqual(2, 1); // => true\n /// (2 : Nat8) >= (1 : Nat8) // => true\n /// ```\n /// \n\n public func greaterOrEqual(x : Nat8, y : Nat8) : Bool { x >= y };\n\n /// General purpose comparison function for `Nat8`. Returns the `Order` (\n /// either `#less`, `#equal`, or `#greater`) of comparing `x` with `y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat8.compare(2, 3) // => #less\n /// ```\n /// \n /// This function can be used as value for a high order function, such as a sort function.\n /// \n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.sort([2, 3, 1] : [Nat8], Nat8.compare) // => [1, 2, 3]\n /// ```\n public func compare(x : Nat8, y : Nat8) : { #less; #equal; #greater } {\n if (x < y) { #less } else if (x == y) { #equal } else { #greater }\n };\n\n /// Returns the sum of `x` and `y`, `x + y`.\n /// Traps on overflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat8.add(1, 2); // => 3\n /// (1 : Nat8) + (2 : Nat8) // => 3\n /// ```\n /// \n\n /// \n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.foldLeft<Nat8, Nat8>([2, 3, 1], 0, Nat8.add) // => 6\n /// ```\n public func add(x : Nat8, y : Nat8) : Nat8 { x + y };\n\n /// Returns the difference of `x` and `y`, `x - y`.\n /// Traps on underflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat8.sub(2, 1); // => 1\n /// (2 : Nat8) - (1 : Nat8) // => 1\n /// ```\n /// \n\n /// \n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.foldLeft<Nat8, Nat8>([2, 3, 1], 20, Nat8.sub) // => 14\n /// ```\n public func sub(x : Nat8, y : Nat8) : Nat8 { x - y };\n\n /// Returns the product of `x` and `y`, `x * y`.\n /// Traps on overflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat8.mul(2, 3); // => 6\n /// (2 : Nat8) * (3 : Nat8) // => 6\n /// ```\n /// \n\n /// \n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.foldLeft<Nat8, Nat8>([2, 3, 1], 1, Nat8.mul) // => 6\n /// ```\n public func mul(x : Nat8, y : Nat8) : Nat8 { x * y };\n\n /// Returns the quotient of `x` divided by `y`, `x / y`.\n /// Traps when `y` is zero.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat8.div(6, 2); // => 3\n /// (6 : Nat8) / (2 : Nat8) // => 3\n /// ```\n /// \n\n public func div(x : Nat8, y : Nat8) : Nat8 { x / y };\n\n /// Returns the remainder of `x` divided by `y`, `x % y`.\n /// Traps when `y` is zero.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat8.rem(6, 4); // => 2\n /// (6 : Nat8) % (4 : Nat8) // => 2\n /// ```\n /// \n\n public func rem(x : Nat8, y : Nat8) : Nat8 { x % y };\n\n /// Returns `x` to the power of `y`, `x ** y`.\n /// Traps on overflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat8.pow(2, 3); // => 8\n /// (2 : Nat8) ** (3 : Nat8) // => 8\n /// ```\n /// \n\n public func pow(x : Nat8, y : Nat8) : Nat8 { x ** y };\n\n /// Returns the bitwise negation of `x`, `^x`.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat8.bitnot(0); // => 255\n /// ^(0 : Nat8) // => 255\n /// ```\n /// \n\n public func bitnot(x : Nat8) : Nat8 { ^x };\n\n /// Returns the bitwise and of `x` and `y`, `x & y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat8.bitand(3, 2); // => 2\n /// (3 : Nat8) & (2 : Nat8) // => 2\n /// ```\n /// \n\n public func bitand(x : Nat8, y : Nat8) : Nat8 { x & y };\n\n /// Returns the bitwise or of `x` and `y`, `x | y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat8.bitor(3, 2); // => 3\n /// (3 : Nat8) | (2 : Nat8) // => 3\n /// ```\n /// \n\n public func bitor(x : Nat8, y : Nat8) : Nat8 { x | y };\n\n /// Returns the bitwise exclusive or of `x` and `y`, `x ^ y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat8.bitxor(3, 2); // => 1\n /// (3 : Nat8) ^ (2 : Nat8) // => 1\n /// ```\n /// \n\n public func bitxor(x : Nat8, y : Nat8) : Nat8 { x ^ y };\n\n /// Returns the bitwise shift left of `x` by `y`, `x << y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat8.bitshiftLeft(1, 2); // => 4\n /// (1 : Nat8) << (2 : Nat8) // => 4\n /// ```\n /// \n\n public func bitshiftLeft(x : Nat8, y : Nat8) : Nat8 { x << y };\n\n /// Returns the bitwise shift right of `x` by `y`, `x >> y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat8.bitshiftRight(4, 2); // => 1\n /// (4 : Nat8) >> (2 : Nat8) // => 1\n /// ```\n /// \n\n public func bitshiftRight(x : Nat8, y : Nat8) : Nat8 { x >> y };\n\n /// Returns the bitwise rotate left of `x` by `y`, `x <<> y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat8.bitrotLeft(128, 1); // => 1\n /// (128 : Nat8) <<> (1 : Nat8) // => 1\n /// ```\n /// \n\n public func bitrotLeft(x : Nat8, y : Nat8) : Nat8 { x <<> y };\n\n /// Returns the bitwise rotate right of `x` by `y`, `x <>> y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat8.bitrotRight(1, 1); // => 128\n /// (1 : Nat8) <>> (1 : Nat8) // => 128\n /// ```\n /// \n\n public func bitrotRight(x : Nat8, y : Nat8) : Nat8 { x <>> y };\n\n /// Returns the value of bit `p mod 8` in `x`, `(x & 2^(p mod 8)) == 2^(p mod 8)`.\n /// This is equivalent to checking if the `p`-th bit is set in `x`, using 0 indexing.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat8.bittest(5, 2); // => true\n /// ```\n public func bittest(x : Nat8, p : Nat) : Bool {\n Prim.btstNat8(x, Prim.natToNat8(p))\n };\n\n /// Returns the value of setting bit `p mod 8` in `x` to `1`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat8.bitset(5, 1); // => 7\n /// ```\n public func bitset(x : Nat8, p : Nat) : Nat8 {\n x | (1 << Prim.natToNat8(p))\n };\n\n /// Returns the value of clearing bit `p mod 8` in `x` to `0`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat8.bitclear(5, 2); // => 1\n /// ```\n public func bitclear(x : Nat8, p : Nat) : Nat8 {\n x & ^(1 << Prim.natToNat8(p))\n };\n\n /// Returns the value of flipping bit `p mod 8` in `x`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat8.bitflip(5, 2); // => 1\n /// ```\n public func bitflip(x : Nat8, p : Nat) : Nat8 {\n x ^ (1 << Prim.natToNat8(p))\n };\n\n /// Returns the count of non-zero bits in `x`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat8.bitcountNonZero(5); // => 2\n /// ```\n public let bitcountNonZero : (x : Nat8) -> Nat8 = Prim.popcntNat8;\n\n /// Returns the count of leading zero bits in `x`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat8.bitcountLeadingZero(5); // => 5\n /// ```\n public let bitcountLeadingZero : (x : Nat8) -> Nat8 = Prim.clzNat8;\n\n /// Returns the count of trailing zero bits in `x`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat8.bitcountTrailingZero(6); // => 1\n /// ```\n public let bitcountTrailingZero : (x : Nat8) -> Nat8 = Prim.ctzNat8;\n\n /// Returns the sum of `x` and `y`, `x +% y`. Wraps on overflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat8.addWrap(230, 26); // => 0\n /// (230 : Nat8) +% (26 : Nat8) // => 0\n /// ```\n /// \n\n public func addWrap(x : Nat8, y : Nat8) : Nat8 { x +% y };\n\n /// Returns the difference of `x` and `y`, `x -% y`. Wraps on underflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat8.subWrap(0, 1); // => 255\n /// (0 : Nat8) -% (1 : Nat8) // => 255\n /// ```\n\n public func subWrap(x : Nat8, y : Nat8) : Nat8 { x -% y };\n\n /// Returns the product of `x` and `y`, `x *% y`. Wraps on overflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat8.mulWrap(230, 26); // => 92\n /// (230 : Nat8) *% (26 : Nat8) // => 92\n /// ```\n /// \n\n public func mulWrap(x : Nat8, y : Nat8) : Nat8 { x *% y };\n\n /// Returns `x` to the power of `y`, `x **% y`. Wraps on overflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat8.powWrap(2, 8); // => 0\n /// (2 : Nat8) **% (8 : Nat8) // => 0\n /// ```\n /// \n\n public func powWrap(x : Nat8, y : Nat8) : Nat8 { x **% y };\n\n}\n"},"TrieSet.mo":{"content":"/// \n/// Sets are partial maps from element type to unit type,\n/// i.e., the partial map represents the set with its domain.\n/// \n/// :::warning Limitations\n/// \n/// This data structure allows at most `MAX_LEAF_SIZE = 8` hash collisions.\n/// Attempts to insert more than 8 elements with the same hash value—either directly via `put` or indirectly via other operations—will trap.\n/// This limitation is inherited from the underlying `Trie` data structure.\n/// :::\n/// \n\n// TODO-Matthew:\n// ---------------\n//\n// - for now, we pass a hash value each time we pass an element value;\n// in the future, we might avoid passing element hashes with each element in the API;\n// related to: https://dfinity.atlassian.net/browse/AST-32\n//\n// - similarly, we pass an equality function when we do some operations.\n// in the future, we might avoid this via https://dfinity.atlassian.net/browse/AST-32\nimport Trie \"Trie\";\nimport Hash \"Hash\";\nimport List \"List\";\nimport Iter \"Iter\";\n\nmodule {\n\n public type Hash = Hash.Hash;\n public type Set<T> = Trie.Trie<T, ()>;\n type Key<K> = Trie.Key<K>;\n type Trie<K, V> = Trie.Trie<K, V>;\n\n // helper for defining equal and sub, avoiding Trie.diff.\n // TODO: add to Trie.mo?\n private func keys<K>(t : Trie<K, Any>) : Iter.Iter<Key<K>> {\n object {\n var stack = ?(t, null) : List.List<Trie<K, Any>>;\n public func next() : ?Key<K> {\n switch stack {\n case null { null };\n case (?(trie, stack2)) {\n switch trie {\n case (#empty) {\n stack := stack2;\n next()\n };\n case (#leaf({ keyvals = null })) {\n stack := stack2;\n next()\n };\n case (#leaf({ size = c; keyvals = ?((k, _v), kvs) })) {\n stack := ?(#leaf({ size = c - 1; keyvals = kvs }), stack2);\n ?k\n };\n case (#branch(br)) {\n stack := ?(br.left, ?(br.right, stack2));\n next()\n }\n }\n }\n }\n }\n }\n };\n\n /// Empty set.\n public func empty<T>() : Set<T> { Trie.empty<T, ()>() };\n\n /// Put an element into the set.\n public func put<T>(s : Set<T>, x : T, xh : Hash, eq : (T, T) -> Bool) : Set<T> {\n let (s2, _) = Trie.put<T, ()>(s, { key = x; hash = xh }, eq, ());\n s2\n };\n\n /// Delete an element from the set.\n public func delete<T>(s : Set<T>, x : T, xh : Hash, eq : (T, T) -> Bool) : Set<T> {\n let (s2, _) = Trie.remove<T, ()>(s, { key = x; hash = xh }, eq);\n s2\n };\n\n /// Test if two sets are equal.\n public func equal<T>(s1 : Set<T>, s2 : Set<T>, eq : (T, T) -> Bool) : Bool {\n if (Trie.size(s1) != Trie.size(s2)) return false;\n for (k in keys(s1)) {\n if (Trie.find<T, ()>(s2, k, eq) == null) {\n return false\n }\n };\n return true\n };\n\n /// The number of set elements, set's cardinality.\n public func size<T>(s : Set<T>) : Nat {\n Trie.size(s)\n };\n\n /// Test if `s` is the empty set.\n public func isEmpty<T>(s : Set<T>) : Bool {\n Trie.size(s) == 0\n };\n\n /// Test if `s1` is a subset of `s2`.\n public func isSubset<T>(s1 : Set<T>, s2 : Set<T>, eq : (T, T) -> Bool) : Bool {\n if (Trie.size(s1) > Trie.size(s2)) return false;\n for (k in keys(s1)) {\n if (Trie.find<T, ()>(s2, k, eq) == null) {\n return false\n }\n };\n return true\n };\n\n /// :::warning Deprecated function\n /// Use `TrieSet.contains()` instead.\n /// :::\n /// \n /// Test if a set contains a given element.\n public func mem<T>(s : Set<T>, x : T, xh : Hash, eq : (T, T) -> Bool) : Bool {\n contains(s, x, xh, eq)\n };\n\n /// Test if a set contains a given element.\n public func contains<T>(s : Set<T>, x : T, xh : Hash, eq : (T, T) -> Bool) : Bool {\n switch (Trie.find<T, ()>(s, { key = x; hash = xh }, eq)) {\n case null { false };\n case (?_) { true }\n }\n };\n\n /// [Set union](https://en.wikipedia.org/wiki/Union_(set_theory)).\n public func union<T>(s1 : Set<T>, s2 : Set<T>, eq : (T, T) -> Bool) : Set<T> {\n let s3 = Trie.merge<T, ()>(s1, s2, eq);\n s3\n };\n\n /// [Set difference](https://en.wikipedia.org/wiki/Difference_(set_theory)).\n public func diff<T>(s1 : Set<T>, s2 : Set<T>, eq : (T, T) -> Bool) : Set<T> {\n let s3 = Trie.diff<T, (), ()>(s1, s2, eq);\n s3\n };\n\n /// [Set intersection](https://en.wikipedia.org/wiki/Intersection_(set_theory)).\n public func intersect<T>(s1 : Set<T>, s2 : Set<T>, eq : (T, T) -> Bool) : Set<T> {\n let noop : ((), ()) -> (()) = func(_ : (), _ : ()) : (()) = ();\n let s3 = Trie.join<T, (), (), ()>(s1, s2, eq, noop);\n s3\n };\n\n /// Construct a set from an array.\n public func fromArray<T>(arr : [T], elemHash : T -> Hash, eq : (T, T) -> Bool) : Set<T> {\n var s = empty<T>();\n for (elem in arr.vals()) {\n s := put<T>(s, elem, elemHash(elem), eq)\n };\n s\n };\n\n /// Returns the set as an array.\n public func toArray<T>(s : Set<T>) : [T] {\n Trie.toArray(s, func(t : T, _ : ()) : T { t })\n }\n\n}\n"},"OrderedMap.mo":{"content":"/// Stable key-value map implemented as a red-black tree with nodes storing key-value pairs.\n/// \n/// A red-black tree is a balanced binary search tree ordered by the keys.\n/// \n/// The tree data structure internally colors each of its nodes either red or black,\n/// and uses this information to balance the tree during the modifying operations.\n/// \n/// | Runtime | Space |\n/// |----------|------------|\n/// | `O(log(n))` (worst case per insertion, removal, or retrieval) | `O(n)` (for storing the entire tree) |\n/// \n/// `n` denotes the number of key-value entries (i.e. nodes) stored in the tree.\n/// \n/// :::note Garbage collection\n/// \n/// Unless stated otherwise, operations that iterate over or modify the map (such as insertion, deletion, traversal, and transformation) may create temporary objects with worst-case space usage of `O(log(n))` or `O(n)`. These objects are short-lived and will be collected by the garbage collector automatically.\n/// \n/// :::\n/// \n/// :::note Assumptions\n/// \n/// Runtime and space complexity assumes that `compare`, `equal`, and other functions execute in `O(1)` time and space.\n/// :::\n/// \n/// :::info Credits\n/// \n/// The core of this implementation is derived from:\n/// \n/// * Ken Friis Larsen's [RedBlackMap.sml](https://github.com/kfl/mosml/blob/master/src/mosmllib/Redblackmap.sml), which itself is based on:\n/// * Stefan Kahrs, \"Red-black trees with types\", Journal of Functional Programming, 11(4): 425-432 (2001), [version 1 in web appendix](http://www.cs.ukc.ac.uk/people/staff/smk/redblack/rb.html).\n/// :::\n/// \n\nimport Debug \"Debug\";\nimport I \"Iter\";\nimport List \"List\";\nimport Nat \"Nat\";\nimport O \"Order\";\n\nmodule {\n /// Collection of key-value entries, ordered by the keys and key unique.\n /// The keys have the generic type `K` and the values the generic type `V`.\n /// If `K` and `V` is stable types then `Map<K, V>` is also stable.\n /// To ensure that property the `Map<K, V>` does not have any methods, instead\n /// they are gathered in the functor-like class `Operations` (see example there).\n public type Map<K, V> = {\n size : Nat;\n root : Tree<K, V>\n };\n\n // Note: Leaves are considered implicitly black.\n type Tree<K, V> = {\n #red : (Tree<K, V>, K, V, Tree<K, V>);\n #black : (Tree<K, V>, K, V, Tree<K, V>);\n #leaf\n };\n\n /// Class that captures key type `K` along with its ordering function `compare`\n /// and provides all operations to work with a map of type `Map<K, _>`.\n /// \n /// An instance object should be created once as a canister field to ensure\n /// that the same ordering function is used for every operation.\n /// \n /// Example:\n /// ```motoko\n /// import Map \"mo:base/OrderedMap\";\n /// import Nat \"mo:base/Nat\";\n /// \n /// actor {\n /// let natMap = Map.Make<Nat>(Nat.compare); // : Operations<Nat>\n /// stable var keyStorage : Map.Map<Nat, Text> = natMap.empty<Text>();\n /// \n /// public func addKey(id : Nat, key : Text) : async () {\n /// keyStorage := natMap.put(keyStorage, id, key);\n /// }\n /// }\n /// ```\n public class Operations<K>(compare : (K, K) -> O.Order) {\n\n /// Returns a new map, containing all entries given by the iterator `i`.\n /// If there are multiple entries with the same key the last one is taken.\n /// \n /// Example:\n /// ```motoko\n /// import Map \"mo:base/OrderedMap\";\n /// import Nat \"mo:base/Nat\";\n /// import Iter \"mo:base/Iter\";\n /// import Debug \"mo:base/Debug\";\n /// \n /// let natMap = Map.Make<Nat>(Nat.compare);\n /// let m = natMap.fromIter<Text>(Iter.fromArray([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")]));\n /// \n /// Debug.print(debug_show(Iter.toArray(natMap.entries(m))));\n /// \n /// // [(0, \"Zero\"), (1, \"One\"), (2, \"Two\")]\n /// ```\n /// \n /// | Runtime | Space |\n /// |----------|------------|\n /// | `O(n * log(n))` | `O(n)` (retained memory + garbage) |\n /// \n /// Note: Creates `O(n * log(n))` temporary objects that will be collected as garbage.\n public func fromIter<V>(i : I.Iter<(K, V)>) : Map<K, V> = Internal.fromIter(i, compare);\n\n /// Insert the value `value` with key `key` into the map `m`. Overwrites any existing entry with key `key`.\n /// Returns a modified map.\n /// \n /// Example:\n /// ```motoko\n /// import Map \"mo:base/OrderedMap\";\n /// import Nat \"mo:base/Nat\";\n /// import Iter \"mo:base/Iter\";\n /// import Debug \"mo:base/Debug\";\n /// \n /// let natMap = Map.Make<Nat>(Nat.compare);\n /// var map = natMap.empty<Text>();\n /// \n /// map := natMap.put(map, 0, \"Zero\");\n /// map := natMap.put(map, 2, \"Two\");\n /// map := natMap.put(map, 1, \"One\");\n /// \n /// Debug.print(debug_show(Iter.toArray(natMap.entries(map))));\n /// \n /// // [(0, \"Zero\"), (1, \"One\"), (2, \"Two\")]\n /// ```\n /// \n /// | Runtime | Space |\n /// |-------------|---------------|\n /// | `O(log(n))` | `O(log(n))` |\n public func put<V>(m : Map<K, V>, key : K, value : V) : Map<K, V> = replace(m, key, value).0;\n\n /// Insert the value `value` with key `key` into the map `m`. Returns modified map and\n /// the previous value associated with key `key` or `null` if no such value exists.\n /// \n /// Example:\n /// ```motoko\n /// import Map \"mo:base/OrderedMap\";\n /// import Nat \"mo:base/Nat\";\n /// import Iter \"mo:base/Iter\";\n /// import Debug \"mo:base/Debug\";\n /// \n /// let natMap = Map.Make<Nat>(Nat.compare);\n /// let map0 = natMap.fromIter<Text>(Iter.fromArray([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")]));\n /// \n /// let (map1, old1) = natMap.replace(map0, 0, \"Nil\");\n /// \n /// Debug.print(debug_show(Iter.toArray(natMap.entries(map1))));\n /// Debug.print(debug_show(old1));\n /// // [(0, \"Nil\"), (1, \"One\"), (2, \"Two\")]\n /// // ?\"Zero\"\n /// \n /// let (map2, old2) = natMap.replace(map0, 3, \"Three\");\n /// \n /// Debug.print(debug_show(Iter.toArray(natMap.entries(map2))));\n /// Debug.print(debug_show(old2));\n /// // [(0, \"Zero\"), (1, \"One\"), (2, \"Two\"), (3, \"Three\")]\n /// // null\n /// ```\n /// \n /// | Runtime | Space |\n /// |---------------|-----------------------------|\n /// | `O(log(n))` | `O(log(n))` retained memory |\n /// \n public func replace<V>(m : Map<K, V>, key : K, value : V) : (Map<K, V>, ?V) {\n switch (Internal.replace(m.root, compare, key, value)) {\n case (t, null) { ({ root = t; size = m.size + 1 }, null) };\n case (t, v) { ({ root = t; size = m.size }, v) }\n }\n };\n\n /// Creates a new map by applying `f` to each entry in the map `m`. For each entry\n /// `(k, v)` in the old map, if `f` evaluates to `null`, the entry is discarded.\n /// Otherwise, the entry is transformed into a new entry `(k, v2)`, where\n /// the new value `v2` is the result of applying `f` to `(k, v)`.\n /// \n /// Example:\n /// ```motoko\n /// import Map \"mo:base/OrderedMap\";\n /// import Nat \"mo:base/Nat\";\n /// import Iter \"mo:base/Iter\";\n /// import Debug \"mo:base/Debug\";\n /// \n /// let natMap = Map.Make<Nat>(Nat.compare);\n /// let map = natMap.fromIter<Text>(Iter.fromArray([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")]));\n /// \n /// func f(key : Nat, val : Text) : ?Text {\n /// if(key == 0) {null}\n /// else { ?(\"Twenty \" # val)}\n /// };\n /// \n /// let newMap = natMap.mapFilter(map, f);\n /// \n /// Debug.print(debug_show(Iter.toArray(natMap.entries(newMap))));\n /// \n /// // [(1, \"Twenty One\"), (2, \"Twenty Two\")]\n /// ```\n /// \n /// | Runtime | Space |\n /// |----------|------------|\n /// | `O(n * log(n))` | `O(n)` (retained memory + garbage) |\n /// \n /// Note: Creates `O(n * log(n))` temporary objects that will be collected as garbage.\n public func mapFilter<V1, V2>(m : Map<K, V1>, f : (K, V1) -> ?V2) : Map<K, V2> = Internal.mapFilter(m, compare, f);\n\n /// Get the value associated with key `key` in the given map `m` if present and `null` otherwise.\n /// \n /// Example:\n /// ```motoko\n /// import Map \"mo:base/OrderedMap\";\n /// import Nat \"mo:base/Nat\";\n /// import Iter \"mo:base/Iter\";\n /// import Debug \"mo:base/Debug\";\n /// \n /// let natMap = Map.Make<Nat>(Nat.compare);\n /// let map = natMap.fromIter<Text>(Iter.fromArray([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")]));\n /// \n /// Debug.print(debug_show(natMap.get(map, 1)));\n /// Debug.print(debug_show(natMap.get(map, 42)));\n /// \n /// // ?\"One\"\n /// // null\n /// ```\n /// \n /// Runtime: `O(log(n))`.\n /// Space: `O(1)`.\n /// where `n` denotes the number of key-value entries stored in the map and\n /// assuming that the `compare` function implements an `O(1)` comparison.\n public func get<V>(m : Map<K, V>, key : K) : ?V = Internal.get(m.root, compare, key);\n\n /// Test whether the map `m` contains any binding for the given `key`.\n /// \n /// Example:\n /// ```motoko\n /// import Map \"mo:base/OrderedMap\";\n /// import Nat \"mo:base/Nat\";\n /// import Iter \"mo:base/Iter\";\n /// import Debug \"mo:base/Debug\";\n /// \n /// let natMap = Map.Make<Nat>(Nat.compare);\n /// let map = natMap.fromIter<Text>(Iter.fromArray([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")]));\n /// \n /// Debug.print(debug_show natMap.contains(map, 1)); // => true\n /// Debug.print(debug_show natMap.contains(map, 42)); // => false\n /// ```\n /// \n /// | Runtime | Space |\n /// |---------------|-----------------------------|\n /// | `O(log(n))` | `O(1)` |\n public func contains<V>(m : Map<K, V>, key : K) : Bool = Internal.contains(m.root, compare, key);\n\n /// Retrieves a key-value pair from the map `m` with a maximal key. If the map is empty returns `null`.\n /// \n /// Example:\n /// ```motoko\n /// import Map \"mo:base/OrderedMap\";\n /// import Nat \"mo:base/Nat\";\n /// import Iter \"mo:base/Iter\";\n /// import Debug \"mo:base/Debug\";\n /// \n /// let natMap = Map.Make<Nat>(Nat.compare);\n /// let map = natMap.fromIter<Text>(Iter.fromArray([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")]));\n /// \n /// Debug.print(debug_show(natMap.maxEntry(map))); // => ?(2, \"Two\")\n /// Debug.print(debug_show(natMap.maxEntry(natMap.empty()))); // => null\n /// ```\n /// \n /// | Runtime | Space |\n /// |---------------|-----------------------------|\n /// | `O(log(n))` | `O(1)` |\n public func maxEntry<V>(m : Map<K, V>) : ?(K, V) = Internal.maxEntry(m.root);\n\n /// Retrieves a key-value pair from the map `m` with a minimal key. If the map is empty returns `null`.\n /// \n /// Example:\n /// ```motoko\n /// import Map \"mo:base/OrderedMap\";\n /// import Iter \"mo:base/Iter\";\n /// import Nat \"mo:base/Nat\";\n /// import Debug \"mo:base/Debug\";\n /// \n /// let natMap = Map.Make<Nat>(Nat.compare);\n /// let map = natMap.fromIter<Text>(Iter.fromArray([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")]));\n /// \n /// Debug.print(debug_show(natMap.minEntry(map))); // => ?(0, \"Zero\")\n /// Debug.print(debug_show(natMap.minEntry(natMap.empty()))); // => null\n /// ```\n /// \n /// | Runtime | Space |\n /// |---------------|-----------------------------|\n /// | `O(log(n))` | `O(1)` |\n public func minEntry<V>(m : Map<K, V>) : ?(K, V) = Internal.minEntry(m.root);\n\n /// Deletes the entry with the key `key` from the map `m`. Has no effect if `key` is not\n /// present in the map. Returns modified map.\n /// \n /// Example:\n /// ```motoko\n /// import Map \"mo:base/OrderedMap\";\n /// import Nat \"mo:base/Nat\";\n /// import Iter \"mo:base/Iter\";\n /// import Debug \"mo:base/Debug\";\n /// \n /// let natMap = Map.Make<Nat>(Nat.compare);\n /// let map = natMap.fromIter<Text>(Iter.fromArray([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")]));\n /// \n /// Debug.print(debug_show(Iter.toArray(natMap.entries(natMap.delete(map, 1)))));\n /// Debug.print(debug_show(Iter.toArray(natMap.entries(natMap.delete(map, 42)))));\n /// \n /// // [(0, \"Zero\"), (2, \"Two\")]\n /// // [(0, \"Zero\"), (1, \"One\"), (2, \"Two\")]\n /// ```\n /// \n /// | Runtime | Space |\n /// |---------------|-----------------------------|\n /// | `O(log(n))` | `O(log(n))` |\n public func delete<V>(m : Map<K, V>, key : K) : Map<K, V> = remove(m, key).0;\n\n /// Deletes the entry with the key `key`. Returns modified map and the\n /// previous value associated with key `key` or `null` if no such value exists.\n /// \n /// Example:\n /// ```motoko\n /// import Map \"mo:base/OrderedMap\";\n /// import Nat \"mo:base/Nat\";\n /// import Iter \"mo:base/Iter\";\n /// import Debug \"mo:base/Debug\";\n /// \n /// let natMap = Map.Make<Nat>(Nat.compare);\n /// let map0 = natMap.fromIter<Text>(Iter.fromArray([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")]));\n /// \n /// let (map1, old1) = natMap.remove(map0, 0);\n /// \n /// Debug.print(debug_show(Iter.toArray(natMap.entries(map1))));\n /// Debug.print(debug_show(old1));\n /// // [(1, \"One\"), (2, \"Two\")]\n /// // ?\"Zero\"\n /// \n /// let (map2, old2) = natMap.remove(map0, 42);\n /// \n /// Debug.print(debug_show(Iter.toArray(natMap.entries(map2))));\n /// Debug.print(debug_show(old2));\n /// // [(0, \"Zero\"), (1, \"One\"), (2, \"Two\")]\n /// // null\n /// ```\n /// \n /// | Runtime | Space |\n /// |---------------|-----------------------------|\n /// | `O(log(n))` | `O(log(n))` |\n public func remove<V>(m : Map<K, V>, key : K) : (Map<K, V>, ?V) {\n switch (Internal.remove(m.root, compare, key)) {\n case (t, null) { ({ root = t; size = m.size }, null) };\n case (t, v) { ({ root = t; size = m.size - 1 }, v) }\n }\n };\n\n /// Create a new empty map.\n /// \n /// Example:\n /// ```motoko\n /// import Map \"mo:base/OrderedMap\";\n /// import Nat \"mo:base/Nat\";\n /// import Debug \"mo:base/Debug\";\n /// \n /// let natMap = Map.Make<Nat>(Nat.compare);\n /// \n /// let map = natMap.empty<Text>();\n /// \n /// Debug.print(debug_show(natMap.size(map)));\n /// \n /// // 0\n /// ```\n /// \n /// Cost of empty map creation\n /// Runtime: `O(1)`.\n /// Space: `O(1)`\n public func empty<V>() : Map<K, V> = Internal.empty();\n\n /// Returns an Iterator (`Iter`) over the key-value pairs in the map.\n /// Iterator provides a single method `next()`, which returns\n /// pairs in ascending order by keys, or `null` when out of pairs to iterate over.\n /// \n /// Example:\n /// ```motoko\n /// import Map \"mo:base/OrderedMap\";\n /// import Nat \"mo:base/Nat\";\n /// import Iter \"mo:base/Iter\";\n /// import Debug \"mo:base/Debug\";\n /// \n /// let natMap = Map.Make<Nat>(Nat.compare);\n /// let map = natMap.fromIter<Text>(Iter.fromArray([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")]));\n /// \n /// Debug.print(debug_show(Iter.toArray(natMap.entries(map))));\n /// // [(0, \"Zero\"), (1, \"One\"), (2, \"Two\")]\n /// var sum = 0;\n /// for ((k, _) in natMap.entries(map)) { sum += k; };\n /// Debug.print(debug_show(sum)); // => 3\n /// ```\n /// | Runtime | Space |\n /// |---------|-------------------------------------|\n /// | `O(n)` | `O(log(n))` retained + `O(n)` garbage |\n public func entries<V>(m : Map<K, V>) : I.Iter<(K, V)> = Internal.iter(m.root, #fwd);\n\n /// Same as `entries` but iterates in the descending order.\n public func entriesRev<V>(m : Map<K, V>) : I.Iter<(K, V)> = Internal.iter(m.root, #bwd);\n\n /// Returns an Iterator (`Iter`) over the keys of the map.\n /// Iterator provides a single method `next()`, which returns\n /// keys in ascending order, or `null` when out of keys to iterate over.\n /// \n /// Example:\n /// ```motoko\n /// import Map \"mo:base/OrderedMap\";\n /// import Nat \"mo:base/Nat\";\n /// import Iter \"mo:base/Iter\";\n /// import Debug \"mo:base/Debug\";\n /// \n /// let natMap = Map.Make<Nat>(Nat.compare);\n /// let map = natMap.fromIter<Text>(Iter.fromArray([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")]));\n /// \n /// Debug.print(debug_show(Iter.toArray(natMap.keys(map))));\n /// \n /// // [0, 1, 2]\n /// ```\n /// | Runtime | Space |\n /// |---------|-------------------------------------|\n /// | `O(n)` | `O(log(n))` retained + `O(n)` garbage |\n public func keys<V>(m : Map<K, V>) : I.Iter<K> = I.map(entries(m), func(kv : (K, V)) : K { kv.0 });\n\n /// Returns an Iterator (`Iter`) over the values of the map.\n /// Iterator provides a single method `next()`, which returns\n /// values in ascending order of associated keys, or `null` when out of values to iterate over.\n /// \n /// Example:\n /// ```motoko\n /// import Map \"mo:base/OrderedMap\";\n /// import Nat \"mo:base/Nat\";\n /// import Iter \"mo:base/Iter\";\n /// import Debug \"mo:base/Debug\";\n /// \n /// let natMap = Map.Make<Nat>(Nat.compare);\n /// let map = natMap.fromIter<Text>(Iter.fromArray([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")]));\n /// \n /// Debug.print(debug_show(Iter.toArray(natMap.vals(map))));\n /// \n /// // [\"Zero\", \"One\", \"Two\"]\n /// ```\n\n /// | Runtime | Space |\n /// |---------|-------------------------------------|\n /// | `O(n)` | `O(log(n))` retained + `O(n)` garbage |\n public func vals<V>(m : Map<K, V>) : I.Iter<V> = I.map(entries(m), func(kv : (K, V)) : V { kv.1 });\n\n /// Creates a new map by applying `f` to each entry in the map `m`. Each entry\n /// `(k, v)` in the old map is transformed into a new entry `(k, v2)`, where\n /// the new value `v2` is created by applying `f` to `(k, v)`.\n /// \n /// Example:\n /// ```motoko\n /// import Map \"mo:base/OrderedMap\";\n /// import Nat \"mo:base/Nat\";\n /// import Iter \"mo:base/Iter\";\n /// import Debug \"mo:base/Debug\";\n /// \n /// let natMap = Map.Make<Nat>(Nat.compare);\n /// let map = natMap.fromIter<Text>(Iter.fromArray([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")]));\n /// \n /// func f(key : Nat, _val : Text) : Nat = key * 2;\n /// \n /// let resMap = natMap.map(map, f);\n /// \n /// Debug.print(debug_show(Iter.toArray(natMap.entries(resMap))));\n /// // [(0, 0), (1, 2), (2, 4)]\n /// ```\n /// \n /// | Runtime | Space |\n /// |---------|------------------------------|\n /// | `O(n)` | `O(n)` |\n public func map<V1, V2>(m : Map<K, V1>, f : (K, V1) -> V2) : Map<K, V2> = Internal.map(m, f);\n\n /// Determine the size of the map as the number of key-value entries.\n /// \n /// Example:\n /// ```motoko\n /// import Map \"mo:base/OrderedMap\";\n /// import Nat \"mo:base/Nat\";\n /// import Iter \"mo:base/Iter\";\n /// import Debug \"mo:base/Debug\";\n /// \n /// let natMap = Map.Make<Nat>(Nat.compare);\n /// let map = natMap.fromIter<Text>(Iter.fromArray([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")]));\n /// \n /// Debug.print(debug_show(natMap.size(map)));\n /// // 3\n /// ```\n /// \n /// | Runtime | Space |\n /// |---------|------------------------------|\n /// | `O(n)` | `O(1)` |\n public func size<V>(m : Map<K, V>) : Nat = m.size;\n\n /// Collapses the elements in the `map` into a single value by starting with `base`\n /// and progressively combining keys and values into `base` with `combine`. Iteration runs\n /// left to right.\n /// \n /// Example:\n /// ```motoko\n /// import Map \"mo:base/OrderedMap\";\n /// import Nat \"mo:base/Nat\";\n /// import Iter \"mo:base/Iter\";\n /// import Debug \"mo:base/Debug\";\n /// \n /// let natMap = Map.Make<Nat>(Nat.compare);\n /// let map = natMap.fromIter<Text>(Iter.fromArray([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")]));\n /// \n /// func folder(accum : (Nat, Text), key : Nat, val : Text) : ((Nat, Text))\n /// = (key + accum.0, accum.1 # val);\n /// \n /// Debug.print(debug_show(natMap.foldLeft(map, (0, \"\"), folder)));\n /// \n /// // (3, \"ZeroOneTwo\")\n /// ```\n /// \n /// | Runtime | Space |\n /// |---------|------------------------------|\n /// | `O(n)` | Depends on `combine` + `O(n)` garbage |\n public func foldLeft<Value, Accum>(\n map : Map<K, Value>,\n base : Accum,\n combine : (Accum, K, Value) -> Accum\n ) : Accum = Internal.foldLeft(map.root, base, combine);\n\n /// Collapses the elements in the `map` into a single value by starting with `base`\n /// and progressively combining keys and values into `base` with `combine`. Iteration runs\n /// right to left.\n /// \n /// Example:\n /// ```motoko\n /// import Map \"mo:base/OrderedMap\";\n /// import Nat \"mo:base/Nat\";\n /// import Iter \"mo:base/Iter\";\n /// import Debug \"mo:base/Debug\";\n /// \n /// let natMap = Map.Make<Nat>(Nat.compare);\n /// let map = natMap.fromIter<Text>(Iter.fromArray([(0, \"Zero\"), (2, \"Two\"), (1, \"One\")]));\n /// \n /// func folder(key : Nat, val : Text, accum : (Nat, Text)) : ((Nat, Text))\n /// = (key + accum.0, accum.1 # val);\n /// \n /// Debug.print(debug_show(natMap.foldRight(map, (0, \"\"), folder)));\n /// \n /// // (3, \"TwoOneZero\")\n /// ```\n /// \n /// | Runtime | Space |\n /// |---------|------------------------------|\n /// | `O(n)` | Depends on `combine` + `O(n)` garbage |\n public func foldRight<Value, Accum>(\n map : Map<K, Value>,\n base : Accum,\n combine : (K, Value, Accum) -> Accum\n ) : Accum = Internal.foldRight(map.root, base, combine);\n\n /// Test whether all key-value pairs satisfy a given predicate `pred`.\n /// \n /// Example:\n /// ```motoko\n /// import Map \"mo:base/OrderedMap\";\n /// import Nat \"mo:base/Nat\";\n /// import Iter \"mo:base/Iter\";\n /// import Debug \"mo:base/Debug\";\n /// \n /// let natMap = Map.Make<Nat>(Nat.compare);\n /// let map = natMap.fromIter<Text>(Iter.fromArray([(0, \"0\"), (2, \"2\"), (1, \"1\")]));\n /// \n /// Debug.print(debug_show(natMap.all<Text>(map, func (k, v) = (v == debug_show(k)))));\n /// // true\n /// Debug.print(debug_show(natMap.all<Text>(map, func (k, v) = (k < 2))));\n /// // false\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(n)` | `O(1)` |\n public func all<V>(m : Map<K, V>, pred : (K, V) -> Bool) : Bool = Internal.all(m.root, pred);\n\n /// Test if there exists a key-value pair satisfying a given predicate `pred`.\n /// \n /// Example:\n /// ```motoko\n /// import Map \"mo:base/OrderedMap\";\n /// import Nat \"mo:base/Nat\";\n /// import Iter \"mo:base/Iter\";\n /// import Debug \"mo:base/Debug\";\n /// \n /// let natMap = Map.Make<Nat>(Nat.compare);\n /// let map = natMap.fromIter<Text>(Iter.fromArray([(0, \"0\"), (2, \"2\"), (1, \"1\")]));\n /// \n /// Debug.print(debug_show(natMap.some<Text>(map, func (k, v) = (k >= 3))));\n /// // false\n /// Debug.print(debug_show(natMap.some<Text>(map, func (k, v) = (k >= 0))));\n /// // true\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(n)` | `O(1)` |\n public func some<V>(m : Map<K, V>, pred : (K, V) -> Bool) : Bool = Internal.some(m.root, pred);\n\n /// Debug helper that check internal invariants of the given map `m`.\n /// Raise an error (for a stack trace) if invariants are violated.\n public func validate<V>(m : Map<K, V>) : () {\n Internal.validate(m, compare)\n }\n };\n\n module Internal {\n\n public func empty<K, V>() : Map<K, V> { { size = 0; root = #leaf } };\n\n public func fromIter<K, V>(i : I.Iter<(K, V)>, compare : (K, K) -> O.Order) : Map<K, V> {\n var map = #leaf : Tree<K, V>;\n var size = 0;\n for (val in i) {\n map := put(map, compare, val.0, val.1);\n size += 1\n };\n { root = map; size }\n };\n\n type IterRep<K, V> = List.List<{ #tr : Tree<K, V>; #xy : (K, V) }>;\n\n public func iter<K, V>(map : Tree<K, V>, direction : { #fwd; #bwd }) : I.Iter<(K, V)> {\n let turnLeftFirst : MapTraverser<K, V> = func(l, x, y, r, ts) {\n ?(#tr(l), ?(#xy(x, y), ?(#tr(r), ts)))\n };\n\n let turnRightFirst : MapTraverser<K, V> = func(l, x, y, r, ts) {\n ?(#tr(r), ?(#xy(x, y), ?(#tr(l), ts)))\n };\n\n switch direction {\n case (#fwd) IterMap(map, turnLeftFirst);\n case (#bwd) IterMap(map, turnRightFirst)\n }\n };\n\n type MapTraverser<K, V> = (Tree<K, V>, K, V, Tree<K, V>, IterRep<K, V>) -> IterRep<K, V>;\n\n class IterMap<K, V>(tree : Tree<K, V>, mapTraverser : MapTraverser<K, V>) {\n var trees : IterRep<K, V> = ?(#tr(tree), null);\n public func next() : ?(K, V) {\n switch (trees) {\n case (null) { null };\n case (?(#tr(#leaf), ts)) {\n trees := ts;\n next()\n };\n case (?(#xy(xy), ts)) {\n trees := ts;\n ?xy\n };\n case (?(#tr(#red(l, x, y, r)), ts)) {\n trees := mapTraverser(l, x, y, r, ts);\n next()\n };\n case (?(#tr(#black(l, x, y, r)), ts)) {\n trees := mapTraverser(l, x, y, r, ts);\n next()\n }\n }\n }\n };\n\n public func map<K, V1, V2>(map : Map<K, V1>, f : (K, V1) -> V2) : Map<K, V2> {\n func mapRec(m : Tree<K, V1>) : Tree<K, V2> {\n switch m {\n case (#leaf) { #leaf };\n case (#red(l, x, y, r)) {\n #red(mapRec l, x, f(x, y), mapRec r)\n };\n case (#black(l, x, y, r)) {\n #black(mapRec l, x, f(x, y), mapRec r)\n }\n }\n };\n { size = map.size; root = mapRec(map.root) }\n };\n\n public func foldLeft<Key, Value, Accum>(\n map : Tree<Key, Value>,\n base : Accum,\n combine : (Accum, Key, Value) -> Accum\n ) : Accum {\n switch (map) {\n case (#leaf) { base };\n case (#red(l, k, v, r)) {\n let left = foldLeft(l, base, combine);\n let middle = combine(left, k, v);\n foldLeft(r, middle, combine)\n };\n case (#black(l, k, v, r)) {\n let left = foldLeft(l, base, combine);\n let middle = combine(left, k, v);\n foldLeft(r, middle, combine)\n }\n }\n };\n\n public func foldRight<Key, Value, Accum>(\n map : Tree<Key, Value>,\n base : Accum,\n combine : (Key, Value, Accum) -> Accum\n ) : Accum {\n switch (map) {\n case (#leaf) { base };\n case (#red(l, k, v, r)) {\n let right = foldRight(r, base, combine);\n let middle = combine(k, v, right);\n foldRight(l, middle, combine)\n };\n case (#black(l, k, v, r)) {\n let right = foldRight(r, base, combine);\n let middle = combine(k, v, right);\n foldRight(l, middle, combine)\n }\n }\n };\n\n public func mapFilter<K, V1, V2>(map : Map<K, V1>, compare : (K, K) -> O.Order, f : (K, V1) -> ?V2) : Map<K, V2> {\n var size = 0;\n func combine(acc : Tree<K, V2>, key : K, value1 : V1) : Tree<K, V2> {\n switch (f(key, value1)) {\n case null { acc };\n case (?value2) {\n size += 1;\n put(acc, compare, key, value2)\n }\n }\n };\n { root = foldLeft(map.root, #leaf, combine); size }\n };\n\n public func get<K, V>(t : Tree<K, V>, compare : (K, K) -> O.Order, x : K) : ?V {\n switch t {\n case (#red(l, x1, y1, r)) {\n switch (compare(x, x1)) {\n case (#less) { get(l, compare, x) };\n case (#equal) { ?y1 };\n case (#greater) { get(r, compare, x) }\n }\n };\n case (#black(l, x1, y1, r)) {\n switch (compare(x, x1)) {\n case (#less) { get(l, compare, x) };\n case (#equal) { ?y1 };\n case (#greater) { get(r, compare, x) }\n }\n };\n case (#leaf) { null }\n }\n };\n\n public func contains<K, V>(m : Tree<K, V>, compare : (K, K) -> O.Order, key : K) : Bool {\n switch (get(m, compare, key)) {\n case (null) { false };\n case (_) { true }\n }\n };\n\n public func maxEntry<K, V>(m : Tree<K, V>) : ?(K, V) {\n func rightmost(m : Tree<K, V>) : (K, V) {\n switch m {\n case (#red(_, k, v, #leaf)) { (k, v) };\n case (#red(_, _, _, r)) { rightmost(r) };\n case (#black(_, k, v, #leaf)) { (k, v) };\n case (#black(_, _, _, r)) { rightmost(r) };\n case (#leaf) { Debug.trap \"OrderedMap.impossible\" }\n }\n };\n switch m {\n case (#leaf) { null };\n case (_) { ?rightmost(m) }\n }\n };\n\n public func minEntry<K, V>(m : Tree<K, V>) : ?(K, V) {\n func leftmost(m : Tree<K, V>) : (K, V) {\n switch m {\n case (#red(#leaf, k, v, _)) { (k, v) };\n case (#red(l, _, _, _)) { leftmost(l) };\n case (#black(#leaf, k, v, _)) { (k, v) };\n case (#black(l, _, _, _)) { leftmost(l) };\n case (#leaf) { Debug.trap \"OrderedMap.impossible\" }\n }\n };\n switch m {\n case (#leaf) { null };\n case (_) { ?leftmost(m) }\n }\n };\n\n public func all<K, V>(m : Tree<K, V>, pred : (K, V) -> Bool) : Bool {\n switch m {\n case (#red(l, k, v, r)) {\n pred(k, v) and all(l, pred) and all(r, pred)\n };\n case (#black(l, k, v, r)) {\n pred(k, v) and all(l, pred) and all(r, pred)\n };\n case (#leaf) { true }\n }\n };\n\n public func some<K, V>(m : Tree<K, V>, pred : (K, V) -> Bool) : Bool {\n switch m {\n case (#red(l, k, v, r)) {\n pred(k, v) or some(l, pred) or some(r, pred)\n };\n case (#black(l, k, v, r)) {\n pred(k, v) or some(l, pred) or some(r, pred)\n };\n case (#leaf) { false }\n }\n };\n\n func redden<K, V>(t : Tree<K, V>) : Tree<K, V> {\n switch t {\n case (#black(l, x, y, r)) { (#red(l, x, y, r)) };\n case _ {\n Debug.trap \"OrderedMap.red\"\n }\n }\n };\n\n func lbalance<K, V>(left : Tree<K, V>, x : K, y : V, right : Tree<K, V>) : Tree<K, V> {\n switch (left, right) {\n case (#red(#red(l1, x1, y1, r1), x2, y2, r2), r) {\n #red(\n #black(l1, x1, y1, r1),\n x2,\n y2,\n #black(r2, x, y, r)\n )\n };\n case (#red(l1, x1, y1, #red(l2, x2, y2, r2)), r) {\n #red(\n #black(l1, x1, y1, l2),\n x2,\n y2,\n #black(r2, x, y, r)\n )\n };\n case _ {\n #black(left, x, y, right)\n }\n }\n };\n\n func rbalance<K, V>(left : Tree<K, V>, x : K, y : V, right : Tree<K, V>) : Tree<K, V> {\n switch (left, right) {\n case (l, #red(l1, x1, y1, #red(l2, x2, y2, r2))) {\n #red(\n #black(l, x, y, l1),\n x1,\n y1,\n #black(l2, x2, y2, r2)\n )\n };\n case (l, #red(#red(l1, x1, y1, r1), x2, y2, r2)) {\n #red(\n #black(l, x, y, l1),\n x1,\n y1,\n #black(r1, x2, y2, r2)\n )\n };\n case _ {\n #black(left, x, y, right)\n }\n }\n };\n\n type ClashResolver<A> = { old : A; new : A } -> A;\n\n func insertWith<K, V>(\n m : Tree<K, V>,\n compare : (K, K) -> O.Order,\n key : K,\n val : V,\n onClash : ClashResolver<V>\n ) : Tree<K, V> {\n func ins(tree : Tree<K, V>) : Tree<K, V> {\n switch tree {\n case (#black(left, x, y, right)) {\n switch (compare(key, x)) {\n case (#less) {\n lbalance(ins left, x, y, right)\n };\n case (#greater) {\n rbalance(left, x, y, ins right)\n };\n case (#equal) {\n let newVal = onClash({ new = val; old = y });\n #black(left, key, newVal, right)\n }\n }\n };\n case (#red(left, x, y, right)) {\n switch (compare(key, x)) {\n case (#less) {\n #red(ins left, x, y, right)\n };\n case (#greater) {\n #red(left, x, y, ins right)\n };\n case (#equal) {\n let newVal = onClash { new = val; old = y };\n #red(left, key, newVal, right)\n }\n }\n };\n case (#leaf) {\n #red(#leaf, key, val, #leaf)\n }\n }\n };\n switch (ins m) {\n case (#red(left, x, y, right)) {\n #black(left, x, y, right)\n };\n case other { other }\n }\n };\n\n public func replace<K, V>(\n m : Tree<K, V>,\n compare : (K, K) -> O.Order,\n key : K,\n val : V\n ) : (Tree<K, V>, ?V) {\n var oldVal : ?V = null;\n func onClash(clash : { old : V; new : V }) : V {\n oldVal := ?clash.old;\n clash.new\n };\n let res = insertWith(m, compare, key, val, onClash);\n (res, oldVal)\n };\n\n public func put<K, V>(\n m : Tree<K, V>,\n compare : (K, K) -> O.Order,\n key : K,\n val : V\n ) : Tree<K, V> = replace(m, compare, key, val).0;\n\n func balLeft<K, V>(left : Tree<K, V>, x : K, y : V, right : Tree<K, V>) : Tree<K, V> {\n switch (left, right) {\n case (#red(l1, x1, y1, r1), r) {\n #red(\n #black(l1, x1, y1, r1),\n x,\n y,\n r\n )\n };\n case (_, #black(l2, x2, y2, r2)) {\n rbalance(left, x, y, #red(l2, x2, y2, r2))\n };\n case (_, #red(#black(l2, x2, y2, r2), x3, y3, r3)) {\n #red(\n #black(left, x, y, l2),\n x2,\n y2,\n rbalance(r2, x3, y3, redden r3)\n )\n };\n case _ { Debug.trap \"balLeft\" }\n }\n };\n\n func balRight<K, V>(left : Tree<K, V>, x : K, y : V, right : Tree<K, V>) : Tree<K, V> {\n switch (left, right) {\n case (l, #red(l1, x1, y1, r1)) {\n #red(\n l,\n x,\n y,\n #black(l1, x1, y1, r1)\n )\n };\n case (#black(l1, x1, y1, r1), r) {\n lbalance(#red(l1, x1, y1, r1), x, y, r)\n };\n case (#red(l1, x1, y1, #black(l2, x2, y2, r2)), r3) {\n #red(\n lbalance(redden l1, x1, y1, l2),\n x2,\n y2,\n #black(r2, x, y, r3)\n )\n };\n case _ { Debug.trap \"balRight\" }\n }\n };\n\n func append<K, V>(left : Tree<K, V>, right : Tree<K, V>) : Tree<K, V> {\n switch (left, right) {\n case (#leaf, _) { right };\n case (_, #leaf) { left };\n case (\n #red(l1, x1, y1, r1),\n #red(l2, x2, y2, r2)\n ) {\n switch (append(r1, l2)) {\n case (#red(l3, x3, y3, r3)) {\n #red(\n #red(l1, x1, y1, l3),\n x3,\n y3,\n #red(r3, x2, y2, r2)\n )\n };\n case r1l2 {\n #red(l1, x1, y1, #red(r1l2, x2, y2, r2))\n }\n }\n };\n case (t1, #red(l2, x2, y2, r2)) {\n #red(append(t1, l2), x2, y2, r2)\n };\n case (#red(l1, x1, y1, r1), t2) {\n #red(l1, x1, y1, append(r1, t2))\n };\n case (#black(l1, x1, y1, r1), #black(l2, x2, y2, r2)) {\n switch (append(r1, l2)) {\n case (#red(l3, x3, y3, r3)) {\n #red(\n #black(l1, x1, y1, l3),\n x3,\n y3,\n #black(r3, x2, y2, r2)\n )\n };\n case r1l2 {\n balLeft(\n l1,\n x1,\n y1,\n #black(r1l2, x2, y2, r2)\n )\n }\n }\n }\n }\n };\n\n public func delete<K, V>(m : Tree<K, V>, compare : (K, K) -> O.Order, key : K) : Tree<K, V> = remove(m, compare, key).0;\n\n public func remove<K, V>(tree : Tree<K, V>, compare : (K, K) -> O.Order, x : K) : (Tree<K, V>, ?V) {\n var y0 : ?V = null;\n func delNode(left : Tree<K, V>, x1 : K, y1 : V, right : Tree<K, V>) : Tree<K, V> {\n switch (compare(x, x1)) {\n case (#less) {\n let newLeft = del left;\n switch left {\n case (#black(_, _, _, _)) {\n balLeft(newLeft, x1, y1, right)\n };\n case _ {\n #red(newLeft, x1, y1, right)\n }\n }\n };\n case (#greater) {\n let newRight = del right;\n switch right {\n case (#black(_, _, _, _)) {\n balRight(left, x1, y1, newRight)\n };\n case _ {\n #red(left, x1, y1, newRight)\n }\n }\n };\n case (#equal) {\n y0 := ?y1;\n append(left, right)\n }\n }\n };\n func del(tree : Tree<K, V>) : Tree<K, V> {\n switch tree {\n case (#red(left, x, y, right)) {\n delNode(left, x, y, right)\n };\n case (#black(left, x, y, right)) {\n delNode(left, x, y, right)\n };\n case (#leaf) {\n tree\n }\n }\n };\n switch (del(tree)) {\n case (#red(left, x, y, right)) { (#black(left, x, y, right), y0) };\n case other { (other, y0) }\n }\n };\n\n // Test helper\n public func validate<K, V>(rbMap : Map<K, V>, comp : (K, K) -> O.Order) {\n ignore blackDepth(rbMap.root, comp)\n };\n\n func blackDepth<K, V>(node : Tree<K, V>, comp : (K, K) -> O.Order) : Nat {\n func checkNode(left : Tree<K, V>, key : K, right : Tree<K, V>) : Nat {\n checkKey(left, func(x : K) : Bool { comp(x, key) == #less });\n checkKey(right, func(x : K) : Bool { comp(x, key) == #greater });\n let leftBlacks = blackDepth(left, comp);\n let rightBlacks = blackDepth(right, comp);\n assert (leftBlacks == rightBlacks);\n leftBlacks\n };\n switch node {\n case (#leaf) 0;\n case (#red(left, key, _, right)) {\n let leftBlacks = checkNode(left, key, right);\n assert (not isRed(left));\n assert (not isRed(right));\n leftBlacks\n };\n case (#black(left, key, _, right)) {\n checkNode(left, key, right) + 1\n }\n }\n };\n\n func isRed<K, V>(node : Tree<K, V>) : Bool {\n switch node {\n case (#red(_, _, _, _)) true;\n case _ false\n }\n };\n\n func checkKey<K, V>(node : Tree<K, V>, isValid : K -> Bool) {\n switch node {\n case (#leaf) {};\n case (#red(_, key, _, _)) {\n assert (isValid(key))\n };\n case (#black(_, key, _, _)) {\n assert (isValid(key))\n }\n }\n }\n };\n\n /// Create `OrderedMap.Operations` object capturing key type `K` and `compare` function.\n /// It is an alias for the `Operations` constructor.\n /// \n /// Example:\n /// ```motoko\n /// import Map \"mo:base/OrderedMap\";\n /// import Nat \"mo:base/Nat\";\n /// \n /// actor {\n /// let natMap = Map.Make<Nat>(Nat.compare);\n /// stable var map : Map.Map<Nat, Text> = natMap.empty<Text>();\n /// };\n /// ```\n public let Make : <K>(compare : (K, K) -> O.Order) -> Operations<K> = Operations\n}\n"},"OrderedSet.mo":{"content":"/// Stable ordered set implemented as a red-black tree.\n/// \n/// A red-black tree is a balanced binary search tree ordered by the elements.\n/// \n/// The tree data structure internally colors each of its nodes either red or black,\n/// and uses this information to balance the tree during the modifying operations.\n/// \n/// | Runtime | Space |\n/// |----------|------------|\n/// | `O(log(n))` (worst case per insertion, removal, or retrieval) | `O(n)` (for storing the entire tree) |\n/// \n/// `n` denotes the number of key-value entries (i.e. nodes) stored in the tree.\n/// \n/// :::note Garbage collection\n/// \n/// Unless stated otherwise, operations that iterate over or modify the map (such as insertion, deletion, traversal, and transformation) may create temporary objects with worst-case space usage of `O(log(n))` or `O(n)`. These objects are short-lived and will be collected by the garbage collector automatically.\n/// \n/// :::\n/// \n/// :::note Assumptions\n/// \n/// Runtime and space complexity assumes that `compare`, `equal`, and other functions execute in `O(1)` time and space.\n/// :::\n/// \n/// :::info Credits\n/// \n/// The core of this implementation is derived from:\n/// \n/// * Ken Friis Larsen's [RedBlackMap.sml](https://github.com/kfl/mosml/blob/master/src/mosmllib/Redblackmap.sml), which itself is based on:\n/// * Stefan Kahrs, \"Red-black trees with types\", Journal of Functional Programming, 11(4): 425-432 (2001), [version 1 in web appendix](http://www.cs.ukc.ac.uk/people/staff/smk/redblack/rb.html).\n/// :::\n/// \nimport Debug \"Debug\";\nimport Buffer \"Buffer\";\nimport I \"Iter\";\nimport List \"List\";\nimport Nat \"Nat\";\nimport O \"Order\";\n\nmodule {\n /// Red-black tree of nodes with ordered set elements.\n /// Leaves are considered implicitly black.\n type Tree<T> = {\n #red : (Tree<T>, T, Tree<T>);\n #black : (Tree<T>, T, Tree<T>);\n #leaf\n };\n\n /// Ordered collection of unique elements of the generic type `T`.\n /// If type `T` is stable then `Set<T>` is also stable.\n /// To ensure that property the `Set<T>` does not have any methods,\n /// instead they are gathered in the functor-like class `Operations` (see example there).\n public type Set<T> = { size : Nat; root : Tree<T> };\n\n /// Class that captures element type `T` along with its ordering function `compare`\n /// and provide all operations to work with a set of type `Set<T>`.\n /// \n /// An instance object should be created once as a canister field to ensure\n /// that the same ordering function is used for every operation.\n /// \n /// Example:\n /// ```motoko\n /// import Set \"mo:base/OrderedSet\";\n /// import Nat \"mo:base/Nat\";\n /// \n /// actor {\n /// let natSet = Set.Make<Nat>(Nat.compare); // : Operations<Nat>\n /// stable var usedIds : Set.Set<Nat> = natSet.empty();\n /// \n /// public func createId(id : Nat) : async () {\n /// usedIds := natSet.put(usedIds, id);\n /// };\n /// \n /// public func idIsUsed(id: Nat) : async Bool {\n /// natSet.contains(usedIds, id)\n /// }\n /// }\n /// ```\n public class Operations<T>(compare : (T, T) -> O.Order) {\n\n /// Returns a new Set, containing all entries given by the iterator `i`.\n /// If there are multiple identical entries only one is taken.\n /// \n /// Example:\n /// ```motoko\n /// import Set \"mo:base/OrderedSet\";\n /// import Nat \"mo:base/Nat\";\n /// import Iter \"mo:base/Iter\";\n /// import Debug \"mo:base/Debug\";\n /// \n /// let natSet = Set.Make<Nat>(Nat.compare);\n /// let set = natSet.fromIter(Iter.fromArray([0, 2, 1]));\n /// \n /// Debug.print(debug_show(Iter.toArray(natSet.vals(set))));\n /// // [0, 1, 2]\n /// ```\n /// \n /// | Runtime | Space |\n /// |----------|------------|\n /// | `O(n * log(n))` | `O(n)` (retained memory + garbage) |\n public func fromIter(i : I.Iter<T>) : Set<T> {\n var set = empty() : Set<T>;\n for (val in i) {\n set := Internal.put(set, compare, val)\n };\n set\n };\n\n /// Insert the value `value` into the set `s`. Has no effect if `value` is already\n /// present in the set. Returns a modified set.\n /// \n /// Example:\n /// ```motoko\n /// import Set \"mo:base/OrderedSet\";\n /// import Nat \"mo:base/Nat\";\n /// import Iter \"mo:base/Iter\";\n /// import Debug \"mo:base/Debug\";\n /// \n /// let natSet = Set.Make<Nat>(Nat.compare);\n /// var set = natSet.empty();\n /// \n /// set := natSet.put(set, 0);\n /// set := natSet.put(set, 2);\n /// set := natSet.put(set, 1);\n /// \n /// Debug.print(debug_show(Iter.toArray(natSet.vals(set))));\n /// // [0, 1, 2]\n /// ```\n /// \n /// Runtime: `O(log(n))`.\n /// Space: `O(log(n))`.\n /// where `n` denotes the number of elements stored in the set and\n /// assuming that the `compare` function implements an `O(1)` comparison.\n /// \n /// Note: The returned set shares with the `s` most of the tree nodes.\n /// Garbage collecting one of sets (e.g. after an assignment `m := natSet.delete(m, k)`)\n /// causes collecting `O(log(n))` nodes.\n public func put(s : Set<T>, value : T) : Set<T> = Internal.put(s, compare, value);\n\n /// Deletes the value `value` from the set `s`. Has no effect if `value` is not\n /// present in the set. Returns modified set.\n /// \n /// Example:\n /// ```motoko\n /// import Set \"mo:base/OrderedSet\";\n /// import Nat \"mo:base/Nat\";\n /// import Iter \"mo:base/Iter\";\n /// import Debug \"mo:base/Debug\";\n /// \n /// let natSet = Set.Make<Nat>(Nat.compare);\n /// let set = natSet.fromIter(Iter.fromArray([0, 2, 1]));\n /// \n /// Debug.print(debug_show(Iter.toArray(natSet.vals(natSet.delete(set, 1)))));\n /// Debug.print(debug_show(Iter.toArray(natSet.vals(natSet.delete(set, 42)))));\n /// // [0, 2]\n /// // [0, 1, 2]\n /// ```\n /// \n /// | Runtime | Space |\n /// |-------------|---------------|\n /// | `O(log(n))` | `O(log(n))` |\n public func delete(s : Set<T>, value : T) : Set<T> = Internal.delete(s, compare, value);\n\n /// Test if the set 's' contains a given element.\n /// \n /// Example:\n /// ```motoko\n /// import Set \"mo:base/OrderedSet\";\n /// import Nat \"mo:base/Nat\";\n /// import Iter \"mo:base/Iter\";\n /// import Debug \"mo:base/Debug\";\n /// \n /// let natSet = Set.Make<Nat>(Nat.compare);\n /// let set = natSet.fromIter(Iter.fromArray([0, 2, 1]));\n /// \n /// Debug.print(debug_show natSet.contains(set, 1)); // => true\n /// Debug.print(debug_show natSet.contains(set, 42)); // => false\n /// ```\n /// \n /// | Runtime | Space |\n /// |-------------|---------------|\n /// | `O(log(n))` | `O(1)` |\n public func contains(s : Set<T>, value : T) : Bool = Internal.contains(s.root, compare, value);\n\n /// Get a maximal element of the set `s` if it is not empty, otherwise returns `null`\n /// \n /// Example:\n /// ```motoko\n /// import Set \"mo:base/OrderedSet\";\n /// import Nat \"mo:base/Nat\";\n /// import Iter \"mo:base/Iter\";\n /// import Debug \"mo:base/Debug\";\n /// \n /// let natSet = Set.Make<Nat>(Nat.compare);\n /// let s1 = natSet.fromIter(Iter.fromArray([0, 2, 1]));\n /// let s2 = natSet.empty();\n /// \n /// Debug.print(debug_show(natSet.max(s1))); // => ?2\n /// Debug.print(debug_show(natSet.max(s2))); // => null\n /// ```\n /// \n /// | Runtime | Space |\n /// |-------------|---------------|\n /// | `O(log(n))` | `O(1)` |\n public func max(s : Set<T>) : ?T = Internal.max(s.root);\n\n /// Get a minimal element of the set `s` if it is not empty, otherwise returns `null`\n /// \n /// Example:\n /// ```motoko\n /// import Set \"mo:base/OrderedSet\";\n /// import Nat \"mo:base/Nat\";\n /// import Iter \"mo:base/Iter\";\n /// import Debug \"mo:base/Debug\";\n /// \n /// let natSet = Set.Make<Nat>(Nat.compare);\n /// let s1 = natSet.fromIter(Iter.fromArray([0, 2, 1]));\n /// let s2 = natSet.empty();\n /// \n /// Debug.print(debug_show(natSet.min(s1))); // => ?0\n /// Debug.print(debug_show(natSet.min(s2))); // => null\n /// ```\n /// \n /// | Runtime | Space |\n /// |-------------|---------------|\n /// | `O(log(n))` | `O(log(1))` |\n public func min(s : Set<T>) : ?T = Internal.min(s.root);\n\n /// [Set union](https://en.wikipedia.org/wiki/Union_(set_theory)) operation.\n /// \n /// Example:\n /// ```motoko\n /// import Set \"mo:base/OrderedSet\";\n /// import Nat \"mo:base/Nat\";\n /// import Iter \"mo:base/Iter\";\n /// import Debug \"mo:base/Debug\";\n /// \n /// let natSet = Set.Make<Nat>(Nat.compare);\n /// let set1 = natSet.fromIter(Iter.fromArray([0, 1, 2]));\n /// let set2 = natSet.fromIter(Iter.fromArray([2, 3, 4]));\n /// \n /// Debug.print(debug_show Iter.toArray(natSet.vals(natSet.union(set1, set2))));\n /// // [0, 1, 2, 3, 4]\n /// ```\n /// \n /// | Runtime | Space |\n /// |-------------|---------------|\n /// | `O(m* log(n))` | `O(m)`retained + garbage |\n public func union(s1 : Set<T>, s2 : Set<T>) : Set<T> {\n if (size(s1) < size(s2)) {\n foldLeft(s1, s2, func(acc : Set<T>, elem : T) : Set<T> { Internal.put(acc, compare, elem) })\n } else {\n foldLeft(s2, s1, func(acc : Set<T>, elem : T) : Set<T> { Internal.put(acc, compare, elem) })\n }\n };\n\n /// [Set intersection](https://en.wikipedia.org/wiki/Intersection_(set_theory)) operation.\n /// \n /// Example:\n /// ```motoko\n /// import Set \"mo:base/OrderedSet\";\n /// import Nat \"mo:base/Nat\";\n /// import Iter \"mo:base/Iter\";\n /// import Debug \"mo:base/Debug\";\n /// \n /// let natSet = Set.Make<Nat>(Nat.compare);\n /// let set1 = natSet.fromIter(Iter.fromArray([0, 1, 2]));\n /// let set2 = natSet.fromIter(Iter.fromArray([1, 2, 3]));\n /// \n /// Debug.print(debug_show Iter.toArray(natSet.vals(natSet.intersect(set1, set2))));\n /// // [1, 2]\n /// ```\n /// \n /// | Runtime | Space |\n /// |-------------|---------------|\n /// | `O(m* log(n))` | `O(m)`retained + garbage |\n /// \n /// Note: Creates `O(m)` temporary objects that will be collected as garbage.\n public func intersect(s1 : Set<T>, s2 : Set<T>) : Set<T> {\n let elems = Buffer.Buffer<T>(Nat.min(Nat.min(s1.size, s2.size), 100));\n if (s1.size < s2.size) {\n Internal.iterate(\n s1.root,\n func(x : T) {\n if (Internal.contains(s2.root, compare, x)) {\n elems.add(x)\n }\n }\n )\n } else {\n Internal.iterate(\n s2.root,\n func(x : T) {\n if (Internal.contains(s1.root, compare, x)) {\n elems.add(x)\n }\n }\n )\n };\n { root = Internal.buildFromSorted(elems); size = elems.size() }\n };\n\n /// [Set difference](https://en.wikipedia.org/wiki/Difference_(set_theory)).\n /// \n /// Example:\n /// ```motoko\n /// import Set \"mo:base/OrderedSet\";\n /// import Nat \"mo:base/Nat\";\n /// import Iter \"mo:base/Iter\";\n /// import Debug \"mo:base/Debug\";\n /// \n /// let natSet = Set.Make<Nat>(Nat.compare);\n /// let set1 = natSet.fromIter(Iter.fromArray([0, 1, 2]));\n /// let set2 = natSet.fromIter(Iter.fromArray([1, 2, 3]));\n /// \n /// Debug.print(debug_show Iter.toArray(natSet.vals(natSet.diff(set1, set2))));\n /// // [0]\n /// ```\n /// \n /// | Runtime | Space |\n /// |-------------|---------------|\n /// | `O(m* log(n))` | `O(m)`retained + garbage |\n public func diff(s1 : Set<T>, s2 : Set<T>) : Set<T> {\n if (size(s1) < size(s2)) {\n let elems = Buffer.Buffer<T>(Nat.min(s1.size, 100));\n Internal.iterate(\n s1.root,\n func(x : T) {\n if (not Internal.contains(s2.root, compare, x)) {\n elems.add(x)\n }\n }\n );\n { root = Internal.buildFromSorted(elems); size = elems.size() }\n } else {\n foldLeft(\n s2,\n s1,\n func(acc : Set<T>, elem : T) : Set<T> {\n if (Internal.contains(acc.root, compare, elem)) {\n Internal.delete(acc, compare, elem)\n } else { acc }\n }\n )\n }\n };\n\n /// Creates a new `Set` by applying `f` to each entry in the set `s`. Each element\n /// `x` in the old set is transformed into a new entry `x2`, where\n /// the new value `x2` is created by applying `f` to `x`.\n /// The result set may be smaller than the original set due to duplicate elements.\n /// \n /// Example:\n /// ```motoko\n /// import Set \"mo:base/OrderedSet\";\n /// import Nat \"mo:base/Nat\";\n /// import Iter \"mo:base/Iter\";\n /// import Debug \"mo:base/Debug\";\n /// \n /// let natSet = Set.Make<Nat>(Nat.compare);\n /// let set = natSet.fromIter(Iter.fromArray([0, 1, 2, 3]));\n /// \n /// func f(x : Nat) : Nat = if (x < 2) { x } else { 0 };\n /// \n /// let resSet = natSet.map(set, f);\n /// \n /// Debug.print(debug_show(Iter.toArray(natSet.vals(resSet))));\n /// // [0, 1]\n /// ```\n /// \n /// Cost of mapping all the elements:\n /// | Runtime | Space |\n /// |-------------|---------------|\n /// | `O(n* log(n))` | `O(n)`retained + garbage |\n ///\n public func map<T1>(s : Set<T1>, f : T1 -> T) : Set<T> = Internal.foldLeft(s.root, empty(), func(acc : Set<T>, elem : T1) : Set<T> { Internal.put(acc, compare, f(elem)) });\n\n /// Creates a new set by applying `f` to each element in the set `s`. For each element\n /// `x` in the old set, if `f` evaluates to `null`, the element is discarded.\n /// Otherwise, the entry is transformed into a new entry `x2`, where\n /// the new value `x2` is the result of applying `f` to `x`.\n /// \n /// Example:\n /// ```motoko\n /// import Set \"mo:base/OrderedSet\";\n /// import Nat \"mo:base/Nat\";\n /// import Iter \"mo:base/Iter\";\n /// import Debug \"mo:base/Debug\";\n /// \n /// let natSet = Set.Make<Nat>(Nat.compare);\n /// let set = natSet.fromIter(Iter.fromArray([0, 1, 2, 3]));\n /// \n /// func f(x : Nat) : ?Nat {\n /// if(x == 0) {null}\n /// else { ?( x * 2 )}\n /// };\n /// \n /// let newRbSet = natSet.mapFilter(set, f);\n /// \n /// Debug.print(debug_show(Iter.toArray(natSet.vals(newRbSet))));\n /// // [2, 4, 6]\n /// ```\n /// \n /// | Runtime | Space |\n /// |-------------|---------------|\n /// | `O(n* log(n))` | `O(n)`retained + garbage |\n public func mapFilter<T1>(s : Set<T1>, f : T1 -> ?T) : Set<T> {\n func combine(acc : Set<T>, elem : T1) : Set<T> {\n switch (f(elem)) {\n case null { acc };\n case (?elem2) {\n Internal.put(acc, compare, elem2)\n }\n }\n };\n Internal.foldLeft(s.root, empty(), combine)\n };\n\n /// Test if `set1` is subset of `set2`.\n /// \n /// Example:\n /// ```motoko\n /// import Set \"mo:base/OrderedSet\";\n /// import Nat \"mo:base/Nat\";\n /// import Iter \"mo:base/Iter\";\n /// import Debug \"mo:base/Debug\";\n /// \n /// let natSet = Set.Make<Nat>(Nat.compare);\n /// let set1 = natSet.fromIter(Iter.fromArray([1, 2]));\n /// let set2 = natSet.fromIter(Iter.fromArray([0, 2, 1]));\n /// \n /// Debug.print(debug_show natSet.isSubset(set1, set2)); // => true\n /// ```\n /// \n /// | Runtime | Space |\n /// |-------------|---------------|\n /// | `O(n* log(n))` | `O(1)` |\n public func isSubset(s1 : Set<T>, s2 : Set<T>) : Bool {\n if (s1.size > s2.size) { return false };\n isSubsetHelper(s1.root, s2.root)\n };\n\n /// Test if two sets are equal.\n /// \n /// Example:\n /// ```motoko\n /// import Set \"mo:base/OrderedSet\";\n /// import Nat \"mo:base/Nat\";\n /// import Iter \"mo:base/Iter\";\n /// import Debug \"mo:base/Debug\";\n /// \n /// let natSet = Set.Make<Nat>(Nat.compare);\n /// let set1 = natSet.fromIter(Iter.fromArray([0, 2, 1]));\n /// let set2 = natSet.fromIter(Iter.fromArray([1, 2]));\n /// \n /// Debug.print(debug_show natSet.equals(set1, set1)); // => true\n /// Debug.print(debug_show natSet.equals(set1, set2)); // => false\n /// ```\n /// \n /// | Runtime | Space |\n /// |-------------|---------------|\n /// | `O(m * log(n))` | `O(1)` |\n public func equals(s1 : Set<T>, s2 : Set<T>) : Bool {\n if (s1.size != s2.size) { return false };\n isSubsetHelper(s1.root, s2.root)\n };\n\n func isSubsetHelper(t1 : Tree<T>, t2 : Tree<T>) : Bool {\n switch (t1, t2) {\n case (#leaf, _) { true };\n case (_, #leaf) { false };\n case ((#red(t1l, x1, t1r) or #black(t1l, x1, t1r)), (#red(t2l, x2, t2r)) or #black(t2l, x2, t2r)) {\n switch (compare(x1, x2)) {\n case (#equal) {\n isSubsetHelper(t1l, t2l) and isSubsetHelper(t1r, t2r)\n };\n // x1 < x2 ==> x1 \\in t2l /\\ t1l \\subset t2l\n case (#less) {\n Internal.contains(t2l, compare, x1) and isSubsetHelper(t1l, t2l) and isSubsetHelper(t1r, t2)\n };\n // x2 < x1 ==> x1 \\in t2r /\\ t1r \\subset t2r\n case (#greater) {\n Internal.contains(t2r, compare, x1) and isSubsetHelper(t1l, t2) and isSubsetHelper(t1r, t2r)\n }\n }\n }\n }\n };\n\n /// Returns an Iterator (`Iter`) over the elements of the set.\n /// Iterator provides a single method `next()`, which returns\n /// elements in ascending order, or `null` when out of elements to iterate over.\n /// \n /// Example:\n /// ```motoko\n /// import Set \"mo:base/OrderedSet\";\n /// import Nat \"mo:base/Nat\";\n /// import Iter \"mo:base/Iter\";\n /// import Debug \"mo:base/Debug\";\n /// \n /// let natSet = Set.Make<Nat>(Nat.compare);\n /// let set = natSet.fromIter(Iter.fromArray([0, 2, 1]));\n /// \n /// Debug.print(debug_show(Iter.toArray(natSet.vals(set))));\n /// // [0, 1, 2]\n /// ```\n\n /// | Runtime | Space |\n /// |-------------|---------------|\n /// | `O(n)` | `O(log(n))` retained + garbage |\n public func vals(s : Set<T>) : I.Iter<T> = Internal.iter(s.root, #fwd);\n\n /// Same as `vals()` but iterates over elements of the set `s` in the descending order.\n /// \n /// Example:\n /// ```motoko\n /// import Set \"mo:base/OrderedSet\";\n /// import Nat \"mo:base/Nat\";\n /// import Iter \"mo:base/Iter\";\n /// import Debug \"mo:base/Debug\";\n /// \n /// let natSet = Set.Make<Nat>(Nat.compare);\n /// let set = natSet.fromIter(Iter.fromArray([0, 2, 1]));\n /// \n /// Debug.print(debug_show(Iter.toArray(natSet.valsRev(set))));\n /// // [2, 1, 0]\n /// ```\n\n /// | Runtime | Space |\n /// |-------------|---------------|\n /// | `O(n)` | `O(log(n))` retained + garbage |\n public func valsRev(s : Set<T>) : I.Iter<T> = Internal.iter(s.root, #bwd);\n\n /// Create a new empty Set.\n /// \n /// Example:\n /// ```motoko\n /// import Set \"mo:base/OrderedSet\";\n /// import Nat \"mo:base/Nat\";\n /// import Debug \"mo:base/Debug\";\n /// \n /// let natSet = Set.Make<Nat>(Nat.compare);\n /// let set = natSet.empty();\n /// \n /// Debug.print(debug_show(natSet.size(set))); // => 0\n /// ```\n /// \n /// Cost of empty set creation\n /// Runtime: `O(1)`.\n /// Space: `O(1)`\n public func empty() : Set<T> = { root = #leaf; size = 0 };\n\n /// Returns the number of elements in the set.\n /// \n /// Example:\n /// ```motoko\n /// import Set \"mo:base/OrderedSet\";\n /// import Nat \"mo:base/Nat\";\n /// import Iter \"mo:base/Iter\";\n /// import Debug \"mo:base/Debug\";\n /// \n /// let natSet = Set.Make<Nat>(Nat.compare);\n /// let set = natSet.fromIter(Iter.fromArray([0, 2, 1]));\n /// \n /// Debug.print(debug_show(natSet.size(set))); // => 3\n /// ```\n /// \n /// | Runtime | Space |\n /// |-------------|---------------|\n /// | `O(1)` | `O(1)` |\n public func size(s : Set<T>) : Nat = s.size;\n\n /// Collapses the elements in `set` into a single value by starting with `base`\n /// and progessively combining elements into `base` with `combine`. Iteration runs\n /// left to right.\n /// \n /// Example:\n /// ```motoko\n /// import Set \"mo:base/OrderedSet\";\n /// import Nat \"mo:base/Nat\";\n /// import Iter \"mo:base/Iter\";\n /// import Debug \"mo:base/Debug\";\n /// \n /// let natSet = Set.Make<Nat>(Nat.compare);\n /// let set = natSet.fromIter(Iter.fromArray([0, 2, 1]));\n /// \n /// func folder(accum : Nat, val : Nat) : Nat = val + accum;\n /// \n /// Debug.print(debug_show(natSet.foldLeft(set, 0, folder)));\n /// // 3\n /// ```\n /// \n\n /// | Runtime | Space |\n /// |---------|------------------------------|\n /// | `O(n)` | Depends on `combine` + `O(n)` garbage |\n public func foldLeft<Accum>(\n set : Set<T>,\n base : Accum,\n combine : (Accum, T) -> Accum\n ) : Accum = Internal.foldLeft(set.root, base, combine);\n\n /// Collapses the elements in `set` into a single value by starting with `base`\n /// and progessively combining elements into `base` with `combine`. Iteration runs\n /// right to left.\n /// \n /// Example:\n /// ```motoko\n /// import Set \"mo:base/OrderedSet\";\n /// import Nat \"mo:base/Nat\";\n /// import Iter \"mo:base/Iter\";\n /// import Debug \"mo:base/Debug\";\n /// \n /// let natSet = Set.Make<Nat>(Nat.compare);\n /// let set = natSet.fromIter(Iter.fromArray([0, 2, 1]));\n /// \n /// func folder(val : Nat, accum : Nat) : Nat = val + accum;\n /// \n /// Debug.print(debug_show(natSet.foldRight(set, 0, folder)));\n /// // 3\n /// ```\n /// \n\n /// | Runtime | Space |\n /// |---------|------------------------------|\n /// | `O(n)` | Depends on `combine` + `O(n)` garbage |\n public func foldRight<Accum>(\n set : Set<T>,\n base : Accum,\n combine : (T, Accum) -> Accum\n ) : Accum = Internal.foldRight(set.root, base, combine);\n\n /// Test if the given set `s` is empty.\n /// \n /// Example:\n /// ```motoko\n /// import Set \"mo:base/OrderedSet\";\n /// import Nat \"mo:base/Nat\";\n /// import Debug \"mo:base/Debug\";\n /// \n /// let natSet = Set.Make<Nat>(Nat.compare);\n /// let set = natSet.empty();\n /// \n /// Debug.print(debug_show(natSet.isEmpty(set))); // => true\n /// ```\n /// \n /// Runtime: `O(1)`.\n /// Space: `O(1)`.\n public func isEmpty(s : Set<T>) : Bool {\n switch (s.root) {\n case (#leaf) { true };\n case _ { false }\n }\n };\n\n /// Test whether all values in the set `s` satisfy a given predicate `pred`.\n /// \n /// Example:\n /// ```motoko\n /// import Set \"mo:base/OrderedSet\";\n /// import Nat \"mo:base/Nat\";\n /// import Iter \"mo:base/Iter\";\n /// import Debug \"mo:base/Debug\";\n /// \n /// let natSet = Set.Make<Nat>(Nat.compare);\n /// let set = natSet.fromIter(Iter.fromArray([0, 2, 1]));\n /// \n /// Debug.print(debug_show(natSet.all(set, func (v) = (v < 10))));\n /// // true\n /// Debug.print(debug_show(natSet.all(set, func (v) = (v < 2))));\n /// // false\n /// ```\n /// \n /// | Runtime | Space |\n /// |---------|------------------------------|\n /// | `O(n)` | `O(n)` |\n public func all(s : Set<T>, pred : T -> Bool) : Bool = Internal.all(s.root, pred);\n\n /// Test if there exists an element in the set `s` satisfying the given predicate `pred`.\n /// \n /// Example:\n /// ```motoko\n /// import Set \"mo:base/OrderedSet\";\n /// import Nat \"mo:base/Nat\";\n /// import Iter \"mo:base/Iter\";\n /// import Debug \"mo:base/Debug\";\n /// \n /// let natSet = Set.Make<Nat>(Nat.compare);\n /// let set = natSet.fromIter(Iter.fromArray([0, 2, 1]));\n /// \n /// Debug.print(debug_show(natSet.some(set, func (v) = (v >= 3))));\n /// // false\n /// Debug.print(debug_show(natSet.some(set, func (v) = (v >= 0))));\n /// // true\n /// ```\n /// \n /// | Runtime | Space |\n /// |---------|------------------------------|\n /// | `O(n)` | `O(1)` |\n public func some(s : Set<T>, pred : (T) -> Bool) : Bool = Internal.some(s.root, pred);\n\n /// Test helper that check internal invariant for the given set `s`.\n /// Raise an error (for a stack trace) if invariants are violated.\n public func validate(s : Set<T>) : () {\n Internal.validate(s, compare)\n }\n };\n\n module Internal {\n public func contains<T>(tree : Tree<T>, compare : (T, T) -> O.Order, elem : T) : Bool {\n func f(t : Tree<T>, x : T) : Bool {\n switch t {\n case (#black(l, x1, r)) {\n switch (compare(x, x1)) {\n case (#less) { f(l, x) };\n case (#equal) { true };\n case (#greater) { f(r, x) }\n }\n };\n case (#red(l, x1, r)) {\n switch (compare(x, x1)) {\n case (#less) { f(l, x) };\n case (#equal) { true };\n case (#greater) { f(r, x) }\n }\n };\n case (#leaf) { false }\n }\n };\n f(tree, elem)\n };\n\n public func max<V>(m : Tree<V>) : ?V {\n func rightmost(m : Tree<V>) : V {\n switch m {\n case (#red(_, v, #leaf)) { v };\n case (#red(_, _, r)) { rightmost(r) };\n case (#black(_, v, #leaf)) { v };\n case (#black(_, _, r)) { rightmost(r) };\n case (#leaf) { Debug.trap \"OrderedSet.impossible\" }\n }\n };\n switch m {\n case (#leaf) { null };\n case (_) { ?rightmost(m) }\n }\n };\n\n public func min<V>(m : Tree<V>) : ?V {\n func leftmost(m : Tree<V>) : V {\n switch m {\n case (#red(#leaf, v, _)) { v };\n case (#red(l, _, _)) { leftmost(l) };\n case (#black(#leaf, v, _)) { v };\n case (#black(l, _, _)) { leftmost(l) };\n case (#leaf) { Debug.trap \"OrderedSet.impossible\" }\n }\n };\n switch m {\n case (#leaf) { null };\n case (_) { ?leftmost(m) }\n }\n };\n\n public func all<V>(m : Tree<V>, pred : V -> Bool) : Bool {\n switch m {\n case (#red(l, v, r)) {\n pred(v) and all(l, pred) and all(r, pred)\n };\n case (#black(l, v, r)) {\n pred(v) and all(l, pred) and all(r, pred)\n };\n case (#leaf) { true }\n }\n };\n\n public func some<V>(m : Tree<V>, pred : V -> Bool) : Bool {\n switch m {\n case (#red(l, v, r)) {\n pred(v) or some(l, pred) or some(r, pred)\n };\n case (#black(l, v, r)) {\n pred(v) or some(l, pred) or some(r, pred)\n };\n case (#leaf) { false }\n }\n };\n\n public func iterate<V>(m : Tree<V>, f : V -> ()) {\n switch m {\n case (#leaf) {};\n case (#black(l, v, r)) { iterate(l, f); f(v); iterate(r, f) };\n case (#red(l, v, r)) { iterate(l, f); f(v); iterate(r, f) }\n }\n };\n\n // build tree from elements arr[l]..arr[r-1]\n public func buildFromSorted<V>(buf : Buffer.Buffer<V>) : Tree<V> {\n var maxDepth = 0;\n var maxSize = 1;\n while (maxSize < buf.size()) {\n maxDepth += 1;\n maxSize += maxSize + 1\n };\n maxDepth := if (maxDepth == 0) { 1 } else { maxDepth }; // keep root black for 1 element tree\n func buildFromSortedHelper(l : Nat, r : Nat, depth : Nat) : Tree<V> {\n if (l + 1 == r) {\n if (depth == maxDepth) {\n return #red(#leaf, buf.get(l), #leaf)\n } else {\n return #black(#leaf, buf.get(l), #leaf)\n }\n };\n if (l >= r) {\n return #leaf\n };\n let m = (l + r) / 2;\n return #black(\n buildFromSortedHelper(l, m, depth +1),\n buf.get(m),\n buildFromSortedHelper(m +1, r, depth +1)\n )\n };\n buildFromSortedHelper(0, buf.size(), 0)\n };\n\n type IterRep<T> = List.List<{ #tr : Tree<T>; #x : T }>;\n\n type SetTraverser<T> = (Tree<T>, T, Tree<T>, IterRep<T>) -> IterRep<T>;\n\n class IterSet<T>(tree : Tree<T>, setTraverser : SetTraverser<T>) {\n var trees : IterRep<T> = ?(#tr(tree), null);\n public func next() : ?T {\n switch (trees) {\n case (null) { null };\n case (?(#tr(#leaf), ts)) {\n trees := ts;\n next()\n };\n case (?(#x(x), ts)) {\n trees := ts;\n ?x\n };\n case (?(#tr(#black(l, x, r)), ts)) {\n trees := setTraverser(l, x, r, ts);\n next()\n };\n case (?(#tr(#red(l, x, r)), ts)) {\n trees := setTraverser(l, x, r, ts);\n next()\n }\n }\n }\n };\n\n public func iter<T>(s : Tree<T>, direction : { #fwd; #bwd }) : I.Iter<T> {\n let turnLeftFirst : SetTraverser<T> = func(l, x, r, ts) {\n ?(#tr(l), ?(#x(x), ?(#tr(r), ts)))\n };\n\n let turnRightFirst : SetTraverser<T> = func(l, x, r, ts) {\n ?(#tr(r), ?(#x(x), ?(#tr(l), ts)))\n };\n\n switch direction {\n case (#fwd) IterSet(s, turnLeftFirst);\n case (#bwd) IterSet(s, turnRightFirst)\n }\n };\n\n public func foldLeft<T, Accum>(\n tree : Tree<T>,\n base : Accum,\n combine : (Accum, T) -> Accum\n ) : Accum {\n switch (tree) {\n case (#leaf) { base };\n case (#black(l, x, r)) {\n let left = foldLeft(l, base, combine);\n let middle = combine(left, x);\n foldLeft(r, middle, combine)\n };\n case (#red(l, x, r)) {\n let left = foldLeft(l, base, combine);\n let middle = combine(left, x);\n foldLeft(r, middle, combine)\n }\n }\n };\n\n public func foldRight<T, Accum>(\n tree : Tree<T>,\n base : Accum,\n combine : (T, Accum) -> Accum\n ) : Accum {\n switch (tree) {\n case (#leaf) { base };\n case (#black(l, x, r)) {\n let right = foldRight(r, base, combine);\n let middle = combine(x, right);\n foldRight(l, middle, combine)\n };\n case (#red(l, x, r)) {\n let right = foldRight(r, base, combine);\n let middle = combine(x, right);\n foldRight(l, middle, combine)\n }\n }\n };\n\n func redden<T>(t : Tree<T>) : Tree<T> {\n switch t {\n case (#black(l, x, r)) { (#red(l, x, r)) };\n case _ {\n Debug.trap \"OrderedSet.red\"\n }\n }\n };\n\n func lbalance<T>(left : Tree<T>, x : T, right : Tree<T>) : Tree<T> {\n switch (left, right) {\n case (#red(#red(l1, x1, r1), x2, r2), r) {\n #red(\n #black(l1, x1, r1),\n x2,\n #black(r2, x, r)\n )\n };\n case (#red(l1, x1, #red(l2, x2, r2)), r) {\n #red(\n #black(l1, x1, l2),\n x2,\n #black(r2, x, r)\n )\n };\n case _ {\n #black(left, x, right)\n }\n }\n };\n\n func rbalance<T>(left : Tree<T>, x : T, right : Tree<T>) : Tree<T> {\n switch (left, right) {\n case (l, #red(l1, x1, #red(l2, x2, r2))) {\n #red(\n #black(l, x, l1),\n x1,\n #black(l2, x2, r2)\n )\n };\n case (l, #red(#red(l1, x1, r1), x2, r2)) {\n #red(\n #black(l, x, l1),\n x1,\n #black(r1, x2, r2)\n )\n };\n case _ {\n #black(left, x, right)\n }\n }\n };\n\n public func put<T>(\n s : Set<T>,\n compare : (T, T) -> O.Order,\n elem : T\n ) : Set<T> {\n var newNodeIsCreated : Bool = false;\n func ins(tree : Tree<T>) : Tree<T> {\n switch tree {\n case (#black(left, x, right)) {\n switch (compare(elem, x)) {\n case (#less) {\n lbalance(ins left, x, right)\n };\n case (#greater) {\n rbalance(left, x, ins right)\n };\n case (#equal) {\n #black(left, x, right)\n }\n }\n };\n case (#red(left, x, right)) {\n switch (compare(elem, x)) {\n case (#less) {\n #red(ins left, x, right)\n };\n case (#greater) {\n #red(left, x, ins right)\n };\n case (#equal) {\n #red(left, x, right)\n }\n }\n };\n case (#leaf) {\n newNodeIsCreated := true;\n #red(#leaf, elem, #leaf)\n }\n }\n };\n let newRoot = switch (ins(s.root)) {\n case (#red(left, x, right)) {\n #black(left, x, right)\n };\n case other { other }\n };\n {\n root = newRoot;\n size = if newNodeIsCreated { s.size + 1 } else { s.size }\n }\n };\n\n func balLeft<T>(left : Tree<T>, x : T, right : Tree<T>) : Tree<T> {\n switch (left, right) {\n case (#red(l1, x1, r1), r) {\n #red(#black(l1, x1, r1), x, r)\n };\n case (_, #black(l2, x2, r2)) {\n rbalance(left, x, #red(l2, x2, r2))\n };\n case (_, #red(#black(l2, x2, r2), x3, r3)) {\n #red(\n #black(left, x, l2),\n x2,\n rbalance(r2, x3, redden r3)\n )\n };\n case _ { Debug.trap \"balLeft\" }\n }\n };\n\n func balRight<T>(left : Tree<T>, x : T, right : Tree<T>) : Tree<T> {\n switch (left, right) {\n case (l, #red(l1, x1, r1)) {\n #red(l, x, #black(l1, x1, r1))\n };\n case (#black(l1, x1, r1), r) {\n lbalance(#red(l1, x1, r1), x, r)\n };\n case (#red(l1, x1, #black(l2, x2, r2)), r3) {\n #red(\n lbalance(redden l1, x1, l2),\n x2,\n #black(r2, x, r3)\n )\n };\n case _ { Debug.trap \"balRight\" }\n }\n };\n\n func append<T>(left : Tree<T>, right : Tree<T>) : Tree<T> {\n switch (left, right) {\n case (#leaf, _) { right };\n case (_, #leaf) { left };\n case (\n #red(l1, x1, r1),\n #red(l2, x2, r2)\n ) {\n switch (append(r1, l2)) {\n case (#red(l3, x3, r3)) {\n #red(\n #red(l1, x1, l3),\n x3,\n #red(r3, x2, r2)\n )\n };\n case r1l2 {\n #red(l1, x1, #red(r1l2, x2, r2))\n }\n }\n };\n case (t1, #red(l2, x2, r2)) {\n #red(append(t1, l2), x2, r2)\n };\n case (#red(l1, x1, r1), t2) {\n #red(l1, x1, append(r1, t2))\n };\n case (#black(l1, x1, r1), #black(l2, x2, r2)) {\n switch (append(r1, l2)) {\n case (#red(l3, x3, r3)) {\n #red(\n #black(l1, x1, l3),\n x3,\n #black(r3, x2, r2)\n )\n };\n case r1l2 {\n balLeft(\n l1,\n x1,\n #black(r1l2, x2, r2)\n )\n }\n }\n }\n }\n };\n\n public func delete<T>(s : Set<T>, compare : (T, T) -> O.Order, x : T) : Set<T> {\n var changed : Bool = false;\n func delNode(left : Tree<T>, x1 : T, right : Tree<T>) : Tree<T> {\n switch (compare(x, x1)) {\n case (#less) {\n let newLeft = del left;\n switch left {\n case (#black(_, _, _)) {\n balLeft(newLeft, x1, right)\n };\n case _ {\n #red(newLeft, x1, right)\n }\n }\n };\n case (#greater) {\n let newRight = del right;\n switch right {\n case (#black(_, _, _)) {\n balRight(left, x1, newRight)\n };\n case _ {\n #red(left, x1, newRight)\n }\n }\n };\n case (#equal) {\n changed := true;\n append(left, right)\n }\n }\n };\n func del(tree : Tree<T>) : Tree<T> {\n switch tree {\n case (#black(left, x1, right)) {\n delNode(left, x1, right)\n };\n case (#red(left, x1, right)) {\n delNode(left, x1, right)\n };\n case (#leaf) {\n tree\n }\n }\n };\n let newRoot = switch (del(s.root)) {\n case (#red(left, x1, right)) {\n #black(left, x1, right)\n };\n case other { other }\n };\n {\n root = newRoot;\n size = if changed { s.size -1 } else { s.size }\n }\n };\n\n // check binary search tree order of elements and black depth invariant of the RB-tree\n public func validate<T>(s : Set<T>, comp : (T, T) -> O.Order) {\n ignore blackDepth(s.root, comp)\n };\n\n func blackDepth<T>(node : Tree<T>, comp : (T, T) -> O.Order) : Nat {\n func checkNode(left : Tree<T>, x1 : T, right : Tree<T>) : Nat {\n checkElem(left, func(x : T) : Bool { comp(x, x1) == #less });\n checkElem(right, func(x : T) : Bool { comp(x, x1) == #greater });\n let leftBlacks = blackDepth(left, comp);\n let rightBlacks = blackDepth(right, comp);\n assert (leftBlacks == rightBlacks);\n leftBlacks\n };\n switch node {\n case (#leaf) 0;\n case (#red(left, x1, right)) {\n assert (not isRed(left));\n assert (not isRed(right));\n checkNode(left, x1, right)\n };\n case (#black(left, x1, right)) {\n checkNode(left, x1, right) + 1\n }\n }\n };\n\n func isRed<T>(node : Tree<T>) : Bool {\n switch node {\n case (#red(_, _, _)) true;\n case _ false\n }\n };\n\n func checkElem<T>(node : Tree<T>, isValid : T -> Bool) {\n switch node {\n case (#leaf) {};\n case (#black(_, elem, _)) {\n assert (isValid(elem))\n };\n case (#red(_, elem, _)) {\n assert (isValid(elem))\n }\n }\n }\n };\n\n /// Create `OrderedSet.Operations` object capturing element type `T` and `compare` function.\n /// It is an alias for the `Operations` constructor.\n /// \n /// Example:\n /// ```motoko\n /// import Set \"mo:base/OrderedSet\";\n /// import Nat \"mo:base/Nat\";\n /// \n /// actor {\n /// let natSet = Set.Make<Nat>(Nat.compare);\n /// stable var set : Set.Set<Nat> = natSet.empty();\n /// };\n /// ```\n public let Make : <T>(compare : (T, T) -> O.Order) -> Operations<T> = Operations\n}\n"},"TrieMap.mo":{"content":"/// Class `TrieMap<K, V>` provides a map from keys of type `K` to values of type `V`.\n/// The class wraps and manipulates an underlying hash trie, found in the `Trie` module.\n/// The trie is a binary tree where element positions are determined using the hash of the keys.\n/// \n/// :::warning Limitations\n/// \n/// This data structure allows at most `MAX_LEAF_SIZE = 8` hash collisions.\n/// Attempts to insert more than 8 keys (whether directly via `put` or indirectly via other operations) with the same hash value will trap.\n/// This limitation is inherited from the underlying `Trie` data structure.\n/// :::\n/// \n/// :::note Interface compatibility\n/// \n/// The `class` `TrieMap` exposes the same interface as `HashMap`.\n/// :::\n/// \n/// :::note Assumptions\n/// \n/// Runtime and space complexity assumes that `hash`, `equal`, and other function parameters execute in `O(1)` time and space.\n/// Where applicable, runtimes also assume the trie is reasonably balanced.\n/// :::\n/// \n/// :::note Iterator performance\n/// \n/// All iterator-related runtime and space costs refer to iterator construction.\n/// The iteration itself takes linear time and logarithmic space to execute.\n/// :::\n/// \n/// Creating a map:\n/// The equality function is used to compare keys, and the hash function is used to hash keys. See the example below.\n/// \n/// ```motoko name=initialize\n/// import TrieMap \"mo:base/TrieMap\";\n/// import Nat \"mo:base/Nat\";\n/// import Hash \"mo:base/Hash\";\n/// import Iter \"mo:base/Iter\";\n/// \n/// let map = TrieMap.TrieMap<Nat, Nat>(Nat.equal, Hash.hash)\n/// ```\n\nimport T \"Trie\";\nimport P \"Prelude\";\nimport I \"Iter\";\nimport Hash \"Hash\";\nimport List \"List\";\n\nmodule {\n public class TrieMap<K, V>(isEq : (K, K) -> Bool, hashOf : K -> Hash.Hash) {\n var map = T.empty<K, V>();\n var _size : Nat = 0;\n\n /// Returns the number of entries in the map.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// map.size()\n /// ```\n /// \n /// | Runtime | Space |\n /// |----------------|---------------|\n /// | `O(1)` | `O(log(1))` |\n public func size() : Nat { _size };\n\n /// Maps `key` to `value`, and overwrites the old entry if the key\n /// was already present.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// map.put(0, 10);\n /// map.put(2, 12);\n /// Iter.toArray(map.entries())\n /// ```\n /// \n /// | Runtime | Space |\n /// |----------------|---------------|\n /// | `O(log(size))` | `O(log(size))` |\n public func put(key : K, value : V) = ignore replace(key, value);\n\n /// Maps `key` to `value`. Overwrites _and_ returns the old entry as an\n /// option if the key was already present, and `null` otherwise.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// map.put(0, 10);\n /// map.replace(0, 20)\n /// ```\n /// \n /// | Runtime | Space |\n /// |----------------|---------------|\n /// | `O(log(size))` | `O(log(size))` |\n public func replace(key : K, value : V) : ?V {\n let keyObj = { key; hash = hashOf(key) };\n let (map2, ov) = T.put<K, V>(map, keyObj, isEq, value);\n map := map2;\n switch (ov) {\n case null { _size += 1 };\n case _ {}\n };\n ov\n };\n\n /// Gets the value associated with the key `key` in an option, or `null` if it\n /// doesn't exist.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// map.put(0, 10);\n /// map.get(0)\n /// ```\n /// \n /// | Runtime | Space |\n /// |----------------|---------------|\n /// | `O(log(size))` | `O(log(size))` |\n public func get(key : K) : ?V {\n let keyObj = { key; hash = hashOf(key) };\n T.find<K, V>(map, keyObj, isEq)\n };\n\n /// Delete the entry associated with key `key`, if it exists. If the key is\n /// absent, there is no effect.\n /// \n /// :::note\n /// The deletion of an existing key shrinks the trie map.\n /// :::\n /// \n /// Example:\n /// ```motoko include=initialize\n /// map.put(0, 10);\n /// map.delete(0);\n /// map.get(0)\n /// ```\n /// \n /// | Runtime | Space |\n /// |----------------|---------------|\n /// | `O(log(size))` | `O(log(size))` |\n public func delete(key : K) = ignore remove(key);\n\n /// Delete the entry associated with key `key`. Return the deleted value\n /// as an option if it exists, and `null` otherwise.\n /// \n /// :::note\n /// The deletion of an existing key shrinks the trie map.\n /// :::\n /// \n /// Example:\n /// ```motoko include=initialize\n /// map.put(0, 10);\n /// map.remove(0)\n /// ```\n /// \n /// | Runtime | Space |\n /// |----------------|---------------|\n /// | `O(log(size))` | `O(log(size))` |\n public func remove(key : K) : ?V {\n let keyObj = { key; hash = hashOf(key) };\n let (t, ov) = T.remove<K, V>(map, keyObj, isEq);\n map := t;\n switch (ov) {\n case null {};\n case (?_) { _size -= 1 }\n };\n ov\n };\n\n /// Returns an iterator over the keys of the map.\n /// \n /// Each iterator gets a _snapshot view_ of the mapping, and is unaffected\n /// by concurrent updates to the iterated map.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// map.put(0, 10);\n /// map.put(1, 11);\n /// map.put(2, 12);\n /// \n /// // find the sum of all the keys\n /// var sum = 0;\n /// for (key in map.keys()) {\n /// sum += key;\n /// };\n /// // 0 + 1 + 2\n /// sum\n /// ```\n /// \n /// | Runtime | Space |\n /// |---------|--------|\n /// | `O(1)` | `O(1)` |\n public func keys() : I.Iter<K> {\n I.map(entries(), func(kv : (K, V)) : K { kv.0 })\n };\n\n /// Returns an iterator over the values in the map.\n /// \n /// Each iterator gets a _snapshot view_ of the mapping, and is unaffected\n /// by concurrent updates to the iterated map.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// map.put(0, 10);\n /// map.put(1, 11);\n /// map.put(2, 12);\n /// \n /// // find the sum of all the values\n /// var sum = 0;\n /// for (key in map.vals()) {\n /// sum += key;\n /// };\n /// // 10 + 11 + 12\n /// sum\n /// ```\n /// \n /// | Runtime | Space |\n /// |---------|--------|\n /// | `O(1)` | `O(1)` |\n public func vals() : I.Iter<V> {\n I.map(entries(), func(kv : (K, V)) : V { kv.1 })\n };\n\n /// Returns an iterator over the entries (key-value pairs) in the map.\n /// \n /// Each iterator gets a _snapshot view_ of the mapping, and is unaffected\n /// by concurrent updates to the iterated map.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// map.put(0, 10);\n /// map.put(1, 11);\n /// map.put(2, 12);\n /// \n /// // find the sum of all the products of key-value pairs\n /// var sum = 0;\n /// for ((key, value) in map.entries()) {\n /// sum += key * value;\n /// };\n /// // (0 * 10) + (1 * 11) + (2 * 12)\n /// sum\n /// ```\n /// \n /// | Runtime | Space |\n /// |---------|--------|\n /// | `O(1)` | `O(1)` |\n public func entries() : I.Iter<(K, V)> {\n object {\n var stack = ?(map, null) : List.List<T.Trie<K, V>>;\n public func next() : ?(K, V) {\n switch stack {\n case null { null };\n case (?(trie, stack2)) {\n switch trie {\n case (#empty) {\n stack := stack2;\n next()\n };\n case (#leaf({ keyvals = null })) {\n stack := stack2;\n next()\n };\n case (#leaf({ size = c; keyvals = ?((k, v), kvs) })) {\n stack := ?(#leaf({ size = c -1; keyvals = kvs }), stack2);\n ?(k.key, v)\n };\n case (#branch(br)) {\n stack := ?(br.left, ?(br.right, stack2));\n next()\n }\n }\n }\n }\n }\n }\n }\n };\n\n /// Produce a copy of `map`, using `keyEq` to compare keys and `keyHash` to\n /// hash keys.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// map.put(0, 10);\n /// map.put(1, 11);\n /// map.put(2, 12);\n /// // Clone using the same equality and hash functions used to initialize `map`\n /// let mapCopy = TrieMap.clone(map, Nat.equal, Hash.hash);\n /// Iter.toArray(mapCopy.entries())\n /// ```\n /// \n /// | Runtime | Space |\n /// |---------------------|----------|\n /// | `O(size * log(size))` | `O(size)` |\n public func clone<K, V>(\n map : TrieMap<K, V>,\n keyEq : (K, K) -> Bool,\n keyHash : K -> Hash.Hash\n ) : TrieMap<K, V> {\n let h2 = TrieMap<K, V>(keyEq, keyHash);\n for ((k, v) in map.entries()) {\n h2.put(k, v)\n };\n h2\n };\n\n /// Create a new map from the entries in `entries`, using `keyEq` to compare\n /// keys and `keyHash` to hash keys.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// let entries = [(0, 10), (1, 11), (2, 12)];\n /// let newMap = TrieMap.fromEntries<Nat, Nat>(entries.vals(), Nat.equal, Hash.hash);\n /// newMap.get(2)\n /// ```\n /// \n /// | Runtime | Space |\n /// |---------------------|----------|\n /// | `O(size * log(size))` | `O(size)` |\n public func fromEntries<K, V>(\n entries : I.Iter<(K, V)>,\n keyEq : (K, K) -> Bool,\n keyHash : K -> Hash.Hash\n ) : TrieMap<K, V> {\n let h = TrieMap<K, V>(keyEq, keyHash);\n for ((k, v) in entries) {\n h.put(k, v)\n };\n h\n };\n\n /// Transform (map) the values in `map` using function `f`, retaining the keys.\n /// Uses `keyEq` to compare keys and `keyHash` to hash keys.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// map.put(0, 10);\n /// map.put(1, 11);\n /// map.put(2, 12);\n /// // double all the values in map\n /// let newMap = TrieMap.map<Nat, Nat, Nat>(map, Nat.equal, Hash.hash, func(key, value) = value * 2);\n /// Iter.toArray(newMap.entries())\n /// ```\n /// \n /// | Runtime | Space |\n /// |---------------------|----------|\n /// | `O(size * log(size))` | `O(size)` |\n public func map<K, V1, V2>(\n map : TrieMap<K, V1>,\n keyEq : (K, K) -> Bool,\n keyHash : K -> Hash.Hash,\n f : (K, V1) -> V2\n ) : TrieMap<K, V2> {\n let h2 = TrieMap<K, V2>(keyEq, keyHash);\n for ((k, v1) in map.entries()) {\n let v2 = f(k, v1);\n h2.put(k, v2)\n };\n h2\n };\n\n /// Transform (map) the values in `map` using function `f`, discarding entries\n /// for which `f` evaluates to `null`. Uses `keyEq` to compare keys and\n /// `keyHash` to hash keys.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// map.put(0, 10);\n /// map.put(1, 11);\n /// map.put(2, 12);\n /// // double all the values in map, only keeping entries that have an even key\n /// let newMap =\n /// TrieMap.mapFilter<Nat, Nat, Nat>(\n /// map,\n /// Nat.equal,\n /// Hash.hash,\n /// func(key, value) = if (key % 2 == 0) { ?(value * 2) } else { null }\n /// );\n /// Iter.toArray(newMap.entries())\n /// ```\n /// \n /// | Runtime | Space |\n /// |---------------------|----------|\n /// | `O(size * log(size))` | `O(size)`\n public func mapFilter<K, V1, V2>(\n map : TrieMap<K, V1>,\n keyEq : (K, K) -> Bool,\n keyHash : K -> Hash.Hash,\n f : (K, V1) -> ?V2\n ) : TrieMap<K, V2> {\n let h2 = TrieMap<K, V2>(keyEq, keyHash);\n for ((k, v1) in map.entries()) {\n switch (f(k, v1)) {\n case null {};\n case (?v2) {\n h2.put(k, v2)\n }\n }\n };\n h2\n }\n}\n"},"Int32.mo":{"content":"/// Provides utility functions on 32-bit signed integers.\n/// \n/// :::note\n/// Most operations are available as built-in operators (e.g. `1 + 1`).\n/// :::\n/// \n/// :::info Function form for higher-order use\n/// \n/// Several arithmetic and comparison functions (e.g. `add`, `sub`, `bitor`, `bitand`, `pow`) are defined in this module to enable their use as first-class function values, which is not possible with operators like `+`, `-`, `==`, etc., in Motoko. This allows you to pass these operations to higher-order functions such as `map`, `foldLeft`, or `sort`.\n/// :::\n/// \n/// ```motoko name=import\n/// import Int32 \"mo:base/Int32\";\n/// ```\nimport Int \"Int\";\nimport Prim \"mo:⛔\";\n\nmodule {\n\n /// 32-bit signed integers.\n public type Int32 = Prim.Types.Int32;\n\n /// Minimum 32-bit integer value, `-2 ** 31`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int32.minimumValue // => -2_147_483_648\n /// ```\n public let minimumValue = -2_147_483_648 : Int32;\n\n /// Maximum 32-bit integer value, `+2 ** 31 - 1`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int32.maximumValue // => +2_147_483_647\n /// ```\n public let maximumValue = 2_147_483_647 : Int32;\n\n /// Converts a 32-bit signed integer to a signed integer with infinite precision.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int32.toInt(123_456) // => 123_456 : Int\n /// ```\n public let toInt : Int32 -> Int = Prim.int32ToInt;\n\n /// Converts a signed integer with infinite precision to a 32-bit signed integer.\n /// \n /// Traps on overflow/underflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int32.fromInt(123_456) // => +123_456 : Int32\n /// ```\n public let fromInt : Int -> Int32 = Prim.intToInt32;\n\n /// Converts a signed integer with infinite precision to a 32-bit signed integer.\n /// \n /// Wraps on overflow/underflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int32.fromIntWrap(-123_456) // => -123_456 : Int\n /// ```\n public let fromIntWrap : Int -> Int32 = Prim.intToInt32Wrap;\n\n /// Converts a 16-bit signed integer to a 32-bit signed integer.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int32.fromInt16(-123) // => -123 : Int32\n /// ```\n public let fromInt16 : Int16 -> Int32 = Prim.int16ToInt32;\n\n /// Converts a 32-bit signed integer to a 16-bit signed integer.\n /// \n /// Traps on overflow/underflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int32.toInt16(-123) // => -123 : Int16\n /// ```\n public let toInt16 : Int32 -> Int16 = Prim.int32ToInt16;\n\n /// Converts a 64-bit signed integer to a 32-bit signed integer.\n /// \n /// Traps on overflow/underflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int32.fromInt64(-123_456) // => -123_456 : Int32\n /// ```\n public let fromInt64 : Int64 -> Int32 = Prim.int64ToInt32;\n\n /// Converts a 32-bit signed integer to a 64-bit signed integer.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int32.toInt64(-123_456) // => -123_456 : Int64\n /// ```\n public let toInt64 : Int32 -> Int64 = Prim.int32ToInt64;\n\n /// Converts an unsigned 32-bit integer to a signed 32-bit integer.\n /// \n /// Wraps on overflow/underflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int32.fromNat32(123_456) // => +123_456 : Int32\n /// ```\n public let fromNat32 : Nat32 -> Int32 = Prim.nat32ToInt32;\n\n /// Converts a signed 32-bit integer to an unsigned 32-bit integer.\n /// \n /// Wraps on overflow/underflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int32.toNat32(-1) // => 4_294_967_295 : Nat32 // underflow\n /// ```\n public let toNat32 : Int32 -> Nat32 = Prim.int32ToNat32;\n\n /// Returns the Text representation of `x`. Textual representation _do not_\n /// contain underscores to represent commas.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int32.toText(-123456) // => \"-123456\"\n /// ```\n public func toText(x : Int32) : Text {\n Int.toText(toInt(x))\n };\n\n /// Returns the absolute value of `x`.\n /// \n /// Traps when `x == -2 ** 31` (the minimum `Int32` value).\n /// \n /// Example:\n /// ```motoko include=import\n /// Int32.abs(-123456) // => +123_456\n /// ```\n public func abs(x : Int32) : Int32 {\n fromInt(Int.abs(toInt(x)))\n };\n\n /// Returns the minimum of `x` and `y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int32.min(+2, -3) // => -3\n /// ```\n public func min(x : Int32, y : Int32) : Int32 {\n if (x < y) { x } else { y }\n };\n\n /// Returns the maximum of `x` and `y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int32.max(+2, -3) // => +2\n /// ```\n public func max(x : Int32, y : Int32) : Int32 {\n if (x < y) { y } else { x }\n };\n\n /// Equality function for Int32 types.\n /// This is equivalent to `x == y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int32.equal(-1, -1); // => true\n /// ```\n /// \n\n /// \n /// Example:\n /// ```motoko include=import\n /// import Buffer \"mo:base/Buffer\";\n /// \n /// let buffer1 = Buffer.Buffer<Int32>(1);\n /// buffer1.add(-3);\n /// let buffer2 = Buffer.Buffer<Int32>(1);\n /// buffer2.add(-3);\n /// Buffer.equal(buffer1, buffer2, Int32.equal) // => true\n /// ```\n public func equal(x : Int32, y : Int32) : Bool { x == y };\n\n /// Inequality function for Int32 types.\n /// This is equivalent to `x != y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int32.notEqual(-1, -2); // => true\n /// ```\n /// \n\n public func notEqual(x : Int32, y : Int32) : Bool { x != y };\n\n /// \"Less than\" function for Int32 types.\n /// This is equivalent to `x < y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int32.less(-2, 1); // => true\n /// ```\n /// \n\n public func less(x : Int32, y : Int32) : Bool { x < y };\n\n /// \"Less than or equal\" function for Int32 types.\n /// This is equivalent to `x <= y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int32.lessOrEqual(-2, -2); // => true\n /// ```\n /// \n\n public func lessOrEqual(x : Int32, y : Int32) : Bool { x <= y };\n\n /// \"Greater than\" function for Int32 types.\n /// This is equivalent to `x > y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int32.greater(-2, -3); // => true\n /// ```\n /// \n\n public func greater(x : Int32, y : Int32) : Bool { x > y };\n\n /// \"Greater than or equal\" function for Int32 types.\n /// This is equivalent to `x >= y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int32.greaterOrEqual(-2, -2); // => true\n /// ```\n /// \n\n public func greaterOrEqual(x : Int32, y : Int32) : Bool { x >= y };\n\n /// General-purpose comparison function for `Int32`. Returns the `Order` (\n /// either `#less`, `#equal`, or `#greater`) of comparing `x` with `y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int32.compare(-3, 2) // => #less\n /// ```\n /// \n /// This function can be used as value for a high order function, such as a sort function.\n /// \n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.sort([1, -2, -3] : [Int32], Int32.compare) // => [-3, -2, 1]\n /// ```\n public func compare(x : Int32, y : Int32) : { #less; #equal; #greater } {\n if (x < y) { #less } else if (x == y) { #equal } else { #greater }\n };\n\n /// Returns the negation of `x`, `-x`.\n /// \n /// Traps on overflow, i.e. for `neg(-2 ** 31)`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int32.neg(123) // => -123\n /// ```\n /// \n\n public func neg(x : Int32) : Int32 { -x };\n\n /// Returns the sum of `x` and `y`, `x + y`.\n /// \n /// Traps on overflow/underflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int32.add(100, 23) // => +123\n /// ```\n /// \n\n /// \n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.foldLeft<Int32, Int32>([1, -2, -3], 0, Int32.add) // => -4\n /// ```\n public func add(x : Int32, y : Int32) : Int32 { x + y };\n\n /// Returns the difference of `x` and `y`, `x - y`.\n /// \n /// Traps on overflow/underflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int32.sub(1234, 123) // => +1_111\n /// ```\n /// \n\n /// \n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.foldLeft<Int32, Int32>([1, -2, -3], 0, Int32.sub) // => 6\n /// ```\n public func sub(x : Int32, y : Int32) : Int32 { x - y };\n\n /// Returns the product of `x` and `y`, `x * y`.\n /// \n /// Traps on overflow/underflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int32.mul(123, 100) // => +12_300\n /// ```\n /// \n\n /// \n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.foldLeft<Int32, Int32>([1, -2, -3], 1, Int32.mul) // => 6\n /// ```\n public func mul(x : Int32, y : Int32) : Int32 { x * y };\n\n /// Returns the signed integer division of `x` by `y`, `x / y`.\n /// Rounds the quotient towards zero, which is the same as truncating the decimal places of the quotient.\n /// \n /// Traps when `y` is zero.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int32.div(123, 10) // => +12\n /// ```\n /// \n\n public func div(x : Int32, y : Int32) : Int32 { x / y };\n\n /// Returns the remainder of the signed integer division of `x` by `y`, `x % y`,\n /// which is defined as `x - x / y * y`.\n /// \n /// Traps when `y` is zero.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int32.rem(123, 10) // => +3\n /// ```\n /// \n\n public func rem(x : Int32, y : Int32) : Int32 { x % y };\n\n /// Returns `x` to the power of `y`, `x ** y`.\n /// \n /// Traps on overflow/underflow and when `y < 0 or y >= 32`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int32.pow(2, 10) // => +1_024\n /// ```\n /// \n\n public func pow(x : Int32, y : Int32) : Int32 { x ** y };\n\n /// Returns the bitwise negation of `x`, `^x`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int32.bitnot(-256 /* 0xffff_ff00 */) // => +255 // 0xff\n /// ```\n /// \n\n public func bitnot(x : Int32) : Int32 { ^x };\n\n /// Returns the bitwise \"and\" of `x` and `y`, `x & y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int32.bitand(0xffff, 0x00f0) // => +240 // 0xf0\n /// ```\n /// \n\n public func bitand(x : Int32, y : Int32) : Int32 { x & y };\n\n /// Returns the bitwise \"or\" of `x` and `y`, `x | y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int32.bitor(0xffff, 0x00f0) // => +65_535 // 0xffff\n /// ```\n /// \n\n public func bitor(x : Int32, y : Int32) : Int32 { x | y };\n\n /// Returns the bitwise \"exclusive or\" of `x` and `y`, `x ^ y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int32.bitxor(0xffff, 0x00f0) // => +65_295 // 0xff0f\n /// ```\n /// \n\n public func bitxor(x : Int32, y : Int32) : Int32 { x ^ y };\n\n /// Returns the bitwise left shift of `x` by `y`, `x << y`.\n /// The right bits of the shift filled with zeros.\n /// Left-overflowing bits, including the sign bit, are discarded.\n /// \n /// For `y >= 32`, the semantics is the same as for `bitshiftLeft(x, y % 32)`.\n /// For `y < 0`, the semantics is the same as for `bitshiftLeft(x, y + y % 32)`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int32.bitshiftLeft(1, 8) // => +256 // 0x100 equivalent to `2 ** 8`.\n /// ```\n /// \n\n public func bitshiftLeft(x : Int32, y : Int32) : Int32 { x << y };\n\n /// Returns the signed bitwise right shift of `x` by `y`, `x >> y`.\n /// The sign bit is retained and the left side is filled with the sign bit.\n /// Right-underflowing bits are discarded, i.e. not rotated to the left side.\n /// \n /// For `y >= 32`, the semantics is the same as for `bitshiftRight(x, y % 32)`.\n /// For `y < 0`, the semantics is the same as for `bitshiftRight (x, y + y % 32)`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int32.bitshiftRight(1024, 8) // => +4 // equivalent to `1024 / (2 ** 8)`\n /// ```\n /// \n\n public func bitshiftRight(x : Int32, y : Int32) : Int32 { x >> y };\n\n /// Returns the bitwise left rotatation of `x` by `y`, `x <<> y`.\n /// Each left-overflowing bit is inserted again on the right side.\n /// The sign bit is rotated like other bits, i.e. the rotation interprets the number as unsigned.\n /// \n /// Changes the direction of rotation for negative `y`.\n /// For `y >= 32`, the semantics is the same as for `bitrotLeft(x, y % 32)`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int32.bitrotLeft(0x2000_0001, 4) // => +18 // 0x12.\n /// ```\n /// \n\n public func bitrotLeft(x : Int32, y : Int32) : Int32 { x <<> y };\n\n /// Returns the bitwise right rotation of `x` by `y`, `x <>> y`.\n /// Each right-underflowing bit is inserted again on the right side.\n /// The sign bit is rotated like other bits, i.e. the rotation interprets the number as unsigned.\n /// \n /// Changes the direction of rotation for negative `y`.\n /// For `y >= 32`, the semantics is the same as for `bitrotRight(x, y % 32)`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int32.bitrotRight(0x0002_0001, 8) // => +16_777_728 // 0x0100_0200.\n /// ```\n /// \n\n public func bitrotRight(x : Int32, y : Int32) : Int32 { x <>> y };\n\n /// Returns the value of bit `p` in `x`, `x & 2**p == 2**p`.\n /// If `p >= 32`, the semantics is the same as for `bittest(x, p % 32)`.\n /// This is equivalent to checking if the `p`-th bit is set in `x`, using 0 indexing.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int32.bittest(128, 7) // => true\n /// ```\n public func bittest(x : Int32, p : Nat) : Bool {\n Prim.btstInt32(x, Prim.intToInt32(p))\n };\n\n /// Returns the value of setting bit `p` in `x` to `1`.\n /// If `p >= 32`, the semantics is the same as for `bitset(x, p % 32)`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int32.bitset(0, 7) // => +128\n /// ```\n public func bitset(x : Int32, p : Nat) : Int32 {\n x | (1 << Prim.intToInt32(p))\n };\n\n /// Returns the value of clearing bit `p` in `x` to `0`.\n /// If `p >= 32`, the semantics is the same as for `bitclear(x, p % 32)`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int32.bitclear(-1, 7) // => -129\n /// ```\n public func bitclear(x : Int32, p : Nat) : Int32 {\n x & ^(1 << Prim.intToInt32(p))\n };\n\n /// Returns the value of flipping bit `p` in `x`.\n /// If `p >= 32`, the semantics is the same as for `bitclear(x, p % 32)`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int32.bitflip(255, 7) // => +127\n /// ```\n public func bitflip(x : Int32, p : Nat) : Int32 {\n x ^ (1 << Prim.intToInt32(p))\n };\n\n /// Returns the count of non-zero bits in `x`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int32.bitcountNonZero(0xffff) // => +16\n /// ```\n public let bitcountNonZero : (x : Int32) -> Int32 = Prim.popcntInt32;\n\n /// Returns the count of leading zero bits in `x`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int32.bitcountLeadingZero(0x8000) // => +16\n /// ```\n public let bitcountLeadingZero : (x : Int32) -> Int32 = Prim.clzInt32;\n\n /// Returns the count of trailing zero bits in `x`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int32.bitcountTrailingZero(0x0201_0000) // => +16\n /// ```\n public let bitcountTrailingZero : (x : Int32) -> Int32 = Prim.ctzInt32;\n\n /// Returns the upper (i.e. most significant), lower (least significant)\n /// and in-between bytes of `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int32.explode 0x66885511 // => (102, 136, 85, 17)\n /// ```\n public let explode : (x : Int32) -> (msb : Nat8, Nat8, Nat8, lsb : Nat8) = Prim.explodeInt32;\n\n /// Returns the sum of `x` and `y`, `x +% y`.\n ///\n /// Wraps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int32.addWrap(2 ** 30, 2 ** 30) // => -2_147_483_648 // overflow\n /// ```\n ///\n /// :::info\n /// The reason why this function is defined in this library (in addition\n /// to the existing `+%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `+%`\n /// as a function value at the moment.\n /// :::\n public func addWrap(x : Int32, y : Int32) : Int32 { x +% y };\n\n /// Returns the difference of `x` and `y`, `x -% y`.\n /// \n /// Wraps on overflow/underflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int32.subWrap(-2 ** 31, 1) // => +2_147_483_647 // underflow\n /// ```\n /// \n\n public func subWrap(x : Int32, y : Int32) : Int32 { x -% y };\n\n /// Returns the product of `x` and `y`, `x *% y`. Wraps on overflow.\n /// \n /// Wraps on overflow/underflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int32.mulWrap(2 ** 16, 2 ** 16) // => 0 // overflow\n /// ```\n /// \n\n public func mulWrap(x : Int32, y : Int32) : Int32 { x *% y };\n\n /// Returns `x` to the power of `y`, `x **% y`.\n /// \n /// Wraps on overflow/underflow.\n /// Traps if `y < 0 or y >= 32`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int32.powWrap(2, 31) // => -2_147_483_648 // overflow\n /// ```\n /// \n\n public func powWrap(x : Int32, y : Int32) : Int32 { x **% y };\n\n}\n"},"Random.mo":{"content":"/// A module for obtaining randomness on the Internet Computer (IC).\n/// \n/// This module provides the fundamentals for user abstractions to build on.\n/// \n/// Dealing with randomness on a deterministic computing platform, such\n/// as the IC, is intricate. Some basic rules need to be followed by the\n/// user of this module to obtain (and maintain) the benefits of crypto-\n/// graphic randomness:\n/// \n/// - Cryptographic entropy (randomness source) is only obtainable\n/// asyncronously in discrete chunks of 256 bits (32-byte sized `Blob`s).\n/// - All bets must be closed *before* entropy is being asked for in\n/// order to decide them.\n/// - This implies that the same entropy (i.e. `Blob`) - or surplus entropy\n/// not utilised yet - cannot be used for a new round of bets without\n/// losing the cryptographic guarantees.\n/// \n/// Concretely, the below class `Finite`, as well as the\n/// `*From` methods risk the carrying-over of state from previous rounds.\n/// These are provided for performance (and convenience) reasons, and need\n/// special care when used. Similar caveats apply for user-defined (pseudo)\n/// random number generators.\n/// \n/// Usage:\n/// \n/// ```motoko no-repl\n/// import Random \"mo:base/Random\";\n/// ```\n\nimport I \"Iter\";\nimport Option \"Option\";\nimport Prim \"mo:⛔\";\n\nmodule {\n\n let raw_rand = (actor \"aaaaa-aa\" : actor { raw_rand : () -> async Blob }).raw_rand;\n\n /// Obtains a full blob (32 bytes) worth of fresh entropy.\n /// \n /// Example:\n /// ```motoko no-repl\n /// let random = Random.Finite(await Random.blob());\n /// ```\n public let blob : shared () -> async Blob = raw_rand;\n\n /// Drawing from a finite supply of entropy, `Finite` provides\n /// methods to obtain random values. When the entropy is used up,\n /// `null` is returned. Otherwise the outcomes' distributions are\n /// stated for each method. The uniformity of outcomes is\n /// guaranteed only when the supplied entropy is originally obtained\n /// by the `blob()` call, and is never reused.\n /// \n /// Example:\n /// ```motoko no-repl\n /// import Random \"mo:base/Random\";\n /// \n /// let random = Random.Finite(await Random.blob());\n /// \n /// let seed : Blob = \"\\14\\C9\\72\\09\\03\\D4\\D5\\72\\82\\95\\E5\\43\\AF\\FA\\A9\\44\\49\\2F\\25\\56\\13\\F3\\6E\\C7\\B0\\87\\DC\\76\\08\\69\\14\\CF\";\n /// let seedRandom = Random.Finite(seed);\n /// ```\n public class Finite(entropy : Blob) {\n let it : I.Iter<Nat8> = entropy.vals();\n\n /// Uniformly distributes outcomes in the numeric range [0 .. 255].\n /// Consumes 1 byte of entropy.\n /// \n /// Example:\n /// ```motoko no-repl\n /// let seed : Blob = \"\\14\\C9\\72\\09\\03\\D4\\D5\\72\\82\\95\\E5\\43\\AF\\FA\\A9\\44\\49\\2F\\25\\56\\13\\F3\\6E\\C7\\B0\\87\\DC\\76\\08\\69\\14\\CF\";\n /// let random = Random.Finite(seed);\n /// random.byte() // => ?20\n /// ```\n public func byte() : ?Nat8 {\n it.next()\n };\n\n /// Bool iterator splitting up a byte of entropy into 8 bits\n let bit : I.Iter<Bool> = object {\n var mask = 0x00 : Nat8;\n var byte = 0x00 : Nat8;\n public func next() : ?Bool {\n if (0 : Nat8 == mask) {\n switch (it.next()) {\n case null { null };\n case (?w) {\n byte := w;\n mask := 0x40;\n ?(0 : Nat8 != byte & (0x80 : Nat8))\n }\n }\n } else {\n let m = mask;\n mask >>= (1 : Nat8);\n ?(0 : Nat8 != byte & m)\n }\n }\n };\n\n /// Simulates a coin toss. Both outcomes have equal probability.\n /// Consumes 1 bit of entropy (amortised).\n /// \n /// Example:\n /// ```motoko no-repl\n /// let seed : Blob = \"\\14\\C9\\72\\09\\03\\D4\\D5\\72\\82\\95\\E5\\43\\AF\\FA\\A9\\44\\49\\2F\\25\\56\\13\\F3\\6E\\C7\\B0\\87\\DC\\76\\08\\69\\14\\CF\";\n /// let random = Random.Finite(seed);\n /// random.coin() // => ?false\n /// ```\n public func coin() : ?Bool {\n bit.next()\n };\n\n /// Uniformly distributes outcomes in the numeric range [0 .. 2^p - 1].\n /// Consumes ⌈p/8⌉ bytes of entropy.\n /// \n /// Example:\n /// ```motoko no-repl\n /// let seed : Blob = \"\\14\\C9\\72\\09\\03\\D4\\D5\\72\\82\\95\\E5\\43\\AF\\FA\\A9\\44\\49\\2F\\25\\56\\13\\F3\\6E\\C7\\B0\\87\\DC\\76\\08\\69\\14\\CF\";\n /// let random = Random.Finite(seed);\n /// random.range(32) // => ?348746249\n /// ```\n public func range(p : Nat8) : ?Nat {\n var pp = p;\n var acc : Nat = 0;\n for (i in it) {\n if (8 : Nat8 <= pp) {\n acc := acc * 256 + Prim.nat8ToNat(i)\n } else if (0 : Nat8 == pp) {\n return ?acc\n } else {\n acc *= Prim.nat8ToNat(1 << pp);\n let mask : Nat8 = 0xff >> (8 - pp);\n return ?(acc + Prim.nat8ToNat(i & mask))\n };\n pp -= 8\n };\n if (0 : Nat8 == pp) ?acc else null\n };\n\n /// Counts the number of heads in `n` fair coin tosses.\n /// Consumes ⌈n/8⌉ bytes of entropy.\n /// \n /// Example:\n /// ```motoko no-repl\n /// let seed : Blob = \"\\14\\C9\\72\\09\\03\\D4\\D5\\72\\82\\95\\E5\\43\\AF\\FA\\A9\\44\\49\\2F\\25\\56\\13\\F3\\6E\\C7\\B0\\87\\DC\\76\\08\\69\\14\\CF\";\n /// let random = Random.Finite(seed);\n /// random.binomial(5) // => ?1\n /// ```\n public func binomial(n : Nat8) : ?Nat8 {\n var nn = n;\n var acc : Nat8 = 0;\n for (i in it) {\n if (8 : Nat8 <= nn) {\n acc +%= Prim.popcntNat8(i)\n } else if (0 : Nat8 == nn) {\n return ?acc\n } else {\n let mask : Nat8 = 0xff << (8 - nn);\n let residue = Prim.popcntNat8(i & mask);\n return ?(acc +% residue)\n };\n nn -= 8\n };\n if (0 : Nat8 == nn) ?acc else null\n }\n };\n\n /// Distributes outcomes in the numeric range [0 .. 255].\n /// Seed blob must contain at least a byte.\n /// \n /// Example:\n /// ```motoko no-repl\n /// let seed : Blob = \"\\14\\C9\\72\\09\\03\\D4\\D5\\72\\82\\95\\E5\\43\\AF\\FA\\A9\\44\\49\\2F\\25\\56\\13\\F3\\6E\\C7\\B0\\87\\DC\\76\\08\\69\\14\\CF\";\n /// Random.byteFrom(seed) // => 20\n /// ```\n public func byteFrom(seed : Blob) : Nat8 {\n switch (seed.vals().next()) {\n case (?w) { w };\n case _ { Prim.trap \"Random.byteFrom\" }\n }\n };\n\n /// Simulates a coin toss.\n /// Seed blob must contain at least a byte.\n /// \n /// Example:\n /// ```motoko no-repl\n /// let seed : Blob = \"\\14\\C9\\72\\09\\03\\D4\\D5\\72\\82\\95\\E5\\43\\AF\\FA\\A9\\44\\49\\2F\\25\\56\\13\\F3\\6E\\C7\\B0\\87\\DC\\76\\08\\69\\14\\CF\";\n /// Random.coinFrom(seed) // => false\n /// ```\n public func coinFrom(seed : Blob) : Bool {\n switch (seed.vals().next()) {\n case (?w) { w > (127 : Nat8) };\n case _ { Prim.trap \"Random.coinFrom\" }\n }\n };\n\n /// Distributes outcomes in the numeric range [0 .. 2^p - 1].\n /// Seed blob must contain at least ((p+7) / 8) bytes.\n /// \n /// Example:\n /// ```motoko no-repl\n /// let seed : Blob = \"\\14\\C9\\72\\09\\03\\D4\\D5\\72\\82\\95\\E5\\43\\AF\\FA\\A9\\44\\49\\2F\\25\\56\\13\\F3\\6E\\C7\\B0\\87\\DC\\76\\08\\69\\14\\CF\";\n /// Random.rangeFrom(32, seed) // => 348746249\n /// ```\n public func rangeFrom(p : Nat8, seed : Blob) : Nat {\n rangeIter(p, seed.vals())\n };\n\n // internal worker method, expects iterator with sufficient supply\n func rangeIter(p : Nat8, it : I.Iter<Nat8>) : Nat {\n var pp = p;\n var acc : Nat = 0;\n for (i in it) {\n if (8 : Nat8 <= pp) {\n acc := acc * 256 + Prim.nat8ToNat(i)\n } else if (0 : Nat8 == pp) {\n return acc\n } else {\n acc *= Prim.nat8ToNat(1 << pp);\n let mask : Nat8 = 0xff >> (8 - pp);\n return acc + Prim.nat8ToNat(i & mask)\n };\n pp -= 8\n };\n if (0 : Nat8 == pp) {\n return acc\n } else Prim.trap(\"Random.rangeFrom\")\n };\n\n /// Counts the number of heads in `n` coin tosses.\n /// Seed blob must contain at least ((n+7) / 8) bytes.\n /// \n /// Example:\n /// ```motoko no-repl\n /// let seed : Blob = \"\\14\\C9\\72\\09\\03\\D4\\D5\\72\\82\\95\\E5\\43\\AF\\FA\\A9\\44\\49\\2F\\25\\56\\13\\F3\\6E\\C7\\B0\\87\\DC\\76\\08\\69\\14\\CF\";\n /// Random.binomialFrom(5, seed) // => 1\n /// ```\n public func binomialFrom(n : Nat8, seed : Blob) : Nat8 {\n binomialIter(n, seed.vals())\n };\n\n // internal worker method, expects iterator with sufficient supply\n func binomialIter(n : Nat8, it : I.Iter<Nat8>) : Nat8 {\n var nn = n;\n var acc : Nat8 = 0;\n for (i in it) {\n if (8 : Nat8 <= nn) {\n acc +%= Prim.popcntNat8(i)\n } else if (0 : Nat8 == nn) {\n return acc\n } else {\n let mask : Nat8 = 0xff << (8 - nn);\n let residue = Prim.popcntNat8(i & mask);\n return (acc +% residue)\n };\n nn -= 8\n };\n if (0 : Nat8 == nn) {\n return acc\n } else Prim.trap(\"Random.binomialFrom\")\n }\n\n}\n"},"Result.mo":{"content":"/// Error handling with the `Result` type.\n\nimport Prim \"mo:⛔\";\nimport P \"Prelude\";\nimport Order \"Order\";\n\nmodule {\n\n /// `Result<Ok, Err>` is the type used for returning and propagating errors. It\n /// is a type with the variants, `#ok(Ok)`, representing success and containing\n /// a value, and `#err(Err)`, representing error and containing an error value.\n /// \n /// The simplest way of working with `Result`s is to pattern match on them:\n /// \n /// For example, given a function `createUser(user : User) : Result<Id, String>`\n /// where `String` is an error message we could use it like so:\n /// ```motoko no-repl\n /// switch(createUser(myUser)) {\n /// case (#ok(id)) { Debug.print(\"Created new user with id: \" # id) };\n /// case (#err(msg)) { Debug.print(\"Failed to create user with the error: \" # msg) };\n /// }\n /// ```\n public type Result<Ok, Err> = {\n #ok : Ok;\n #err : Err\n };\n\n // Compares two Result's for equality.\n public func equal<Ok, Err>(\n eqOk : (Ok, Ok) -> Bool,\n eqErr : (Err, Err) -> Bool,\n r1 : Result<Ok, Err>,\n r2 : Result<Ok, Err>\n ) : Bool {\n switch (r1, r2) {\n case (#ok(ok1), #ok(ok2)) {\n eqOk(ok1, ok2)\n };\n case (#err(err1), #err(err2)) {\n eqErr(err1, err2)\n };\n case _ { false }\n }\n };\n\n // Compares two Results. `#ok` is larger than `#err`. This ordering is\n // arbitrary, but it lets you for example use Results as keys in ordered maps.\n public func compare<Ok, Err>(\n compareOk : (Ok, Ok) -> Order.Order,\n compareErr : (Err, Err) -> Order.Order,\n r1 : Result<Ok, Err>,\n r2 : Result<Ok, Err>\n ) : Order.Order {\n switch (r1, r2) {\n case (#ok(ok1), #ok(ok2)) {\n compareOk(ok1, ok2)\n };\n case (#err(err1), #err(err2)) {\n compareErr(err1, err2)\n };\n case (#ok(_), _) { #greater };\n case (#err(_), _) { #less }\n }\n };\n\n /// Allows sequencing of `Result` values and functions that return\n /// `Result`'s themselves.\n /// ```motoko\n /// import Result \"mo:base/Result\";\n /// type Result<T,E> = Result.Result<T, E>;\n /// func largerThan10(x : Nat) : Result<Nat, Text> =\n /// if (x > 10) { #ok(x) } else { #err(\"Not larger than 10.\") };\n /// \n /// func smallerThan20(x : Nat) : Result<Nat, Text> =\n /// if (x < 20) { #ok(x) } else { #err(\"Not smaller than 20.\") };\n /// \n /// func between10And20(x : Nat) : Result<Nat, Text> =\n /// Result.chain(largerThan10(x), smallerThan20);\n /// \n /// assert(between10And20(15) == #ok(15));\n /// assert(between10And20(9) == #err(\"Not larger than 10.\"));\n /// assert(between10And20(21) == #err(\"Not smaller than 20.\"));\n /// ```\n public func chain<R1, R2, Error>(\n x : Result<R1, Error>,\n y : R1 -> Result<R2, Error>\n ) : Result<R2, Error> {\n switch x {\n case (#err(e)) { #err(e) };\n case (#ok(r)) { y(r) }\n }\n };\n\n /// Flattens a nested `Result`.\n /// \n /// ```motoko\n /// import Result \"mo:base/Result\";\n /// assert(Result.flatten<Nat, Text>(#ok(#ok(10))) == #ok(10));\n /// assert(Result.flatten<Nat, Text>(#err(\"Wrong\")) == #err(\"Wrong\"));\n /// assert(Result.flatten<Nat, Text>(#ok(#err(\"Wrong\"))) == #err(\"Wrong\"));\n /// ```\n public func flatten<Ok, Error>(\n result : Result<Result<Ok, Error>, Error>\n ) : Result<Ok, Error> {\n switch result {\n case (#ok(ok)) { ok };\n case (#err(err)) { #err(err) }\n }\n };\n\n /// Maps the `Ok` type/value, leaving any `Error` type/value unchanged.\n public func mapOk<Ok1, Ok2, Error>(\n x : Result<Ok1, Error>,\n f : Ok1 -> Ok2\n ) : Result<Ok2, Error> {\n switch x {\n case (#err(e)) { #err(e) };\n case (#ok(r)) { #ok(f(r)) }\n }\n };\n\n /// Maps the `Err` type/value, leaving any `Ok` type/value unchanged.\n public func mapErr<Ok, Error1, Error2>(\n x : Result<Ok, Error1>,\n f : Error1 -> Error2\n ) : Result<Ok, Error2> {\n switch x {\n case (#err(e)) { #err(f(e)) };\n case (#ok(r)) { #ok(r) }\n }\n };\n\n /// Create a `Result` from an option, including an error value to handle the `null` case.\n /// ```motoko\n /// import Result \"mo:base/Result\";\n /// assert(Result.fromOption(?42, \"err\") == #ok(42));\n /// assert(Result.fromOption(null, \"err\") == #err(\"err\"));\n /// ```\n public func fromOption<R, E>(x : ?R, err : E) : Result<R, E> {\n switch x {\n case (?x) { #ok(x) };\n case null { #err(err) }\n }\n };\n\n /// Create an option from a `Result`, turning all #err into `null`.\n /// ```motoko\n /// import Result \"mo:base/Result\";\n /// assert(Result.toOption(#ok(42)) == ?42);\n /// assert(Result.toOption(#err(\"err\")) == null);\n /// ```\n public func toOption<R, E>(r : Result<R, E>) : ?R {\n switch r {\n case (#ok(x)) { ?x };\n case (#err(_)) { null }\n }\n };\n\n /// Applies a function to a successful value, but discards the result. Use\n /// `iterate` if you're only interested in the side effect `f` produces.\n /// \n /// ```motoko\n /// import Result \"mo:base/Result\";\n /// var counter : Nat = 0;\n /// Result.iterate<Nat, Text>(#ok(5), func (x : Nat) { counter += x });\n /// assert(counter == 5);\n /// Result.iterate<Nat, Text>(#err(\"Wrong\"), func (x : Nat) { counter += x });\n /// assert(counter == 5);\n /// ```\n public func iterate<Ok, Err>(res : Result<Ok, Err>, f : Ok -> ()) {\n switch res {\n case (#ok(ok)) { f(ok) };\n case _ {}\n }\n };\n\n // Whether this Result is an `#ok`\n public func isOk(r : Result<Any, Any>) : Bool {\n switch r {\n case (#ok(_)) { true };\n case (#err(_)) { false }\n }\n };\n\n // Whether this Result is an `#err`\n public func isErr(r : Result<Any, Any>) : Bool {\n switch r {\n case (#ok(_)) { false };\n case (#err(_)) { true }\n }\n };\n\n /// Asserts that its argument is an `#ok` result, traps otherwise.\n public func assertOk(r : Result<Any, Any>) {\n switch (r) {\n case (#err(_)) { assert false };\n case (#ok(_)) {}\n }\n };\n\n /// Asserts that its argument is an `#err` result, traps otherwise.\n public func assertErr(r : Result<Any, Any>) {\n switch (r) {\n case (#err(_)) {};\n case (#ok(_)) assert false\n }\n };\n\n /// Converts an upper cased `#Ok`, `#Err` result type into a lowercased `#ok`, `#err` result type.\n /// On the IC, a common convention is to use `#Ok` and `#Err` as the variants of a result type,\n /// but in Motoko, we use `#ok` and `#err` instead.\n public func fromUpper<Ok, Err>(\n result : { #Ok : Ok; #Err : Err }\n ) : Result<Ok, Err> {\n switch result {\n case (#Ok(ok)) { #ok(ok) };\n case (#Err(err)) { #err(err) }\n }\n };\n\n /// Converts a lower cased `#ok`, `#err` result type into an upper cased `#Ok`, `#Err` result type.\n /// On the IC, a common convention is to use `#Ok` and `#Err` as the variants of a result type,\n /// but in Motoko, we use `#ok` and `#err` instead.\n public func toUpper<Ok, Err>(\n result : Result<Ok, Err>\n ) : { #Ok : Ok; #Err : Err } {\n switch result {\n case (#ok(ok)) { #Ok(ok) };\n case (#err(err)) { #Err(err) }\n }\n };\n\n}\n"},"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"},"Int64.mo":{"content":"/// Provides utility functions on 64-bit signed integers.\n/// \n/// :::note\n/// Most operations are available as built-in operators (e.g. `1 + 1`).\n/// :::\n/// \n/// :::info Function form for higher-order use\n/// \n/// Several arithmetic and comparison functions (e.g. `add`, `sub`, `bitor`, `bitand`, `pow`) are defined in this module to enable their use as first-class function values, which is not possible with operators like `+`, `-`, `==`, etc., in Motoko. This allows you to pass these operations to higher-order functions such as `map`, `foldLeft`, or `sort`.\n/// :::\n/// \n/// Import from the base library to use this module.\n/// ```motoko name=import\n/// import Int64 \"mo:base/Int64\";\n/// ```\n\nimport Int \"Int\";\nimport Prim \"mo:⛔\";\n\nmodule {\n\n /// 64-bit signed integers.\n public type Int64 = Prim.Types.Int64;\n\n /// Minimum 64-bit integer value, `-2 ** 63`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int64.minimumValue // => -9_223_372_036_854_775_808\n /// ```\n public let minimumValue = -9_223_372_036_854_775_808 : Int64;\n\n /// Maximum 64-bit integer value, `+2 ** 63 - 1`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int64.maximumValue // => +9_223_372_036_854_775_807\n /// ```\n public let maximumValue = 9_223_372_036_854_775_807 : Int64;\n\n /// Converts a 64-bit signed integer to a signed integer with infinite precision.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int64.toInt(123_456) // => 123_456 : Int\n /// ```\n public let toInt : Int64 -> Int = Prim.int64ToInt;\n\n /// Converts a signed integer with infinite precision to a 64-bit signed integer.\n /// \n /// Traps on overflow/underflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int64.fromInt(123_456) // => +123_456 : Int64\n /// ```\n public let fromInt : Int -> Int64 = Prim.intToInt64;\n\n /// Converts a 32-bit signed integer to a 64-bit signed integer.\n /// \n /// Traps on overflow/underflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int64.fromInt32(-123_456) // => -123_456 : Int64\n /// ```\n public let fromInt32 : Int32 -> Int64 = Prim.int32ToInt64;\n\n /// Converts a 64-bit signed integer to a 32-bit signed integer.\n /// \n /// Wraps on overflow/underflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int64.toInt32(-123_456) // => -123_456 : Int32\n /// ```\n public let toInt32 : Int64 -> Int32 = Prim.int64ToInt32;\n\n /// Converts a signed integer with infinite precision to a 64-bit signed integer.\n /// \n /// Wraps on overflow/underflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int64.fromIntWrap(-123_456) // => -123_456 : Int64\n /// ```\n public let fromIntWrap : Int -> Int64 = Prim.intToInt64Wrap;\n\n /// Converts an unsigned 64-bit integer to a signed 64-bit integer.\n /// \n /// Wraps on overflow/underflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int64.fromNat64(123_456) // => +123_456 : Int64\n /// ```\n public let fromNat64 : Nat64 -> Int64 = Prim.nat64ToInt64;\n\n /// Converts a signed 64-bit integer to an unsigned 64-bit integer.\n /// \n /// Wraps on overflow/underflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int64.toNat64(-1) // => 18_446_744_073_709_551_615 : Nat64 // underflow\n /// ```\n public let toNat64 : Int64 -> Nat64 = Prim.int64ToNat64;\n\n /// Returns the Text representation of `x`. Textual representation _do not_\n /// contain underscores to represent commas.\n /// \n /// \n /// Example:\n /// ```motoko include=import\n /// Int64.toText(-123456) // => \"-123456\"\n /// ```\n public func toText(x : Int64) : Text {\n Int.toText(toInt(x))\n };\n\n /// Returns the absolute value of `x`.\n /// \n /// Traps when `x == -2 ** 63` (the minimum `Int64` value).\n /// \n /// Example:\n /// ```motoko include=import\n /// Int64.abs(-123456) // => +123_456\n /// ```\n public func abs(x : Int64) : Int64 {\n fromInt(Int.abs(toInt(x)))\n };\n\n /// Returns the minimum of `x` and `y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int64.min(+2, -3) // => -3\n /// ```\n public func min(x : Int64, y : Int64) : Int64 {\n if (x < y) { x } else { y }\n };\n\n /// Returns the maximum of `x` and `y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int64.max(+2, -3) // => +2\n /// ```\n public func max(x : Int64, y : Int64) : Int64 {\n if (x < y) { y } else { x }\n };\n\n /// Equality function for Int64 types.\n /// This is equivalent to `x == y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int64.equal(-1, -1); // => true\n /// ```\n /// \n\n /// \n /// Example:\n /// ```motoko include=import\n /// import Buffer \"mo:base/Buffer\";\n /// \n /// let buffer1 = Buffer.Buffer<Int64>(1);\n /// buffer1.add(-3);\n /// let buffer2 = Buffer.Buffer<Int64>(1);\n /// buffer2.add(-3);\n /// Buffer.equal(buffer1, buffer2, Int64.equal) // => true\n /// ```\n public func equal(x : Int64, y : Int64) : Bool { x == y };\n\n /// Inequality function for Int64 types.\n /// This is equivalent to `x != y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int64.notEqual(-1, -2); // => true\n /// ```\n /// \n\n public func notEqual(x : Int64, y : Int64) : Bool { x != y };\n\n /// \"Less than\" function for Int64 types.\n /// This is equivalent to `x < y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int64.less(-2, 1); // => true\n /// ```\n /// \n\n public func less(x : Int64, y : Int64) : Bool { x < y };\n\n /// \"Less than or equal\" function for Int64 types.\n /// This is equivalent to `x <= y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int64.lessOrEqual(-2, -2); // => true\n /// ```\n /// \n\n public func lessOrEqual(x : Int64, y : Int64) : Bool { x <= y };\n\n /// \"Greater than\" function for Int64 types.\n /// This is equivalent to `x > y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int64.greater(-2, -3); // => true\n /// ```\n /// \n\n public func greater(x : Int64, y : Int64) : Bool { x > y };\n\n /// \"Greater than or equal\" function for Int64 types.\n /// This is equivalent to `x >= y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int64.greaterOrEqual(-2, -2); // => true\n /// ```\n /// \n\n public func greaterOrEqual(x : Int64, y : Int64) : Bool { x >= y };\n\n /// General-purpose comparison function for `Int64`. Returns the `Order` (\n /// either `#less`, `#equal`, or `#greater`) of comparing `x` with `y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int64.compare(-3, 2) // => #less\n /// ```\n /// \n /// This function can be used as value for a high order function, such as a sort function.\n /// \n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.sort([1, -2, -3] : [Int64], Int64.compare) // => [-3, -2, 1]\n /// ```\n public func compare(x : Int64, y : Int64) : { #less; #equal; #greater } {\n if (x < y) { #less } else if (x == y) { #equal } else { #greater }\n };\n\n /// Returns the negation of `x`, `-x`.\n /// \n /// Traps on overflow, i.e. for `neg(-2 ** 63)`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int64.neg(123) // => -123\n /// ```\n /// \n\n public func neg(x : Int64) : Int64 { -x };\n\n /// Returns the sum of `x` and `y`, `x + y`.\n /// \n /// Traps on overflow/underflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int64.add(1234, 123) // => +1_357\n /// ```\n /// \n\n /// \n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.foldLeft<Int64, Int64>([1, -2, -3], 0, Int64.add) // => -4\n /// ```\n public func add(x : Int64, y : Int64) : Int64 { x + y };\n\n /// Returns the difference of `x` and `y`, `x - y`.\n /// \n /// Traps on overflow/underflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int64.sub(123, 100) // => +23\n /// ```\n /// \n\n /// \n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.foldLeft<Int64, Int64>([1, -2, -3], 0, Int64.sub) // => 4\n /// ```\n public func sub(x : Int64, y : Int64) : Int64 { x - y };\n\n /// Returns the product of `x` and `y`, `x * y`.\n /// \n /// Traps on overflow/underflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int64.mul(123, 10) // => +1_230\n /// ```\n /// \n\n /// \n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.foldLeft<Int64, Int64>([1, -2, -3], 1, Int64.mul) // => 6\n /// ```\n public func mul(x : Int64, y : Int64) : Int64 { x * y };\n\n /// Returns the signed integer division of `x` by `y`, `x / y`.\n /// Rounds the quotient towards zero, which is the same as truncating the decimal places of the quotient.\n /// \n /// Traps when `y` is zero.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int64.div(123, 10) // => +12\n /// ```\n /// \n\n public func div(x : Int64, y : Int64) : Int64 { x / y };\n\n /// Returns the remainder of the signed integer division of `x` by `y`, `x % y`,\n /// which is defined as `x - x / y * y`.\n /// \n /// Traps when `y` is zero.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int64.rem(123, 10) // => +3\n /// ```\n /// \n\n public func rem(x : Int64, y : Int64) : Int64 { x % y };\n\n /// Returns `x` to the power of `y`, `x ** y`.\n /// \n /// Traps on overflow/underflow and when `y < 0 or y >= 64`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int64.pow(2, 10) // => +1_024\n /// ```\n /// \n\n public func pow(x : Int64, y : Int64) : Int64 { x ** y };\n\n /// Returns the bitwise negation of `x`, `^x`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int64.bitnot(-256 /* 0xffff_ffff_ffff_ff00 */) // => +255 // 0xff\n /// ```\n /// \n\n public func bitnot(x : Int64) : Int64 { ^x };\n\n /// Returns the bitwise \"and\" of `x` and `y`, `x & y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int64.bitand(0xffff, 0x00f0) // => +240 // 0xf0\n /// ```\n /// \n\n public func bitand(x : Int64, y : Int64) : Int64 { x & y };\n\n /// Returns the bitwise \"or\" of `x` and `y`, `x | y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int64.bitor(0xffff, 0x00f0) // => +65_535 // 0xffff\n /// ```\n /// \n\n public func bitor(x : Int64, y : Int64) : Int64 { x | y };\n\n /// Returns the bitwise \"exclusive or\" of `x` and `y`, `x ^ y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int64.bitxor(0xffff, 0x00f0) // => +65_295 // 0xff0f\n /// ```\n /// \n\n public func bitxor(x : Int64, y : Int64) : Int64 { x ^ y };\n\n /// Returns the bitwise left shift of `x` by `y`, `x << y`.\n /// The right bits of the shift filled with zeros.\n /// Left-overflowing bits, including the sign bit, are discarded.\n /// \n /// For `y >= 64`, the semantics is the same as for `bitshiftLeft(x, y % 64)`.\n /// For `y < 0`, the semantics is the same as for `bitshiftLeft(x, y + y % 64)`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int64.bitshiftLeft(1, 8) // => +256 // 0x100 equivalent to `2 ** 8`.\n /// ```\n /// \n\n public func bitshiftLeft(x : Int64, y : Int64) : Int64 { x << y };\n\n /// Returns the signed bitwise right shift of `x` by `y`, `x >> y`.\n /// The sign bit is retained and the left side is filled with the sign bit.\n /// Right-underflowing bits are discarded, i.e. not rotated to the left side.\n /// \n /// For `y >= 64`, the semantics is the same as for `bitshiftRight(x, y % 64)`.\n /// For `y < 0`, the semantics is the same as for `bitshiftRight (x, y + y % 64)`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int64.bitshiftRight(1024, 8) // => +4 // equivalent to `1024 / (2 ** 8)`\n /// ```\n /// \n\n public func bitshiftRight(x : Int64, y : Int64) : Int64 { x >> y };\n\n /// Returns the bitwise left rotatation of `x` by `y`, `x <<> y`.\n /// Each left-overflowing bit is inserted again on the right side.\n /// The sign bit is rotated like other bits, i.e. the rotation interprets the number as unsigned.\n /// \n /// Changes the direction of rotation for negative `y`.\n /// For `y >= 64`, the semantics is the same as for `bitrotLeft(x, y % 64)`.\n /// \n /// Example:\n /// ```motoko include=import\n /// \n /// Int64.bitrotLeft(0x2000_0000_0000_0001, 4) // => +18 // 0x12.\n /// ```\n /// \n\n public func bitrotLeft(x : Int64, y : Int64) : Int64 { x <<> y };\n\n /// Returns the bitwise right rotation of `x` by `y`, `x <>> y`.\n /// Each right-underflowing bit is inserted again on the right side.\n /// The sign bit is rotated like other bits, i.e. the rotation interprets the number as unsigned.\n /// \n /// Changes the direction of rotation for negative `y`.\n /// For `y >= 64`, the semantics is the same as for `bitrotRight(x, y % 64)`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int64.bitrotRight(0x0002_0000_0000_0001, 48) // => +65538 // 0x1_0002.\n /// ```\n /// \n\n public func bitrotRight(x : Int64, y : Int64) : Int64 { x <>> y };\n\n /// Returns the value of bit `p` in `x`, `x & 2**p == 2**p`.\n /// If `p >= 64`, the semantics is the same as for `bittest(x, p % 64)`.\n /// This is equivalent to checking if the `p`-th bit is set in `x`, using 0 indexing.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int64.bittest(128, 7) // => true\n /// ```\n public func bittest(x : Int64, p : Nat) : Bool {\n Prim.btstInt64(x, Prim.intToInt64(p))\n };\n\n /// Returns the value of setting bit `p` in `x` to `1`.\n /// If `p >= 64`, the semantics is the same as for `bitset(x, p % 64)`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int64.bitset(0, 7) // => +128\n /// ```\n public func bitset(x : Int64, p : Nat) : Int64 {\n x | (1 << Prim.intToInt64(p))\n };\n\n /// Returns the value of clearing bit `p` in `x` to `0`.\n /// If `p >= 64`, the semantics is the same as for `bitclear(x, p % 64)`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int64.bitclear(-1, 7) // => -129\n /// ```\n public func bitclear(x : Int64, p : Nat) : Int64 {\n x & ^(1 << Prim.intToInt64(p))\n };\n\n /// Returns the value of flipping bit `p` in `x`.\n /// If `p >= 64`, the semantics is the same as for `bitclear(x, p % 64)`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int64.bitflip(255, 7) // => +127\n /// ```\n public func bitflip(x : Int64, p : Nat) : Int64 {\n x ^ (1 << Prim.intToInt64(p))\n };\n\n /// Returns the count of non-zero bits in `x`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int64.bitcountNonZero(0xffff) // => +16\n /// ```\n public let bitcountNonZero : (x : Int64) -> Int64 = Prim.popcntInt64;\n\n /// Returns the count of leading zero bits in `x`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int64.bitcountLeadingZero(0x8000_0000) // => +32\n /// ```\n public let bitcountLeadingZero : (x : Int64) -> Int64 = Prim.clzInt64;\n\n /// Returns the count of trailing zero bits in `x`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int64.bitcountTrailingZero(0x0201_0000) // => +16\n /// ```\n public let bitcountTrailingZero : (x : Int64) -> Int64 = Prim.ctzInt64;\n\n /// Returns the upper (i.e. most significant), lower (least significant)\n /// and in-between bytes of `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int64.explode 0x33772266aa885511 // => (51, 119, 34, 102, 170, 136, 85, 17)\n /// ```\n public let explode : (x : Int64) -> (msb : Nat8, Nat8, Nat8, Nat8, Nat8, Nat8, Nat8, lsb : Nat8) = Prim.explodeInt64;\n\n /// Returns the sum of `x` and `y`, `x +% y`.\n ///\n /// Wraps on overflow/underflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// Int64.addWrap(2 ** 62, 2 ** 62) // => -9_223_372_036_854_775_808 // overflow\n /// ```\n ///\n /// :::info \n /// The reason why this function is defined in this library (in addition\n /// to the existing `+%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `+%`\n /// as a function value at the moment.\n /// :::\n public func addWrap(x : Int64, y : Int64) : Int64 { x +% y };\n\n /// Returns the difference of `x` and `y`, `x -% y`.\n /// \n /// Wraps on overflow/underflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int64.subWrap(-2 ** 63, 1) // => +9_223_372_036_854_775_807 // underflow\n /// ```\n /// \n\n public func subWrap(x : Int64, y : Int64) : Int64 { x -% y };\n\n /// Returns the product of `x` and `y`, `x *% y`. Wraps on overflow.\n /// \n /// Wraps on overflow/underflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int64.mulWrap(2 ** 32, 2 ** 32) // => 0 // overflow\n /// ```\n /// \n\n public func mulWrap(x : Int64, y : Int64) : Int64 { x *% y };\n\n /// Returns `x` to the power of `y`, `x **% y`.\n /// \n /// Wraps on overflow/underflow.\n /// Traps if `y < 0 or y >= 64`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Int64.powWrap(2, 63) // => -9_223_372_036_854_775_808 // overflow\n /// ```\n /// \n\n public func powWrap(x : Int64, y : Int64) : Int64 { x **% y }\n}\n"},"Nat32.mo":{"content":"/// Provides utility functions on 32-bit unsigned integers.\n/// \n/// :::note\n/// Most operations on integer numbers (e.g. addition) are available as built-in operators (e.g. `1 + 1`).\n/// This module provides equivalent functions and `Text` conversion.\n/// :::\n/// \n/// :::info Function form for higher-order use\n/// \n/// Several arithmetic and comparison functions (e.g. `add`, `sub`, `equal`, `less`, `pow`) are defined in this module to enable their use as first-class function values, which is not possible with operators like `+`, `-`, `==`, etc., in Motoko. This allows you to pass these operations to higher-order functions such as `map`, `foldLeft`, or `sort`.\n/// :::\n/// \n/// Import from the base library to use this module.\n/// \n/// ```motoko name=import\n/// import Nat32 \"mo:base/Nat32\";\n/// ```\n\nimport Nat \"Nat\";\nimport Prim \"mo:⛔\";\n\nmodule {\n\n /// 32-bit natural numbers.\n public type Nat32 = Prim.Types.Nat32;\n\n /// Maximum 32-bit natural number. `2 ** 32 - 1`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat32.maximumValue; // => 4294967295 : Nat32\n /// ```\n public let maximumValue = 4294967295 : Nat32;\n\n /// Converts a 32-bit unsigned integer to an unsigned integer with infinite precision.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat32.toNat(123); // => 123 : Nat\n /// ```\n public let toNat : Nat32 -> Nat = Prim.nat32ToNat;\n\n /// Converts an unsigned integer with infinite precision to a 32-bit unsigned integer.\n /// \n /// Traps on overflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat32.fromNat(123); // => 123 : Nat32\n /// ```\n public let fromNat : Nat -> Nat32 = Prim.natToNat32;\n\n /// Converts a 16-bit unsigned integer to a 32-bit unsigned integer.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat32.fromNat16(123); // => 123 : Nat32\n /// ```\n public func fromNat16(x : Nat16) : Nat32 {\n Prim.nat16ToNat32(x)\n };\n\n /// Converts a 32-bit unsigned integer to a 16-bit unsigned integer.\n /// \n /// Traps on overflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat32.toNat16(123); // => 123 : Nat16\n /// ```\n public func toNat16(x : Nat32) : Nat16 {\n Prim.nat32ToNat16(x)\n };\n\n /// Converts a 64-bit unsigned integer to a 32-bit unsigned integer.\n /// \n /// Traps on overflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat32.fromNat64(123); // => 123 : Nat32\n /// ```\n public func fromNat64(x : Nat64) : Nat32 {\n Prim.nat64ToNat32(x)\n };\n\n /// Converts a 32-bit unsigned integer to a 64-bit unsigned integer.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat32.toNat64(123); // => 123 : Nat64\n /// ```\n public func toNat64(x : Nat32) : Nat64 {\n Prim.nat32ToNat64(x)\n };\n\n /// Converts a signed integer with infinite precision to a 32-bit unsigned integer.\n /// \n /// Traps on overflow/underflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat32.fromIntWrap(123); // => 123 : Nat32\n /// ```\n public let fromIntWrap : Int -> Nat32 = Prim.intToNat32Wrap;\n\n /// Converts `x` to its textual representation. Textual representation _do not_\n /// contain underscores to represent commas.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat32.toText(1234); // => \"1234\" : Text\n /// ```\n public func toText(x : Nat32) : Text {\n Nat.toText(toNat(x))\n };\n\n /// Returns the minimum of `x` and `y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat32.min(123, 456); // => 123 : Nat32\n /// ```\n public func min(x : Nat32, y : Nat32) : Nat32 {\n if (x < y) { x } else { y }\n };\n\n /// Returns the maximum of `x` and `y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat32.max(123, 456); // => 456 : Nat32\n /// ```\n public func max(x : Nat32, y : Nat32) : Nat32 {\n if (x < y) { y } else { x }\n };\n\n /// Equality function for Nat32 types.\n /// This is equivalent to `x == y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat32.equal(1, 1); // => true\n /// (1 : Nat32) == (1 : Nat32) // => true\n /// ```\n /// \n\n /// \n /// Example:\n /// ```motoko include=import\n /// import Buffer \"mo:base/Buffer\";\n /// \n /// let buffer1 = Buffer.Buffer<Nat32>(3);\n /// let buffer2 = Buffer.Buffer<Nat32>(3);\n /// Buffer.equal(buffer1, buffer2, Nat32.equal) // => true\n /// ```\n public func equal(x : Nat32, y : Nat32) : Bool { x == y };\n\n /// Inequality function for Nat32 types.\n /// This is equivalent to `x != y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat32.notEqual(1, 2); // => true\n /// (1 : Nat32) != (2 : Nat32) // => true\n /// ```\n /// \n\n public func notEqual(x : Nat32, y : Nat32) : Bool { x != y };\n\n /// \"Less than\" function for Nat32 types.\n /// This is equivalent to `x < y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat32.less(1, 2); // => true\n /// (1 : Nat32) < (2 : Nat32) // => true\n /// ```\n /// \n\n public func less(x : Nat32, y : Nat32) : Bool { x < y };\n\n /// \"Less than or equal\" function for Nat32 types.\n /// This is equivalent to `x <= y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat32.lessOrEqual(1, 2); // => true\n /// (1 : Nat32) <= (2 : Nat32) // => true\n /// ```\n /// \n\n public func lessOrEqual(x : Nat32, y : Nat32) : Bool { x <= y };\n\n /// \"Greater than\" function for Nat32 types.\n /// This is equivalent to `x > y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat32.greater(2, 1); // => true\n /// (2 : Nat32) > (1 : Nat32) // => true\n /// ```\n /// \n\n public func greater(x : Nat32, y : Nat32) : Bool { x > y };\n\n /// \"Greater than or equal\" function for Nat32 types.\n /// This is equivalent to `x >= y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat32.greaterOrEqual(2, 1); // => true\n /// (2 : Nat32) >= (1 : Nat32) // => true\n /// ```\n /// \n\n public func greaterOrEqual(x : Nat32, y : Nat32) : Bool { x >= y };\n\n /// General purpose comparison function for `Nat32`. Returns the `Order` (\n /// either `#less`, `#equal`, or `#greater`) of comparing `x` with `y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat32.compare(2, 3) // => #less\n /// ```\n /// \n /// This function can be used as value for a high order function, such as a sort function.\n /// \n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.sort([2, 3, 1] : [Nat32], Nat32.compare) // => [1, 2, 3]\n /// ```\n public func compare(x : Nat32, y : Nat32) : { #less; #equal; #greater } {\n if (x < y) { #less } else if (x == y) { #equal } else { #greater }\n };\n\n /// Returns the sum of `x` and `y`, `x + y`.\n /// Traps on overflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat32.add(1, 2); // => 3\n /// (1 : Nat32) + (2 : Nat32) // => 3\n /// ```\n /// \n\n /// \n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.foldLeft<Nat32, Nat32>([2, 3, 1], 0, Nat32.add) // => 6\n /// ```\n public func add(x : Nat32, y : Nat32) : Nat32 { x + y };\n\n /// Returns the difference of `x` and `y`, `x - y`.\n /// Traps on underflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat32.sub(2, 1); // => 1\n /// (2 : Nat32) - (1 : Nat32) // => 1\n /// ```\n /// \n\n /// \n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.foldLeft<Nat32, Nat32>([2, 3, 1], 20, Nat32.sub) // => 14\n /// ```\n public func sub(x : Nat32, y : Nat32) : Nat32 { x - y };\n\n /// Returns the product of `x` and `y`, `x * y`.\n /// Traps on overflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat32.mul(2, 3); // => 6\n /// (2 : Nat32) * (3 : Nat32) // => 6\n /// ```\n /// \n\n /// \n /// Example:\n /// ```motoko include=import\n /// import Array \"mo:base/Array\";\n /// Array.foldLeft<Nat32, Nat32>([2, 3, 1], 1, Nat32.mul) // => 6\n /// ```\n public func mul(x : Nat32, y : Nat32) : Nat32 { x * y };\n\n /// Returns the division of `x by y`, `x / y`.\n /// Traps when `y` is zero.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat32.div(6, 2); // => 3\n /// (6 : Nat32) / (2 : Nat32) // => 3\n /// ```\n /// \n\n public func div(x : Nat32, y : Nat32) : Nat32 { x / y };\n\n /// Returns the remainder of `x` divided by `y`, `x % y`.\n /// Traps when `y` is zero.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat32.rem(6, 4); // => 2\n /// (6 : Nat32) % (4 : Nat32) // => 2\n /// ```\n /// \n\n public func rem(x : Nat32, y : Nat32) : Nat32 { x % y };\n\n /// Returns `x` to the power of `y`, `x ** y`. Traps on overflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat32.pow(2, 3); // => 8\n /// (2 : Nat32) ** (3 : Nat32) // => 8\n /// ```\n /// \n\n public func pow(x : Nat32, y : Nat32) : Nat32 { x ** y };\n\n /// Returns the bitwise negation of `x`, `^x`.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat32.bitnot(0) // => 4294967295\n /// ^(0 : Nat32) // => 4294967295\n /// ```\n /// \n\n public func bitnot(x : Nat32) : Nat32 { ^x };\n\n /// Returns the bitwise and of `x` and `y`, `x & y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat32.bitand(1, 3); // => 1\n /// (1 : Nat32) & (3 : Nat32) // => 1\n /// ```\n /// \n\n public func bitand(x : Nat32, y : Nat32) : Nat32 { x & y };\n\n /// Returns the bitwise or of `x` and `y`, `x | y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat32.bitor(1, 3); // => 3\n /// (1 : Nat32) | (3 : Nat32) // => 3\n /// ```\n /// \n\n public func bitor(x : Nat32, y : Nat32) : Nat32 { x | y };\n\n /// Returns the bitwise exclusive or of `x` and `y`, `x ^ y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat32.bitxor(1, 3); // => 2\n /// (1 : Nat32) ^ (3 : Nat32) // => 2\n /// ```\n /// \n\n public func bitxor(x : Nat32, y : Nat32) : Nat32 { x ^ y };\n\n /// Returns the bitwise shift left of `x` by `y`, `x << y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat32.bitshiftLeft(1, 3); // => 8\n /// (1 : Nat32) << (3 : Nat32) // => 8\n /// ```\n /// \n\n public func bitshiftLeft(x : Nat32, y : Nat32) : Nat32 { x << y };\n\n /// Returns the bitwise shift right of `x` by `y`, `x >> y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat32.bitshiftRight(8, 3); // => 1\n /// (8 : Nat32) >> (3 : Nat32) // => 1\n /// ```\n /// \n\n public func bitshiftRight(x : Nat32, y : Nat32) : Nat32 { x >> y };\n\n /// Returns the bitwise rotate left of `x` by `y`, `x <<> y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat32.bitrotLeft(1, 3); // => 8\n /// (1 : Nat32) <<> (3 : Nat32) // => 8\n /// ```\n /// \n\n public func bitrotLeft(x : Nat32, y : Nat32) : Nat32 { x <<> y };\n\n /// Returns the bitwise rotate right of `x` by `y`, `x <>> y`.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat32.bitrotRight(1, 1); // => 2147483648\n /// (1 : Nat32) <>> (1 : Nat32) // => 2147483648\n /// ```\n /// \n\n public func bitrotRight(x : Nat32, y : Nat32) : Nat32 { x <>> y };\n\n /// Returns the value of bit `p mod 32` in `x`, `(x & 2^(p mod 32)) == 2^(p mod 32)`.\n /// This is equivalent to checking if the `p`-th bit is set in `x`, using 0 indexing.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat32.bittest(5, 2); // => true\n /// ```\n public func bittest(x : Nat32, p : Nat) : Bool {\n Prim.btstNat32(x, Prim.natToNat32(p))\n };\n\n /// Returns the value of setting bit `p mod 32` in `x` to `1`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat32.bitset(5, 1); // => 7\n /// ```\n public func bitset(x : Nat32, p : Nat) : Nat32 {\n x | (1 << Prim.natToNat32(p))\n };\n\n /// Returns the value of clearing bit `p mod 32` in `x` to `0`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat32.bitclear(5, 2); // => 1\n /// ```\n public func bitclear(x : Nat32, p : Nat) : Nat32 {\n x & ^(1 << Prim.natToNat32(p))\n };\n\n /// Returns the value of flipping bit `p mod 32` in `x`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat32.bitflip(5, 2); // => 1\n /// ```\n public func bitflip(x : Nat32, p : Nat) : Nat32 {\n x ^ (1 << Prim.natToNat32(p))\n };\n\n /// Returns the count of non-zero bits in `x`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat32.bitcountNonZero(5); // => 2\n /// ```\n public let bitcountNonZero : (x : Nat32) -> Nat32 = Prim.popcntNat32;\n\n /// Returns the count of leading zero bits in `x`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat32.bitcountLeadingZero(5); // => 29\n /// ```\n public let bitcountLeadingZero : (x : Nat32) -> Nat32 = Prim.clzNat32;\n\n /// Returns the count of trailing zero bits in `x`.\n /// \n /// Example:\n /// ```motoko include=import\n /// Nat32.bitcountTrailingZero(16); // => 4\n /// ```\n public let bitcountTrailingZero : (x : Nat32) -> Nat32 = Prim.ctzNat32;\n\n /// Returns the upper (i.e. most significant), lower (least significant)\n /// and in-between bytes of `x`.\n ///\n /// Example:\n /// ```motoko include=import\n /// Nat32.explode 0xaa885511 // => (170, 136, 85, 17)\n /// ```\n public let explode : (x : Nat32) -> (msb : Nat8, Nat8, Nat8, lsb : Nat8) = Prim.explodeNat32;\n\n /// Returns the sum of `x` and `y`, `x +% y`. Wraps on overflow.\n ///\n /// Example:\n /// ```motoko include=import\n /// ignore Nat32.addWrap(4294967295, 1); // => 0\n /// (4294967295 : Nat32) +% (1 : Nat32) // => 0\n /// ```\n ///\n /// :::info\n /// The reason why this function is defined in this library (in addition\n /// to the existing `+%` operator) is so that you can use it as a function\n /// value to pass to a higher order function. It is not possible to use `+%`\n /// as a function value at the moment.\n /// :::\n public func addWrap(x : Nat32, y : Nat32) : Nat32 { x +% y };\n\n /// Returns the difference of `x` and `y`, `x -% y`. Wraps on underflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat32.subWrap(0, 1); // => 4294967295\n /// (0 : Nat32) -% (1 : Nat32) // => 4294967295\n /// ```\n /// \n\n public func subWrap(x : Nat32, y : Nat32) : Nat32 { x -% y };\n\n /// Returns the product of `x` and `y`, `x *% y`. Wraps on overflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat32.mulWrap(2147483648, 2); // => 0\n /// (2147483648 : Nat32) *% (2 : Nat32) // => 0\n /// ```\n /// \n\n public func mulWrap(x : Nat32, y : Nat32) : Nat32 { x *% y };\n\n /// Returns `x` to the power of `y`, `x **% y`. Wraps on overflow.\n /// \n /// Example:\n /// ```motoko include=import\n /// ignore Nat32.powWrap(2, 32); // => 0\n /// (2 : Nat32) **% (32 : Nat32) // => 0\n /// ```\n /// \n\n public func powWrap(x : Nat32, y : Nat32) : Nat32 { x **% y };\n\n}\n"},"Text.mo":{"content":"/// Utility functions for `Text` values.\n/// \n/// A `Text` value represents human-readable text as a sequence of characters of type `Char`.\n/// \n/// ```motoko\n/// let text = \"Hello!\";\n/// let size = text.size(); // 6\n/// let iter = text.chars(); // iterator ('H', 'e', 'l', 'l', 'o', '!')\n/// let concat = text # \" 👋\"; // \"Hello! 👋\"\n/// ```\n/// \n/// The `\"mo:base/Text\"` module defines additional operations on `Text` values.\n/// \n/// Import the module from the base library:\n/// \n/// ```motoko name=import\n/// import Text \"mo:base/Text\";\n/// ```\n/// \n/// :::note\n/// `Text` values are represented as ropes of UTF-8 character sequences with O(1) concatenation.\n/// :::\n\nimport Char \"Char\";\nimport Iter \"Iter\";\nimport Hash \"Hash\";\nimport List \"List\";\nimport Stack \"Stack\";\nimport Prim \"mo:⛔\";\n\nmodule {\n\n /// The type corresponding to primitive `Text` values.\n /// \n /// ```motoko\n /// let hello = \"Hello!\";\n /// let emoji = \"👋\";\n /// let concat = hello # \" \" # emoji; // \"Hello! 👋\"\n /// ```\n public type Text = Prim.Types.Text;\n\n /// Converts the given `Char` to a `Text` value.\n /// \n /// ```motoko include=import\n /// let text = Text.fromChar('A'); // \"A\"\n /// ```\n public let fromChar : (c : Char) -> Text = Prim.charToText;\n\n /// Converts the given `[Char]` to a `Text` value.\n /// \n /// ```motoko include=import\n /// let text = Text.fromArray(['A', 'v', 'o', 'c', 'a', 'd', 'o']); // \"Avocado\"\n /// ```\n /// \n/// | Runtime | Space |\n/// |-----------|-----------|\n/// | O(a.size()) | O(a.size()) |\n public func fromArray(a : [Char]) : Text = fromIter(a.vals());\n\n /// Converts the given `[var Char]` to a `Text` value.\n /// \n /// ```motoko include=import\n /// let text = Text.fromVarArray([var 'E', 'g', 'g', 'p', 'l', 'a', 'n', 't']); // \"Eggplant\"\n /// ```\n /// \n/// | Runtime | Space |\n/// |-----------|-----------|\n/// | O(a.size()) | O(a.size()) |\n public func fromVarArray(a : [var Char]) : Text = fromIter(a.vals());\n\n /// Iterates over each `Char` value in the given `Text`.\n /// \n /// Equivalent to calling the `t.chars()` method where `t` is a `Text` value.\n /// \n /// ```motoko include=import\n /// import { print } \"mo:base/Debug\";\n /// \n /// for (c in Text.toIter(\"abc\")) {\n /// print(debug_show c);\n /// }\n /// ```\n public func toIter(t : Text) : Iter.Iter<Char> = t.chars();\n\n /// Creates a new `Array` containing characters of the given `Text`.\n /// \n /// Equivalent to `Iter.toArray(t.chars())`.\n /// \n /// ```motoko include=import\n /// assert Text.toArray(\"Café\") == ['C', 'a', 'f', 'é'];\n /// ```\n /// \n/// | Runtime | Space |\n/// |-----------|-----------|\n/// | O(t.size()) | O(t.size()) |\n public func toArray(t : Text) : [Char] {\n let cs = t.chars();\n // We rely on Array_tabulate's implementation details: it fills\n // the array from left to right sequentially.\n Prim.Array_tabulate<Char>(\n t.size(),\n func _ {\n switch (cs.next()) {\n case (?c) { c };\n case null { Prim.trap(\"Text.toArray\") }\n }\n }\n )\n };\n\n /// Creates a new mutable `Array` containing characters of the given `Text`.\n /// \n /// Equivalent to `Iter.toArrayMut(t.chars())`.\n /// \n /// ```motoko include=import\n /// assert Text.toVarArray(\"Café\") == [var 'C', 'a', 'f', 'é'];\n /// ```\n /// \n/// | Runtime | Space |\n/// |-----------|-----------|\n/// | O(t.size()) | O(t.size()) |\n public func toVarArray(t : Text) : [var Char] {\n let n = t.size();\n if (n == 0) {\n return [var]\n };\n let array = Prim.Array_init<Char>(n, ' ');\n var i = 0;\n for (c in t.chars()) {\n array[i] := c;\n i += 1\n };\n array\n };\n\n /// Creates a `Text` value from a `Char` iterator.\n /// \n /// ```motoko include=import\n /// let text = Text.fromIter(['a', 'b', 'c'].vals()); // \"abc\"\n /// ```\n public func fromIter(cs : Iter.Iter<Char>) : Text {\n var r = \"\";\n for (c in cs) {\n r #= Prim.charToText(c)\n };\n return r\n };\n\n /// Create a text from a character list.\n /// Example:\n /// ```motoko include=initialize\n /// fromList(?('H', ?('e', ?('l', ?('l', ?('o', null))))));\n /// // => \"Hello\"\n /// ```\n /// \n/// | Runtime | Space |\n/// |-----------|-----------|\n/// | O(size cs) | O(size cs) |\n public func fromList(cs : List.List<Char>) : Text = fromIter(List.toIter cs);\n\n /// Create a character list from a text.\n /// Example:\n /// ```motoko include=initialize\n /// toList(\"Hello\");\n /// // => ?('H', ?('e', ?('l', ?('l', ?('o', null)))))\n /// ```\n /// \n/// | Runtime | Space |\n/// |-----------|-----------|\n/// | O(t.size()) | O(t.size()) |\n public func toList(t : Text) : List.List<Char> {\n var acc : List.List<Char> = null;\n for (c in t.chars()) {\n acc := ?(c, acc)\n };\n List.reverse acc\n };\n\n /// Returns the number of characters in the given `Text`.\n /// \n /// Equivalent to calling `t.size()` where `t` is a `Text` value.\n /// \n /// ```motoko include=import\n /// let size = Text.size(\"abc\"); // 3\n /// ```\n public func size(t : Text) : Nat { t.size() };\n\n /// Returns a hash obtained by using the `djb2` algorithm ([more details](http://www.cse.yorku.ca/~oz/hash.html)).\n /// \n /// ```motoko include=import\n /// let hash = Text.hash(\"abc\");\n /// ```\n /// \n /// :::info\n /// This algorithm is intended for use in data structures rather than as a cryptographic hash function.\n /// :::\n public func hash(t : Text) : Hash.Hash {\n var x : Nat32 = 5381;\n for (char in t.chars()) {\n let c : Nat32 = Prim.charToNat32(char);\n x := ((x << 5) +% x) +% c\n };\n return x\n };\n\n /// Returns `t1 # t2`, where `#` is the `Text` concatenation operator.\n /// \n /// ```motoko include=import\n /// let a = \"Hello\";\n /// let b = \"There\";\n /// let together = a # b; // \"HelloThere\"\n /// let withSpace = a # \" \" # b; // \"Hello There\"\n /// let togetherAgain = Text.concat(a, b); // \"HelloThere\"\n /// ```\n public func concat(t1 : Text, t2 : Text) : Text = t1 # t2;\n\n /// Returns `t1 == t2`.\n public func equal(t1 : Text, t2 : Text) : Bool { t1 == t2 };\n\n /// Returns `t1 != t2`.\n public func notEqual(t1 : Text, t2 : Text) : Bool { t1 != t2 };\n\n /// Returns `t1 < t2`.\n public func less(t1 : Text, t2 : Text) : Bool { t1 < t2 };\n\n /// Returns `t1 <= t2`.\n public func lessOrEqual(t1 : Text, t2 : Text) : Bool { t1 <= t2 };\n\n /// Returns `t1 > t2`.\n public func greater(t1 : Text, t2 : Text) : Bool { t1 > t2 };\n\n /// Returns `t1 >= t2`.\n public func greaterOrEqual(t1 : Text, t2 : Text) : Bool { t1 >= t2 };\n\n /// Compares `t1` and `t2` lexicographically.\n /// \n /// ```motoko include=import\n /// import { print } \"mo:base/Debug\";\n /// \n /// print(debug_show Text.compare(\"abc\", \"abc\")); // #equal\n /// print(debug_show Text.compare(\"abc\", \"def\")); // #less\n /// print(debug_show Text.compare(\"abc\", \"ABC\")); // #greater\n /// ```\n public func compare(t1 : Text, t2 : Text) : { #less; #equal; #greater } {\n let c = Prim.textCompare(t1, t2);\n if (c < 0) #less else if (c == 0) #equal else #greater\n };\n\n private func extract(t : Text, i : Nat, j : Nat) : Text {\n let size = t.size();\n if (i == 0 and j == size) return t;\n assert (j <= size);\n let cs = t.chars();\n var r = \"\";\n var n = i;\n while (n > 0) {\n ignore cs.next();\n n -= 1\n };\n n := j;\n while (n > 0) {\n switch (cs.next()) {\n case null { assert false };\n case (?c) { r #= Prim.charToText(c) }\n };\n n -= 1\n };\n return r\n };\n\n /// Join an iterator of `Text` values with a given delimiter.\n /// \n /// ```motoko include=import\n /// let joined = Text.join(\", \", [\"a\", \"b\", \"c\"].vals()); // \"a, b, c\"\n /// ```\n public func join(sep : Text, ts : Iter.Iter<Text>) : Text {\n var r = \"\";\n if (sep.size() == 0) {\n for (t in ts) {\n r #= t\n };\n return r\n };\n let next = ts.next;\n switch (next()) {\n case null { return r };\n case (?t) {\n r #= t\n }\n };\n loop {\n switch (next()) {\n case null { return r };\n case (?t) {\n r #= sep;\n r #= t\n }\n }\n }\n };\n\n /// Applies a function to each character in a `Text` value, returning the concatenated `Char` results.\n /// \n /// ```motoko include=import\n /// // Replace all occurrences of '?' with '!'\n /// let result = Text.map(\"Motoko?\", func(c) {\n /// if (c == '?') '!'\n /// else c\n /// });\n /// ```\n public func map(t : Text, f : Char -> Char) : Text {\n var r = \"\";\n for (c in t.chars()) {\n r #= Prim.charToText(f(c))\n };\n return r\n };\n\n /// Returns the result of applying `f` to each character in `ts`, concatenating the intermediate text values.\n /// \n /// ```motoko include=import\n /// // Replace all occurrences of '?' with \"!!\"\n /// let result = Text.translate(\"Motoko?\", func(c) {\n /// if (c == '?') \"!!\"\n /// else Text.fromChar(c)\n /// }); // \"Motoko!!\"\n /// ```\n public func translate(t : Text, f : Char -> Text) : Text {\n var r = \"\";\n for (c in t.chars()) {\n r #= f(c)\n };\n return r\n };\n\n /// A pattern `p` describes a sequence of characters. A pattern has one of the following forms:\n /// \n /// * `#char c` matches the single character sequence, `c`.\n /// * `#text t` matches multi-character text sequence `t`.\n /// * `#predicate p` matches any single character sequence `c` satisfying predicate `p(c)`.\n /// \n /// A _match_ for `p` is any sequence of characters matching the pattern `p`.\n /// \n /// ```motoko include=import\n /// let charPattern = #char 'A';\n /// let textPattern = #text \"phrase\";\n /// let predicatePattern : Text.Pattern = #predicate (func(c) { c == 'A' or c == 'B' }); // matches \"A\" or \"B\"\n /// ```\n public type Pattern = {\n #char : Char;\n #text : Text;\n #predicate : (Char -> Bool)\n };\n\n private func take(n : Nat, cs : Iter.Iter<Char>) : Iter.Iter<Char> {\n var i = n;\n object {\n public func next() : ?Char {\n if (i == 0) return null;\n i -= 1;\n return cs.next()\n }\n }\n };\n\n private func empty() : Iter.Iter<Char> {\n object {\n public func next() : ?Char = null\n }\n };\n\n private type Match = {\n /// #success on complete match\n #success;\n /// #fail(cs,c) on partial match of cs, but failing match on c\n #fail : (cs : Iter.Iter<Char>, c : Char);\n /// #empty(cs) on partial match of cs and empty stream\n #empty : (cs : Iter.Iter<Char>)\n };\n\n private func sizeOfPattern(pat : Pattern) : Nat {\n switch pat {\n case (#text(t)) { t.size() };\n case (#predicate(_) or #char(_)) { 1 }\n }\n };\n\n private func matchOfPattern(pat : Pattern) : (cs : Iter.Iter<Char>) -> Match {\n switch pat {\n case (#char(p)) {\n func(cs : Iter.Iter<Char>) : Match {\n switch (cs.next()) {\n case (?c) {\n if (p == c) {\n #success\n } else {\n #fail(empty(), c)\n }\n };\n case null { #empty(empty()) }\n }\n }\n };\n case (#predicate(p)) {\n func(cs : Iter.Iter<Char>) : Match {\n switch (cs.next()) {\n case (?c) {\n if (p(c)) {\n #success\n } else {\n #fail(empty(), c)\n }\n };\n case null { #empty(empty()) }\n }\n }\n };\n case (#text(p)) {\n func(cs : Iter.Iter<Char>) : Match {\n var i = 0;\n let ds = p.chars();\n loop {\n switch (ds.next()) {\n case (?d) {\n switch (cs.next()) {\n case (?c) {\n if (c != d) {\n return #fail(take(i, p.chars()), c)\n };\n i += 1\n };\n case null {\n return #empty(take(i, p.chars()))\n }\n }\n };\n case null { return #success }\n }\n }\n }\n }\n }\n };\n\n private class CharBuffer(cs : Iter.Iter<Char>) : Iter.Iter<Char> = {\n\n var stack : Stack.Stack<(Iter.Iter<Char>, Char)> = Stack.Stack();\n\n public func pushBack(cs0 : Iter.Iter<Char>, c : Char) {\n stack.push((cs0, c))\n };\n\n public func next() : ?Char {\n switch (stack.peek()) {\n case (?(buff, c)) {\n switch (buff.next()) {\n case null {\n ignore stack.pop();\n return ?c\n };\n case oc {\n return oc\n }\n }\n };\n case null {\n return cs.next()\n }\n }\n }\n };\n\n /// Splits the input `Text` with the specified `Pattern`.\n /// \n /// Two fields are separated by exactly one match.\n /// \n /// ```motoko include=import\n /// let words = Text.split(\"This is a sentence.\", #char ' ');\n /// Text.join(\"|\", words) // \"This|is|a|sentence.\"\n /// ```\n public func split(t : Text, p : Pattern) : Iter.Iter<Text> {\n let match = matchOfPattern(p);\n let cs = CharBuffer(t.chars());\n var state = 0;\n var field = \"\";\n object {\n public func next() : ?Text {\n switch state {\n case (0 or 1) {\n loop {\n switch (match(cs)) {\n case (#success) {\n let r = field;\n field := \"\";\n state := 1;\n return ?r\n };\n case (#empty(cs1)) {\n for (c in cs1) {\n field #= fromChar(c)\n };\n let r = if (state == 0 and field == \"\") {\n null\n } else {\n ?field\n };\n state := 2;\n return r\n };\n case (#fail(cs1, c)) {\n cs.pushBack(cs1, c);\n switch (cs.next()) {\n case (?ci) {\n field #= fromChar(ci)\n };\n case null {\n let r = if (state == 0 and field == \"\") {\n null\n } else {\n ?field\n };\n state := 2;\n return r\n }\n }\n }\n }\n }\n };\n case _ { return null }\n }\n }\n }\n };\n\n /// Returns a sequence of tokens from the input `Text` delimited by the specified `Pattern`, derived from start to end.\n /// A \"token\" is a non-empty maximal subsequence of `t` not containing a match for pattern `p`.\n /// Two tokens may be separated by one or more matches of `p`.\n /// \n /// ```motoko include=import\n /// let tokens = Text.tokens(\"this needs\\n an example\", #predicate (func(c) { c == ' ' or c == '\\n' }));\n /// Text.join(\"|\", tokens) // \"this|needs|an|example\"\n /// ```\n public func tokens(t : Text, p : Pattern) : Iter.Iter<Text> {\n let fs = split(t, p);\n object {\n public func next() : ?Text {\n switch (fs.next()) {\n case (?\"\") { next() };\n case ot { ot }\n }\n }\n }\n };\n\n /// Returns `true` if the input `Text` contains a match for the specified `Pattern`.\n /// \n /// ```motoko include=import\n /// Text.contains(\"Motoko\", #text \"oto\") // true\n /// ```\n public func contains(t : Text, p : Pattern) : Bool {\n let match = matchOfPattern(p);\n let cs = CharBuffer(t.chars());\n loop {\n switch (match(cs)) {\n case (#success) {\n return true\n };\n case (#empty(_cs1)) {\n return false\n };\n case (#fail(cs1, c)) {\n cs.pushBack(cs1, c);\n switch (cs.next()) {\n case null {\n return false\n };\n case _ {}; // continue\n }\n }\n }\n }\n };\n\n /// Returns `true` if the input `Text` starts with a prefix matching the specified `Pattern`.\n /// \n /// ```motoko include=import\n /// Text.startsWith(\"Motoko\", #text \"Mo\") // true\n /// ```\n public func startsWith(t : Text, p : Pattern) : Bool {\n var cs = t.chars();\n let match = matchOfPattern(p);\n switch (match(cs)) {\n case (#success) { true };\n case _ { false }\n }\n };\n\n /// Returns `true` if the input `Text` ends with a suffix matching the specified `Pattern`.\n /// \n /// ```motoko include=import\n /// Text.endsWith(\"Motoko\", #char 'o') // true\n /// ```\n public func endsWith(t : Text, p : Pattern) : Bool {\n let s2 = sizeOfPattern(p);\n if (s2 == 0) return true;\n let s1 = t.size();\n if (s2 > s1) return false;\n let match = matchOfPattern(p);\n var cs1 = t.chars();\n var diff : Nat = s1 - s2;\n while (diff > 0) {\n ignore cs1.next();\n diff -= 1\n };\n switch (match(cs1)) {\n case (#success) { true };\n case _ { false }\n }\n };\n\n /// Returns the input text `t` with all matches of pattern `p` replaced by text `r`.\n /// \n /// ```motoko include=import\n /// let result = Text.replace(\"abcabc\", #char 'a', \"A\"); // \"AbcAbc\"\n /// ```\n public func replace(t : Text, p : Pattern, r : Text) : Text {\n let match = matchOfPattern(p);\n let size = sizeOfPattern(p);\n let cs = CharBuffer(t.chars());\n var res = \"\";\n label l loop {\n switch (match(cs)) {\n case (#success) {\n res #= r;\n if (size > 0) {\n continue l\n }\n };\n case (#empty(cs1)) {\n for (c1 in cs1) {\n res #= fromChar(c1)\n };\n break l\n };\n case (#fail(cs1, c)) {\n cs.pushBack(cs1, c)\n }\n };\n switch (cs.next()) {\n case null {\n break l\n };\n case (?c1) {\n res #= fromChar(c1)\n }; // continue\n }\n };\n return res\n };\n\n /// Strips one occurrence of the given `Pattern` from the beginning of the input `Text`.\n /// If you want to remove multiple instances of the pattern, use `Text.trimStart()` instead.\n /// \n /// ```motoko include=import\n /// // Try to strip a nonexistent character\n /// let none = Text.stripStart(\"abc\", #char '-'); // null\n /// // Strip just one '-'\n /// let one = Text.stripStart(\"--abc\", #char '-'); // ?\"-abc\"\n /// ```\n public func stripStart(t : Text, p : Pattern) : ?Text {\n let s = sizeOfPattern(p);\n if (s == 0) return ?t;\n var cs = t.chars();\n let match = matchOfPattern(p);\n switch (match(cs)) {\n case (#success) return ?fromIter(cs);\n case _ return null\n }\n };\n\n /// Strips one occurrence of the given `Pattern` from the end of the input `Text`.\n /// If you want to remove multiple instances of the pattern, use `Text.trimEnd()` instead.\n /// \n /// ```motoko include=import\n /// // Try to strip a nonexistent character\n /// let none = Text.stripEnd(\"xyz\", #char '-'); // null\n /// // Strip just one '-'\n /// let one = Text.stripEnd(\"xyz--\", #char '-'); // ?\"xyz-\"\n /// ```\n public func stripEnd(t : Text, p : Pattern) : ?Text {\n let s2 = sizeOfPattern(p);\n if (s2 == 0) return ?t;\n let s1 = t.size();\n if (s2 > s1) return null;\n let match = matchOfPattern(p);\n var cs1 = t.chars();\n var diff : Nat = s1 - s2;\n while (diff > 0) {\n ignore cs1.next();\n diff -= 1\n };\n switch (match(cs1)) {\n case (#success) return ?extract(t, 0, s1 - s2);\n case _ return null\n }\n };\n\n /// Trims the given `Pattern` from the start of the input `Text`.\n /// If you only want to remove a single instance of the pattern, use `Text.stripStart()` instead.\n /// \n /// ```motoko include=import\n /// let trimmed = Text.trimStart(\"---abc\", #char '-'); // \"abc\"\n /// ```\n public func trimStart(t : Text, p : Pattern) : Text {\n let cs = t.chars();\n let size = sizeOfPattern(p);\n if (size == 0) return t;\n var matchSize = 0;\n let match = matchOfPattern(p);\n loop {\n switch (match(cs)) {\n case (#success) {\n matchSize += size\n }; // continue\n case (#empty(cs1)) {\n return if (matchSize == 0) {\n t\n } else {\n fromIter(cs1)\n }\n };\n case (#fail(cs1, c)) {\n return if (matchSize == 0) {\n t\n } else {\n fromIter(cs1) # fromChar(c) # fromIter(cs)\n }\n }\n }\n }\n };\n\n /// Trims the given `Pattern` from the end of the input `Text`.\n /// If you only want to remove a single instance of the pattern, use `Text.stripEnd()` instead.\n /// \n /// ```motoko include=import\n /// let trimmed = Text.trimEnd(\"xyz---\", #char '-'); // \"xyz\"\n /// ```\n public func trimEnd(t : Text, p : Pattern) : Text {\n let cs = CharBuffer(t.chars());\n let size = sizeOfPattern(p);\n if (size == 0) return t;\n let match = matchOfPattern(p);\n var matchSize = 0;\n label l loop {\n switch (match(cs)) {\n case (#success) {\n matchSize += size\n }; // continue\n case (#empty(cs1)) {\n switch (cs1.next()) {\n case null break l;\n case (?_) return t\n }\n };\n case (#fail(cs1, c)) {\n matchSize := 0;\n cs.pushBack(cs1, c);\n ignore cs.next()\n }\n }\n };\n extract(t, 0, t.size() - matchSize)\n };\n\n /// Trims the given `Pattern` from both the start and end of the input `Text`.\n /// \n /// ```motoko include=import\n /// let trimmed = Text.trim(\"---abcxyz---\", #char '-'); // \"abcxyz\"\n /// ```\n public func trim(t : Text, p : Pattern) : Text {\n let cs = t.chars();\n let size = sizeOfPattern(p);\n if (size == 0) return t;\n var matchSize = 0;\n let match = matchOfPattern(p);\n loop {\n switch (match(cs)) {\n case (#success) {\n matchSize += size\n }; // continue\n case (#empty(cs1)) {\n return if (matchSize == 0) { t } else { fromIter(cs1) }\n };\n case (#fail(cs1, c)) {\n let start = matchSize;\n let cs2 = CharBuffer(cs);\n cs2.pushBack(cs1, c);\n ignore cs2.next();\n matchSize := 0;\n label l loop {\n switch (match(cs2)) {\n case (#success) {\n matchSize += size\n }; // continue\n case (#empty(_cs3)) {\n switch (cs1.next()) {\n case null break l;\n case (?_) return t\n }\n };\n case (#fail(cs3, c1)) {\n matchSize := 0;\n cs2.pushBack(cs3, c1);\n ignore cs2.next()\n }\n }\n };\n return extract(t, start, t.size() - matchSize - start)\n }\n }\n }\n };\n\n /// Compares `t1` and `t2` using the provided character-wise comparison function.\n /// \n /// ```motoko include=import\n /// import Char \"mo:base/Char\";\n /// \n /// Text.compareWith(\"abc\", \"ABC\", func(c1, c2) { Char.compare(c1, c2) }) // #greater\n /// ```\n public func compareWith(\n t1 : Text,\n t2 : Text,\n cmp : (Char, Char) -> { #less; #equal; #greater }\n ) : { #less; #equal; #greater } {\n let cs1 = t1.chars();\n let cs2 = t2.chars();\n loop {\n switch (cs1.next(), cs2.next()) {\n case (null, null) { return #equal };\n case (null, ?_) { return #less };\n case (?_, null) { return #greater };\n case (?c1, ?c2) {\n switch (cmp(c1, c2)) {\n case (#equal) {}; // continue\n case other { return other }\n }\n }\n }\n }\n };\n\n /// Returns a UTF-8 encoded `Blob` from the given `Text`.\n /// \n /// ```motoko include=import\n /// let blob = Text.encodeUtf8(\"Hello\");\n /// ```\n public let encodeUtf8 : Text -> Blob = Prim.encodeUtf8;\n\n /// Tries to decode the given `Blob` as UTF-8.\n /// Returns `null` if the blob is not valid UTF-8.\n /// \n /// ```motoko include=import\n /// let text = Text.decodeUtf8(\"\\48\\65\\6C\\6C\\6F\"); // ?\"Hello\"\n /// ```\n public let decodeUtf8 : Blob -> ?Text = Prim.decodeUtf8;\n\n /// Returns the text argument in lowercase.\n /// \n /// :::warning Compliance\n /// Unicode compliant only when compiled, not interpreted.\n /// :::\n /// \n /// ```motoko include=import\n /// let text = Text.toLowercase(\"Good Day\"); // ?\"good day\"\n /// ```\n public let toLowercase : Text -> Text = Prim.textLowercase;\n\n /// Returns the text argument in uppercase. Unicode compliant.\n /// :::warning Compliance\n /// Unicode compliant only when compiled, not interpreted.\n /// :::\n /// \n /// ```motoko include=import\n /// let text = Text.toUppercase(\"Good Day\"); // ?\"GOOD DAY\"\n /// ```\n public let toUppercase : Text -> Text = Prim.textUppercase\n}\n"},"Timer.mo":{"content":"/// Timers for one-off or periodic tasks. Applicable as part of the default mechanism.\n/// \n/// :::note Timer resolution\n/// \n/// The resolution of the timers is in the order of the block rate,\n/// so durations should be chosen well above that. For frequent\n/// canister wake-ups the heartbeat mechanism should be considered.\n/// :::\n/// \n/// :::note Overriding system function\n/// \n/// The functionality described below is enabled only when the actor does not override it by declaring an explicit `system func timer`.\n/// :::\n/// \n/// :::note Upgrade persistence\n/// \n/// Timers are _not_ persisted across upgrades. One possible strategy\n/// to re-establish timers after an upgrade is to walk stable variables\n/// in the `post_upgrade` hook and distill necessary timer information\n/// from there.\n/// :::\n/// \n/// :::note Security warning\n/// \n/// Basing security (e.g. access control) on timers is almost always the wrong choice.\n/// Be sure to inform yourself about state-of-the-art dApp security.\n/// If you _must use_ timers for security controls, be sure to consider reentrancy issues,\n/// and the vanishing of timers on upgrades and reinstalls.\n/// :::\n/// \n/// :::note Further information\n/// \n/// [Further usage information for timers](https://internetcomputer.org/docs/current/developer-docs/backend/periodic-tasks#timers-library-limitations).\n/// :::\n/// \n/// :::note Compilation flag\n/// \n/// If `moc` is invoked with `-no-timer`, the importing will fail.\n/// :::\nimport { setTimer = setTimerNano; cancelTimer = cancel } = \"mo:⛔\";\nimport { fromIntWrap } = \"Nat64\";\n\nmodule {\n\n public type Duration = { #seconds : Nat; #nanoseconds : Nat };\n public type TimerId = Nat;\n\n func toNanos(d : Duration) : Nat64 = fromIntWrap(\n switch d {\n case (#seconds s) s * 1000_000_000;\n case (#nanoseconds ns) ns\n }\n );\n\n /// Installs a one-off timer that upon expiration after given duration `d`\n /// executes the future `job()`.\n /// \n /// ```motoko no-repl\n /// let now = Time.now();\n /// let thirtyMinutes = 1_000_000_000 * 60 * 30;\n /// func alarmUser() : async () {\n /// // ...\n /// };\n /// appt.reminder = setTimer(#nanoseconds (Int.abs(appt.when - now - thirtyMinutes)), alarmUser);\n /// ```\n public func setTimer<system>(d : Duration, job : () -> async ()) : TimerId {\n setTimerNano<system>(toNanos d, false, job)\n };\n\n /// Installs a recurring timer that upon expiration after given duration `d`\n /// executes the future `job()` and reinserts itself for another expiration.\n /// \n /// :::info\n /// A duration of 0 will only expire once.\n /// :::\n /// \n /// ```motoko no-repl\n /// func checkAndWaterPlants() : async () {\n /// // ...\n /// };\n /// let daily = recurringTimer(#seconds (24 * 60 * 60), checkAndWaterPlants);\n /// ```\n public func recurringTimer<system>(d : Duration, job : () -> async ()) : TimerId {\n setTimerNano<system>(toNanos d, true, job)\n };\n\n /// Cancels a still active timer with `(id : TimerId)`. For expired timers\n /// and not recognized `id`s nothing happens.\n /// \n /// ```motoko no-repl\n /// func deleteAppointment(appointment : Appointment) {\n /// cancelTimer (appointment.reminder);\n /// // ...\n /// };\n /// ```\n public let cancelTimer : TimerId -> () = cancel;\n\n}\n"},"Hash.mo":{"content":"\nimport Prim \"mo:⛔\";\nimport Iter \"Iter\";\n\nmodule {\n\n /// Hash values represent a string of _hash bits_, packed into a `Nat32`.\n public type Hash = Nat32;\n\n /// The hash length, always 31.\n public let length : Nat = 31; // Why not 32?\n\n /// Project a given bit from the bit vector.\n public func bit(h : Hash, pos : Nat) : Bool {\n assert (pos <= length);\n (h & (Prim.natToNat32(1) << Prim.natToNat32(pos))) != Prim.natToNat32(0)\n };\n\n /// Test if two hashes are equal.\n public func equal(ha : Hash, hb : Hash) : Bool {\n ha == hb\n };\n\n /// :::warning Deprecated function\n /// This function computes a hash from the least significant 32 bits of `n`, ignoring other bits.\n /// For large `Nat` values, consider using a bespoke hash function that considers all of the argument's bits.\n /// :::\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 /// :::warning Deprecated function\n\n /// This function will be removed in a future version.\n /// :::\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 /// :::warning Deprecated function\n\n /// This function will be removed in a future version.\n /// :::\n public func debugPrintBitsRev(bits : Hash) {\n for (j in Iter.revRange(length - 1, 0)) {\n if (bit(bits, Prim.abs(j))) {\n Prim.debugPrint(\"1\")\n } else {\n Prim.debugPrint(\"0\")\n }\n }\n };\n\n /// [View Jenkin's one at a time](https://en.wikipedia.org/wiki/Jenkins_hash_function#one_at_a_time).\n /// \n /// :::note\n /// The input type should actually be `[Nat8]`.\n /// Be sure to explode each `Nat8` of a `Nat32` into its own `Nat32`, and shift into the lower 8 bits.\n /// :::\n /// :::warning Deprecated function\n\n /// This function may be removed or changed in a future version.\n /// :::\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"},"Time.mo":{"content":"\nimport Prim \"mo:⛔\";\nmodule {\n\n /// System time is represent as nanoseconds since 1970-01-01.\n public type Time = Int;\n\n /// Current system time given as nanoseconds since 1970-01-01. The system guarantees that:\n /// \n /// * The time, as observed by the canister smart contract, is monotonically increasing, even across canister upgrades.\n /// * Within an invocation of one entry point, the time is constant.\n /// \n /// The system times of different canisters are unrelated, and calls from one canister to another may appear to travel \"backwards in time\"\n /// \n /// :::note Accuracy guarantee\n /// While an implementation will likely try to keep the system time close to the real time, this is not formally guaranteed.\n /// :::\n public let now : () -> Time = func() : Int = Prim.nat64ToNat(Prim.time());\n /// \n /// The following example illustrates using the system time:\n /// \n /// ```motoko\n /// import Int = \"mo:base/Int\";\n /// import Time = \"mo:base/Time\";\n /// \n /// actor {\n /// var lastTime = Time.now();\n /// public func greet(name : Text) : async Text {\n /// let now = Time.now();\n /// let elapsedSeconds = (now - lastTime) / 1000_000_000;\n /// lastTime := now;\n /// return \"Hello, \" # name # \"!\" #\n /// \" I was last called \" # Int.toText(elapsedSeconds) # \" seconds ago\";\n /// };\n /// };\n /// ```\n}\n"},"Float.mo":{"content":"/// Double precision (64-bit) floating-point numbers in IEEE 754 representation.\n/// \n/// This module contains common floating-point constants and utility functions.\n/// \n/// Notation for special values in the documentation below:\n/// \n/// `+inf`: Positive infinity\n/// \n/// `-inf`: Negative infinity\n/// \n/// `NaN`: \"not a number\" (can have different sign bit values, but `NaN != NaN` regardless of the sign).\n/// \n/// :::note\n/// Floating point numbers have limited precision and operations may inherently result in numerical errors.\n/// :::\n///\n/// Examples of numerical errors:\n/// ```motoko\n/// 0.1 + 0.1 + 0.1 == 0.3 // => false\n/// ```\n/// \n/// ```motoko\n/// 1e16 + 1.0 != 1e16 // => false\n/// ```\n/// \n/// \n/// Advice:\n/// * Floating point number comparisons by `==` or `!=` are discouraged. Instead, it is better to compare\n/// floating-point numbers with a numerical tolerance, called epsilon.\n/// \n/// Example:\n/// ```motoko\n/// import Float \"mo:base/Float\";\n/// let x = 0.1 + 0.1 + 0.1;\n/// let y = 0.3;\n/// \n/// let epsilon = 1e-6; // This depends on the application case (needs a numerical error analysis).\n/// Float.equalWithin(x, y, epsilon) // => true\n/// ```\n/// \n/// * For absolute precision, it is recommend to encode the fraction number as a pair of a `Nat` for the base\n/// and a `Nat` for the exponent (decimal point).\n/// \n/// `NaN` sign:\n/// * The `NaN` sign is only applied by `abs`, `neg`, and `copySign`. Other operations can have an arbitrary\n/// sign bit for `NaN` results.\n\nimport Prim \"mo:⛔\";\nimport Int \"Int\";\n\nmodule {\n\n /// 64-bit floating point number type.\n public type Float = Prim.Types.Float;\n\n /// Ratio of the circumference of a circle to its diameter.\n /// Note: Limited precision.\n public let pi : Float = 3.14159265358979323846; // taken from musl math.h\n\n /// Base of the natural logarithm.\n /// Note: Limited precision.\n public let e : Float = 2.7182818284590452354; // taken from musl math.h\n\n /// Determines whether the `number` is a `NaN` (\"not a number\" in the floating point representation).\n /// Notes:\n /// * Equality test of `NaN` with itself or another number is always `false`.\n /// * There exist many internal `NaN` value representations, such as positive and negative `NaN`,\n /// signalling and quiet `NaN`s, each with many different bit representations.\n /// \n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n /// \n /// Float.isNaN(0.0/0.0) // => true\n /// ```\n public func isNaN(number : Float) : Bool {\n number != number\n };\n\n /// Returns the absolute value of `x`.\n /// \n /// Special cases:\n /// ```\n /// abs(+inf) => +inf\n /// abs(-inf) => +inf\n /// abs(-NaN) => +NaN\n /// abs(-0.0) => 0.0\n /// ```\n /// \n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n /// \n /// Float.abs(-1.2) // => 1.2\n /// ```\n public let abs : (x : Float) -> Float = Prim.floatAbs;\n\n /// Returns the square root of `x`.\n /// \n /// Special cases:\n /// ```\n /// sqrt(+inf) => +inf\n /// sqrt(-0.0) => -0.0\n /// sqrt(x) => NaN if x < 0.0\n /// sqrt(NaN) => NaN\n /// ```\n /// \n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n /// \n /// Float.sqrt(6.25) // => 2.5\n /// ```\n public let sqrt : (x : Float) -> Float = Prim.floatSqrt;\n\n /// Returns the smallest integral float greater than or equal to `x`.\n /// \n /// Special cases:\n /// ```\n /// ceil(+inf) => +inf\n /// ceil(-inf) => -inf\n /// ceil(NaN) => NaN\n /// ceil(0.0) => 0.0\n /// ceil(-0.0) => -0.0\n /// ```\n /// \n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n /// \n /// Float.ceil(1.2) // => 2.0\n /// ```\n public let ceil : (x : Float) -> Float = Prim.floatCeil;\n\n /// Returns the largest integral float less than or equal to `x`.\n /// \n /// Special cases:\n /// ```\n /// floor(+inf) => +inf\n /// floor(-inf) => -inf\n /// floor(NaN) => NaN\n /// floor(0.0) => 0.0\n /// floor(-0.0) => -0.0\n /// ```\n /// \n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n /// \n /// Float.floor(1.2) // => 1.0\n /// ```\n public let floor : (x : Float) -> Float = Prim.floatFloor;\n\n /// Returns the nearest integral float not greater in magnitude than `x`.\n /// This is equivalent to returning `x` with truncating its decimal places.\n /// \n /// Special cases:\n /// ```\n /// trunc(+inf) => +inf\n /// trunc(-inf) => -inf\n /// trunc(NaN) => NaN\n /// trunc(0.0) => 0.0\n /// trunc(-0.0) => -0.0\n /// ```\n /// \n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n /// \n /// Float.trunc(2.75) // => 2.0\n /// ```\n public let trunc : (x : Float) -> Float = Prim.floatTrunc;\n\n /// Returns the nearest integral float to `x`.\n /// A decimal place of exactly .5 is rounded up for `x > 0`\n /// and rounded down for `x < 0`\n /// \n /// Special cases:\n /// ```\n /// nearest(+inf) => +inf\n /// nearest(-inf) => -inf\n /// nearest(NaN) => NaN\n /// nearest(0.0) => 0.0\n /// nearest(-0.0) => -0.0\n /// ```\n /// \n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n /// \n /// Float.nearest(2.75) // => 3.0\n /// ```\n public let nearest : (x : Float) -> Float = Prim.floatNearest;\n\n /// Returns `x` if `x` and `y` have same sign, otherwise `x` with negated sign.\n /// \n /// The sign bit of zero, infinity, and `NaN` is considered.\n /// \n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n /// \n /// Float.copySign(1.2, -2.3) // => -1.2\n /// ```\n public let copySign : (x : Float, y : Float) -> Float = Prim.floatCopySign;\n\n /// Returns the smaller value of `x` and `y`.\n /// \n /// Special cases:\n /// ```\n /// min(NaN, y) => NaN for any Float y\n /// min(x, NaN) => NaN for any Float x\n /// ```\n /// \n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n /// \n /// Float.min(1.2, -2.3) // => -2.3 (with numerical imprecision)\n /// ```\n public let min : (x : Float, y : Float) -> Float = Prim.floatMin;\n\n /// Returns the larger value of `x` and `y`.\n /// \n /// Special cases:\n /// ```\n /// max(NaN, y) => NaN for any Float y\n /// max(x, NaN) => NaN for any Float x\n /// ```\n /// \n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n /// \n /// Float.max(1.2, -2.3) // => 1.2\n /// ```\n public let max : (x : Float, y : Float) -> Float = Prim.floatMax;\n\n /// Returns the sine of the radian angle `x`.\n /// \n /// Special cases:\n /// ```\n /// sin(+inf) => NaN\n /// sin(-inf) => NaN\n /// sin(NaN) => NaN\n /// ```\n /// \n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n /// \n /// Float.sin(Float.pi / 2) // => 1.0\n /// ```\n public let sin : (x : Float) -> Float = Prim.sin;\n\n /// Returns the cosine of the radian angle `x`.\n /// \n /// Special cases:\n /// ```\n /// cos(+inf) => NaN\n /// cos(-inf) => NaN\n /// cos(NaN) => NaN\n /// ```\n /// \n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n /// \n /// Float.cos(Float.pi / 2) // => 0.0 (with numerical imprecision)\n /// ```\n public let cos : (x : Float) -> Float = Prim.cos;\n\n /// Returns the tangent of the radian angle `x`.\n /// \n /// Special cases:\n /// ```\n /// tan(+inf) => NaN\n /// tan(-inf) => NaN\n /// tan(NaN) => NaN\n /// ```\n /// \n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n /// \n /// Float.tan(Float.pi / 4) // => 1.0 (with numerical imprecision)\n /// ```\n public let tan : (x : Float) -> Float = Prim.tan;\n\n /// Returns the arc sine of `x` in radians.\n /// \n /// Special cases:\n /// ```\n /// arcsin(x) => NaN if x > 1.0\n /// arcsin(x) => NaN if x < -1.0\n /// arcsin(NaN) => NaN\n /// ```\n /// \n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n /// \n /// Float.arcsin(1.0) // => Float.pi / 2\n /// ```\n public let arcsin : (x : Float) -> Float = Prim.arcsin;\n\n /// Returns the arc cosine of `x` in radians.\n /// \n /// Special cases:\n /// ```\n /// arccos(x) => NaN if x > 1.0\n /// arccos(x) => NaN if x < -1.0\n /// arcos(NaN) => NaN\n /// ```\n /// \n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n /// \n /// Float.arccos(1.0) // => 0.0\n /// ```\n public let arccos : (x : Float) -> Float = Prim.arccos;\n\n /// Returns the arc tangent of `x` in radians.\n /// \n /// Special cases:\n /// ```\n /// arctan(+inf) => pi / 2\n /// arctan(-inf) => -pi / 2\n /// arctan(NaN) => NaN\n /// ```\n /// \n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n /// \n /// Float.arctan(1.0) // => Float.pi / 4\n /// ```\n public let arctan : (x : Float) -> Float = Prim.arctan;\n\n /// Given `(y,x)`, returns the arc tangent in radians of `y/x` based on the signs of both values to determine the correct quadrant.\n /// \n /// Special cases:\n /// ```\n /// arctan2(0.0, 0.0) => 0.0\n /// arctan2(-0.0, 0.0) => -0.0\n /// arctan2(0.0, -0.0) => pi\n /// arctan2(-0.0, -0.0) => -pi\n /// arctan2(+inf, +inf) => pi / 4\n /// arctan2(+inf, -inf) => 3 * pi / 4\n /// arctan2(-inf, +inf) => -pi / 4\n /// arctan2(-inf, -inf) => -3 * pi / 4\n /// arctan2(NaN, x) => NaN for any Float x\n /// arctan2(y, NaN) => NaN for any Float y\n /// ```\n /// \n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n /// \n /// let sqrt2over2 = Float.sqrt(2) / 2;\n /// Float.arctan2(sqrt2over2, sqrt2over2) // => Float.pi / 4\n /// ```\n public let arctan2 : (y : Float, x : Float) -> Float = Prim.arctan2;\n\n /// Returns the value of `e` raised to the `x`-th power.\n /// \n /// Special cases:\n /// ```\n /// exp(+inf) => +inf\n /// exp(-inf) => 0.0\n /// exp(NaN) => NaN\n /// ```\n /// \n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n /// \n /// Float.exp(1.0) // => Float.e\n /// ```\n public let exp : (x : Float) -> Float = Prim.exp;\n\n /// Returns the natural logarithm (base-`e`) of `x`.\n /// \n /// Special cases:\n /// ```\n /// log(0.0) => -inf\n /// log(-0.0) => -inf\n /// log(x) => NaN if x < 0.0\n /// log(+inf) => +inf\n /// log(NaN) => NaN\n /// ```\n /// \n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n /// \n /// Float.log(Float.e) // => 1.0\n /// ```\n public let log : (x : Float) -> Float = Prim.log;\n\n /// Formatting. `format(fmt, x)` formats `x` to `Text` according to the\n /// formatting directive `fmt`, which can take one of the following forms:\n /// \n /// * `#fix prec` as fixed-point format with `prec` digits\n /// * `#exp prec` as exponential format with `prec` digits\n /// * `#gen prec` as generic format with `prec` digits\n /// * `#exact` as exact format that can be decoded without loss.\n /// \n /// `-0.0` is formatted with negative sign bit.\n /// Positive infinity is formatted as \"inf\".\n /// Negative infinity is formatted as \"-inf\".\n /// \n /// :::info\n /// The numerical precision and the text format can vary between\n /// Motoko versions and runtime configuration. Moreover, `NaN` can be printed\n /// differently, i.e. \"NaN\" or \"nan\", potentially omitting the `NaN` sign.\n /// \n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n /// \n /// Float.format(#exp 3, 123.0) // => \"1.230e+02\"\n /// ```\n public func format(fmt : { #fix : Nat8; #exp : Nat8; #gen : Nat8; #exact }, x : Float) : Text = switch fmt {\n case (#fix(prec)) { Prim.floatToFormattedText(x, prec, 0) };\n case (#exp(prec)) { Prim.floatToFormattedText(x, prec, 1) };\n case (#gen(prec)) { Prim.floatToFormattedText(x, prec, 2) };\n case (#exact) { Prim.floatToFormattedText(x, 17, 2) }\n };\n\n /// Conversion to `Text`. Use `format(fmt, x)` for more detailed control.\n /// \n /// `-0.0` is formatted with negative sign bit.\n /// Positive infinity is formatted as `inf`.\n /// Negative infinity is formatted as `-inf`.\n /// `NaN` is formatted as `NaN` or `-NaN` depending on its sign bit.\n /// \n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n /// \n /// Float.toText(0.12) // => \"0.12\"\n /// ```\n public let toText : Float -> Text = Prim.floatToText;\n\n /// Conversion to `Int64` by truncating Float, equivalent to `toInt64(trunc(f))`\n /// \n /// Traps if the floating point number is larger or smaller than the representable Int64.\n /// Also traps for `inf`, `-inf`, and `NaN`.\n /// \n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n /// \n /// Float.toInt64(-12.3) // => -12\n /// ```\n public let toInt64 : Float -> Int64 = Prim.floatToInt64;\n\n /// Conversion from `Int64`.\n /// \n /// :::note\n /// The floating point number may be imprecise for large or small `Int64`.\n /// :::\n /// \n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n /// \n /// Float.fromInt64(-42) // => -42.0\n /// ```\n public let fromInt64 : Int64 -> Float = Prim.int64ToFloat;\n\n /// Conversion to `Int`.\n /// \n /// Traps for `inf`, `-inf`, and `NaN`.\n /// \n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n /// \n /// Float.toInt(1.2e6) // => +1_200_000\n /// ```\n public let toInt : Float -> Int = Prim.floatToInt;\n\n /// Conversion from `Int`. May result in `Inf`.\n /// \n /// :::note \n /// The floating point number may be imprecise for large or small Int values.\n /// Returns `inf` if the integer is greater than the maximum floating point number.\n /// Returns `-inf` if the integer is less than the minimum floating point number.\n /// :::\n /// \n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n /// \n /// Float.fromInt(-123) // => -123.0\n /// ```\n public let fromInt : Int -> Float = Prim.intToFloat;\n\n /// Returns `x == y`.\n /// :::warning Deprecated function\n /// Use `Float.equalWithin()` as this function does not consider numerical errors.\n /// :::\n public func equal(x : Float, y : Float) : Bool { x == y };\n\n /// Returns `x != y`.\n /// :::warning Deprecated function\n /// Use `Float.notEqualWithin()` as this function does not consider numerical errors.\n /// :::\n public func notEqual(x : Float, y : Float) : Bool { x != y };\n\n /// Determines whether `x` is equal to `y` within the defined tolerance of `epsilon`.\n /// The `epsilon` considers numerical errors, see comment above.\n /// Equivalent to `Float.abs(x - y) <= epsilon` for a non-negative epsilon.\n /// \n /// Traps if `epsilon` is negative or `NaN`.\n /// \n /// Special cases:\n /// ```\n /// equalWithin(+0.0, -0.0, epsilon) => true for any `epsilon >= 0.0`\n /// equalWithin(-0.0, +0.0, epsilon) => true for any `epsilon >= 0.0`\n /// equalWithin(+inf, +inf, epsilon) => true for any `epsilon >= 0.0`\n /// equalWithin(-inf, -inf, epsilon) => true for any `epsilon >= 0.0`\n /// equalWithin(x, NaN, epsilon) => false for any x and `epsilon >= 0.0`\n /// equalWithin(NaN, y, epsilon) => false for any y and `epsilon >= 0.0`\n /// ```\n /// \n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n /// \n /// let epsilon = 1e-6;\n /// Float.equalWithin(-12.3, -1.23e1, epsilon) // => true\n /// ```\n public func equalWithin(x : Float, y : Float, epsilon : Float) : Bool {\n if (not (epsilon >= 0.0)) {\n // also considers NaN, not identical to `epsilon < 0.0`\n Prim.trap(\"epsilon must be greater or equal 0.0\")\n };\n x == y or abs(x - y) <= epsilon // `x == y` to also consider infinity equal\n };\n\n /// Determines whether `x` is not equal to `y` within the defined tolerance of `epsilon`.\n /// The `epsilon` considers numerical errors, see comment above.\n /// Equivalent to `not equal(x, y, epsilon)`.\n /// \n /// Traps if `epsilon` is negative or `NaN`.\n /// \n /// Special cases:\n /// ```\n /// notEqualWithin(+0.0, -0.0, epsilon) => false for any `epsilon >= 0.0`\n /// notEqualWithin(-0.0, +0.0, epsilon) => false for any `epsilon >= 0.0`\n /// notEqualWithin(+inf, +inf, epsilon) => false for any `epsilon >= 0.0`\n /// notEqualWithin(-inf, -inf, epsilon) => false for any `epsilon >= 0.0`\n /// notEqualWithin(x, NaN, epsilon) => true for any x and `epsilon >= 0.0`\n /// notEqualWithin(NaN, y, epsilon) => true for any y and `epsilon >= 0.0`\n /// ```\n /// \n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n /// \n /// let epsilon = 1e-6;\n /// Float.notEqualWithin(-12.3, -1.23e1, epsilon) // => false\n /// ```\n public func notEqualWithin(x : Float, y : Float, epsilon : Float) : Bool {\n not equalWithin(x, y, epsilon)\n };\n\n /// Returns `x < y`.\n /// \n /// Special cases:\n /// ```\n /// less(+0.0, -0.0) => false\n /// less(-0.0, +0.0) => false\n /// less(NaN, y) => false for any Float y\n /// less(x, NaN) => false for any Float x\n /// ```\n /// \n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n /// \n /// Float.less(Float.e, Float.pi) // => true\n /// ```\n public func less(x : Float, y : Float) : Bool { x < y };\n\n /// Returns `x <= y`.\n /// \n /// Special cases:\n /// ```\n /// lessOrEqual(+0.0, -0.0) => true\n /// lessOrEqual(-0.0, +0.0) => true\n /// lessOrEqual(NaN, y) => false for any Float y\n /// lessOrEqual(x, NaN) => false for any Float x\n /// ```\n /// \n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n /// \n /// Float.lessOrEqual(0.123, 0.1234) // => true\n /// ```\n public func lessOrEqual(x : Float, y : Float) : Bool { x <= y };\n\n /// Returns `x > y`.\n /// \n /// Special cases:\n /// ```\n /// greater(+0.0, -0.0) => false\n /// greater(-0.0, +0.0) => false\n /// greater(NaN, y) => false for any Float y\n /// greater(x, NaN) => false for any Float x\n /// ```\n /// \n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n /// \n /// Float.greater(Float.pi, Float.e) // => true\n /// ```\n public func greater(x : Float, y : Float) : Bool { x > y };\n\n /// Returns `x >= y`.\n /// \n /// Special cases:\n /// ```\n /// greaterOrEqual(+0.0, -0.0) => true\n /// greaterOrEqual(-0.0, +0.0) => true\n /// greaterOrEqual(NaN, y) => false for any Float y\n /// greaterOrEqual(x, NaN) => false for any Float x\n /// ```\n /// \n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n /// \n /// Float.greaterOrEqual(0.1234, 0.123) // => true\n /// ```\n public func greaterOrEqual(x : Float, y : Float) : Bool { x >= y };\n\n /// Defines a total order of `x` and `y` for use in sorting.\n /// \n /// :::note \n /// Using this operation to determine equality or inequality is discouraged for two reasons:\n /// * It does not consider numerical errors, see comment above. Use `equalWithin(x, y, espilon)` or\n /// `notEqualWithin(x, y, epsilon)` to test for equality or inequality, respectively.\n /// * `NaN` are here considered equal if their sign matches, which is different to the standard equality\n /// by `==` or when using `equal()` or `notEqual()`.\n /// :::\n ///\n /// Total order:\n /// * negative `NaN` (no distinction between signalling and quiet negative `NaN`)\n /// * negative infinity\n /// * negative numbers (including negative subnormal numbers in standard order)\n /// * negative zero (`-0.0`)\n /// * positive zero (`+0.0`)\n /// * positive numbers (including positive subnormal numbers in standard order)\n /// * positive infinity\n /// * positive `NaN` (no distinction between signalling and quiet positive `NaN`)\n /// \n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n /// \n /// Float.compare(0.123, 0.1234) // => #less\n /// ```\n public func compare(x : Float, y : Float) : { #less; #equal; #greater } {\n if (isNaN(x)) {\n if (isNegative(x)) {\n if (isNaN(y) and isNegative(y)) { #equal } else { #less }\n } else {\n if (isNaN(y) and not isNegative(y)) { #equal } else { #greater }\n }\n } else if (isNaN(y)) {\n if (isNegative(y)) {\n #greater\n } else {\n #less\n }\n } else {\n if (x == y) { #equal } else if (x < y) { #less } else { #greater }\n }\n };\n\n func isNegative(number : Float) : Bool {\n copySign(1.0, number) < 0.0\n };\n\n /// Returns the negation of `x`, `-x` .\n /// \n /// Changes the sign bit for infinity.\n /// \n /// Special cases:\n /// ```\n /// neg(+inf) => -inf\n /// neg(-inf) => +inf\n /// neg(+NaN) => -NaN\n /// neg(-NaN) => +NaN\n /// neg(+0.0) => -0.0\n /// neg(-0.0) => +0.0\n /// ```\n /// \n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n /// \n /// Float.neg(1.23) // => -1.23\n /// ```\n public func neg(x : Float) : Float { -x };\n\n /// Returns the sum of `x` and `y`, `x + y`.\n /// \n /// :::info\n /// Numerical errors may occur, see comment above.\n /// :::\n /// \n /// Special cases:\n /// ```\n /// add(+inf, y) => +inf if y is any Float except -inf and NaN\n /// add(-inf, y) => -inf if y is any Float except +inf and NaN\n /// add(+inf, -inf) => NaN\n /// add(NaN, y) => NaN for any Float y\n /// ```\n /// The same cases apply commutatively, i.e. for `add(y, x)`.\n /// \n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n /// \n /// Float.add(1.23, 0.123) // => 1.353\n /// ```\n public func add(x : Float, y : Float) : Float { x + y };\n\n /// Returns the difference of `x` and `y`, `x - y`.\n /// \n /// Note: Numerical errors may occur, see comment above.\n /// \n /// Special cases:\n /// ```\n /// sub(+inf, y) => +inf if y is any Float except +inf or NaN\n /// sub(-inf, y) => -inf if y is any Float except -inf and NaN\n /// sub(x, +inf) => -inf if x is any Float except +inf and NaN\n /// sub(x, -inf) => +inf if x is any Float except -inf and NaN\n /// sub(+inf, +inf) => NaN\n /// sub(-inf, -inf) => NaN\n /// sub(NaN, y) => NaN for any Float y\n /// sub(x, NaN) => NaN for any Float x\n /// ```\n /// \n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n /// \n /// Float.sub(1.23, 0.123) // => 1.107\n /// ```\n public func sub(x : Float, y : Float) : Float { x - y };\n\n /// Returns the product of `x` and `y`, `x * y`.\n /// \n /// :::info \n /// Numerical errors may occur, see comment above.\n /// :::\n /// \n /// Special cases:\n /// ```\n /// mul(+inf, y) => +inf if y > 0.0\n /// mul(-inf, y) => -inf if y > 0.0\n /// mul(+inf, y) => -inf if y < 0.0\n /// mul(-inf, y) => +inf if y < 0.0\n /// mul(+inf, 0.0) => NaN\n /// mul(-inf, 0.0) => NaN\n /// mul(NaN, y) => NaN for any Float y\n /// ```\n /// The same cases apply commutatively, i.e. for `mul(y, x)`.\n /// \n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n /// \n /// Float.mul(1.23, 1e2) // => 123.0\n /// ```\n public func mul(x : Float, y : Float) : Float { x * y };\n\n /// Returns the division of `x` by `y`, `x / y`.\n /// \n /// :::info \n /// Numerical errors may occur, see comment above.\n /// :::\n /// \n /// Special cases:\n /// ```\n /// div(0.0, 0.0) => NaN\n /// div(x, 0.0) => +inf for x > 0.0\n /// div(x, 0.0) => -inf for x < 0.0\n /// div(x, +inf) => 0.0 for any x except +inf, -inf, and NaN\n /// div(x, -inf) => 0.0 for any x except +inf, -inf, and NaN\n /// div(+inf, y) => +inf if y >= 0.0\n /// div(+inf, y) => -inf if y < 0.0\n /// div(-inf, y) => -inf if y >= 0.0\n /// div(-inf, y) => +inf if y < 0.0\n /// div(NaN, y) => NaN for any Float y\n /// div(x, NaN) => NaN for any Float x\n /// ```\n /// \n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n /// \n /// Float.div(1.23, 1e2) // => 0.0123\n /// ```\n public func div(x : Float, y : Float) : Float { x / y };\n\n /// Returns the floating point division remainder `x % y`,\n /// which is defined as `x - trunc(x / y) * y`.\n /// \n /// :::info \n /// Numerical errors may occur, see comment above.\n /// :::\n /// \n /// Special cases:\n /// ```\n /// rem(0.0, 0.0) => NaN\n /// rem(x, y) => +inf if sign(x) == sign(y) for any x and y not being +inf, -inf, or NaN\n /// rem(x, y) => -inf if sign(x) != sign(y) for any x and y not being +inf, -inf, or NaN\n /// rem(x, +inf) => x for any x except +inf, -inf, and NaN\n /// rem(x, -inf) => x for any x except +inf, -inf, and NaN\n /// rem(+inf, y) => NaN for any Float y\n /// rem(-inf, y) => NaN for any Float y\n /// rem(NaN, y) => NaN for any Float y\n /// rem(x, NaN) => NaN for any Float x\n /// ```\n /// \n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n /// \n /// Float.rem(7.2, 2.3) // => 0.3 (with numerical imprecision)\n /// ```\n public func rem(x : Float, y : Float) : Float { x % y };\n\n /// Returns `x` to the power of `y`, `x ** y`.\n /// \n /// :::info \n /// Numerical errors may occur, see comment above.\n /// :::\n /// \n /// Special cases:\n /// ```\n /// pow(+inf, y) => +inf for any y > 0.0 including +inf\n /// pow(+inf, 0.0) => 1.0\n /// pow(+inf, y) => 0.0 for any y < 0.0 including -inf\n /// pow(x, +inf) => +inf if x > 0.0 or x < 0.0\n /// pow(0.0, +inf) => 0.0\n /// pow(x, -inf) => 0.0 if x > 0.0 or x < 0.0\n /// pow(0.0, -inf) => +inf\n /// pow(x, y) => NaN if x < 0.0 and y is a non-integral Float\n /// pow(-inf, y) => +inf if y > 0.0 and y is a non-integral or an even integral Float\n /// pow(-inf, y) => -inf if y > 0.0 and y is an odd integral Float\n /// pow(-inf, 0.0) => 1.0\n /// pow(-inf, y) => 0.0 if y < 0.0\n /// pow(-inf, +inf) => +inf\n /// pow(-inf, -inf) => 1.0\n /// pow(NaN, y) => NaN if y != 0.0\n /// pow(NaN, 0.0) => 1.0\n /// pow(x, NaN) => NaN for any Float x\n /// ```\n /// \n /// Example:\n /// ```motoko\n /// import Float \"mo:base/Float\";\n /// \n /// Float.pow(2.5, 2.0) // => 6.25\n /// ```\n public func pow(x : Float, y : Float) : Float { x ** y };\n\n}\n"},"AssocList.mo":{"content":"/// Map implemented as a linked-list of key-value pairs (\"Associations\").\n/// \n/// :::note Usage context\n/// \n/// This map implementation primarily serves as the underlying bucket structure for other map types. In most cases, those higher-level map implementations are easier to use.\n/// :::\n/// \n/// :::note Assumptions\n/// \n/// Runtime and space complexity assumes that `combine`, `equal`, and other functions execute in `O(1)` time and space.\n/// :::\n\nimport List \"List\";\n\nmodule {\n /// Import from the base library to use this module.\n /// \n /// ```motoko name=import\n /// import AssocList \"mo:base/AssocList\";\n /// import List \"mo:base/List\";\n /// import Nat \"mo:base/Nat\";\n /// \n /// type AssocList<K, V> = AssocList.AssocList<K, V>;\n /// ```\n /// \n /// Initialize an empty map using an empty list.\n /// ```motoko name=initialize include=import\n /// var map : AssocList<Nat, Nat> = List.nil(); // Empty list as an empty map\n /// map := null; // Alternative: null as empty list.\n /// map\n /// ```\n public type AssocList<K, V> = List.List<(K, V)>;\n\n /// Find the value associated with key `key`, or `null` if no such key exists.\n /// Compares keys using the provided function `equal`.\n /// \n /// Example:\n /// \n /// ```motoko include=import,initialize\n /// // Create map = [(0, 10), (1, 11), (2, 12)]\n /// map := AssocList.replace(map, 0, Nat.equal, ?10).0;\n /// map := AssocList.replace(map, 1, Nat.equal, ?11).0;\n /// map := AssocList.replace(map, 2, Nat.equal, ?12).0;\n /// \n /// // Find value associated with key 1\n /// AssocList.find(map, 1, Nat.equal)\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size)` | `O(1)` |\n public func find<K, V>(\n map : AssocList<K, V>,\n key : K,\n equal : (K, K) -> Bool\n ) : ?V {\n switch (map) {\n case (?((hd_k, hd_v), tl)) {\n if (equal(key, hd_k)) {\n ?hd_v\n } else {\n find(tl, key, equal)\n }\n };\n case (null) { null }\n }\n };\n\n /// Maps `key` to `value` in `map`, and overwrites the old entry if the key\n /// was already present. Returns the old value in an option if it existed and\n /// `null` otherwise, as well as the new map. Compares keys using the provided\n /// function `equal`.\n /// \n /// Example:\n /// \n /// ```motoko include=import,initialize\n /// // Add three entries to the map\n /// // map = [(0, 10), (1, 11), (2, 12)]\n /// map := AssocList.replace(map, 0, Nat.equal, ?10).0;\n /// map := AssocList.replace(map, 1, Nat.equal, ?11).0;\n /// map := AssocList.replace(map, 2, Nat.equal, ?12).0;\n /// // Override second entry\n /// map := AssocList.replace(map, 1, Nat.equal, ?21).0;\n /// \n /// List.toArray(map)\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size)` | `O(size)` |\n public func replace<K, V>(\n map : AssocList<K, V>,\n key : K,\n equal : (K, K) -> Bool,\n value : ?V\n ) : (AssocList<K, V>, ?V) {\n var prev : ?V = null;\n func del(al : AssocList<K, V>) : AssocList<K, V> {\n switch (al) {\n case (?(kv, tl)) {\n if (equal(key, kv.0)) {\n prev := ?kv.1;\n tl\n } else {\n let tl1 = del(tl);\n switch (prev) {\n case null { al };\n case (?_) { ?(kv, tl1) }\n }\n }\n };\n case null {\n null\n }\n }\n };\n let map1 = del(map);\n switch value {\n case (?value) { (?((key, value), map1), prev) };\n case null { (map1, prev) }\n }\n };\n\n /// Produces a new map containing all entries from `map1` whose keys are not\n /// contained in `map2`. The \"extra\" entries in `map2` are ignored. Compares\n /// keys using the provided function `equal`.\n /// \n /// Example:\n /// \n /// ```motoko include=import,initialize\n /// // Create map1 = [(0, 10), (1, 11), (2, 12)]\n /// var map1 : AssocList<Nat, Nat> = null;\n /// map1 := AssocList.replace(map1, 0, Nat.equal, ?10).0;\n /// map1 := AssocList.replace(map1, 1, Nat.equal, ?11).0;\n /// map1 := AssocList.replace(map1, 2, Nat.equal, ?12).0;\n /// \n /// // Create map2 = [(2, 12), (3, 13)]\n /// var map2 : AssocList<Nat, Nat> = null;\n /// map2 := AssocList.replace(map2, 2, Nat.equal, ?12).0;\n /// map2 := AssocList.replace(map2, 3, Nat.equal, ?13).0;\n /// \n /// // Take the difference\n /// let newMap = AssocList.diff(map1, map2, Nat.equal);\n /// List.toArray(newMap)\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size1 * size2)` | `O(1)` |\n public func diff<K, V, W>(\n map1 : AssocList<K, V>,\n map2 : AssocList<K, W>,\n equal : (K, K) -> Bool\n ) : AssocList<K, V> {\n func rec(al1 : AssocList<K, V>) : AssocList<K, V> {\n switch al1 {\n case (null) { null };\n case (?((k, v1), tl)) {\n switch (find<K, W>(map2, k, equal)) {\n case (null) { ?((k, v1), rec(tl)) };\n case (?_v2) { rec(tl) }\n }\n }\n }\n };\n rec(map1)\n };\n\n /// :::warning Deprecated function\n /// \n /// `mapAppend` is deprecated and may be removed in future versions. Consider using an alternative approach.\n /// :::\n public func mapAppend<K, V, W, X>(\n map1 : AssocList<K, V>,\n map2 : AssocList<K, W>,\n f : (?V, ?W) -> X\n ) : AssocList<K, X> {\n func rec(al1 : AssocList<K, V>, al2 : AssocList<K, W>) : AssocList<K, X> {\n switch (al1, al2) {\n case (null, null) { null };\n case (?((k, v), al1_), _) { ?((k, f(?v, null)), rec(al1_, al2)) };\n case (null, ?((k, v), al2_)) { ?((k, f(null, ?v)), rec(null, al2_)) }\n }\n };\n rec(map1, map2)\n };\n\n /// Produces a new map by mapping entries in `map1` and `map2` using `f` and\n /// concatenating the results. Assumes that there are no collisions between\n /// keys in `map1` and `map2`.\n /// \n /// Example:\n /// \n /// ```motoko include=import,initialize\n /// import { trap } \"mo:base/Debug\";\n /// \n /// // Create map1 = [(0, 10), (1, 11), (2, 12)]\n /// var map1 : AssocList<Nat, Nat> = null;\n /// map1 := AssocList.replace(map1, 0, Nat.equal, ?10).0;\n /// map1 := AssocList.replace(map1, 1, Nat.equal, ?11).0;\n /// map1 := AssocList.replace(map1, 2, Nat.equal, ?12).0;\n /// \n /// // Create map2 = [(4, \"14\"), (3, \"13\")]\n /// var map2 : AssocList<Nat, Text> = null;\n /// map2 := AssocList.replace(map2, 4, Nat.equal, ?\"14\").0;\n /// map2 := AssocList.replace(map2, 3, Nat.equal, ?\"13\").0;\n /// \n /// // Map and append the two AssocLists\n /// let newMap =\n /// AssocList.disjDisjoint<Nat, Nat, Text, Text>(\n /// map1,\n /// map2,\n /// func((v1, v2) : (?Nat, ?Text)) {\n /// switch(v1, v2) {\n /// case(?v1, null) {\n /// debug_show(v1) // convert values from map1 to Text\n /// };\n /// case(null, ?v2) {\n /// v2 // keep values from map2 as Text\n /// };\n /// case _ {\n /// trap \"These cases will never happen in mapAppend\"\n /// }\n /// }\n /// }\n /// );\n /// \n /// List.toArray(newMap)\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size1 + size2)` | `O(size1 + size2)` |\n\n public func disjDisjoint<K, V, W, X>(\n map1 : AssocList<K, V>,\n map2 : AssocList<K, W>,\n f : (?V, ?W) -> X\n ) : AssocList<K, X> {\n mapAppend<K, V, W, X>(map1, map2, f)\n };\n\n /// Creates a new map by merging entries from `map1` and `map2`, and mapping\n /// them using `combine`. `combine` is also used to combine the values of colliding keys.\n /// Keys are compared using the given `equal` function.\n /// \n /// :::note Behavior guarantee\n /// \n /// `combine` will never be applied to `(null, null)`.\n /// \n /// :::\n /// \n /// Example:\n /// \n /// ```motoko include=import,initialize\n /// import { trap } \"mo:base/Debug\";\n /// \n /// // Create map1 = [(0, 10), (1, 11), (2, 12)]\n /// var map1 : AssocList<Nat, Nat> = null;\n /// map1 := AssocList.replace(map1, 0, Nat.equal, ?10).0;\n /// map1 := AssocList.replace(map1, 1, Nat.equal, ?11).0;\n /// map1 := AssocList.replace(map1, 2, Nat.equal, ?12).0;\n /// \n /// // Create map2 = [(2, 12), (3, 13)]\n /// var map2 : AssocList<Nat, Nat> = null;\n /// map2 := AssocList.replace(map2, 2, Nat.equal, ?12).0;\n /// map2 := AssocList.replace(map2, 3, Nat.equal, ?13).0;\n /// \n /// // Merge the two maps using `combine`\n /// let newMap =\n /// AssocList.disj<Nat, Nat, Nat, Nat>(\n /// map1,\n /// map2,\n /// Nat.equal,\n /// func((v1, v2) : (?Nat, ?Nat)) : Nat {\n /// switch(v1, v2) {\n /// case(?v1, ?v2) {\n /// v1 + v2 // combine values of colliding keys by adding them\n /// };\n /// case(?v1, null) {\n /// v1 // when a key doesn't collide, keep the original value\n /// };\n /// case(null, ?v2) {\n /// v2\n /// };\n /// case _ {\n /// trap \"This case will never happen in disj\"\n /// }\n /// }\n /// }\n /// );\n /// \n /// List.toArray(newMap)\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size1 * size2)` | `O(size1 + size2)` |\n public func disj<K, V, W, X>(\n map1 : AssocList<K, V>,\n map2 : AssocList<K, W>,\n equal : (K, K) -> Bool,\n combine : (?V, ?W) -> X\n ) : AssocList<K, X> {\n func rec1(al1Rec : AssocList<K, V>) : AssocList<K, X> {\n switch al1Rec {\n case (null) {\n func rec2(al2 : AssocList<K, W>) : AssocList<K, X> {\n switch al2 {\n case (null) { null };\n case (?((k, v2), tl)) {\n switch (find<K, V>(map1, k, equal)) {\n case (null) { ?((k, combine(null, ?v2)), rec2(tl)) };\n case (?v1) { ?((k, combine(?v1, ?v2)), rec2(tl)) }\n }\n }\n }\n };\n rec2(map2)\n };\n case (?((k, v1), tl)) {\n switch (find<K, W>(map2, k, equal)) {\n case (null) { ?((k, combine(?v1, null)), rec1(tl)) };\n case (?_v2) { /* handled above */ rec1(tl) }\n }\n }\n }\n };\n rec1(map1)\n };\n\n /// Takes the intersection of `map1` and `map2`, only keeping colliding keys\n /// and combining values using the `combine` function. Keys are compared using\n /// the `equal` function.\n /// \n /// Example:\n /// \n /// ```motoko include=import,initialize\n /// // Create map1 = [(0, 10), (1, 11), (2, 12)]\n /// var map1 : AssocList<Nat, Nat> = null;\n /// map1 := AssocList.replace(map1, 0, Nat.equal, ?10).0;\n /// map1 := AssocList.replace(map1, 1, Nat.equal, ?11).0;\n /// map1 := AssocList.replace(map1, 2, Nat.equal, ?12).0;\n /// \n /// // Create map2 = [(2, 12), (3, 13)]\n /// var map2 : AssocList<Nat, Nat> = null;\n /// map2 := AssocList.replace(map2, 2, Nat.equal, ?12).0;\n /// map2 := AssocList.replace(map2, 3, Nat.equal, ?13).0;\n /// \n /// // Take the intersection of the two maps, combining values by adding them\n /// let newMap = AssocList.join<Nat, Nat, Nat, Nat>(map1, map2, Nat.equal, Nat.add);\n /// \n /// List.toArray(newMap)\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size1 * size2)` | `O(size1 + size2)` |\n public func join<K, V, W, X>(\n map1 : AssocList<K, V>,\n map2 : AssocList<K, W>,\n equal : (K, K) -> Bool,\n combine : (V, W) -> X\n ) : AssocList<K, X> {\n func rec(al1 : AssocList<K, V>) : AssocList<K, X> {\n switch al1 {\n case (null) { null };\n case (?((k, v1), tl)) {\n switch (find<K, W>(map2, k, equal)) {\n case (null) { rec(tl) };\n case (?v2) { ?((k, combine(v1, v2)), rec(tl)) }\n }\n }\n }\n };\n rec(map1)\n };\n\n /// Collapses the elements in `map` into a single value by starting with `base`\n /// and progessively combining elements into `base` with `combine`. Iteration runs\n /// left to right.\n /// \n /// Example:\n /// \n /// ```motoko include=import,initialize\n /// // Create map = [(0, 10), (1, 11), (2, 12)]\n /// var map : AssocList<Nat, Nat> = null;\n /// map := AssocList.replace(map, 0, Nat.equal, ?10).0;\n /// map := AssocList.replace(map, 1, Nat.equal, ?11).0;\n /// map := AssocList.replace(map, 2, Nat.equal, ?12).0;\n /// \n /// // (0 * 10) + (1 * 11) + (2 * 12)\n /// AssocList.fold<Nat, Nat, Nat>(map, 0, func(k, v, sumSoFar) = (k * v) + sumSoFar)\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size)` | `O(size)` |\n public func fold<K, V, X>(\n map : AssocList<K, V>,\n base : X,\n combine : (K, V, X) -> X\n ) : X {\n func rec(al : AssocList<K, V>) : X {\n switch al {\n case null { base };\n case (?((k, v), t)) { combine(k, v, rec(t)) }\n }\n };\n rec(map)\n }\n}\n"},"Deque.mo":{"content":"/// Double-ended queue (deque) of a generic element type `T`.\n/// \n/// The interface of deques is purely functional, not imperative, and deques are immutable values.\n/// In particular, deque operations such as push and pop do not update their input deque but instead return the value of the modified deque, alongside any other data.\n/// The input deque is left unchanged.\n/// \n/// Examples of use-cases:\n/// Queue (FIFO) by using `pushBack()` and `popFront()`.\n/// Stack (LIFO) by using `pushFront()` and `popFront()`.\n/// \n/// A deque is internally implemented as two lists, a head access list and a (reversed) tail access list, that are dynamically size-balanced by splitting.\n/// \n/// Construction: Create a new deque with the `empty<T>()` function.\n/// \n/// :::note Performance characteristics\n/// \n/// Push and pop operations have `O(1)` amortized cost and `O(n)` worst-case cost per call.\n/// Space usage follows the same pattern.\n/// `n` denotes the number of elements stored in the deque.\n/// :::\n\nimport List \"List\";\nimport P \"Prelude\";\n\nmodule {\n type List<T> = List.List<T>;\n\n /// Double-ended queue (deque) data type.\n public type Deque<T> = (List<T>, List<T>);\n\n /// Create a new empty deque.\n /// \n /// Example:\n /// ```motoko\n /// import Deque \"mo:base/Deque\";\n /// \n /// Deque.empty<Nat>()\n /// ```\n /// \n /// | Runtime | Space |\n /// |---------|--------|\n /// | `O(1)` | `O(1)` |\n\n public func empty<T>() : Deque<T> { (List.nil(), List.nil()) };\n\n /// Determine whether a deque is empty.\n /// Returns true if `deque` is empty, otherwise `false`.\n /// \n /// Example:\n /// ```motoko\n /// import Deque \"mo:base/Deque\";\n /// \n /// let deque = Deque.empty<Nat>();\n /// Deque.isEmpty(deque) // => true\n /// ```\n /// \n /// | Runtime | Space |\n /// |---------|--------|\n /// | `O(1)` | `O(1)` |\n public func isEmpty<T>(deque : Deque<T>) : Bool {\n switch deque {\n case (f, r) { List.isNil(f) and List.isNil(r) }\n }\n };\n\n func check<T>(q : Deque<T>) : Deque<T> {\n switch q {\n case (null, r) {\n let (a, b) = List.split(List.size(r) / 2, r);\n (List.reverse(b), a)\n };\n case (f, null) {\n let (a, b) = List.split(List.size(f) / 2, f);\n (a, List.reverse(b))\n };\n case q { q }\n }\n };\n\n /// Insert a new element on the front end of a deque.\n /// Returns the new deque with `element` in the front followed by the elements of `deque`.\n /// \n /// This may involve dynamic rebalancing of the two, internally used lists.\n /// \n /// Example:\n /// ```motoko\n /// import Deque \"mo:base/Deque\";\n /// \n /// Deque.pushFront(Deque.pushFront(Deque.empty<Nat>(), 2), 1) // deque with elements [1, 2]\n /// ```\n /// \n /// | Runtime (worst) | Runtime (amortized) | Space (worst) | Space (amortized) |\n /// |------------------|----------------------|----------------|---------------------|\n /// | `O(n)` | `O(1)` | `O(n)` | `O(1)` |\n /// \n /// `n` denotes the number of elements stored in the deque.\n public func pushFront<T>(deque : Deque<T>, element : T) : Deque<T> {\n check(List.push(element, deque.0), deque.1)\n };\n\n /// Inspect the optional element on the front end of a deque.\n /// Returns `null` if `deque` is empty. Otherwise, the front element of `deque`.\n /// \n /// Example:\n /// ```motoko\n /// import Deque \"mo:base/Deque\";\n /// \n /// let deque = Deque.pushFront(Deque.pushFront(Deque.empty<Nat>(), 2), 1);\n /// Deque.peekFront(deque) // => ?1\n /// ```\n /// \n /// | Runtime | Space |\n /// |---------|--------|\n /// | `O(1)` | `O(1)` |\n /// \n public func peekFront<T>(deque : Deque<T>) : ?T {\n switch deque {\n case (?(x, _f), _r) { ?x };\n case (null, ?(x, _r)) { ?x };\n case _ { null }\n }\n };\n\n /// Remove the element on the front end of a deque.\n /// Returns `null` if `deque` is empty. Otherwise, it returns a pair of\n /// the first element and a new deque that contains all the remaining elements of `deque`.\n /// \n /// This may involve dynamic rebalancing of the two, internally used lists.\n /// \n /// Example:\n /// ```motoko\n /// import Deque \"mo:base/Deque\";\n /// import Debug \"mo:base/Debug\";\n /// let initial = Deque.pushFront(Deque.pushFront(Deque.empty<Nat>(), 2), 1);\n /// // initial deque with elements [1, 2]\n /// let reduced = Deque.popFront(initial);\n /// switch reduced {\n /// case null {\n /// Debug.trap \"Empty queue impossible\"\n /// };\n /// case (?result) {\n /// let removedElement = result.0; // 1\n /// let reducedDeque = result.1; // deque with element [2].\n /// }\n /// }\n /// ```\n /// \n /// | Runtime (worst) | Runtime (amortized) | Space (worst) | Space (amortized) |\n /// |------------------|----------------------|----------------|---------------------|\n /// | `O(n)` | `O(1)` | `O(n)` | `O(1)` |\n public func popFront<T>(deque : Deque<T>) : ?(T, Deque<T>) {\n switch deque {\n case (?(x, f), r) { ?(x, check(f, r)) };\n case (null, ?(x, r)) { ?(x, check(null, r)) };\n case _ { null }\n }\n };\n\n /// Insert a new element on the back end of a deque.\n /// Returns the new deque with all the elements of `deque`, followed by `element` on the back.\n /// \n /// This may involve dynamic rebalancing of the two, internally used lists.\n /// \n /// Example:\n /// ```motoko\n /// import Deque \"mo:base/Deque\";\n /// \n /// Deque.pushBack(Deque.pushBack(Deque.empty<Nat>(), 1), 2) // deque with elements [1, 2]\n /// ```\n /// \n /// | Runtime (worst) | Runtime (amortized) | Space (worst) | Space (amortized) |\n /// |------------------|----------------------|----------------|---------------------|\n /// | `O(n)` | `O(1)` | `O(n)` | `O(1)` |\n /// \n /// `n` denotes the number of elements stored in the deque.\n public func pushBack<T>(deque : Deque<T>, element : T) : Deque<T> {\n check(deque.0, List.push(element, deque.1))\n };\n\n /// Inspect the optional element on the back end of a deque.\n /// Returns `null` if `deque` is empty. Otherwise, the back element of `deque`.\n /// \n /// Example:\n /// ```motoko\n /// import Deque \"mo:base/Deque\";\n /// \n /// let deque = Deque.pushBack(Deque.pushBack(Deque.empty<Nat>(), 1), 2);\n /// Deque.peekBack(deque) // => ?2\n /// ```\n /// \n /// | Runtime | Space |\n /// |---------|--------|\n /// | `O(1)` | `O(1)` |\n /// \n /// \n public func peekBack<T>(deque : Deque<T>) : ?T {\n switch deque {\n case (_f, ?(x, _r)) { ?x };\n case (?(x, _r), null) { ?x };\n case _ { null }\n }\n };\n\n /// Remove the element on the back end of a deque.\n /// Returns `null` if `deque` is empty. Otherwise, it returns a pair of\n /// a new deque that contains the remaining elements of `deque`\n /// and, as the second pair item, the removed back element.\n /// \n /// This may involve dynamic rebalancing of the two, internally used lists.\n /// \n /// Example:\n /// ```motoko\n /// import Deque \"mo:base/Deque\";\n /// import Debug \"mo:base/Debug\";\n /// \n /// let initial = Deque.pushBack(Deque.pushBack(Deque.empty<Nat>(), 1), 2);\n /// // initial deque with elements [1, 2]\n /// let reduced = Deque.popBack(initial);\n /// switch reduced {\n /// case null {\n /// Debug.trap \"Empty queue impossible\"\n /// };\n /// case (?result) {\n /// let reducedDeque = result.0; // deque with element [1].\n /// let removedElement = result.1; // 2\n /// }\n /// }\n /// ```\n /// \n /// | Runtime (worst) | Runtime (amortized) | Space (worst) | Space (amortized) |\n /// |------------------|----------------------|----------------|---------------------|\n /// | `O(n)` | `O(1)` | `O(n)` | `O(1)` |\n public func popBack<T>(deque : Deque<T>) : ?(Deque<T>, T) {\n switch deque {\n case (f, ?(x, r)) { ?(check(f, r), x) };\n case (?(x, f), null) { ?(check(f, null), x) };\n case _ { null }\n }\n }\n}\n"},"ExperimentalInternetComputer.mo":{"content":"/// Low-level interface to the Internet Computer.\n/// \n/// :::warning Experimental API\n/// This low-level API is **experimental** and likely to change or even disappear.\n/// :::\nimport Prim \"mo:⛔\";\n\nmodule {\n\n /// Calls ``canister``'s update or query function, `name`, with the binary contents of `data` as IC argument.\n /// Returns the response to the call, an IC _reply_ or _reject_, as a Motoko future:\n /// \n /// * The message data of an IC reply determines the binary contents of `reply`.\n /// * The error code and textual message data of an IC reject determines the future's `Error` value.\n /// \n /// Asynchronous context required: `call` is an asynchronous function and can only be applied in an asynchronous context.\n \n /// Example:\n /// ```motoko no-repl\n /// import IC \"mo:base/ExperimentalInternetComputer\";\n /// import Principal \"mo:base/Principal\";\n /// \n /// let ledger = Principal.fromText(\"ryjl3-tyaaa-aaaaa-aaaba-cai\");\n /// let method = \"decimals\";\n /// let input = ();\n /// type OutputType = { decimals : Nat32 };\n /// \n /// let rawReply = await IC.call(ledger, method, to_candid(input)); // serialized Candid\n /// let output : ?OutputType = from_candid(rawReply); // { decimals = 8 }\n /// ```\n /// \n /// [Learn more about Candid serialization](https://internetcomputer.org/docs/current/motoko/main/reference/language-manual#candid-serialization)\n public let call : (canister : Principal, name : Text, data : Blob) -> async (reply : Blob) = Prim.call_raw;\n\n /// `isReplicated` is true for update messages and for queries that passed through consensus.\n public let isReplicated : () -> Bool = Prim.isReplicatedExecution;\n\n /// Given computation, `comp`, counts the number of actual and (for IC system calls) notional WebAssembly\n /// instructions performed during the execution of `comp()`.\n\n /// More precisely, returns the difference between the state of the IC instruction counter (_performance counter_ `0`) before and after executing `comp()`\n /// (see [Performance Counter](https://internetcomputer.org/docs/current/references/ic-interface-spec#system-api-performance-counter)).\n\n /// :::note Garbage collection cost not included\n\n /// `countInstructions(comp)` will _not_ account for any deferred garbage collection costs incurred by `comp()`.\n /// :::\n\n /// Example:\n\n /// ```motoko no-repl\n /// import IC \"mo:base/ExperimentalInternetComputer\";\n /// \n /// let count = IC.countInstructions(func() {\n // ...\n /// });\n /// ```\n public func countInstructions(comp : () -> ()) : Nat64 {\n let init = Prim.performanceCounter(0);\n let pre = Prim.performanceCounter(0);\n comp();\n let post = Prim.performanceCounter(0);\n // performance_counter costs around 200 extra instructions, we perform an empty measurement to decide the overhead\n let overhead = pre - init;\n post - pre - overhead\n };\n\n /// Returns the current value of IC _performance counter_ `counter`.\n /// \n /// * Counter `0` is the _current execution instruction counter_, counting instructions only since the beginning of the current IC message.\n /// This counter is reset to value `0` on shared function entry and every `await`.\n /// It is therefore only suitable for measuring the cost of synchronous code.\n /// \n /// * Counter `1` is the _call context instruction counter_ for the current shared function call.\n /// For replicated message executing, this excludes the cost of nested IC calls (even to the current canister).\n /// For non-replicated messages, such as composite queries, it includes the cost of nested calls.\n /// The current value of this counter is preserved across `awaits` (unlike counter `0`).\n /// \n /// * The function (currently) traps if `counter` >= 2.\n /// \n /// Consult [Performance Counter](https://internetcomputer.org/docs/current/references/ic-interface-spec#system-api-performance-counter) for details.\n /// \n /// Example:\n /// ```motoko no-repl\n /// import IC \"mo:base/ExperimentalInternetComputer\";\n /// \n /// let c1 = IC.performanceCounter(1);\n /// work();\n /// let diff : Nat64 = IC.performanceCounter(1) - c1;\n /// ```\n public let performanceCounter : (counter : Nat32) -> (value : Nat64) = Prim.performanceCounter;\n\n /// Returns the time (in nanoseconds from the epoch start) by when the update message should\n /// reply to the best effort message so that it can be received by the requesting canister.\n /// Queries and unbounded-time update messages return null.\n public func replyDeadline() : ?Nat {\n let raw = Prim.replyDeadline();\n if (raw == 0) null else ?Prim.nat64ToNat(raw)\n };\n\n /// Returns the subnet's principal for the running actor.\n /// Note: Due to canister migration the hosting subnet can vary with time.\n /// \n /// Example:\n /// ```motoko no-repl\n /// import IC \"mo:base/ExperimentalInternetComputer\";\n /// \n /// let subnetPrincipal = IC.subnet();\n /// ```\n public let subnet : () -> Principal = Prim.canisterSubnet;\n\n}\n"},"RBTree.mo":{"content":"/// Key-value map implemented as a red-black tree (RBTree) with nodes storing key-value pairs.\n/// \n/// A red-black tree is a balanced binary search tree ordered by the keys.\n/// \n/// The tree data structure internally colors each of its nodes either red or black,\n/// and uses this information to balance the tree during the modifying operations.\n/// \n/// Creation:\n/// Instantiate class `RBTree<K, V>` that provides a map from keys of type `K` to values of type `V`.\n/// \n/// Example:\n/// ```motoko\n/// import RBTree \"mo:base/RBTree\";\n/// import Nat \"mo:base/Nat\";\n/// import Debug \"mo:base/Debug\";\n/// \n/// let tree = RBTree.RBTree<Nat, Text>(Nat.compare); // Create a new red-black tree mapping Nat to Text\n/// tree.put(1, \"one\");\n/// tree.put(2, \"two\");\n/// tree.put(3, \"tree\");\n/// for (entry in tree.entries()) {\n/// Debug.print(\"Entry key=\" # debug_show(entry.0) # \" value=\\\"\" # entry.1 #\"\\\"\");\n/// }\n/// ```\n/// \n/// :::note Performance\n/// * Runtime: `O(log(n))` worst case cost per insertion, removal, and retrieval operation.\n/// * Heap space: `O(n)` for storing the entire tree.\n/// * Stack space: `O(log(n)) for storing the entire tree.\n/// `n` denotes the number of key-value entries (i.e. nodes) stored in the tree.\n/// :::\n/// \n/// :::note\n/// Tree insertion, replacement, and removal produce `O(log(n))` garbage objects.\n/// :::\n/// \n/// :::info Credits\n/// The core of this implementation is derived from:\n/// \n/// * Ken Friis Larsen's [RedBlackMap.sml](https://github.com/kfl/mosml/blob/master/src/mosmllib/Redblackmap.sml), which itself is based on:\n/// * Stefan Kahrs, \"Red-black trees with types\", Journal of Functional Programming, 11(4): 425-432 (2001), [version 1 in web appendix](http://www.cs.ukc.ac.uk/people/staff/smk/redblack/rb.html).\n/// :::\n\nimport Debug \"Debug\";\nimport I \"Iter\";\nimport List \"List\";\nimport Nat \"Nat\";\nimport O \"Order\";\n\n// TODO: a faster, more compact and less indirect representation would be:\n// type Tree<K, V> = {\n// #red : (Tree<K, V>, K, V, Tree<K, V>);\n// #black : (Tree<K, V>, K, V, Tree<K, V>);\n// #leaf\n//};\n// (this inlines the colors into the variant, flattens a tuple, and removes a (now) redundant optin, for considerable heap savings.)\n// It would also make sense to maintain the size in a separate root for 0(1) access.\n\n// FUTURE: deprecate RBTree.mo and replace by RedBlackMap.mo, using this new representation\n\nmodule {\n\n /// Node color: Either red (`#R`) or black (`#B`).\n public type Color = { #R; #B };\n\n /// Red-black tree of nodes with key-value entries, ordered by the keys.\n /// The keys have the generic type `K` and the values the generic type `V`.\n /// Leaves are considered implicitly black.\n public type Tree<K, V> = {\n #node : (Color, Tree<K, V>, (K, ?V), Tree<K, V>);\n #leaf\n };\n\n /// A map from keys of type `K` to values of type `V` implemented as a red-black tree.\n /// The entries of key-value pairs are ordered by `compare` function applied to the keys.\n /// \n /// The class enables imperative usage in object-oriented-style.\n /// However, internally, the class uses a functional implementation.\n /// \n /// The `compare` function should implement a consistent total order among all possible values of `K` and\n /// for efficiency, only involves `O(1)` runtime costs without space allocation.\n /// \n /// Example:\n /// ```motoko name=initialize\n /// import RBTree \"mo:base/RBTree\";\n /// import Nat \"mo:base/Nat\";\n /// \n /// let tree = RBTree.RBTree<Nat, Text>(Nat.compare); // Create a map of `Nat` to `Text` using the `Nat.compare` order\n /// ```\n /// \n /// | Runtime | Space (Heap) | Space (Stack) |\n /// |----------------|--------------|----------------|\n /// | `O(1)` | `O(1))` | `O(1))` |\n public class RBTree<K, V>(compare : (K, K) -> O.Order) {\n\n var tree : Tree<K, V> = (#leaf : Tree<K, V>);\n\n /// Return a snapshot of the internal functional tree representation as sharable data.\n /// The returned tree representation is not affected by subsequent changes of the `RBTree` instance.\n /// \n /// \n /// Example:\n /// ```motoko include=initialize\n /// tree.put(1, \"one\");\n /// let treeSnapshot = tree.share();\n /// tree.put(2, \"second\");\n /// RBTree.size(treeSnapshot) // => 1 (Only the first insertion is part of the snapshot.)\n /// ```\n /// \n /// Useful for storing the state of a tree object as a stable variable, determining its size, pretty-printing, and sharing it across async function calls,\n /// i.e. passing it in async arguments or async results.\n /// \n /// | Runtime | Space (Heap) | Space (Stack) |\n /// |----------------|--------------|----------------|\n /// | `O(1)` | `O(1))` | `O(1))` |\n public func share() : Tree<K, V> {\n tree\n };\n\n /// Reset the current state of the tree object from a functional tree representation.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// import Iter \"mo:base/Iter\";\n /// \n /// tree.put(1, \"one\");\n /// let snapshot = tree.share(); // save the current state of the tree object in a snapshot\n /// tree.put(2, \"two\");\n /// tree.unshare(snapshot); // restore the tree object from the snapshot\n /// Iter.toArray(tree.entries()) // => [(1, \"one\")]\n /// ```\n /// \n /// Useful for restoring the state of a tree object from stable data, saved, for example, in a stable variable.\n /// \n /// | Runtime | Space (Heap) | Space (Stack) |\n /// |----------------|--------------|----------------|\n /// | `O(1)` | `O(1))` | `O(1))` |\n public func unshare(t : Tree<K, V>) : () {\n tree := t\n };\n\n /// Retrieve the value associated with a given key, if present. Returns `null`, if the key is absent.\n /// The key is searched according to the `compare` function defined on the class instantiation.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// \n /// tree.put(1, \"one\");\n /// tree.put(2, \"two\");\n /// \n /// tree.get(1) // => ?\"one\"\n /// ```\n /// \n /// | Runtime | Space (Heap) | Space (Stack) |\n /// |----------------|--------------|----------------|\n /// | `O(log(n))` | `O(1))` retained + garbage | `O(log(n))` |\n public func get(key : K) : ?V {\n getRec(key, compare, tree)\n };\n\n /// Replace the value associated with a given key, if the key is present.\n /// Otherwise, if the key does not yet exist, insert the key-value entry.\n /// \n /// Returns the previous value of the key, if the key already existed.\n /// Otherwise, `null`, if the key did not yet exist before.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// import Iter \"mo:base/Iter\";\n /// \n /// tree.put(1, \"old one\");\n /// tree.put(2, \"two\");\n /// \n /// ignore tree.replace(1, \"new one\");\n /// Iter.toArray(tree.entries()) // => [(1, \"new one\"), (2, \"two\")]\n /// ```\n /// \n /// | Runtime | Space (Heap) | Space (Stack) |\n /// |----------------|--------------|----------------|\n /// | `O(log(n))` | `O(1))` retained + garbage | `O(log(n))` |\n public func replace(key : K, value : V) : ?V {\n let (t, res) = insert(tree, compare, key, value);\n tree := t;\n res\n };\n\n /// Insert a key-value entry in the tree. If the key already exists, it overwrites the associated value.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// import Iter \"mo:base/Iter\";\n /// \n /// tree.put(1, \"one\");\n /// tree.put(2, \"two\");\n /// tree.put(3, \"three\");\n /// Iter.toArray(tree.entries()) // now contains three entries\n /// ```\n /// \n /// | Runtime | Space (Heap) | Space (Stack) |\n /// |----------------|--------------|----------------|\n /// | `O(log(n))` | `O(1))` retained + garbage | `O(log(n))` |\n public func put(key : K, value : V) {\n let (t, _res) = insert(tree, compare, key, value);\n tree := t\n };\n\n /// Delete the entry associated with a given key, if the key exists.\n /// No effect if the key is absent. Same as `remove(key)` except that it\n /// does not have a return value.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// import Iter \"mo:base/Iter\";\n /// \n /// tree.put(1, \"one\");\n /// tree.put(2, \"two\");\n /// \n /// tree.delete(1);\n /// Iter.toArray(tree.entries()) // => [(2, \"two\")].\n /// ```\n /// \n /// | Runtime | Space (Heap) | Space (Stack) |\n /// |----------------|--------------|----------------|\n /// | `O(log(n))` | `O(1))` retained + garbage | `O(log(n))` |\n public func delete(key : K) {\n let (_res, t) = removeRec(key, compare, tree);\n tree := t\n };\n\n /// Remove the entry associated with a given key, if the key exists, and return the associated value.\n /// Returns `null` without any other effect if the key is absent.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// import Iter \"mo:base/Iter\";\n /// \n /// tree.put(1, \"one\");\n /// tree.put(2, \"two\");\n /// \n /// ignore tree.remove(1);\n /// Iter.toArray(tree.entries()) // => [(2, \"two\")].\n /// ```\n /// \n /// | Runtime | Space (Heap) | Space (Stack) |\n /// |----------------|--------------|----------------|\n /// | `O(log(n))` | `O(1))` retained + garbage | `O(log(n))` |\n public func remove(key : K) : ?V {\n let (res, t) = removeRec(key, compare, tree);\n tree := t;\n res\n };\n\n /// An iterator for the key-value entries of the map, in ascending key order.\n /// The iterator takes a snapshot view of the tree and is not affected by concurrent modifications.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// import Debug \"mo:base/Debug\";\n /// \n /// tree.put(1, \"one\");\n /// tree.put(2, \"two\");\n /// tree.put(3, \"two\");\n /// \n /// for (entry in tree.entries()) {\n /// Debug.print(\"Entry key=\" # debug_show(entry.0) # \" value=\\\"\" # entry.1 #\"\\\"\");\n /// }\n /// \n /// // Entry key=1 value=\"one\"\n /// // Entry key=2 value=\"two\"\n /// // Entry key=3 value=\"three\"\n /// ```\n /// \n\n /// | Runtime | Space (Heap) | Space (Stack) |\n /// |----------------|--------------|----------------|\n /// | `O(n)` | `O(log(n))` retained + garbage | `O(log(n))` |\n public func entries() : I.Iter<(K, V)> { iter(tree, #fwd) };\n\n /// An iterator for the key-value entries of the map, in descending key order.\n /// The iterator takes a snapshot view of the tree and is not affected by concurrent modifications.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// import Debug \"mo:base/Debug\";\n /// \n /// let tree = RBTree.RBTree<Nat, Text>(Nat.compare);\n /// tree.put(1, \"one\");\n /// tree.put(2, \"two\");\n /// tree.put(3, \"two\");\n /// \n /// for (entry in tree.entriesRev()) {\n /// Debug.print(\"Entry key=\" # debug_show(entry.0) # \" value=\\\"\" # entry.1 #\"\\\"\");\n /// }\n /// \n /// // Entry key=3 value=\"three\"\n /// // Entry key=2 value=\"two\"\n /// // Entry key=1 value=\"one\"\n /// ```\n /// \n\n /// | Runtime | Space (Heap) | Space (Stack) |\n /// |----------------|--------------|----------------|\n /// | `O(n)` | `O(log(n))` retained + garbage | `O(log(n))` |\n public func entriesRev() : I.Iter<(K, V)> { iter(tree, #bwd) };\n\n }; // end class\n\n type IterRep<X, Y> = List.List<{ #tr : Tree<X, Y>; #xy : (X, ?Y) }>;\n\n /// Get an iterator for the entries of the `tree`, in ascending (`#fwd`) or descending (`#bwd`) order as specified by `direction`.\n /// The iterator takes a snapshot view of the tree and is not affected by concurrent modifications.\n /// \n /// Example:\n /// ```motoko\n /// import RBTree \"mo:base/RBTree\";\n /// import Nat \"mo:base/Nat\";\n /// import Debug \"mo:base/Debug\";\n /// \n /// let tree = RBTree.RBTree<Nat, Text>(Nat.compare);\n /// tree.put(1, \"one\");\n /// tree.put(2, \"two\");\n /// tree.put(3, \"two\");\n /// \n /// for (entry in RBTree.iter(tree.share(), #bwd)) { // backward iteration\n /// Debug.print(\"Entry key=\" # debug_show(entry.0) # \" value=\\\"\" # entry.1 #\"\\\"\");\n /// }\n /// \n /// // Entry key=3 value=\"three\"\n /// // Entry key=2 value=\"two\"\n /// // Entry key=1 value=\"one\"\n /// ```\n /// \n\n /// | Runtime | Space (Heap) | Space (Stack) |\n /// |----------------|--------------|----------------|\n /// | `O(n)` | `O(log(n))` retained + garbage | `O(log(n))` |\n public func iter<X, Y>(tree : Tree<X, Y>, direction : { #fwd; #bwd }) : I.Iter<(X, Y)> {\n object {\n var trees : IterRep<X, Y> = ?(#tr(tree), null);\n public func next() : ?(X, Y) {\n switch (direction, trees) {\n case (_, null) { null };\n case (_, ?(#tr(#leaf), ts)) {\n trees := ts;\n next()\n };\n case (_, ?(#xy(xy), ts)) {\n trees := ts;\n switch (xy.1) {\n case null { next() };\n case (?y) { ?(xy.0, y) }\n }\n };\n case (#fwd, ?(#tr(#node(_, l, xy, r)), ts)) {\n trees := ?(#tr(l), ?(#xy(xy), ?(#tr(r), ts)));\n next()\n };\n case (#bwd, ?(#tr(#node(_, l, xy, r)), ts)) {\n trees := ?(#tr(r), ?(#xy(xy), ?(#tr(l), ts)));\n next()\n }\n }\n }\n }\n };\n\n /// Remove the value associated with a given key.\n func removeRec<X, Y>(x : X, compare : (X, X) -> O.Order, t : Tree<X, Y>) : (?Y, Tree<X, Y>) {\n let (t1, r) = remove(t, compare, x);\n (r, t1)\n };\n\n func getRec<X, Y>(x : X, compare : (X, X) -> O.Order, t : Tree<X, Y>) : ?Y {\n switch t {\n case (#leaf) { null };\n case (#node(_c, l, xy, r)) {\n switch (compare(x, xy.0)) {\n case (#less) { getRec(x, compare, l) };\n case (#equal) { xy.1 };\n case (#greater) { getRec(x, compare, r) }\n }\n }\n }\n };\n\n /// Determine the size of the tree as the number of key-value entries.\n /// \n /// Example:\n /// ```motoko\n /// import RBTree \"mo:base/RBTree\";\n /// import Nat \"mo:base/Nat\";\n /// \n /// let tree = RBTree.RBTree<Nat, Text>(Nat.compare);\n /// tree.put(1, \"one\");\n /// tree.put(2, \"two\");\n /// tree.put(3, \"three\");\n /// \n /// RBTree.size(tree.share()) // 3 entries\n /// ```\n /// \n /// | Runtime | Space (Heap) | Space (Stack) |\n /// |----------------|--------------|----------------|\n /// | `O(log(n))` | `O(1)` | `O(log(n))` |\n public func size<X, Y>(t : Tree<X, Y>) : Nat {\n switch t {\n case (#leaf) { 0 };\n case (#node(_, l, xy, r)) {\n size(l) + size(r) + (switch (xy.1) { case null 0; case _ 1 })\n }\n }\n };\n\n func redden<X, Y>(t : Tree<X, Y>) : Tree<X, Y> {\n switch t {\n case (#node(#B, l, xy, r)) { (#node(#R, l, xy, r)) };\n case _ {\n Debug.trap \"RBTree.red\"\n }\n }\n };\n\n func lbalance<X, Y>(left : Tree<X, Y>, xy : (X, ?Y), right : Tree<X, Y>) : Tree<X, Y> {\n switch (left, right) {\n case (#node(#R, #node(#R, l1, xy1, r1), xy2, r2), r) {\n #node(\n #R,\n #node(#B, l1, xy1, r1),\n xy2,\n #node(#B, r2, xy, r)\n )\n };\n case (#node(#R, l1, xy1, #node(#R, l2, xy2, r2)), r) {\n #node(\n #R,\n #node(#B, l1, xy1, l2),\n xy2,\n #node(#B, r2, xy, r)\n )\n };\n case _ {\n #node(#B, left, xy, right)\n }\n }\n };\n\n func rbalance<X, Y>(left : Tree<X, Y>, xy : (X, ?Y), right : Tree<X, Y>) : Tree<X, Y> {\n switch (left, right) {\n case (l, #node(#R, l1, xy1, #node(#R, l2, xy2, r2))) {\n #node(\n #R,\n #node(#B, l, xy, l1),\n xy1,\n #node(#B, l2, xy2, r2)\n )\n };\n case (l, #node(#R, #node(#R, l1, xy1, r1), xy2, r2)) {\n #node(\n #R,\n #node(#B, l, xy, l1),\n xy1,\n #node(#B, r1, xy2, r2)\n )\n };\n case _ {\n #node(#B, left, xy, right)\n }\n }\n };\n\n func insert<X, Y>(\n tree : Tree<X, Y>,\n compare : (X, X) -> O.Order,\n x : X,\n y : Y\n ) : (Tree<X, Y>, ?Y) {\n var y0 : ?Y = null;\n func ins(tree : Tree<X, Y>) : Tree<X, Y> {\n switch tree {\n case (#leaf) {\n #node(#R, #leaf, (x, ?y), #leaf)\n };\n case (#node(#B, left, xy, right)) {\n switch (compare(x, xy.0)) {\n case (#less) {\n lbalance(ins left, xy, right)\n };\n case (#greater) {\n rbalance(left, xy, ins right)\n };\n case (#equal) {\n y0 := xy.1;\n #node(#B, left, (x, ?y), right)\n }\n }\n };\n case (#node(#R, left, xy, right)) {\n switch (compare(x, xy.0)) {\n case (#less) {\n #node(#R, ins left, xy, right)\n };\n case (#greater) {\n #node(#R, left, xy, ins right)\n };\n case (#equal) {\n y0 := xy.1;\n #node(#R, left, (x, ?y), right)\n }\n }\n }\n }\n };\n switch (ins tree) {\n case (#node(#R, left, xy, right)) {\n (#node(#B, left, xy, right), y0)\n };\n case other { (other, y0) }\n }\n };\n\n func balLeft<X, Y>(left : Tree<X, Y>, xy : (X, ?Y), right : Tree<X, Y>) : Tree<X, Y> {\n switch (left, right) {\n case (#node(#R, l1, xy1, r1), r) {\n #node(\n #R,\n #node(#B, l1, xy1, r1),\n xy,\n r\n )\n };\n case (_, #node(#B, l2, xy2, r2)) {\n rbalance(left, xy, #node(#R, l2, xy2, r2))\n };\n case (_, #node(#R, #node(#B, l2, xy2, r2), xy3, r3)) {\n #node(\n #R,\n #node(#B, left, xy, l2),\n xy2,\n rbalance(r2, xy3, redden r3)\n )\n };\n case _ { Debug.trap \"balLeft\" }\n }\n };\n\n func balRight<X, Y>(left : Tree<X, Y>, xy : (X, ?Y), right : Tree<X, Y>) : Tree<X, Y> {\n switch (left, right) {\n case (l, #node(#R, l1, xy1, r1)) {\n #node(\n #R,\n l,\n xy,\n #node(#B, l1, xy1, r1)\n )\n };\n case (#node(#B, l1, xy1, r1), r) {\n lbalance(#node(#R, l1, xy1, r1), xy, r)\n };\n case (#node(#R, l1, xy1, #node(#B, l2, xy2, r2)), r3) {\n #node(\n #R,\n lbalance(redden l1, xy1, l2),\n xy2,\n #node(#B, r2, xy, r3)\n )\n };\n case _ { Debug.trap \"balRight\" }\n }\n };\n\n func append<X, Y>(left : Tree<X, Y>, right : Tree<X, Y>) : Tree<X, Y> {\n switch (left, right) {\n case (#leaf, _) { right };\n case (_, #leaf) { left };\n case (\n #node(#R, l1, xy1, r1),\n #node(#R, l2, xy2, r2)\n ) {\n switch (append(r1, l2)) {\n case (#node(#R, l3, xy3, r3)) {\n #node(\n #R,\n #node(#R, l1, xy1, l3),\n xy3,\n #node(#R, r3, xy2, r2)\n )\n };\n case r1l2 {\n #node(#R, l1, xy1, #node(#R, r1l2, xy2, r2))\n }\n }\n };\n case (t1, #node(#R, l2, xy2, r2)) {\n #node(#R, append(t1, l2), xy2, r2)\n };\n case (#node(#R, l1, xy1, r1), t2) {\n #node(#R, l1, xy1, append(r1, t2))\n };\n case (#node(#B, l1, xy1, r1), #node(#B, l2, xy2, r2)) {\n switch (append(r1, l2)) {\n case (#node(#R, l3, xy3, r3)) {\n #node(\n #R,\n #node(#B, l1, xy1, l3),\n xy3,\n #node(#B, r3, xy2, r2)\n )\n };\n case r1l2 {\n balLeft(\n l1,\n xy1,\n #node(#B, r1l2, xy2, r2)\n )\n }\n }\n }\n }\n };\n\n func remove<X, Y>(tree : Tree<X, Y>, compare : (X, X) -> O.Order, x : X) : (Tree<X, Y>, ?Y) {\n var y0 : ?Y = null;\n func delNode(left : Tree<X, Y>, xy : (X, ?Y), right : Tree<X, Y>) : Tree<X, Y> {\n switch (compare(x, xy.0)) {\n case (#less) {\n let newLeft = del left;\n switch left {\n case (#node(#B, _, _, _)) {\n balLeft(newLeft, xy, right)\n };\n case _ {\n #node(#R, newLeft, xy, right)\n }\n }\n };\n case (#greater) {\n let newRight = del right;\n switch right {\n case (#node(#B, _, _, _)) {\n balRight(left, xy, newRight)\n };\n case _ {\n #node(#R, left, xy, newRight)\n }\n }\n };\n case (#equal) {\n y0 := xy.1;\n append(left, right)\n }\n }\n };\n func del(tree : Tree<X, Y>) : Tree<X, Y> {\n switch tree {\n case (#leaf) {\n tree\n };\n case (#node(_, left, xy, right)) {\n delNode(left, xy, right)\n }\n }\n };\n switch (del(tree)) {\n case (#node(#R, left, xy, right)) {\n (#node(#B, left, xy, right), y0)\n };\n case other { (other, y0) }\n }\n }\n\n}\n"},"Buffer.mo":{"content":"/// Class `Buffer<X>` provides a mutable list of elements of type `X`.\n/// It wraps a resizable underlying array and is comparable to `ArrayList` or `Vector` in other languages.\n/// \n/// You can convert a buffer to a fixed-size array using `Buffer.toArray`, which is recommended for storing data in stable variables.\n/// \n/// Like arrays, buffer elements are indexed from `0` to `size - 1`.\n/// \n/// :::note Assumptions\n/// \n/// Runtime and space complexity assumes that `combine`, `equal`, and other functions execute in `O(1)` time and space.\n/// \n/// :::\n/// \n/// :::note Size vs capacity\n/// \n/// - `size`: Number of elements in the buffer.\n/// - `capacity`: Length of the underlying array.\n/// \n/// The invariant `capacity >= size` always holds.\n/// :::\n/// \n/// :::warning Performance caveat\n/// \n/// Operations like `add` are amortized `O(1)` but can take `O(n)` in the worst case.\n/// For large buffers, these worst cases may exceed the cycle limit per message.\n/// Use with care when growing buffers dynamically.\n/// :::\n/// \n/// :::info Constructor behavior\n/// \n/// The `initCapacity` argument sets the initial capacity of the underlying array.\n/// \n/// - When the capacity is exceeded, the array grows by a factor of 1.5.\n/// - When the buffer size drops below 1/4 of the capacity, it shrinks by a factor of 2.\n/// :::\n/// \n/// Example:\n/// \n/// ```motoko name=initialize\n/// import Buffer \"mo:base/Buffer\";\n/// \n/// let buffer = Buffer.Buffer<Nat>(3); // Creates a new Buffer\n/// ```\n/// \n/// | Runtime | Space |\n/// |-----------|-----------|\n/// | `O(initCapacity)` | `O(initCapacity)` |\n\nimport Prim \"mo:⛔\";\nimport Result \"Result\";\nimport Order \"Order\";\nimport Array \"Array\";\n\nmodule {\n type Order = Order.Order;\n\n // The following constants are used to manage the capacity.\n // The length of `elements` is increased by `INCREASE_FACTOR` when capacity is reached.\n // The length of `elements` is decreased by `DECREASE_FACTOR` when capacity is strictly less than\n // `DECREASE_THRESHOLD`.\n\n // INCREASE_FACTOR = INCREASE_FACTOR_NUME / INCREASE_FACTOR_DENOM (with floating point division)\n // Keep INCREASE_FACTOR low to minimize cycle limit problem\n private let INCREASE_FACTOR_NUME = 3;\n private let INCREASE_FACTOR_DENOM = 2;\n private let DECREASE_THRESHOLD = 4; // Don't decrease capacity too early to avoid thrashing\n private let DECREASE_FACTOR = 2;\n private let DEFAULT_CAPACITY = 8;\n\n private func newCapacity(oldCapacity : Nat) : Nat {\n if (oldCapacity == 0) {\n 1\n } else {\n // calculates ceil(oldCapacity * INCREASE_FACTOR) without floats\n ((oldCapacity * INCREASE_FACTOR_NUME) + INCREASE_FACTOR_DENOM - 1) / INCREASE_FACTOR_DENOM\n }\n };\n\n public class Buffer<X>(initCapacity : Nat) = this {\n var _size : Nat = 0; // avoid name clash with `size()` method\n var elements : [var ?X] = Prim.Array_init(initCapacity, null);\n\n /// Returns the current number of elements in the buffer.\n /// \n /// Example:\n /// \n /// ```motoko include=initialize\n /// buffer.size() // => 0\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(1)` | `O(1)` |\n public func size() : Nat = _size;\n\n /// Adds a single element to the end of the buffer, doubling\n /// the size of the array if capacity is exceeded.\n /// \n /// Example:\n /// \n /// ```motoko include=initialize\n /// buffer.add(0); // add 0 to buffer\n /// buffer.add(1);\n /// buffer.add(2);\n /// buffer.add(3); // causes underlying array to increase in capacity\n /// Buffer.toArray(buffer) // => [0, 1, 2, 3]\n /// ```\n /// \n /// | Runtime (worst) | Runtime (amortized) | Space (worst) | Space (amortized) |\n /// |------------------|----------------------|----------------|---------------------|\n /// | `O(size)` | `O(1)` | `O(size)` | `O(1)` |\n public func add(element : X) {\n if (_size == elements.size()) {\n reserve(newCapacity(elements.size()))\n };\n elements[_size] := ?element;\n _size += 1\n };\n\n /// Returns the element at index `index`. Traps if `index >= size`. Indexing is zero-based.\n /// \n /// Example:\n /// \n /// ```motoko include=initialize\n /// buffer.add(10);\n /// buffer.add(11);\n /// buffer.get(0); // => 10\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(1)` | `O(1)` |\n public func get(index : Nat) : X {\n switch (elements[index]) {\n case (?element) element;\n case null Prim.trap(\"Buffer index out of bounds in get\")\n }\n };\n\n /// Returns the element at index `index` as an option.\n /// Returns `null` when `index >= size`. Indexing is zero-based.\n /// \n /// Example:\n /// \n /// ```motoko include=initialize\n /// buffer.add(10);\n /// buffer.add(11);\n /// let x = buffer.getOpt(0); // => ?10\n /// let y = buffer.getOpt(2); // => null\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(1)` | `O(1)` |\n\n \n public func getOpt(index : Nat) : ?X {\n if (index < _size) {\n elements[index]\n } else {\n null\n }\n };\n /// ```motoko include=initialize\n /// buffer.add(10);\n /// buffer.put(0, 20); // overwrites 10 at index 0 with 20\n /// Buffer.toArray(buffer) // => [20]\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(1)` | `O(1)` |\n ///\n public func put(index : Nat, element : X) {\n if (index >= _size) {\n Prim.trap \"Buffer index out of bounds in put\"\n };\n elements[index] := ?element\n };\n\n /// Removes and returns the last item in the buffer or `null` if\n /// the buffer is empty.\n /// \n /// Example:\n /// \n /// ```motoko include=initialize\n /// buffer.add(10);\n /// buffer.add(11);\n /// buffer.removeLast(); // => ?11\n /// ```\n /// \n /// | Runtime (worst) | Runtime (amortized) | Space (worst) | Space (amortized) |\n /// |------------------|----------------------|----------------|---------------------|\n /// | `O(size)` | `O(1)` | `O(size)` | `O(1)` |\n ///\n public func removeLast() : ?X {\n if (_size == 0) {\n return null\n };\n\n _size -= 1;\n let lastElement = elements[_size];\n elements[_size] := null;\n\n if (_size < elements.size() / DECREASE_THRESHOLD) {\n // FIXME should this new capacity be a function of _size\n // instead of the current capacity? E.g. _size * INCREASE_FACTOR\n reserve(elements.size() / DECREASE_FACTOR)\n };\n\n lastElement\n };\n\n /// Removes and returns the element at `index` from the buffer.\n /// All elements with index > `index` are shifted one position to the left.\n /// This may cause a downsizing of the array.\n /// \n /// Traps if index >= size.\n /// \n /// :::warning Inefficient pattern\n /// \n /// Repeated removal of elements using this method is inefficient and may indicate that a different data structure would better suit your use case.\n /// :::\n /// \n /// Example:\n /// \n /// ```motoko include=initialize\n /// buffer.add(10);\n /// buffer.add(11);\n /// buffer.add(12);\n /// let x = buffer.remove(1); // evaluates to 11. 11 no longer in list.\n /// Buffer.toArray(buffer) // => [10, 12]\n /// ```\n /// \n /// | Runtime (worst) | Runtime (amortized) | Space (worst) | Space (amortized) |\n /// |------------------|----------------------|----------------|---------------------|\n /// | `O(size)` |- | `O(size)` | `O(1)` |\n public func remove(index : Nat) : X {\n if (index >= _size) {\n Prim.trap \"Buffer index out of bounds in remove\"\n };\n\n let element = elements[index];\n\n // copy elements to new array and shift over in one pass\n if ((_size - 1) : Nat < elements.size() / DECREASE_THRESHOLD) {\n let elements2 = Prim.Array_init<?X>(elements.size() / DECREASE_FACTOR, null);\n\n var i = 0;\n var j = 0;\n label l while (i < _size) {\n if (i == index) {\n i += 1;\n continue l\n };\n\n elements2[j] := elements[i];\n i += 1;\n j += 1\n };\n elements := elements2\n } else {\n // just shift over elements\n var i = index;\n while (i < (_size - 1 : Nat)) {\n elements[i] := elements[i + 1];\n i += 1\n };\n elements[_size - 1] := null\n };\n\n _size -= 1;\n\n switch (element) {\n case (?element) {\n element\n };\n case null {\n Prim.trap \"Malformed buffer in remove\"\n }\n }\n };\n\n /// Resets the buffer. Capacity is set to 8.\n /// \n /// Example:\n /// \n /// ```motoko include=initialize\n /// buffer.add(10);\n /// buffer.add(11);\n /// buffer.add(12);\n /// buffer.clear(); // buffer is now empty\n /// Buffer.toArray(buffer) // => []\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(1)` | `O(1)` |\n public func clear() {\n _size := 0;\n reserve(DEFAULT_CAPACITY)\n };\n\n /// Removes all elements from the buffer for which the predicate returns false.\n /// The predicate is given both the index of the element and the element itself.\n /// This may cause a downsizing of the array.\n /// \n /// Example:\n /// \n /// ```motoko include=initialize\n /// buffer.add(10);\n /// buffer.add(11);\n /// buffer.add(12);\n /// buffer.filterEntries(func(_, x) = x % 2 == 0); // only keep even elements\n /// Buffer.toArray(buffer) // => [10, 12]\n /// ```\n /// \n /// | Runtime (worst) | Runtime (amortized) | Space (worst) | Space (amortized) |\n /// |------------------|----------------------|----------------|---------------------|\n /// | `O(size)` | - | `O(size)` | `O(1)` |\n /// \n public func filterEntries(predicate : (Nat, X) -> Bool) {\n var numRemoved = 0;\n let keep = Prim.Array_tabulate<Bool>(\n _size,\n func i {\n switch (elements[i]) {\n case (?element) {\n if (predicate(i, element)) {\n true\n } else {\n numRemoved += 1;\n false\n }\n };\n case null {\n Prim.trap \"Malformed buffer in filter()\"\n }\n }\n }\n );\n\n let capacity = elements.size();\n\n if ((_size - numRemoved : Nat) < capacity / DECREASE_THRESHOLD) {\n let elements2 = Prim.Array_init<?X>(capacity / DECREASE_FACTOR, null);\n\n var i = 0;\n var j = 0;\n while (i < _size) {\n if (keep[i]) {\n elements2[j] := elements[i];\n i += 1;\n j += 1\n } else {\n i += 1\n }\n };\n\n elements := elements2\n } else {\n var i = 0;\n var j = 0;\n while (i < _size) {\n if (keep[i]) {\n elements[j] := elements[i];\n i += 1;\n j += 1\n } else {\n i += 1\n }\n };\n\n while (j < _size) {\n elements[j] := null;\n j += 1\n }\n };\n\n _size -= numRemoved\n };\n\n /// Returns the capacity of the buffer (the length of the underlying array).\n /// \n /// Example:\n /// \n /// ```motoko include=initialize\n /// let buffer = Buffer.Buffer<Nat>(2); // underlying array has capacity 2\n /// buffer.add(10);\n /// let c1 = buffer.capacity(); // => 2\n /// buffer.add(11);\n /// buffer.add(12); // causes capacity to increase by factor of 1.5\n /// let c2 = buffer.capacity(); // => 3\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(1)` | `O(1)` |\n public func capacity() : Nat = elements.size();\n\n /// Changes the capacity to `capacity`. Traps if `capacity` < `size`.\n /// \n /// ```motoko include=initialize\n /// buffer.reserve(4);\n /// buffer.add(10);\n /// buffer.add(11);\n /// buffer.capacity(); // => 4\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(capacity)` | `O(capacity)` |\n public func reserve(capacity : Nat) {\n if (capacity < _size) {\n Prim.trap \"capacity must be >= size in reserve\"\n };\n\n let elements2 = Prim.Array_init<?X>(capacity, null);\n\n var i = 0;\n while (i < _size) {\n elements2[i] := elements[i];\n i += 1\n };\n elements := elements2\n };\n\n /// Adds all elements in buffer `b` to this buffer.\n /// \n /// ```motoko include=initialize\n /// let buffer1 = Buffer.Buffer<Nat>(2);\n /// let buffer2 = Buffer.Buffer<Nat>(2);\n /// buffer1.add(10);\n /// buffer1.add(11);\n /// buffer2.add(12);\n /// buffer2.add(13);\n /// buffer1.append(buffer2); // adds elements from buffer2 to buffer1\n /// Buffer.toArray(buffer1) // => [10, 11, 12, 13]\n /// ```\n /// \n /// | Runtime (worst) | Runtime (amortized) | Space (worst) | Space (amortized) |\n /// |------------------|----------------------|----------------|---------------------|\n /// | `O(size1 + size2)` | `O(size2)` | `O(size1 +size2)` | `O(1)` |\n\n public func append(buffer2 : Buffer<X>) {\n let size2 = buffer2.size();\n // Make sure you only allocate a new array at most once\n if (_size + size2 > elements.size()) {\n // FIXME would be nice to have a tabulate for var arrays here\n reserve(newCapacity(_size + size2))\n };\n var i = 0;\n while (i < size2) {\n elements[_size + i] := buffer2.getOpt i;\n i += 1\n };\n\n _size += size2\n };\n\n /// Inserts `element` at `index`, shifts all elements to the right of\n /// `index` over by one index. Traps if `index` is greater than size.\n /// \n /// ```motoko include=initialize\n /// let buffer1 = Buffer.Buffer<Nat>(2);\n /// let buffer2 = Buffer.Buffer<Nat>(2);\n /// buffer.add(10);\n /// buffer.add(11);\n /// buffer.insert(1, 9);\n /// Buffer.toArray(buffer) // => [10, 9, 11]\n /// ```\n /// \n /// | Runtime (worst) | Runtime (amortized) | Space (worst) | Space (amortized) |\n /// |------------------|----------------------|----------------|---------------------|\n /// | `O(size)` | - | `O(size)` | `O(1)` |\n public func insert(index : Nat, element : X) {\n if (index > _size) {\n Prim.trap \"Buffer index out of bounds in insert\"\n };\n let capacity = elements.size();\n\n if (_size + 1 > capacity) {\n let capacity = elements.size();\n let elements2 = Prim.Array_init<?X>(newCapacity capacity, null);\n var i = 0;\n while (i < _size + 1) {\n if (i < index) {\n elements2[i] := elements[i]\n } else if (i == index) {\n elements2[i] := ?element\n } else {\n elements2[i] := elements[i - 1]\n };\n\n i += 1\n };\n elements := elements2\n } else {\n var i : Nat = _size;\n while (i > index) {\n elements[i] := elements[i - 1];\n i -= 1\n };\n elements[index] := ?element\n };\n\n _size += 1\n };\n\n /// Inserts `buffer2` at `index`, and shifts all elements to the right of\n /// `index` over by size2. Traps if `index` is greater than size.\n /// \n /// ```motoko include=initialize\n /// let buffer1 = Buffer.Buffer<Nat>(2);\n /// let buffer2 = Buffer.Buffer<Nat>(2);\n /// buffer1.add(10);\n /// buffer1.add(11);\n /// buffer2.add(12);\n /// buffer2.add(13);\n /// buffer1.insertBuffer(1, buffer2);\n /// Buffer.toArray(buffer1) // => [10, 12, 13, 11]\n /// ```\n /// \n /// | Runtime (worst) | Runtime (amortized) | Space (worst) | Space (amortized) |\n /// |------------------|----------------------|----------------|---------------------|\n /// | `O(size)` | - | `O(size1 +size2)` | `O(1)` |\n public func insertBuffer(index : Nat, buffer2 : Buffer<X>) {\n if (index > _size) {\n Prim.trap \"Buffer index out of bounds in insertBuffer\"\n };\n\n let size2 = buffer2.size();\n let capacity = elements.size();\n\n // copy elements to new array and shift over in one pass\n if (_size + size2 > capacity) {\n let elements2 = Prim.Array_init<?X>(newCapacity(_size + size2), null);\n var i = 0;\n for (element in elements.vals()) {\n if (i == index) {\n i += size2\n };\n elements2[i] := element;\n i += 1\n };\n\n i := 0;\n while (i < size2) {\n elements2[i + index] := buffer2.getOpt(i);\n i += 1\n };\n elements := elements2\n } // just insert\n else {\n var i = index;\n while (i < index + size2) {\n if (i < _size) {\n elements[i + size2] := elements[i]\n };\n elements[i] := buffer2.getOpt(i - index);\n\n i += 1\n }\n };\n\n _size += size2\n };\n\n /// Sorts the elements in the buffer according to `compare`.\n /// Sort is deterministic, stable, and in-place.\n /// \n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n /// \n /// buffer.add(11);\n /// buffer.add(12);\n /// buffer.add(10);\n /// buffer.sort(Nat.compare);\n /// Buffer.toArray(buffer) // => [10, 11, 12]\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size * log(size))` | `O(size)` |\n public func sort(compare : (X, X) -> Order.Order) {\n // Stable merge sort in a bottom-up iterative style\n if (_size == 0) {\n return\n };\n let scratchSpace = Prim.Array_init<?X>(_size, null);\n\n let sizeDec = _size - 1 : Nat;\n var currSize = 1; // current size of the subarrays being merged\n // when the current size == size, the array has been merged into a single sorted array\n while (currSize < _size) {\n var leftStart = 0; // selects the current left subarray being merged\n while (leftStart < sizeDec) {\n let mid : Nat = if (leftStart + currSize - 1 : Nat < sizeDec) {\n leftStart + currSize - 1\n } else { sizeDec };\n let rightEnd : Nat = if (leftStart + (2 * currSize) - 1 : Nat < sizeDec) {\n leftStart + (2 * currSize) - 1\n } else { sizeDec };\n\n // Merge subarrays elements[leftStart...mid] and elements[mid+1...rightEnd]\n var left = leftStart;\n var right = mid + 1;\n var nextSorted = leftStart;\n while (left < mid + 1 and right < rightEnd + 1) {\n let leftOpt = elements[left];\n let rightOpt = elements[right];\n switch (leftOpt, rightOpt) {\n case (?leftElement, ?rightElement) {\n switch (compare(leftElement, rightElement)) {\n case (#less or #equal) {\n scratchSpace[nextSorted] := leftOpt;\n left += 1\n };\n case (#greater) {\n scratchSpace[nextSorted] := rightOpt;\n right += 1\n }\n }\n };\n case (_, _) {\n // only sorting non-null items\n Prim.trap \"Malformed buffer in sort\"\n }\n };\n nextSorted += 1\n };\n while (left < mid + 1) {\n scratchSpace[nextSorted] := elements[left];\n nextSorted += 1;\n left += 1\n };\n while (right < rightEnd + 1) {\n scratchSpace[nextSorted] := elements[right];\n nextSorted += 1;\n right += 1\n };\n\n // Copy over merged elements\n var i = leftStart;\n while (i < rightEnd + 1) {\n elements[i] := scratchSpace[i];\n i += 1\n };\n\n leftStart += 2 * currSize\n };\n currSize *= 2\n }\n };\n\n /// Returns an Iterator (`Iter`) over the elements of this buffer.\n /// Iterator provides a single method `next()`, which returns\n /// elements in order, or `null` when out of elements to iterate over.\n /// \n /// ```motoko include=initialize\n /// buffer.add(10);\n /// buffer.add(11);\n /// buffer.add(12);\n /// \n /// var sum = 0;\n /// for (element in buffer.vals()) {\n /// sum += element;\n /// };\n /// sum // => 33\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(1)` | `O(1)` |\n public func vals() : { next : () -> ?X } = object {\n // FIXME either handle modification to underlying list\n // or explicitly warn users in documentation\n var nextIndex = 0;\n public func next() : ?X {\n if (nextIndex >= _size) {\n return null\n };\n let nextElement = elements[nextIndex];\n nextIndex += 1;\n nextElement\n }\n };\n\n // FOLLOWING METHODS ARE DEPRECATED\n\n /// :::warning Deprecated function\n /// \n /// Use the static library function instead of this instance method.\n /// :::\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 /// :::warning Deprecated function\n /// \n /// Use the static library function instead of this instance method.\n /// :::\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 /// :::warning Deprecated function\n /// \n /// Use the static library function instead of this instance method.\n /// :::\n public func toVarArray() : [var X] {\n if (_size == 0) { [var] } else {\n let newArray = Prim.Array_init<X>(_size, get 0);\n var i = 0;\n for (element in vals()) {\n newArray[i] := element;\n i += 1\n };\n newArray\n }\n }\n };\n\n /// Returns true if and only if the buffer is empty.\n /// \n /// Example:\n /// \n /// ```motoko include=initialize\n /// buffer.add(2);\n /// buffer.add(0);\n /// buffer.add(3);\n /// Buffer.isEmpty(buffer); // => false\n /// ```\n /// \n /// ```motoko include=initialize\n /// Buffer.isEmpty(buffer); // => true\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(1)` | `O(1)` |\n public func isEmpty<X>(buffer : Buffer<X>) : Bool = buffer.size() == 0;\n\n /// Returns true if `buffer` contains `element` with respect to equality\n /// defined by `equal`.\n /// \n /// Example:\n /// \n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n /// \n /// buffer.add(2);\n /// buffer.add(0);\n /// buffer.add(3);\n /// Buffer.contains<Nat>(buffer, 2, Nat.equal); // => true\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size)` | `O(1)` |\n public func contains<X>(buffer : Buffer<X>, element : X, equal : (X, X) -> Bool) : Bool {\n for (current in buffer.vals()) {\n if (equal(current, element)) {\n return true\n }\n };\n\n false\n };\n\n /// Returns a copy of `buffer`, with the same capacity.\n /// \n /// Example:\n /// \n /// ```motoko include=initialize\n /// buffer.add(1);\n /// \n /// let clone = Buffer.clone(buffer);\n /// Buffer.toArray(clone); // => [1]\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size)` | `O(size)` |\n public func clone<X>(buffer : Buffer<X>) : Buffer<X> {\n let newBuffer = Buffer<X>(buffer.capacity());\n for (element in buffer.vals()) {\n newBuffer.add(element)\n };\n newBuffer\n };\n\n /// Finds the greatest element in `buffer` defined by `compare`.\n /// Returns `null` if `buffer` is empty.\n /// \n /// Example:\n /// \n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n /// \n /// buffer.add(1);\n /// buffer.add(2);\n /// \n /// Buffer.max(buffer, Nat.compare); // => ?2\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size)` | `O(1)` |\n public func max<X>(buffer : Buffer<X>, compare : (X, X) -> Order) : ?X {\n if (buffer.size() == 0) {\n return null\n };\n\n var maxSoFar = buffer.get(0);\n for (current in buffer.vals()) {\n switch (compare(current, maxSoFar)) {\n case (#greater) {\n maxSoFar := current\n };\n case _ {}\n }\n };\n\n ?maxSoFar\n };\n\n /// Finds the least element in `buffer` defined by `compare`.\n /// Returns `null` if `buffer` is empty.\n /// \n /// Example:\n /// \n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n /// \n /// buffer.add(1);\n /// buffer.add(2);\n /// \n /// Buffer.min(buffer, Nat.compare); // => ?1\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size)` | `O(1)` |\n public func min<X>(buffer : Buffer<X>, compare : (X, X) -> Order) : ?X {\n if (buffer.size() == 0) {\n return null\n };\n\n var minSoFar = buffer.get(0);\n for (current in buffer.vals()) {\n switch (compare(current, minSoFar)) {\n case (#less) {\n minSoFar := current\n };\n case _ {}\n }\n };\n\n ?minSoFar\n };\n\n /// Defines equality for two buffers, using `equal` to recursively compare elements in the\n /// buffers. Returns true if the two buffers are of the same size, and `equal`\n /// evaluates to true for every pair of elements in the two buffers of the same\n /// index.\n /// \n /// Example:\n /// \n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n /// \n /// let buffer1 = Buffer.Buffer<Nat>(2);\n /// buffer1.add(1);\n /// buffer1.add(2);\n /// \n /// let buffer2 = Buffer.Buffer<Nat>(5);\n /// buffer2.add(1);\n /// buffer2.add(2);\n /// \n /// Buffer.equal(buffer1, buffer2, Nat.equal); // => true\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size)` | `O(1)` |\n public func equal<X>(buffer1 : Buffer<X>, buffer2 : Buffer<X>, equal : (X, X) -> Bool) : Bool {\n let size1 = buffer1.size();\n\n if (size1 != buffer2.size()) {\n return false\n };\n\n var i = 0;\n while (i < size1) {\n if (not equal(buffer1.get(i), buffer2.get(i))) {\n return false\n };\n i += 1\n };\n\n true\n };\n\n /// Defines comparison for two buffers, using `compare` to recursively compare elements in the\n /// buffers. Comparison is defined lexicographically.\n /// \n /// Example:\n /// \n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n /// \n /// let buffer1 = Buffer.Buffer<Nat>(2);\n /// buffer1.add(1);\n /// buffer1.add(2);\n /// \n /// let buffer2 = Buffer.Buffer<Nat>(3);\n /// buffer2.add(3);\n /// buffer2.add(4);\n /// \n /// Buffer.compare<Nat>(buffer1, buffer2, Nat.compare); // => #less\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size)` | `O(1)` |\n public func compare<X>(buffer1 : Buffer<X>, buffer2 : Buffer<X>, compare : (X, X) -> Order.Order) : Order.Order {\n let size1 = buffer1.size();\n let size2 = buffer2.size();\n let minSize = if (size1 < size2) { size1 } else { size2 };\n\n var i = 0;\n while (i < minSize) {\n switch (compare(buffer1.get(i), buffer2.get(i))) {\n case (#less) {\n return #less\n };\n case (#greater) {\n return #greater\n };\n case _ {}\n };\n i += 1\n };\n\n if (size1 < size2) {\n #less\n } else if (size1 == size2) {\n #equal\n } else {\n #greater\n }\n };\n\n /// Creates a textual representation of `buffer`, using `toText` to recursively\n /// convert the elements into Text.\n /// \n /// Example:\n /// \n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n /// \n /// buffer.add(1);\n /// buffer.add(2);\n /// buffer.add(3);\n /// buffer.add(4);\n /// \n /// Buffer.toText(buffer, Nat.toText); // => \"[1, 2, 3, 4]\"\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size)` | `O(size)` |\n\n public func toText<X>(buffer : Buffer<X>, toText : X -> Text) : Text {\n let size : Int = buffer.size();\n var i = 0;\n var text = \"\";\n while (i < size - 1) {\n text := text # toText(buffer.get(i)) # \", \"; // Text implemented as rope\n i += 1\n };\n if (size > 0) {\n // avoid the trailing comma\n text := text # toText(buffer.get(i))\n };\n\n \"[\" # text # \"]\"\n };\n\n /// Hashes `buffer` using `hash` to hash the underlying elements.\n /// The deterministic hash function is a function of the elements in the `buffer`, as well\n /// as their ordering.\n /// \n /// Example:\n /// \n /// ```motoko include=initialize\n /// import Hash \"mo:base/Hash\";\n /// \n /// buffer.add(1);\n /// buffer.add(2);\n /// buffer.add(3);\n /// buffer.add(1000);\n /// \n /// Buffer.hash<Nat>(buffer, Hash.hash); // => 2_872_640_342\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size)` | `O(1)` |\n public func hash<X>(buffer : Buffer<X>, hash : X -> Nat32) : Nat32 {\n let size = buffer.size();\n var i = 0;\n var accHash : Nat32 = 0;\n\n while (i < size) {\n accHash := Prim.intToNat32Wrap(i) ^ accHash ^ hash(buffer.get(i));\n i += 1\n };\n\n accHash\n };\n\n /// Finds the first index of `element` in `buffer` using equality of elements defined\n /// by `equal`. Returns `null` if `element` is not found.\n /// \n /// Example:\n /// \n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n /// \n /// buffer.add(1);\n /// buffer.add(2);\n /// buffer.add(3);\n /// buffer.add(4);\n /// \n /// Buffer.indexOf<Nat>(3, buffer, Nat.equal); // => ?2\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size)` | `O(size)` |\n public func indexOf<X>(element : X, buffer : Buffer<X>, equal : (X, X) -> Bool) : ?Nat {\n let size = buffer.size();\n var i = 0;\n while (i < size) {\n if (equal(buffer.get(i), element)) {\n return ?i\n };\n i += 1\n };\n\n null\n };\n\n /// Finds the last index of `element` in `buffer` using equality of elements defined\n /// by `equal`. Returns `null` if `element` is not found.\n /// \n /// Example:\n /// \n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n /// \n /// buffer.add(1);\n /// buffer.add(2);\n /// buffer.add(3);\n /// buffer.add(4);\n /// buffer.add(2);\n /// buffer.add(2);\n /// \n /// Buffer.lastIndexOf<Nat>(2, buffer, Nat.equal); // => ?5\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size)` | `O(size)` |\n public func lastIndexOf<X>(element : X, buffer : Buffer<X>, equal : (X, X) -> Bool) : ?Nat {\n let size = buffer.size();\n if (size == 0) {\n return null\n };\n var i = size;\n while (i >= 1) {\n i -= 1;\n if (equal(buffer.get(i), element)) {\n return ?i\n }\n };\n\n null\n };\n\n /// Searches for `subBuffer` in `buffer`, and returns the starting index if it is found.\n /// \n /// Example:\n /// \n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n /// \n /// buffer.add(1);\n /// buffer.add(2);\n /// buffer.add(3);\n /// buffer.add(4);\n /// buffer.add(5);\n /// buffer.add(6);\n /// \n /// let sub = Buffer.Buffer<Nat>(2);\n /// sub.add(4);\n /// sub.add(5);\n /// sub.add(6);\n /// \n /// Buffer.indexOfBuffer<Nat>(sub, buffer, Nat.equal); // => ?3\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size of buffer + size of subBuffer)` | `O(size of subBuffer)` |\n public func indexOfBuffer<X>(subBuffer : Buffer<X>, buffer : Buffer<X>, equal : (X, X) -> Bool) : ?Nat {\n // Uses the KMP substring search algorithm\n // Implementation from: https://www.educative.io/answers/what-is-the-knuth-morris-pratt-algorithm\n let size = buffer.size();\n let subSize = subBuffer.size();\n if (subSize > size or subSize == 0) {\n return null\n };\n\n // precompute lps\n let lps = Prim.Array_init<Nat>(subSize, 0);\n var i = 0;\n var j = 1;\n\n while (j < subSize) {\n if (equal(subBuffer.get(i), subBuffer.get(j))) {\n i += 1;\n lps[j] := i;\n j += 1\n } else if (i == 0) {\n lps[j] := 0;\n j += 1\n } else {\n i := lps[i - 1]\n }\n };\n\n // start search\n i := 0;\n j := 0;\n let subSizeDec = subSize - 1 : Nat; // hoisting loop invariant\n while (i < subSize and j < size) {\n if (equal(subBuffer.get(i), buffer.get(j)) and i == subSizeDec) {\n return ?(j - i)\n } else if (equal(subBuffer.get(i), buffer.get(j))) {\n i += 1;\n j += 1\n } else {\n if (i != 0) {\n i := lps[i - 1]\n } else {\n j += 1\n }\n }\n };\n\n null\n };\n\n /// Similar to `indexOf`, but runs in logarithmic time. Assumes that `buffer` is sorted.\n /// Behavior is undefined if `buffer` is not sorted. Uses `compare` to\n /// perform the search. Returns an index of `element` if it is found.\n /// \n /// Example:\n /// \n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n /// \n /// buffer.add(1);\n /// buffer.add(4);\n /// buffer.add(5);\n /// buffer.add(6);\n /// \n /// Buffer.binarySearch<Nat>(5, buffer, Nat.compare); // => ?2\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(log(size))` | `O(1)` |\n public func binarySearch<X>(element : X, buffer : Buffer<X>, compare : (X, X) -> Order.Order) : ?Nat {\n var low = 0;\n var high = buffer.size();\n\n while (low < high) {\n let mid = (low + high) / 2;\n let current = buffer.get(mid);\n switch (compare(element, current)) {\n case (#equal) {\n return ?mid\n };\n case (#less) {\n high := mid\n };\n case (#greater) {\n low := mid + 1\n }\n }\n };\n\n null\n };\n\n /// Returns the sub-buffer of `buffer` starting at index `start`\n /// of length `length`. Traps if `start` is out of bounds, or `start + length`\n /// is greater than the size of `buffer`.\n /// \n /// Example:\n /// \n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n /// \n /// buffer.add(1);\n /// buffer.add(2);\n /// buffer.add(3);\n /// buffer.add(4);\n /// buffer.add(5);\n /// buffer.add(6);\n /// \n /// let sub = Buffer.subBuffer(buffer, 3, 2);\n /// Buffer.toText(sub, Nat.toText); // => [4, 5]\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(length)` | `O(length)` |\n public func subBuffer<X>(buffer : Buffer<X>, start : Nat, length : Nat) : Buffer<X> {\n let size = buffer.size();\n let end = start + length; // exclusive\n if (start >= size or end > size) {\n Prim.trap \"Buffer index out of bounds in subBuffer\"\n };\n\n let newBuffer = Buffer<X>(newCapacity length);\n\n var i = start;\n while (i < end) {\n newBuffer.add(buffer.get(i));\n\n i += 1\n };\n\n newBuffer\n };\n\n /// Checks if `subBuffer` is a sub-Buffer of `buffer`. Uses `equal` to\n /// compare elements.\n /// \n /// Example:\n /// \n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n /// \n /// buffer.add(1);\n /// buffer.add(2);\n /// buffer.add(3);\n /// buffer.add(4);\n /// buffer.add(5);\n /// buffer.add(6);\n /// \n /// let sub = Buffer.Buffer<Nat>(2);\n /// sub.add(2);\n /// sub.add(3);\n /// Buffer.isSubBufferOf(sub, buffer, Nat.equal); // => true\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size of subBuffer + size of buffer)` | `O(size of subBuffer)` |\n public func isSubBufferOf<X>(subBuffer : Buffer<X>, buffer : Buffer<X>, equal : (X, X) -> Bool) : Bool {\n switch (indexOfBuffer(subBuffer, buffer, equal)) {\n case null subBuffer.size() == 0;\n case _ true\n }\n };\n\n /// Checks if `subBuffer` is a strict subBuffer of `buffer`, i.e. `subBuffer` must be\n /// strictly contained inside both the first and last indices of `buffer`.\n /// Uses `equal` to compare elements.\n /// \n /// Example:\n /// \n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n /// \n /// buffer.add(1);\n /// buffer.add(2);\n /// buffer.add(3);\n /// buffer.add(4);\n /// \n /// let sub = Buffer.Buffer<Nat>(2);\n /// sub.add(2);\n /// sub.add(3);\n /// Buffer.isStrictSubBufferOf(sub, buffer, Nat.equal); // => true\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size of subBuffer + size of buffer)` | `O(size of subBuffer)` |\n public func isStrictSubBufferOf<X>(subBuffer : Buffer<X>, buffer : Buffer<X>, equal : (X, X) -> Bool) : Bool {\n let subBufferSize = subBuffer.size();\n\n switch (indexOfBuffer(subBuffer, buffer, equal)) {\n case (?index) {\n index != 0 and index != (buffer.size() - subBufferSize : Nat) // enforce strictness\n };\n case null {\n subBufferSize == 0 and subBufferSize != buffer.size()\n }\n }\n };\n\n /// Returns the prefix of `buffer` of length `length`. Traps if `length`\n /// is greater than the size of `buffer`.\n /// \n /// Example:\n /// \n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n /// \n /// buffer.add(1);\n /// buffer.add(2);\n /// buffer.add(3);\n /// buffer.add(4);\n /// \n /// let pre = Buffer.prefix(buffer, 3); // => [1, 2, 3]\n /// Buffer.toText(pre, Nat.toText);\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(length)` | `O(length)` |\n /// \n public func prefix<X>(buffer : Buffer<X>, length : Nat) : Buffer<X> {\n let size = buffer.size();\n if (length > size) {\n Prim.trap \"Buffer index out of bounds in prefix\"\n };\n\n let newBuffer = Buffer<X>(newCapacity length);\n\n var i = 0;\n while (i < length) {\n newBuffer.add(buffer.get(i));\n i += 1\n };\n\n newBuffer\n };\n\n /// Checks if `prefix` is a prefix of `buffer`. Uses `equal` to\n /// compare elements.\n /// \n /// Example:\n /// \n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n /// \n /// buffer.add(1);\n /// buffer.add(2);\n /// buffer.add(3);\n /// buffer.add(4);\n /// \n /// let pre = Buffer.Buffer<Nat>(2);\n /// pre.add(1);\n /// pre.add(2);\n /// Buffer.isPrefixOf(pre, buffer, Nat.equal); // => true\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size of prefix)` | `O(size of prefix)` |\n public func isPrefixOf<X>(prefix : Buffer<X>, buffer : Buffer<X>, equal : (X, X) -> Bool) : Bool {\n let sizePrefix = prefix.size();\n if (buffer.size() < sizePrefix) {\n return false\n };\n\n var i = 0;\n while (i < sizePrefix) {\n if (not equal(buffer.get(i), prefix.get(i))) {\n return false\n };\n\n i += 1\n };\n\n return true\n };\n\n /// Checks if `prefix` is a strict prefix of `buffer`. Uses `equal` to\n /// compare elements.\n /// \n /// Example:\n /// \n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n /// \n /// buffer.add(1);\n /// buffer.add(2);\n /// buffer.add(3);\n /// buffer.add(4);\n /// \n /// let pre = Buffer.Buffer<Nat>(3);\n /// pre.add(1);\n /// pre.add(2);\n /// pre.add(3);\n /// Buffer.isStrictPrefixOf(pre, buffer, Nat.equal); // => true\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size of prefix)` | `O(size of prefix)` |\n public func isStrictPrefixOf<X>(prefix : Buffer<X>, buffer : Buffer<X>, equal : (X, X) -> Bool) : Bool {\n if (buffer.size() <= prefix.size()) {\n return false\n };\n isPrefixOf(prefix, buffer, equal)\n };\n\n /// Returns the suffix of `buffer` of length `length`.\n /// Traps if `length`is greater than the size of `buffer`.\n /// \n /// Example:\n /// \n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n /// \n /// buffer.add(1);\n /// buffer.add(2);\n /// buffer.add(3);\n /// buffer.add(4);\n /// \n /// let suf = Buffer.suffix(buffer, 3); // => [2, 3, 4]\n /// Buffer.toText(suf, Nat.toText);\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(length)` | `O(length)` |\n public func suffix<X>(buffer : Buffer<X>, length : Nat) : Buffer<X> {\n let size = buffer.size();\n\n if (length > size) {\n Prim.trap \"Buffer index out of bounds in suffix\"\n };\n\n let newBuffer = Buffer<X>(newCapacity length);\n\n var i = size - length : Nat;\n while (i < size) {\n newBuffer.add(buffer.get(i));\n\n i += 1\n };\n\n newBuffer\n };\n\n /// Checks if `suffix` is a suffix of `buffer`. Uses `equal` to compare\n /// elements.\n /// \n /// Example:\n /// \n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n /// \n /// buffer.add(1);\n /// buffer.add(2);\n /// buffer.add(3);\n /// buffer.add(4);\n /// \n /// let suf = Buffer.Buffer<Nat>(3);\n /// suf.add(2);\n /// suf.add(3);\n /// suf.add(4);\n /// Buffer.isSuffixOf(suf, buffer, Nat.equal); // => true\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(length of suffix)` | `O(length of suffix)` |\n public func isSuffixOf<X>(suffix : Buffer<X>, buffer : Buffer<X>, equal : (X, X) -> Bool) : Bool {\n let suffixSize = suffix.size();\n let bufferSize = buffer.size();\n if (bufferSize < suffixSize) {\n return false\n };\n\n var i = bufferSize;\n var j = suffixSize;\n while (i >= 1 and j >= 1) {\n i -= 1;\n j -= 1;\n if (not equal(buffer.get(i), suffix.get(j))) {\n return false\n }\n };\n\n return true\n };\n\n /// Checks if `suffix` is a strict suffix of `buffer`. Uses `equal` to compare\n /// elements.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n /// \n /// buffer.add(1);\n /// buffer.add(2);\n /// buffer.add(3);\n /// buffer.add(4);\n /// \n /// let suf = Buffer.Buffer<Nat>(3);\n /// suf.add(2);\n /// suf.add(3);\n /// suf.add(4);\n /// Buffer.isStrictSuffixOf(suf, buffer, Nat.equal); // => true\n /// ```\n /// \n/// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(length)` | `O(length)` |\n public func isStrictSuffixOf<X>(suffix : Buffer<X>, buffer : Buffer<X>, equal : (X, X) -> Bool) : Bool {\n if (buffer.size() <= suffix.size()) {\n return false\n };\n isSuffixOf(suffix, buffer, equal)\n };\n\n /// Returns true if every element in `buffer` satisfies `predicate`.\n /// \n /// Example:\n /// \n /// ```motoko include=initialize\n /// buffer.add(2);\n /// buffer.add(3);\n /// buffer.add(4);\n /// \n /// Buffer.forAll<Nat>(buffer, func x { x > 1 }); // => true\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size)` | `O(1)` |\n public func forAll<X>(buffer : Buffer<X>, predicate : X -> Bool) : Bool {\n for (element in buffer.vals()) {\n if (not predicate element) {\n return false\n }\n };\n\n true\n };\n\n /// Returns true if some element in `buffer` satisfies `predicate`.\n /// \n /// Example:\n /// \n /// ```motoko include=initialize\n /// buffer.add(2);\n /// buffer.add(3);\n /// buffer.add(4);\n /// \n /// Buffer.forSome<Nat>(buffer, func x { x > 3 }); // => true\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size)` | `O(1)` |\n public func forSome<X>(buffer : Buffer<X>, predicate : X -> Bool) : Bool {\n for (element in buffer.vals()) {\n if (predicate element) {\n return true\n }\n };\n\n false\n };\n\n /// Returns true if no element in `buffer` satisfies `predicate`.\n /// \n /// Example:\n /// \n /// ```motoko include=initialize\n /// buffer.add(2);\n /// buffer.add(3);\n /// buffer.add(4);\n /// \n /// Buffer.forNone<Nat>(buffer, func x { x == 0 }); // => true\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size)` | `O(1)` |\n public func forNone<X>(buffer : Buffer<X>, predicate : X -> Bool) : Bool {\n for (element in buffer.vals()) {\n if (predicate element) {\n return false\n }\n };\n\n true\n };\n\n /// Creates an `array` containing elements from `buffer`.\n /// \n /// Example:\n /// \n /// ```motoko include=initialize\n /// buffer.add(1);\n /// buffer.add(2);\n /// buffer.add(3);\n /// \n /// Buffer.toArray<Nat>(buffer); // => [1, 2, 3]\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size)` | `O(size)` |\n public func toArray<X>(buffer : Buffer<X>) : [X] =\n // immutable clone of array\n Prim.Array_tabulate<X>(\n buffer.size(),\n func(i : Nat) : X { buffer.get(i) }\n );\n ///``` motoko include=initialize\n /// func toVarArray<X>(buffer : Buffer<X>) : [var X]\n /// ```\n /// \n /// Creates a mutable array containing elements from `buffer`.\n /// \n /// Example:\n /// \n /// ```motoko include=initialize\n /// buffer.add(1);\n /// buffer.add(2);\n /// buffer.add(3);\n /// \n /// Buffer.toVarArray<Nat>(buffer); // => [1, 2, 3]\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size)` | `O(size)` |\n public func toVarArray<X>(buffer : Buffer<X>) : [var X] {\n let size = buffer.size();\n if (size == 0) { [var] } else {\n let newArray = Prim.Array_init<X>(size, buffer.get(0));\n var i = 1;\n while (i < size) {\n newArray[i] := buffer.get(i);\n i += 1\n };\n newArray\n }\n };\n\n /// Creates a `buffer` containing elements from `array`.\n /// \n /// Example:\n /// \n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n /// \n /// let array = [2, 3];\n /// \n /// let buf = Buffer.fromArray<Nat>(array); // => [2, 3]\n /// Buffer.toText(buf, Nat.toText);\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size)` | `O(size)` |\n public func fromArray<X>(array : [X]) : Buffer<X> {\n // When returning new buffer, if possible, set the capacity\n // to the capacity of the old buffer. Otherwise, return them\n // at 2/3 capacity (like in this case). Alternative is to\n // calculate what the size would be if the elements were\n // sequentially added using `add`. This current strategy (2/3)\n // is the upper bound of that calculation (if the last element\n // added caused a capacity increase).\n let newBuffer = Buffer<X>(newCapacity(array.size()));\n\n for (element in array.vals()) {\n newBuffer.add(element)\n };\n\n newBuffer\n };\n\n /// Creates a `buffer` containing elements from `array`.\n /// \n /// Example:\n /// \n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n /// \n /// let array = [var 1, 2, 3];\n /// \n /// let buf = Buffer.fromVarArray<Nat>(array); // => [1, 2, 3]\n /// Buffer.toText(buf, Nat.toText);\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size)` | `O(size)` |\n public func fromVarArray<X>(array : [var X]) : Buffer<X> {\n let newBuffer = Buffer<X>(newCapacity(array.size()));\n\n for (element in array.vals()) {\n newBuffer.add(element)\n };\n\n newBuffer\n };\n\n /// Creates a `buffer` containing elements from `iter`.\n /// \n /// Example:\n /// \n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n /// \n /// let array = [1, 1, 1];\n /// let iter = array.vals();\n /// \n /// let buf = Buffer.fromIter<Nat>(iter); // => [1, 1, 1]\n /// Buffer.toText(buf, Nat.toText);\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size)` | `O(size)` |\n public func fromIter<X>(iter : { next : () -> ?X }) : Buffer<X> {\n let newBuffer = Buffer<X>(DEFAULT_CAPACITY); // can't get size from `iter`\n\n for (element in iter) {\n newBuffer.add(element)\n };\n\n newBuffer\n };\n\n /// Reallocates the array underlying `buffer` such that capacity == size.\n /// \n /// Example:\n /// \n /// ```motoko include=initialize\n /// let buffer = Buffer.Buffer<Nat>(10);\n /// buffer.add(1);\n /// buffer.add(2);\n /// buffer.add(3);\n /// \n /// Buffer.trimToSize<Nat>(buffer);\n /// buffer.capacity(); // => 3\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size)` | `O(size)` |\n public func trimToSize<X>(buffer : Buffer<X>) {\n let size = buffer.size();\n if (size < buffer.capacity()) {\n buffer.reserve(size)\n }\n };\n\n /// Creates a new `buffer` by applying `f` to each element in `buffer`.\n /// \n /// Example:\n /// \n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n /// \n /// buffer.add(1);\n /// buffer.add(2);\n /// buffer.add(3);\n /// \n /// let newBuf = Buffer.map<Nat, Nat>(buffer, func (x) { x + 1 });\n /// Buffer.toText(newBuf, Nat.toText); // => [2, 3, 4]\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size)` | `O(size)` |\n public func map<X, Y>(buffer : Buffer<X>, f : X -> Y) : Buffer<Y> {\n let newBuffer = Buffer<Y>(buffer.capacity());\n\n for (element in buffer.vals()) {\n newBuffer.add(f element)\n };\n\n newBuffer\n };\n\n /// Applies `f` to each element in `buffer`.\n /// \n /// Example:\n /// \n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n /// import Debug \"mo:base/Debug\";\n /// \n /// buffer.add(1);\n /// buffer.add(2);\n /// buffer.add(3);\n /// \n /// Buffer.iterate<Nat>(buffer, func (x) {\n /// Debug.print(Nat.toText(x)); // prints each element in buffer\n /// });\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size)` | `O(size)` |\n /// \n public func iterate<X>(buffer : Buffer<X>, f : X -> ()) {\n for (element in buffer.vals()) {\n f element\n }\n };\n\n /// Applies `f` to each element in `buffer` and its index.\n /// \n /// Example:\n /// \n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n /// buffer.add(1);\n /// buffer.add(2);\n /// buffer.add(3);\n /// \n /// let newBuf = Buffer.mapEntries<Nat, Nat>(buffer, func (x, i) { x + i + 1 });\n /// Buffer.toText(newBuf, Nat.toText); // => [2, 4, 6]\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size)` | `O(size)` |\n public func mapEntries<X, Y>(buffer : Buffer<X>, f : (Nat, X) -> Y) : Buffer<Y> {\n let newBuffer = Buffer<Y>(buffer.capacity());\n\n var i = 0;\n let size = buffer.size();\n while (i < size) {\n newBuffer.add(f(i, buffer.get(i)));\n i += 1\n };\n\n newBuffer\n };\n\n /// Creates a new buffer by applying `f` to each element in `buffer`,\n /// and keeping all non-null elements.\n /// \n /// Example:\n /// \n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n /// buffer.add(1);\n /// buffer.add(2);\n /// buffer.add(3);\n /// \n /// let newBuf = Buffer.mapFilter<Nat, Nat>(buffer, func (x) {\n /// if (x > 1) {\n /// ?(x * 2);\n /// } else {\n /// null;\n /// }\n /// });\n /// Buffer.toText(newBuf, Nat.toText); // => [4, 6]\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size)` | `O(size)` |\n public func mapFilter<X, Y>(buffer : Buffer<X>, f : X -> ?Y) : Buffer<Y> {\n let newBuffer = Buffer<Y>(buffer.capacity());\n\n for (element in buffer.vals()) {\n switch (f element) {\n case (?element) {\n newBuffer.add(element)\n };\n case _ {}\n }\n };\n\n newBuffer\n };\n\n /// Creates a new buffer by applying `f` to each element in `buffer`.\n /// If any invocation of `f` produces an `#err`, returns an `#err`. Otherwise\n /// Returns an `#ok` containing the new buffer.\n /// \n /// Example:\n /// \n /// ```motoko include=initialize\n /// import Result \"mo:base/Result\";\n /// buffer.add(1);\n /// buffer.add(2);\n /// buffer.add(3);\n /// \n /// let result = Buffer.mapResult<Nat, Nat, Text>(buffer, func (k) {\n /// if (k > 0) {\n /// #ok(k);\n /// } else {\n /// #err(\"One or more elements are zero.\");\n /// }\n /// });\n /// \n /// Result.mapOk<Buffer.Buffer<Nat>, [Nat], Text>(result, func buffer = Buffer.toArray(buffer)) // => #ok([1, 2, 3])\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size)` | `O(size)` |\n public func mapResult<X, Y, E>(buffer : Buffer<X>, f : X -> Result.Result<Y, E>) : Result.Result<Buffer<Y>, E> {\n let newBuffer = Buffer<Y>(buffer.capacity());\n\n for (element in buffer.vals()) {\n switch (f element) {\n case (#ok result) {\n newBuffer.add(result)\n };\n case (#err e) {\n return #err e\n }\n }\n };\n\n #ok newBuffer\n };\n\n /// Creates a new `buffer` by applying `k` to each element in `buffer`,\n /// and concatenating the resulting buffers in order. This operation\n /// is similar to what in other functional languages is known as monadic bind.\n /// \n /// Example:\n /// \n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n /// buffer.add(1);\n /// buffer.add(2);\n /// buffer.add(3);\n /// \n /// let chain = Buffer.chain<Nat, Nat>(buffer, func (x) {\n /// let b = Buffer.Buffer<Nat>(2);\n /// b.add(x);\n /// b.add(x * 2);\n /// return b;\n /// });\n /// Buffer.toText(chain, Nat.toText); // => [1, 2, 2, 4, 3, 6]\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size)` | `O(size)` |\n public func chain<X, Y>(buffer : Buffer<X>, k : X -> Buffer<Y>) : Buffer<Y> {\n let newBuffer = Buffer<Y>(buffer.size() * 4);\n\n for (element in buffer.vals()) {\n newBuffer.append(k element)\n };\n\n newBuffer\n };\n\n /// Collapses the elements in `buffer` into a single value by starting with `base`\n /// and progessively combining elements into `base` with `combine`. Iteration runs\n /// left to right.\n /// \n /// Example:\n /// \n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n /// buffer.add(1);\n /// buffer.add(2);\n /// buffer.add(3);\n /// \n /// Buffer.foldLeft<Text, Nat>(buffer, \"\", func (acc, x) { acc # Nat.toText(x)}); // => \"123\"\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size)` | `O(1)` |\n public func foldLeft<A, X>(buffer : Buffer<X>, base : A, combine : (A, X) -> A) : A {\n var accumulation = base;\n\n for (element in buffer.vals()) {\n accumulation := combine(accumulation, element)\n };\n\n accumulation\n };\n\n /// Collapses the elements in `buffer` into a single value by starting with `base`\n /// and progessively combining elements into `base` with `combine`. Iteration runs\n /// right to left.\n /// \n /// Example:\n /// \n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n /// buffer.add(1);\n /// buffer.add(2);\n /// buffer.add(3);\n /// \n /// Buffer.foldRight<Nat, Text>(buffer, \"\", func (x, acc) { Nat.toText(x) # acc }); // => \"123\"\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size)` | `O(1)` |\n public func foldRight<X, A>(buffer : Buffer<X>, base : A, combine : (X, A) -> A) : A {\n let size = buffer.size();\n if (size == 0) {\n return base\n };\n var accumulation = base;\n\n var i = size;\n while (i >= 1) {\n i -= 1; // to avoid Nat underflow, subtract first and stop iteration at 1\n accumulation := combine(buffer.get(i), accumulation)\n };\n\n accumulation\n };\n\n /// Returns the first element of `buffer`. Traps if `buffer` is empty.\n /// \n /// Example:\n /// \n /// ```motoko include=initialize\n /// buffer.add(1);\n /// buffer.add(2);\n /// buffer.add(3);\n /// \n /// Buffer.first(buffer); // => 1\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(1)` | `O(1)` |\n public func first<X>(buffer : Buffer<X>) : X = buffer.get(0);\n\n /// Returns the last element of `buffer`. Traps if `buffer` is empty.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// buffer.add(1);\n /// buffer.add(2);\n /// buffer.add(3);\n /// \n /// Buffer.last(buffer); // => 3\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(1)` | `O(1)` |\n public func last<X>(buffer : Buffer<X>) : X = buffer.get(buffer.size() - 1);\n\n /// Returns a new `buffer` with capacity and size 1, containing `element`.\n /// \n /// Example:\n /// \n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n /// \n /// let buffer = Buffer.make<Nat>(1);\n /// Buffer.toText(buffer, Nat.toText); // => [1]\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(1)` | `O(1)` |\n public func make<X>(element : X) : Buffer<X> {\n let newBuffer = Buffer<X>(1);\n newBuffer.add(element);\n newBuffer\n };\n\n /// Reverses the order of elements in `buffer`.\n /// \n /// Example:\n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n /// \n /// buffer.add(1);\n /// buffer.add(2);\n /// buffer.add(3);\n /// \n /// Buffer.reverse(buffer);\n /// Buffer.toText(buffer, Nat.toText); // => [3, 2, 1]\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size)` | `O(1)` |\n public func reverse<X>(buffer : Buffer<X>) {\n let size = buffer.size();\n if (size == 0) {\n return\n };\n\n var i = 0;\n var j = size - 1 : Nat;\n var temp = buffer.get(0);\n while (i < size / 2) {\n temp := buffer.get(j);\n buffer.put(j, buffer.get(i));\n buffer.put(i, temp);\n i += 1;\n j -= 1\n }\n };\n\n /// Merges two sorted buffers into a single sorted `buffer`, using `compare` to define\n /// the ordering. The final ordering is stable. Behavior is undefined if either\n /// `buffer1` or `buffer2` is not sorted.\n /// \n /// Example:\n /// \n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n /// \n /// let buffer1 = Buffer.Buffer<Nat>(2);\n /// buffer1.add(1);\n /// buffer1.add(2);\n /// buffer1.add(4);\n /// \n /// let buffer2 = Buffer.Buffer<Nat>(2);\n /// buffer2.add(2);\n /// buffer2.add(4);\n /// buffer2.add(6);\n /// \n /// let merged = Buffer.merge<Nat>(buffer1, buffer2, Nat.compare);\n /// Buffer.toText(merged, Nat.toText); // => [1, 2, 2, 4, 4, 6]\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size1 + size2)` | `O(size1 + size2)` |\n public func merge<X>(buffer1 : Buffer<X>, buffer2 : Buffer<X>, compare : (X, X) -> Order) : Buffer<X> {\n let size1 = buffer1.size();\n let size2 = buffer2.size();\n\n let newBuffer = Buffer<X>(newCapacity(size1 + size2));\n\n var pointer1 = 0;\n var pointer2 = 0;\n\n while (pointer1 < size1 and pointer2 < size2) {\n let current1 = buffer1.get(pointer1);\n let current2 = buffer2.get(pointer2);\n\n switch (compare(current1, current2)) {\n case (#less) {\n newBuffer.add(current1);\n pointer1 += 1\n };\n case _ {\n newBuffer.add(current2);\n pointer2 += 1\n }\n }\n };\n\n while (pointer1 < size1) {\n newBuffer.add(buffer1.get(pointer1));\n pointer1 += 1\n };\n\n while (pointer2 < size2) {\n newBuffer.add(buffer2.get(pointer2));\n pointer2 += 1\n };\n\n newBuffer\n };\n\n /// Eliminates all duplicate elements in `buffer` as defined by `compare`.\n /// Elimination is stable with respect to the original ordering of the elements.\n /// \n /// Example:\n /// \n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n /// \n /// buffer.add(1);\n /// buffer.add(2);\n /// buffer.add(3);\n /// buffer.add(1);\n /// buffer.add(2);\n /// buffer.add(3);\n /// \n /// Buffer.removeDuplicates<Nat>(buffer, Nat.compare);\n /// Buffer.toText(buffer, Nat.toText); // => [1, 2, 3]\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size * log(size))` | `O(size)` |\n public func removeDuplicates<X>(buffer : Buffer<X>, compare : (X, X) -> Order) {\n let size = buffer.size();\n let indices = Prim.Array_tabulate<(Nat, X)>(size, func i = (i, buffer.get(i)));\n // Sort based on element, while carrying original index information\n // This groups together the duplicate elements\n let sorted = Array.sort<(Nat, X)>(indices, func(pair1, pair2) = compare(pair1.1, pair2.1));\n let uniques = Buffer<(Nat, X)>(size);\n\n // Iterate over elements\n var i = 0;\n while (i < size) {\n var j = i;\n // Iterate over duplicate elements, and find the smallest index among them (for stability)\n var minIndex = sorted[j];\n label duplicates while (j < (size - 1 : Nat)) {\n let pair1 = sorted[j];\n let pair2 = sorted[j + 1];\n switch (compare(pair1.1, pair2.1)) {\n case (#equal) {\n if (pair2.0 < pair1.0) {\n minIndex := pair2\n };\n j += 1\n };\n case _ {\n break duplicates\n }\n }\n };\n\n uniques.add(minIndex);\n i := j + 1\n };\n\n // resort based on original ordering and place back in buffer\n uniques.sort(\n func(pair1, pair2) {\n if (pair1.0 < pair2.0) {\n #less\n } else if (pair1.0 == pair2.0) {\n #equal\n } else {\n #greater\n }\n }\n );\n\n buffer.clear();\n buffer.reserve(uniques.size());\n for (element in uniques.vals()) {\n buffer.add(element.1)\n }\n };\n\n /// Splits `buffer` into a pair of buffers where all elements in the left\n /// `buffer` satisfy `predicate` and all elements in the right `buffer` do not.\n /// \n /// Example:\n /// \n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n /// \n /// buffer.add(1);\n /// buffer.add(2);\n /// buffer.add(3);\n /// buffer.add(4);\n /// buffer.add(5);\n /// buffer.add(6);\n /// \n /// let partitions = Buffer.partition<Nat>(buffer, func (x) { x % 2 == 0 });\n /// (Buffer.toArray(partitions.0), Buffer.toArray(partitions.1)) // => ([2, 4, 6], [1, 3, 5])\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size)` | `O(size)` |\n public func partition<X>(buffer : Buffer<X>, predicate : X -> Bool) : (Buffer<X>, Buffer<X>) {\n let size = buffer.size();\n let trueBuffer = Buffer<X>(size);\n let falseBuffer = Buffer<X>(size);\n\n for (element in buffer.vals()) {\n if (predicate element) {\n trueBuffer.add(element)\n } else {\n falseBuffer.add(element)\n }\n };\n\n (trueBuffer, falseBuffer)\n };\n\n /// Splits the buffer into two buffers at `index`, where the left buffer contains\n /// all elements with indices less than `index`, and the right buffer contains all\n /// elements with indices greater than or equal to `index`. Traps if `index` is out\n /// of bounds.\n /// \n /// Example:\n /// \n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n /// \n /// buffer.add(1);\n /// buffer.add(2);\n /// buffer.add(3);\n /// buffer.add(4);\n /// buffer.add(5);\n /// buffer.add(6);\n /// \n /// let split = Buffer.split<Nat>(buffer, 3);\n /// (Buffer.toArray(split.0), Buffer.toArray(split.1)) // => ([1, 2, 3], [4, 5, 6])\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size)` | `O(size)` |\n\n public func split<X>(buffer : Buffer<X>, index : Nat) : (Buffer<X>, Buffer<X>) {\n let size = buffer.size();\n\n if (index < 0 or index > size) {\n Prim.trap \"Index out of bounds in split\"\n };\n\n let buffer1 = Buffer<X>(newCapacity index);\n let buffer2 = Buffer<X>(newCapacity(size - index));\n\n var i = 0;\n while (i < index) {\n buffer1.add(buffer.get(i));\n i += 1\n };\n while (i < size) {\n buffer2.add(buffer.get(i));\n i += 1\n };\n\n (buffer1, buffer2)\n };\n\n /// Breaks up `buffer` into buffers of size `size`. The last chunk may\n /// have less than `size` elements if the number of elements is not divisible\n /// by the chunk size.\n /// \n /// Example:\n /// \n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n /// \n /// buffer.add(1);\n /// buffer.add(2);\n /// buffer.add(3);\n /// buffer.add(4);\n /// buffer.add(5);\n /// buffer.add(6);\n /// \n /// let chunks = Buffer.chunk<Nat>(buffer, 3);\n /// Buffer.toText<Buffer.Buffer<Nat>>(chunks, func buf = Buffer.toText(buf, Nat.toText)); // => [[1, 2, 3], [4, 5, 6]]\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(number of elements in buffer)` | `O(number of elements in buffer)` |\n /// \n public func chunk<X>(buffer : Buffer<X>, size : Nat) : Buffer<Buffer<X>> {\n if (size == 0) {\n Prim.trap \"Chunk size must be non-zero in chunk\"\n };\n\n // ceil(buffer.size() / size)\n let newBuffer = Buffer<Buffer<X>>((buffer.size() + size - 1) / size);\n\n var newInnerBuffer = Buffer<X>(newCapacity size);\n var innerSize = 0;\n for (element in buffer.vals()) {\n if (innerSize == size) {\n newBuffer.add(newInnerBuffer);\n newInnerBuffer := Buffer<X>(newCapacity size);\n innerSize := 0\n };\n newInnerBuffer.add(element);\n innerSize += 1\n };\n if (innerSize > 0) {\n newBuffer.add(newInnerBuffer)\n };\n\n newBuffer\n };\n\n /// Groups equal and adjacent elements in the list into sub lists.\n /// \n /// Example:\n /// \n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n /// \n /// buffer.add(1);\n /// buffer.add(2);\n /// buffer.add(2);\n /// buffer.add(4);\n /// buffer.add(5);\n /// buffer.add(5);\n /// \n /// let grouped = Buffer.groupBy<Nat>(buffer, func (x, y) { x == y });\n /// Buffer.toText<Buffer.Buffer<Nat>>(grouped, func buf = Buffer.toText(buf, Nat.toText)); // => [[1], [2, 2], [4], [5, 5]]\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size)` | `O(size)` |\n public func groupBy<X>(buffer : Buffer<X>, equal : (X, X) -> Bool) : Buffer<Buffer<X>> {\n let size = buffer.size();\n let newBuffer = Buffer<Buffer<X>>(size);\n if (size == 0) {\n return newBuffer\n };\n\n var i = 0;\n var baseElement = buffer.get(0);\n var newInnerBuffer = Buffer<X>(size);\n while (i < size) {\n let element = buffer.get(i);\n\n if (equal(baseElement, element)) {\n newInnerBuffer.add(element)\n } else {\n newBuffer.add(newInnerBuffer);\n baseElement := element;\n newInnerBuffer := Buffer<X>(size - i);\n newInnerBuffer.add(element)\n };\n i += 1\n };\n if (newInnerBuffer.size() > 0) {\n newBuffer.add(newInnerBuffer)\n };\n\n newBuffer\n };\n\n /// Flattens the `buffer` of buffers into a single `buffer`.\n /// \n /// Example:\n /// \n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n /// \n /// let buffer = Buffer.Buffer<Buffer.Buffer<Nat>>(1);\n /// \n /// let inner1 = Buffer.Buffer<Nat>(2);\n /// inner1.add(1);\n /// inner1.add(2);\n /// \n /// let inner2 = Buffer.Buffer<Nat>(2);\n /// inner2.add(3);\n /// inner2.add(4);\n /// \n /// buffer.add(inner1);\n /// buffer.add(inner2);\n /// // buffer = [[1, 2], [3, 4]]\n /// \n /// let flat = Buffer.flatten<Nat>(buffer);\n /// Buffer.toText<Nat>(flat, Nat.toText); // => [1, 2, 3, 4]\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(number of elements in buffer)` | `O(number of elements in buffer)` |\n public func flatten<X>(buffer : Buffer<Buffer<X>>) : Buffer<X> {\n let size = buffer.size();\n if (size == 0) {\n return Buffer<X>(0)\n };\n\n let newBuffer = Buffer<X>(\n if (buffer.get(0).size() != 0) {\n newCapacity(buffer.get(0).size() * size)\n } else {\n newCapacity(size)\n }\n );\n\n for (innerBuffer in buffer.vals()) {\n for (innerElement in innerBuffer.vals()) {\n newBuffer.add(innerElement)\n }\n };\n\n newBuffer\n };\n\n /// Combines the two buffers into a single buffer of pairs, pairing together\n /// elements with the same index. If one buffer is longer than the other, the\n /// remaining elements from the longer buffer are not included.\n /// \n /// Example:\n /// \n /// ```motoko include=initialize\n /// \n /// let buffer1 = Buffer.Buffer<Nat>(2);\n /// buffer1.add(1);\n /// buffer1.add(2);\n /// buffer1.add(3);\n /// \n /// let buffer2 = Buffer.Buffer<Nat>(2);\n /// buffer2.add(4);\n /// buffer2.add(5);\n /// \n /// let zipped = Buffer.zip(buffer1, buffer2);\n /// Buffer.toArray(zipped); // => [(1, 4), (2, 5)]\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(min(size1, size2))` | `O(min(size1, size2))` |\n public func zip<X, Y>(buffer1 : Buffer<X>, buffer2 : Buffer<Y>) : Buffer<(X, Y)> {\n // compiler should pull lamda out as a static function since it is fully closed\n zipWith<X, Y, (X, Y)>(buffer1, buffer2, func(x, y) = (x, y))\n };\n\n /// Combines the two buffers into a single buffer, pairing together\n /// elements with the same index and combining them using `zip`. If\n /// one buffer is longer than the other, the remaining elements from\n /// the longer buffer are not included.\n /// \n /// Example:\n /// \n /// ```motoko include=initialize\n /// \n /// let buffer1 = Buffer.Buffer<Nat>(2);\n /// buffer1.add(1);\n /// buffer1.add(2);\n /// buffer1.add(3);\n /// \n /// let buffer2 = Buffer.Buffer<Nat>(2);\n /// buffer2.add(4);\n /// buffer2.add(5);\n /// buffer2.add(6);\n /// \n /// let zipped = Buffer.zipWith<Nat, Nat, Nat>(buffer1, buffer2, func (x, y) { x + y });\n /// Buffer.toArray(zipped) // => [5, 7, 9]\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(min(size1, size2))` | `O(min(size1, size2))` |\n /// \n public func zipWith<X, Y, Z>(buffer1 : Buffer<X>, buffer2 : Buffer<Y>, zip : (X, Y) -> Z) : Buffer<Z> {\n let size1 = buffer1.size();\n let size2 = buffer2.size();\n let minSize = if (size1 < size2) { size1 } else { size2 };\n\n var i = 0;\n let newBuffer = Buffer<Z>(newCapacity minSize);\n while (i < minSize) {\n newBuffer.add(zip(buffer1.get(i), buffer2.get(i)));\n i += 1\n };\n newBuffer\n };\n\n /// Creates a new buffer taking elements in order from `buffer` until predicate\n /// returns false.\n /// \n /// Example:\n /// \n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n /// \n /// buffer.add(1);\n /// buffer.add(2);\n /// buffer.add(3);\n /// \n /// let newBuf = Buffer.takeWhile<Nat>(buffer, func (x) { x < 3 });\n /// Buffer.toText(newBuf, Nat.toText); // => [1, 2]\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size)` | `O(size)` |\n public func takeWhile<X>(buffer : Buffer<X>, predicate : X -> Bool) : Buffer<X> {\n let newBuffer = Buffer<X>(buffer.size());\n\n for (element in buffer.vals()) {\n if (not predicate element) {\n return newBuffer\n };\n newBuffer.add(element)\n };\n\n newBuffer\n };\n\n /// Creates a new buffer excluding elements in order from `buffer` until predicate\n /// returns false.\n /// \n /// Example:\n /// \n /// ```motoko include=initialize\n /// import Nat \"mo:base/Nat\";\n /// \n /// buffer.add(1);\n /// buffer.add(2);\n /// buffer.add(3);\n /// \n /// let newBuf = Buffer.dropWhile<Nat>(buffer, func x { x < 3 }); // => [3]\n /// Buffer.toText(newBuf, Nat.toText);\n /// ```\n /// \n /// | Runtime | Space |\n /// |-----------|-----------|\n /// | `O(size)` | `O(size)` |\n public func dropWhile<X>(buffer : Buffer<X>, predicate : X -> Bool) : Buffer<X> {\n let size = buffer.size();\n let newBuffer = Buffer<X>(size);\n\n var i = 0;\n var take = false;\n label iter for (element in buffer.vals()) {\n if (not (take or predicate element)) {\n take := true\n };\n if (take) {\n newBuffer.add(element)\n }\n };\n newBuffer\n }\n}\n"},"Order.mo":{"content":"\nmodule {\n\n /// A type to represent an order.\n public type Order = {\n #less;\n #equal;\n #greater\n };\n\n /// Check if an order is `#less`.\n public func isLess(order : Order) : Bool {\n switch order {\n case (#less) { true };\n case _ { false }\n }\n };\n\n /// Check if an order is `#equal`.\n public func isEqual(order : Order) : Bool {\n switch order {\n case (#equal) { true };\n case _ { false }\n }\n };\n\n /// Check if an order is `#greater`.\n public func isGreater(order : Order) : Bool {\n switch order {\n case (#greater) { true };\n case _ { false }\n }\n };\n\n /// Returns true if only if `o1` and `o2` are the same ordering.\n public func equal(o1 : Order, o2 : Order) : Bool {\n switch (o1, o2) {\n case (#less, #less) { true };\n case (#equal, #equal) { true };\n case (#greater, #greater) { true };\n case _ { false }\n }\n };\n\n}\n"}}}