# (lispkit vector)

Vectors are heterogeneous data structures whose elements are indexed by a range of integers. A vector typically occupies less space than a list of the same length, and a randomly chosen element can be accessed in constant time vs. linear time for lists.

The *length* of a vector is the number of elements that it contains. This number is a non-negative integer that is fixed when the vector is created. The valid indexes of a vector are the exact, non-negative integers less than the length of the vector. The first element in a vector is indexed by zero, and the last element is indexed by one less than the length of the vector.

Two vectors are `equal?` if they have the same length, and if the values in corresponding slots of the vectors are `equal?`.

A vector can be *mutable* or *immutable*. Trying to change the state of an *immutable vector*, e.g. via `vector-set!` will result in an error being raised.

Vectors are written using the notation `#(obj ...)`. For example, a vector of length 3 containing the number zero in element 0, the list (1 2 3 4) in element 1, and the string "Lisp" in element 2 can be written as follows: `#(0 (1 2 3 4) "Lisp")`.

Vector constants are self-evaluating, so they do not need to be quoted in programs. Vector constants, i.e. vectors created with a vector literal, are *immutable*.

LispKit also supports *growable vectors* via library `(lispkit gvector)`. As opposed to regular vectors, a growable vector does not have a fixed size and supports adding and removing elements. While a growable vector does not satisfay the `vector?` predicate, this library also accepts growable vectors as parameters whenever a vector is expected. Use predicate `mutable-vector?` for determining whether a vector is either a regular mutable vector or a growable vector.

## Predicates

**(vector?&#x20;*****obj*****)**     <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-d20368c588cfbb523beb2fae4f8be0f8ef011884%2Fproc.png?alt=media" alt="" data-size="line">

Returns `#t` if *obj* is a regular vector; otherwise returns `#f`. This function returns `#f` for growable vectors; see library `(lispkit gvector)`.

**(mutable-vector?&#x20;*****obj*****)**     <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-d20368c588cfbb523beb2fae4f8be0f8ef011884%2Fproc.png?alt=media" alt="" data-size="line">

Returns `#t` if *obj* is either a mutable regular vector or a growable vector (see library `(lispkit gvector)`); otherwise returns `#f`.

**(immutable-vector?&#x20;*****obj*****)**     <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-d20368c588cfbb523beb2fae4f8be0f8ef011884%2Fproc.png?alt=media" alt="" data-size="line">

Returns `#t` if *obj* is an immutable vector; otherwise returns `#f`.

**(vector=&#x20;*****eql vector ...*****)**     <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-d20368c588cfbb523beb2fae4f8be0f8ef011884%2Fproc.png?alt=media" alt="" data-size="line">

Procedure `vector=` is a generic comparator for vectors. Vectors *a* and *b* are considered equal by `vector=` if their lengths are the same, and for each respective elements *ai* and *bi*, `(eql ai bi)` evaluates to true. *eql* is always applied to two arguments.

If there are only zero or one vector argument, `#t` is automatically returned. The dynamic order in which comparisons of elements and of vectors are performed is unspecified.

```scheme
(vector= eq? #(a b c d) #(a b c d))  ⇒  #t 
(vector= eq? #(a b c d) #(a b d c))  ⇒  #f 
(vector= = #(1 2 3 4 5) #(1 2 3 4))  ⇒  #f 
(vector= = #(1 2 3 4) #(1.0 2.0 3.0 4.0))  ⇒  #t 
(vector= eq?) ⇒  #t 
(vector= eq? '#(a))  ⇒  #t 
```

## Constructors

**(make-vector&#x20;*****k*****)**     <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-d20368c588cfbb523beb2fae4f8be0f8ef011884%2Fproc.png?alt=media" alt="" data-size="line">\
\&#xNAN;**(make-vector&#x20;*****k fill*****)**

Returns a newly allocated vector of *k* elements. If a second argument is given, then each element is initialized to *fill*. Otherwise the initial contents of each element is unspecified.

**(vector&#x20;*****obj ...*****)**     <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-d20368c588cfbb523beb2fae4f8be0f8ef011884%2Fproc.png?alt=media" alt="" data-size="line">

Returns a newly allocated mutable vector whose elements contain the given arguments. It is analogous to `list`.

```scheme
(vector ’a ’b ’c)  ⇒  #(a b c)
```

**(immutable-vector&#x20;*****obj ...*****)**     <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-d20368c588cfbb523beb2fae4f8be0f8ef011884%2Fproc.png?alt=media" alt="" data-size="line">

Returns a newly allocated immutable vector whose elements contain the given arguments in the given order.

**(list->vector&#x20;*****list*****)**     <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-d20368c588cfbb523beb2fae4f8be0f8ef011884%2Fproc.png?alt=media" alt="" data-size="line">

The `list->vector` procedure returns a newly created mutable vector initialized to the elements of the list *list* in the order of the list.

```scheme
(list->vector ’(a b c))  ⇒  #(a b c)
```

**(list->immutable-vector&#x20;*****list*****)**     <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-d20368c588cfbb523beb2fae4f8be0f8ef011884%2Fproc.png?alt=media" alt="" data-size="line">

The `list->vector` procedure returns a newly created immutable vector initialized to the elements of the list *list* in the order of the list.

**(string->vector&#x20;*****str*****)**     <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-d20368c588cfbb523beb2fae4f8be0f8ef011884%2Fproc.png?alt=media" alt="" data-size="line">\
\&#xNAN;**(string->vector&#x20;*****str start*****)**\
\&#xNAN;**(string->vector&#x20;*****str start end*****)**

The `string->vector` procedure returns a newly created mutable vector initialized to the elements of the string *str* between *start* and *end* (i.e. including all characters from index *start* to index *end*-1).

```scheme
(string->vector "ABC")  ⇒  #(#\A #\B #\C)
```

**(vector-copy&#x20;*****vector*****)**     <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-d20368c588cfbb523beb2fae4f8be0f8ef011884%2Fproc.png?alt=media" alt="" data-size="line">\
\&#xNAN;**(vector-copy&#x20;*****vector mutable*****)**\
\&#xNAN;**(vector-copy&#x20;*****vector start*****)**\
\&#xNAN;**(vector-copy&#x20;*****vector start end*****)**\
\&#xNAN;**(vector-copy&#x20;*****vector start end mutable*****)**

Returns a newly allocated copy of the elements of the given vector between *start* and *end*, but excluding the element at index *end*. The elements of the new vector are the same (in the sense of `eqv?`) as the elements of the old.

*mutable* is a boolean argument. If it is set to `#f`, an immutable copy of *vector* will be created. The type of the second argument of `vector-copy` is used to disambiguate between the second and third version of the function. An exact integer will always be interpreted as *start*, a boolean value will always be interpreted as *mutable*.

```scheme
(define a #(1 8 2 8))         ; a may be immutable
(define b (vector-copy a))    ; creates a mutable copy of a
(vector-set! b 0 3)           ; b is mutable
b  ⇒  #(3 8 2 8)
(define c (vector-copy a #f)) ; creates an immutable copy of a
(vector-set! c 0 3)  ⇒  error  ; error, since c is immutable
(define d (vector-copy b 1 3))
d  ⇒  #(8 2)
```

**(vector-append&#x20;*****vector ...*****)**     <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-d20368c588cfbb523beb2fae4f8be0f8ef011884%2Fproc.png?alt=media" alt="" data-size="line">

Returns a newly allocated mutable vector whose elements are the concatenation of the elements of the given vectors.

```scheme
(vector-append #(a b c) #(d e f))  ⇒  #(a b c d e f)
```

**(vector-concatenate&#x20;*****vector xs*****)**     <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-d20368c588cfbb523beb2fae4f8be0f8ef011884%2Fproc.png?alt=media" alt="" data-size="line">

Returns a newly allocated mutable vector whose elements are the concatenation of the elements of the vectors in *xs*. *xs* is a proper list of vectors.

```scheme
(vector-concatenate '(#(a b c) #(d) #(e f)))  ⇒  #(a b c d e f)
```

**(vector-map&#x20;*****f vector1 vector2 ...*****)**     <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-d20368c588cfbb523beb2fae4f8be0f8ef011884%2Fproc.png?alt=media" alt="" data-size="line">

Constructs a new mutable vector of the shortest size of the vector arguments *vector1*, *vector2*, etc. Each element at index *i* of the new vector is mapped from the old vectors by `(f (vector-ref vector1 i) (vector-ref vector2 i) ...)`. The dynamic order of the application of f is unspecified.

```scheme
(vector-map + #(1 2 3 4 5) #(10 20 30 40))  ⇒  #(11 22 33 44)
```

**(vector-map/index&#x20;*****f vector1 vector2 ...*****)**     <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-d20368c588cfbb523beb2fae4f8be0f8ef011884%2Fproc.png?alt=media" alt="" data-size="line">

Constructs a new mutable vector of the shortest size of the vector arguments *vector1*, *vector2*, etc. Each element at index *i* of the new vector is mapped from the old vectors by `(f i (vector-ref vector1 i) (vector-ref vector2 i) ...)`. The dynamic order of the application of f is unspecified.

```scheme
(vector-map/index (lambda (i x y) (cons i (+ x y))) #(1 2 3) #(10 20 30))
⇒  #((0 . 11) (1 . 22) (2 . 33))
```

**(vector-sort&#x20;*****pred vector*****)**     <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-d20368c588cfbb523beb2fae4f8be0f8ef011884%2Fproc.png?alt=media" alt="" data-size="line">\
\&#xNAN;**(vector-sort&#x20;*****pred vector start*****)**\
\&#xNAN;**(vector-sort&#x20;*****pred vector start end*****)**

Procedure `vector-sort` returns a new vector containing the elements of *vector* in sorted order using *pred* as the "less than" predicate. If *start* and *end* are given, they indicate the sub-vector that should be sorted.

```scheme
(vector-sort < (vector 7 4 9 1 2 8 5))
⇒  #(1 2 4 5 7 8 9)
```

## Iterating over vectors

**(vector-for-each&#x20;*****f vector1 vector2 ...*****)**     <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-d20368c588cfbb523beb2fae4f8be0f8ef011884%2Fproc.png?alt=media" alt="" data-size="line">

`vector-for-each` implements a simple vector iterator: it applies *f* to the corresponding list of parallel elements from *vector1 vector2 ...* in the range *\[0, length)*, where *length* is the length of the smallest vector argument passed. In contrast with `vector-map`, *f* is reliably applied to each subsequent element, starting at index 0, in the vectors.

```scheme
(vector-for-each (lambda (x) (display x) (newline)) 
                 #("foo" "bar" "baz" "quux" "zot"))
⇒
foo
bar
baz
quux
zot
```

**(vector-for-each/index&#x20;*****f vector1 vector2 ...*****)**     <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-d20368c588cfbb523beb2fae4f8be0f8ef011884%2Fproc.png?alt=media" alt="" data-size="line">

`vector-for-each/index` implements a simple vector iterator: it applies *f* to the index *i* and the corresponding list of parallel elements from *vector1 vector2 ...* in the range *\[0, length)*, where *length* is the length of the smallest vector argument passed. The only difference to `vector-for-each` is that `vector-for-each/index` always passes the current index as the first argument of *f* in addition to the elements from the vectors *vector1 vector2 ...*.

```scheme
(vector-for-each/index
  (lambda (i x) (display i)(display ": ")(display x)(newline))
  #("foo" "bar" "baz" "quux" "zot"))
⇒
0: foo
1: bar
2: baz
3: quux
4: zot
```

## Managing vector state

**(vector-length&#x20;*****vector*****)**     <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-d20368c588cfbb523beb2fae4f8be0f8ef011884%2Fproc.png?alt=media" alt="" data-size="line">

Returns the number of elements in *vector* as an exact integer.

**(vector-ref&#x20;*****vector k*****)**     <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-d20368c588cfbb523beb2fae4f8be0f8ef011884%2Fproc.png?alt=media" alt="" data-size="line">

The `vector-ref` procedure returns the contents of element *k* of *vector*. It is an error if *k* is not a valid index of *vector*.

```scheme
(vector-ref ’#(1 1 2 3 5 8 13 21) 5) ⇒  8
(vector-ref ’#(1 1 2 3 5 8 13 21) (exact (round (* 2 (acos -1)))))  ⇒  13
```

**(vector-set!&#x20;*****vector k obj*****)**     <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-d20368c588cfbb523beb2fae4f8be0f8ef011884%2Fproc.png?alt=media" alt="" data-size="line">

The `vector-set!` procedure stores *obj* in element *k* of *vector*. It is an error if *k* is not a valid index of *vector*.

```scheme
(let ((vec (vector 0 '(2 2 2 2) "Anna")))
  (vector-set! vec 1 '("Sue" "Sue"))
  vec)
  ⇒  #(0 ("Sue" "Sue") "Anna")
(vector-set! '#(0 1 2) 1 "doe")
  ⇒  error    ;; constant/immutable vector
```

**(vector-swap!&#x20;*****vector j k*****)**     <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-d20368c588cfbb523beb2fae4f8be0f8ef011884%2Fproc.png?alt=media" alt="" data-size="line">

The `vector-swap!` procedure swaps the element *j* of *vector* with the element *k* of *vector*.

## Destructive vector operations

Procedures which operate only on a part of a vector specify the applicable range in terms of an index interval \[*start*; *end*\[; i.e. the *end* index is always exclusive.

**(vector-copy!&#x20;*****to at from*****)**     <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-d20368c588cfbb523beb2fae4f8be0f8ef011884%2Fproc.png?alt=media" alt="" data-size="line">\
\&#xNAN;**(vector-copy!&#x20;*****to at from start*****)**\
\&#xNAN;**(vector-copy!&#x20;*****to at from start end*****)**

Copies the elements of vector *from* between *start* and *end* to vector *to*, starting at *at*. The order in which elements are copied is unspecified, except that if the source and destination overlap, copying takes place as if the source is first copied into a temporary vector and then into the destination. *start* defaults to 0 and *end* defaults to the length of *vector*.

It is an error if *at* is less than zero or greater than the length of *to*. It is also an error if `(- (vector-length to) at)` is less than `(- end start)`.

```scheme
(define a (vector 1 2 3 4 5))
(define b (vector 10 20 30 40 50)) (vector-copy! b 1 a 0 2)
b  ⇒  #(10 1 2 40 50)
```

**(vector-fill!&#x20;*****vector fill*****)**     <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-d20368c588cfbb523beb2fae4f8be0f8ef011884%2Fproc.png?alt=media" alt="" data-size="line">\
\&#xNAN;**(vector-fill!&#x20;*****vector fill start*****)**\
\&#xNAN;**(vector-fill!&#x20;*****vector fill start end*****)**

The `vector-fill!` procedure stores *fill* in the elements of *vector* between *start* and *end*. *start* defaults to 0 and *end* defaults to the length of *vector*.

```scheme
(define a (vector 1 2 3 4 5))
(vector-fill! a ’smash 2 4)
a  ⇒  #(1 2 smash smash 5)
```

**(vector-reverse!&#x20;*****vector*****)**     <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-d20368c588cfbb523beb2fae4f8be0f8ef011884%2Fproc.png?alt=media" alt="" data-size="line">\
\&#xNAN;**(vector-reverse!&#x20;*****vector start*****)**\
\&#xNAN;**(vector-reverse!&#x20;*****vector start end*****)**

Procedure `vector-reverse!` destructively reverses the contents of *vector* between *start* and *end*. *start* defaults to 0 and *end* defaults to the length of *vector*.

```scheme
(define a (vector 1 2 3 4 5))
(vector-reverse! a)
a  ⇒  #(5 4 3 2 1)
```

**(vector-sort!&#x20;*****pred vector*****)**     <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-d20368c588cfbb523beb2fae4f8be0f8ef011884%2Fproc.png?alt=media" alt="" data-size="line">\
\&#xNAN;**(vector-sort!&#x20;*****pred vector start*****)**\
\&#xNAN;**(vector-sort!&#x20;*****pred vector start end*****)**

Procedure `vector-sort!` destructively sorts the elements of *vector* using the "less than" predicate *pred* between the indices *start* and *end*. Default for *start* is 0, for *end* it is the length of the vector.

```scheme
(define a (vector 7 4 9 1 2 8 5))
(vector-sort! < a)
a  ⇒  #(1 2 4 5 7 8 9)
```

**(vector-map!&#x20;*****f vector1 vector2 ...*****)**     <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-d20368c588cfbb523beb2fae4f8be0f8ef011884%2Fproc.png?alt=media" alt="" data-size="line">

Similar to `vector-map` which maps the various elements into a new vector via function *f*, procedure `vector-map!` destructively inserts the mapped elements into *vector1*. The dynamic order in which *f* gets applied to the elements is unspecified.

```scheme
(define a (vector 1 2 3 4))
(vector-map! + a #(10 20 30))
a  ⇒  #(11 22 33 4)
```

**(vector-map/index!&#x20;*****f vector1 vector2 ...*****)**     <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-d20368c588cfbb523beb2fae4f8be0f8ef011884%2Fproc.png?alt=media" alt="" data-size="line">

Similar to `vector-map/index` which maps the various elements together with their index into a new vector via function *f*, procedure `vector-map/index!` destructively inserts the mapped elements into *vector1*. The dynamic order in which *f* gets applied to the elements is unspecified.

```scheme
(define a (vector 1 2 3 4))
(vector-map/index! (lambda (i x y) (cons i (+ x y))) a #(10 20 30))
a  ⇒  #((0 . 11) (1 . 22) (2 . 33) 4)
```

## Converting vectors

**(vector->list&#x20;*****vector*****)**     <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-d20368c588cfbb523beb2fae4f8be0f8ef011884%2Fproc.png?alt=media" alt="" data-size="line">\
\&#xNAN;**(vector->list&#x20;*****vector start*****)**\
\&#xNAN;**(vector->list&#x20;*****vector start end*****)**

The `vector->list` procedure returns a newly allocated list of the objects contained in the elements of *vector* between *start* and *end* in the same order line in *vector*.

```scheme
(vector->list ’#(dah dah didah))  ⇒  (dah dah didah)
(vector->list ’#(dah dah didah) 1 2)  ⇒  (dah)
```

**(vector->string&#x20;*****vector*****)**     <img src="https://1467949168-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fna2foeoaXHYkSD3fhs0t%2Fuploads%2Fgit-blob-d20368c588cfbb523beb2fae4f8be0f8ef011884%2Fproc.png?alt=media" alt="" data-size="line">\
\&#xNAN;**(vector->string&#x20;*****vector start*****)**\
\&#xNAN;**(vector->string&#x20;*****vector start end*****)**

The `vector->string` procedure returns a newly allocated string of the objects contained in the elements of *vector* between *start* and *end*. This procedure preserves the order of the characters. It is an error if any element of vector between *start* and *end* is not a character.

```scheme
(vector->string #(#\1 #\2 #\3)  ⇒  "123"
```
