(.using
  [library
   [lux "*"
    ["$" documentation {"+" documentation:}]
    [data
     [text {"+" \n}
      ["%" format {"+" format}]]]
    [macro
     ["[0]" template]]]]
  [\\library
   ["[0]" /]])

(documentation: /.Binary
  "A binary BLOB of data.")

(documentation: /.empty
  "A fresh/empty binary BLOB of the specified size."
  [(empty size)])

(documentation: /.aggregate
  ""
  [(aggregate f init binary)])

(documentation: /.read/8!
  "Read 1 byte (8 bits) at the given index."
  [(read/8! index binary)])

(documentation: /.read/16!
  "Read 2 bytes (16 bits) at the given index."
  [(read/16! index binary)])

(documentation: /.read/32!
  "Read 4 bytes (32 bits) at the given index."
  [(read/32! index binary)])

(documentation: /.read/64!
  "Read 8 bytes (64 bits) at the given index."
  [(read/64! index binary)])

(documentation: /.write/8!
  "Write 1 byte (8 bits) at the given index."
  [(write/8! index value binary)])

(documentation: /.write/16!
  "Write 2 bytes (16 bits) at the given index."
  [(write/16! index value binary)])

(documentation: /.write/32!
  "Write 4 bytes (32 bits) at the given index."
  [(write/32! index value binary)])

(documentation: /.write/64!
  "Write 8 bytes (64 bits) at the given index."
  [(write/64! index value binary)])

(documentation: /.copy
  "Mutates the target binary BLOB by copying bytes from the source BLOB to it."
  [(copy bytes source_offset source target_offset target)])

(documentation: /.slice
  "Yields a subset of the binary BLOB, so long as the specified range is valid."
  [(slice offset length binary)])

(documentation: /.after
  "Yields a binary BLOB with at most the specified number of bytes removed."
  [(after bytes binary)])

(.def: .public documentation
  (.List $.Module)
  ($.module /._
            ""
            [..Binary
             ..empty
             ..aggregate
             ..read/8!
             ..read/16!
             ..read/32!
             ..read/64!
             ..write/8!
             ..write/16!
             ..write/32!
             ..write/64!
             ..copy
             ..slice
             ..after
             ($.default /.index_out_of_bounds)
             ($.default /.slice_out_of_bounds)
             ($.default /.size)
             ($.default /.equivalence)
             ($.default /.monoid)]
            []))
