upgrade structures and migrate to nextra v4
This commit is contained in:
363
content/Swap/CSE361S_L2.md
Normal file
363
content/Swap/CSE361S_L2.md
Normal file
@@ -0,0 +1,363 @@
|
||||
# Lecture 2: Binary Representation
|
||||
|
||||
## Bits review
|
||||
|
||||
- 1 byte = 8 bits
|
||||
|
||||
### Converting between binary and decimal
|
||||
|
||||
$162_{10} = 10100010_{2}$
|
||||
|
||||
$$
|
||||
\begin{aligned}
|
||||
162_{10} &= 1 \cdot 2^7 + 0 \cdot 2^6 + 1 \cdot 2^5 + 0 \cdot 2^4 + 0 \cdot 2^3 + 0 \cdot 2^2 + 1 \cdot 2^1 + 0 \cdot 2^0 \\
|
||||
&= 128 + 32 + 2 \\
|
||||
&= 162
|
||||
\end{aligned}
|
||||
$$
|
||||
|
||||
## Example Data representations
|
||||
|
||||
| C Data Type | Size (bytes 32bit) | Size (bytes 64bit) | x86-64 |
|
||||
| ----------- | ----------------- | ----------------- | ----- |
|
||||
| `char` | 1 | 1 | 1 |
|
||||
| `short` | 2 | 2 | 2 |
|
||||
| `int` | 4 | 4 | 4 |
|
||||
| `long` | 4 | 8 | 8 |
|
||||
| `float` | 4 | 4 | 4 |
|
||||
| `double` | 8 | 8 | 8 |
|
||||
| `long double` | - | - | 10/16 |
|
||||
| `pointer` | 4 | 8 | 8 |
|
||||
|
||||
Same size if declared as `unsigned`
|
||||
|
||||
### Encoding Integers (w bits)
|
||||
|
||||
#### Unsigned Integers
|
||||
|
||||
$$
|
||||
B2U(X)= \sum_{i=0}^{w-1} x_i \cdot 2^i
|
||||
$$
|
||||
|
||||
Example:
|
||||
|
||||
$$
|
||||
\begin{aligned}
|
||||
B2U(01101) &= 0 \cdot 2^4 + 1 \cdot 2^3 + 1 \cdot 2^2 + 0 \cdot 2^1 + 1 \cdot 2^0 \\
|
||||
&= 0 + 8 + 4 + 0 + 1 \\
|
||||
&= 13
|
||||
\end{aligned}
|
||||
$$
|
||||
|
||||
$$
|
||||
\begin{aligned}
|
||||
B2U(11101) &= 1 \cdot 2^4 + 1 \cdot 2^3 + 1 \cdot 2^2 + 0 \cdot 2^1 + 1 \cdot 2^0 \\
|
||||
&= 16 + 8 + 4 + 0 + 1 \\
|
||||
&= 29
|
||||
\end{aligned}
|
||||
$$
|
||||
|
||||
#### Two's Complement
|
||||
|
||||
$$
|
||||
B2T(X)= -x_{w-1} \cdot 2^{w-1} + \sum_{i=0}^{w-2} x_i \cdot 2^i
|
||||
$$
|
||||
|
||||
|
||||
Example:
|
||||
|
||||
$$
|
||||
\begin{aligned}
|
||||
B2T(01101) &= 0 \cdot 2^4 + 1 \cdot 2^3 + 1 \cdot 2^2 + 0 \cdot 2^1 + 1 \cdot 2^0 \\
|
||||
&= 0 + 8 + 4 + 0 + 1 \\
|
||||
&= 13
|
||||
\end{aligned}
|
||||
$$
|
||||
|
||||
$$
|
||||
\begin{aligned}
|
||||
B2T(11101) &= -1 \cdot 2^4 + 1 \cdot 2^3 + 1 \cdot 2^2 + 0 \cdot 2^1 + 1 \cdot 2^0 \\
|
||||
&= -16 + 8 + 4 + 0 + 1 \\
|
||||
&= -3
|
||||
\end{aligned}
|
||||
$$
|
||||
|
||||
#### Sign Bit
|
||||
|
||||
- For 2's complement, most significant bit is the sign bit
|
||||
- 0 for positive
|
||||
- 1 for negative
|
||||
|
||||
#### Numeric Ranges
|
||||
|
||||
- Assume you have a integer type that is 4 bits long
|
||||
- Unsigned: 0 to 15
|
||||
- $0b1111=15$
|
||||
- 2's Complement: -8 to 7
|
||||
- $0b1000=-8$
|
||||
|
||||
- Unsigned Values:
|
||||
- $UMin=0=B2U(000\ldots 0)$
|
||||
- $UMax=2^w-1=B2U(111\ldots 1)$
|
||||
- 2's Complement Values
|
||||
- $TMin=-2^{w-1}=B2T(100\ldots 0)$
|
||||
- $TMax=2^{w-1}-1=B2T(011\ldots 1)$
|
||||
- Other interesting values $-1=B2T(111\ldots 1)$
|
||||
|
||||
#### Values for different word sizez
|
||||
|
||||
| | W=8 | W=16 | W=32 | W=64 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| TMin | -128 | -32768 | -2147483648 | -9223372036854775808 |
|
||||
| TMax | 127 | 32767 | 2147483647 | 9223372036854775807 |
|
||||
| UMin | 0 | 0 | 0 | 0 |
|
||||
| UMax | 255 | 65535 | 4294967295 | 18446744073709551615 |
|
||||
|
||||
## C Operators for bitwise operations
|
||||
|
||||
### Boolean algebra
|
||||
|
||||
And
|
||||
|
||||
|`&`| 0 | 1 |
|
||||
| --- | --- | --- |
|
||||
| 0 | 0 | 0 |
|
||||
| 1 | 0 | 1 |
|
||||
|
||||
Example:
|
||||
|
||||
```c
|
||||
int a = 0b1010;
|
||||
int b = 0b1100;
|
||||
int c = a & b; // should return 0b1000
|
||||
```
|
||||
|
||||
Or
|
||||
|
||||
|`\|`| 0 | 1 |
|
||||
| --- | --- | --- |
|
||||
| 0 | 0 | 1 |
|
||||
| 1 | 1 | 1 |
|
||||
|
||||
Example:
|
||||
|
||||
```c
|
||||
int a = 0b1010;
|
||||
int b = 0b1100;
|
||||
int c = a | b; // should return 0b1110
|
||||
```
|
||||
|
||||
Xor
|
||||
|
||||
|`^`| 0 | 1 |
|
||||
| --- | --- | --- |
|
||||
| 0 | 0 | 1 |
|
||||
| 1 | 1 | 0 |
|
||||
|
||||
Example:
|
||||
|
||||
```c
|
||||
int a = 0b1010;
|
||||
int b = 0b1100;
|
||||
int c = a ^ b; // should return 0b0110
|
||||
```
|
||||
|
||||
Not
|
||||
|
||||
|`~`| 0 | 1 |
|
||||
| --- | --- | --- |
|
||||
| | 1 | 0 |
|
||||
|
||||
Example:
|
||||
|
||||
```c
|
||||
int a = 0b1010;
|
||||
int c = ~a; // should return 0b0101
|
||||
```
|
||||
|
||||
#### Imagine as set operations
|
||||
|
||||
- `&` is intersection
|
||||
- `|` is union
|
||||
- `^` is exclusive or (symmetric difference)
|
||||
- `~` is complement
|
||||
|
||||
#### Logic operators on C
|
||||
|
||||
- `&&` is and
|
||||
- `||` is or
|
||||
- `!` is not
|
||||
|
||||
Interesting properties:
|
||||
|
||||
- View `0` as `false` and any non-zero value as `true`
|
||||
- Always returns `0` or `1`
|
||||
- Early termination: if the first operand is `0`, the second operand is not evaluated
|
||||
|
||||
Example:
|
||||
|
||||
```c
|
||||
int a = 0x69;
|
||||
int b = 0x55;
|
||||
int c = a && b; // should return 0x01
|
||||
int d = a || b; // should return 0x01 (the program will not check b at all since a is non-zero by early termination)
|
||||
int e = !a; // should return 0x00
|
||||
int f = !!a; // should return 0x01
|
||||
int g = !0; // should return 0x01
|
||||
|
||||
int *p = NULL;
|
||||
bool should_access = p && *p; // (avoid null pointer access, returns 0 if p is NULL, otherwise returns true if *p is non-zero)
|
||||
```
|
||||
|
||||
#### Using bit masks
|
||||
|
||||
```c
|
||||
// goal: compute val mod x and x is a power of 2
|
||||
unsigned int val = 137; // some value to take mod of
|
||||
unsigned int x = 16; // x is a power of 2
|
||||
unsigned int mask = x - 1; // mask is a bit mask that is all 1s except for the least significant bit
|
||||
unsigned int mod = val & mask; // mod is the result of val mod x
|
||||
```
|
||||
|
||||
#### Shift operations
|
||||
|
||||
- `<<` is left shift
|
||||
- Shift bit-vector x left y positions
|
||||
- `>>` is right shift
|
||||
- Shift bit-vector x right y positions
|
||||
- Logical shift: fill with 0s
|
||||
- Arithmetic shift: fill with the sign bit
|
||||
- Undefined behavior: shift by a number greater than or equal to the word size
|
||||
|
||||
Example:
|
||||
|
||||
| `x` | `0b01100010` |
|
||||
| --- | --- |
|
||||
| `x<<3` | `0b00010000` |
|
||||
| Logical shift `x>>2` | `0b00011000` |
|
||||
| Arithmetic shift `x>>2` | `0b00011000` |
|
||||
|
||||
For negative numbers:
|
||||
|
||||
| `x` | `0b10100010` |
|
||||
| --- | --- |
|
||||
| `x<<3` | `0b00010000` |
|
||||
| Logical shift `x>>2` | `0b00101000` |
|
||||
| Arithmetic shift `x>>2` | `0b11101000` |
|
||||
|
||||
#### Pop count function
|
||||
|
||||
- How do you implement a pop count function in a 4-byte memory?
|
||||
|
||||
Trivial way:
|
||||
|
||||
```c
|
||||
# define MASK 0x1;
|
||||
|
||||
int pop_count(unsigned int x) {
|
||||
// does not work for negative numbers
|
||||
int count = 0;
|
||||
while (x!=0) {
|
||||
if (x & MASK) count++;
|
||||
x >>= 1;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
```
|
||||
|
||||
#### Casting Between Signed and Unsigned Integers in C
|
||||
|
||||
Constants
|
||||
|
||||
- By default, constants are signed
|
||||
- To make a constant unsigned, add the `U` suffix
|
||||
|
||||
```c
|
||||
unsigned int a = 0x1234U;
|
||||
```
|
||||
|
||||
Casting
|
||||
|
||||
- Explicitly cast to a different type
|
||||
|
||||
```c
|
||||
int tx,ty;
|
||||
unsigned int ux,uy;
|
||||
|
||||
tx = (int) ux;
|
||||
uy = (unsigned) ty;
|
||||
```
|
||||
|
||||
- Implicit casting also occurs via assignments and procedure calls
|
||||
|
||||
```c
|
||||
tx = ux;
|
||||
pop_count(tx); // popcount is a built-in function that returns the number of 1s in the binary representation of x (unsigned int)
|
||||
```
|
||||
|
||||
#### When should I use unsigned integers?
|
||||
|
||||
- Don't use just because the number are non-negative
|
||||
- Easy to make mistakes
|
||||
|
||||
```c
|
||||
unsigned i;
|
||||
for (i = cnt-2; i < 0; i++) {
|
||||
// do something
|
||||
}
|
||||
```
|
||||
|
||||
If `cnt=1` then `i` will be `-1` and the loop will not terminate in short time. LOL.
|
||||
|
||||
- Can be very subtle
|
||||
|
||||
```c
|
||||
#define DELTA sizeof(int) // sizeof(int) returns unsigned
|
||||
|
||||
int x = 0;
|
||||
for (int i = CNT; i-DELTA >=0; i-=DELTA) {
|
||||
// do something
|
||||
}
|
||||
```
|
||||
|
||||
The expression `i-DELTA >= 0` will be evaluated as `unsigned` and will not terminate.
|
||||
|
||||
#### Code Security Example
|
||||
|
||||
You can access the kernel memory region holding non user-accessible data. if you give negative index to the array, it will access the kernel memory region by interpreting the negative index as an unsigned integer.
|
||||
|
||||
## Change int size
|
||||
|
||||
### Extension
|
||||
|
||||
- When operating with types of different widths, C automatically perform extension
|
||||
- Converting from smaller to larger type is always safe
|
||||
- Given w-bit integer `x`,
|
||||
- Convert `x` to `w+k` bit integer with the same value
|
||||
- Two different types of extension
|
||||
- zero extension: use for unsigned (similar to logical shift)
|
||||
- sign extension: use for signed (similar to arithmetic shift)
|
||||
|
||||
### Truncation
|
||||
|
||||
- Task:
|
||||
- Given w-bit integer `x`,
|
||||
- Convert `x` to `k` bit integer with the same value
|
||||
- Rule:
|
||||
- Drop high-order `w-k` bits
|
||||
- Effect:
|
||||
- can change the value of `x`
|
||||
- unsigned: mathematical mode on `x`
|
||||
- signed: reinterprets the bit (add -2^k to the value)
|
||||
|
||||
#### Code puzzle
|
||||
|
||||
what is the output of the following code?
|
||||
|
||||
```c
|
||||
unsigned short y=0xFFFF;
|
||||
int x = y;
|
||||
printf("%x", x); /* print the value of x as a hexadecimal number */
|
||||
```
|
||||
|
||||
The output is `0x0000FFFF` it will try to preserve the value of `y` by sign extending the value of `y` to `x`.
|
||||
42
content/Swap/CSE361S_W1.md
Normal file
42
content/Swap/CSE361S_W1.md
Normal file
@@ -0,0 +1,42 @@
|
||||
# CSE361S Week 1 (Compact Version)
|
||||
|
||||
## Conservation of Bits
|
||||
|
||||
What you get is what you assigned.
|
||||
|
||||
### Signed and Unsigned
|
||||
|
||||
- Signed: The most significant bit is the sign bit.
|
||||
- Two's complement: Range is from -2^(w-1) to 2^(w-1) - 1.
|
||||
- Created by `int i = -1;`
|
||||
- Unsigned: The most significant bit is the value bit.
|
||||
- Range is from 0 to 2^w - 1.
|
||||
- Created by `unsigned int i = 1;` or `int i = 1U;`
|
||||
|
||||
During the conversion, the binary representation of the number is the same.
|
||||
|
||||
For example, `-1` in signed is `0b11111111` in signed. and `0b11111111` in signed is `255` in unsigned.
|
||||
|
||||
Any arithmetic operation in signed and unsigned follows the same rules. `0b00000000` is `0` in signed and unsigned. and `0-1=255` in unsigned but `-1` in signed. (The binary representation of `-1` in signed is `0b11111111` and `0b11111111` is `255` in unsigned.)
|
||||
|
||||
### Shift Operations
|
||||
|
||||
- Logical Shift: Shift the bits and fill in the new bits with 0. (used for unsigned numbers)
|
||||
- Arithmetic Shift: Shift the bits and fill in the new bits with the sign bit. (used for signed numbers)
|
||||
|
||||
## Bytes
|
||||
|
||||
### Byte Ordering
|
||||
|
||||
For Example: `0x12345678`
|
||||
|
||||
- Little Endian: The least significant byte is stored at the lowest address.
|
||||
- `0x78` is stored at the lowest address.
|
||||
- Big Endian: The most significant byte is stored at the lowest address.
|
||||
- `0x12` is stored at the lowest address.
|
||||
|
||||
### Representing Strings
|
||||
|
||||
- `char *str = "12345";`
|
||||
|
||||
In memory, it is stored as `0x31 0x32 0x33 0x34 0x35` with terminating null character `0x00`.
|
||||
160
content/Swap/Math4351_L1.md
Normal file
160
content/Swap/Math4351_L1.md
Normal file
@@ -0,0 +1,160 @@
|
||||
# Lecture 1
|
||||
|
||||
## Toy example (RSA encryption)
|
||||
|
||||
$Enc$
|
||||
|
||||
1. Choose a letter, count to number of letters in the alphabet.
|
||||
2. Calculate $s^7$, then divide by 33, take the remainder.
|
||||
3. Send the remainder.
|
||||
|
||||
$Dec: s = r^3 \mod 33$
|
||||
|
||||
To build up such system.
|
||||
|
||||
Step 1: Understanding the arithmetic of remainders.
|
||||
|
||||
## Part 1: Divisibility and prime numbers
|
||||
|
||||
### Divisibility and division algorithm
|
||||
|
||||
Let $a, b\in \mathbb{Z}$, with $b>0$. There are unique integers, $q$ (quotient) and $r$ (remainder), such that $a = bq + r$ and $0 \leq r < b$.
|
||||
|
||||
Example: $31=7\times 4 + 3$
|
||||
|
||||
Proof:
|
||||
|
||||
The quotient and remainder are unique.
|
||||
|
||||
(1) Existence:
|
||||
|
||||
Let $S = \{a - bk \mid k \in \mathbb{Z}, a - bk \geq 0\}$. Choose $r$ to be the smallest non-negative element of $S$. This means $r = a - bq$ for some $q \in \mathbb{Z}$. i.e. $a=bq+r$.
|
||||
|
||||
> New notion: $\triangle FSOC$ means For the sake of contradiction.
|
||||
|
||||
Notice that $r \geq 0$, by contradiction, suppose $r \geq b$, then $r-b \geq 0$ and $r-b \in S$, but $r-b < r$, which contradicts the minimality of $r$.
|
||||
|
||||
Therefore, $r \geq 0$ and $r < b$.
|
||||
|
||||
Example: $a=31, b=7$, $S = \{31-7k \mid k \in \mathbb{Z}, 31-7k \geq 0\}=\{\cdots, -32, -25, -18, -11, -4, 3, 10, 17, 24, 31, \cdots\}$, $r=3$.
|
||||
|
||||
So We choose $q=4$ and $r=3$.
|
||||
|
||||
(2) Uniqueness:
|
||||
|
||||
Suppose we have two pairs $(q, r)$ and $(q', r')$ such that $a = bq + r = bq' + r'$ Suppose $q \neq q'$, without loss of generality, suppose $q > q'$, $q-q' \geq 1$. Then $b(q-q') = r'-r$.
|
||||
|
||||
Since $r'=b(q-q')+r \geq b(q-q') \geq b$, which contradicts that $r' < b$.
|
||||
|
||||
Therefore, $q=q'$ and $r=r'$.
|
||||
|
||||
QED
|
||||
|
||||
#### Definition: Divisibility
|
||||
|
||||
Let $a, b \in \mathbb{Z}$, we say $b$ divides $a$ and write $b \mid a$ if there exists $k\in \mathbb{Z}$ such that $a = bk$.
|
||||
|
||||
Example: $3 \mid 12$ because $12 = 3 \times 4$.
|
||||
|
||||
#### Properties of divisibility
|
||||
|
||||
Let $a, b, c \in \mathbb{Z}$.
|
||||
|
||||
(1) $b \mid a \iff r=0$ in the division algorithm.
|
||||
|
||||
(2) If $a \mid b$ and $b \mid c$, then $a \mid c$.
|
||||
|
||||
(3) If $a \mid b$ and $b \mid a$, then $a = \pm b$.
|
||||
|
||||
(4) If $a \mid b$ and $a \mid c$, then $a \mid bx + cy$ for all $x, y \in \mathbb{Z}$. (We call such $bx+cy$ a linear combination of $b$ and $c$.)
|
||||
|
||||
(5) If $c\neq 0$ and $a \mid b \iff ac \mid bc$.
|
||||
|
||||
Some proof examples:
|
||||
|
||||
(2) Since $a \mid b$ and $b \mid c$, there exist $k, l \in \mathbb{Z}$ such that $b = ak$ and $c = bl$. Then $c = bl = (ak)l = a(kl)$, so $a \mid c$.
|
||||
|
||||
QED
|
||||
|
||||
(3) If $a \mid b$ and $b \mid a$, then there exist $k, l \in \mathbb{Z}$ such that $b = ak$ and $a = bl$. Then $a = bl = (ak)l = a(kl)$, so $a(1-kl) = 0$.
|
||||
|
||||
Case 1: $a=0$, then $b=0$, so $a=b$.
|
||||
|
||||
Case 2: $a \neq 0$, then $1-kl=0$, so $kl=1$. Since $k, l \in \mathbb{Z}$, $k=l=\pm 1$, so $a = \pm b$.
|
||||
|
||||
QED
|
||||
|
||||
#### Definition: Divisor
|
||||
|
||||
Let $a\in \mathbb{Z}$, we define $D(a) = \{d\in \mathbb{Z} \mid d \mid a\}$.
|
||||
|
||||
**Note that $D(0) = \mathbb{Z}$.**
|
||||
|
||||
Example: $D(12) = \{\pm 1, \pm 2, \pm 3, \pm 4, \pm 6, \pm 12\}$.
|
||||
|
||||
#### Definition: Greatest common divisor
|
||||
|
||||
Let $a, b \in \mathbb{Z}$, where $a,b$ not both zero, we define the greatest common divisor of $a$ and $b$ to be the largest element in $D(a) \cap D(b)$. It is denoted by $(a,b)$.
|
||||
|
||||
> Terrible, I really hate this notation. But professor said it's unlikely to be confused with the interval $(a,b)$ since they don't show up in the same context usually.
|
||||
|
||||
Example:
|
||||
|
||||
$(12, 18) = 6$.
|
||||
|
||||
**Note that $(0,0)$ is not defined. (there is no largest element in $D(0) \cap D(0)$.)**
|
||||
|
||||
but it is okay that one of $a, b$ is zero. For example, $(0, 18) = 18$.
|
||||
|
||||
$(n,n) = |n|$ for all $n \in \mathbb{Z}$.
|
||||
|
||||
In general, if $(a,b)=0$ we say $a$ and $b$ are relatively prime, or coprime.
|
||||
|
||||
$\forall a, b \in \mathbb{Z}$, $(a,b) \geq 1$.
|
||||
|
||||
#### Theorem for calculating gcd
|
||||
|
||||
Let $a, b \in \mathbb{Z}$, with $b\neq 0$, then for any $k\in \mathbb{Z}$, $(a,b) = (b,a-bk)$.
|
||||
|
||||
Example: $(12, 18) = (18, 12-18) = (18, -6) = 6$.
|
||||
|
||||
$(938,210)=(210,938-210\times 4)=(210,938-840)=(210,98)$.
|
||||
|
||||
Proof:
|
||||
|
||||
We will prove that $D(a) \cap D(b) = D(b) \cap D(a-bk)$.
|
||||
|
||||
(1) $D(a) \cap D(b) \subseteq D(b) \cap D(a-bk)$:
|
||||
|
||||
Let $d \in D(a) \cap D(b)$, then $d \mid a$ and $d \mid b$.
|
||||
|
||||
By property of divisibility (4), If $a\mid b$ and $b\mid c$, then for all $x,y\in \mathbb{Z}$, $a\mid bx+cy$.
|
||||
|
||||
So $d\mid a+b\cdot (-k) = a-bk$.
|
||||
|
||||
Therefore, $d \in D(b) \cap D(a-bk)$.
|
||||
|
||||
(2) $D(b) \cap D(a-bk) \subseteq D(a) \cap D(b)$:
|
||||
|
||||
Let $d \in D(b) \cap D(a-bk)$, then $d \mid b$ and $d \mid a-bk$.
|
||||
|
||||
By property of divisibility (4), $d \mid bk + (a-bk) = a$.
|
||||
|
||||
Therefore, $d \in D(a) \cap D(b)$.
|
||||
|
||||
QED
|
||||
|
||||
This theorem gives rise to the Euclidean algorithm which is a efficient way to compute the greatest common divisor of two integers. $2\Theta(\log n)+1=O(\log n)$ ([Proof in CSE 442T Lecture 7](https://notenextra.trance-0.com/CSE442T/CSE442T_L7#euclidean-algorithm)).
|
||||
|
||||
### Euclidean algorithm
|
||||
|
||||
We will skip this part, it's already the third time we see this algorithm in wustl.
|
||||
|
||||
#### Theorem: Euclidean algorithm returns correct gcd
|
||||
|
||||
Let $a>b>0$, be integers. Using the Euclidean algorithm, we can find $b>r_0>r_1>r_2>\cdots>r_n$ such that $a=bq_0+r_0, b=r_0q_1+r_1, \cdots, r_{n-1}=r_nq_{n+1}+r_{n+1}, r_n=0$. Then $(a,b)=r_n$.
|
||||
|
||||
Proof:
|
||||
|
||||
(a) This process terminates. $b>r_0>r_1>r_2>\cdots>r_n$ is a strictly decreasing sequence of positive integers, so it must terminate.
|
||||
|
||||
Reference in New Issue
Block a user