mirror of
https://github.com/RobTillaart/Arduino.git
synced 2024-10-03 18:09:02 -04:00
0.4.1 printHelpers
This commit is contained in:
parent
d70def77dc
commit
669feb85f8
@ -6,6 +6,17 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
||||
and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
|
||||
## [0.4.1] - 2023-07-13
|
||||
- fix #16 signed/unsigned warning
|
||||
- update example **print_toRoman.ino** to print 1..5000
|
||||
- update example **print_sci.ino** when double = 8 bytes.
|
||||
- update readme.md
|
||||
- fix description range **toBytes()**
|
||||
- change return type of **size_t sci(Stream, value, decimals)**
|
||||
- add **printInch(inch, step)** e.g 7 7/16
|
||||
- add **printFeet(feet)**
|
||||
|
||||
|
||||
## [0.4.0] - 2023-01-28
|
||||
- bump version number as fix in 0.3.1 was serious
|
||||
- add **toRoman()**
|
||||
|
@ -24,9 +24,13 @@ data in a way not possible in the standard print library of the Arduino.
|
||||
- **hex()** generates hexadecimal output with leading zeros up to **uint64_t**.
|
||||
- **bin()** generates binary output with leading zeros up to **uint64_t**.
|
||||
- **toRoman()** generates a ROMAN representation of a (positive) number.
|
||||
- **printInch(float inch, uint16_t step)** experimental.
|
||||
- **printFeet(float feet)** experimental.
|
||||
|
||||
Details, see below.
|
||||
|
||||
If a (generic) print format is missing, please open an issue.
|
||||
|
||||
|
||||
#### Thread safety
|
||||
|
||||
@ -48,31 +52,36 @@ The following functions are implemented:
|
||||
|
||||
#### print64()
|
||||
|
||||
- **char \* print64(int64_t value, uint8_t base)** converts a 64 bit integer
|
||||
- **char \* print64(int64_t value, uint8_t base = 10)** converts a 64 bit integer
|
||||
number to a char array.
|
||||
The plus sign is not printed, neither are leading zero's.
|
||||
Base 10 (DEC) and 16 (HEX) are supported and other bases up to 36 can be used.
|
||||
Default base == 10 == decimal.
|
||||
Note that negative numbers will always get a minus sign for any base.
|
||||
Cast the number to uint64_t to suppress the sign.
|
||||
|
||||
- **char \* print64(uint64_t value, uint8_t base)** converts a unsigned 64 bit
|
||||
- **char \* print64(uint64_t value, uint8_t base = 10)** converts a unsigned 64 bit
|
||||
int number to a char array.
|
||||
No sign is printed, neither are leading zero's.
|
||||
Base 10 (DEC) and 16 (HEX) are supported and bases up to 36 can be used.
|
||||
Default base == 10 == decimal.
|
||||
|
||||
|
||||
#### sci() eng()
|
||||
|
||||
- **char \* sci(double value, uint8_t decimals)** converts a float or double to a
|
||||
char array.
|
||||
E.g. **print(sci(f, 4))** ==> results in "6.7407E+21".
|
||||
E.g. **print(sci(f, 4))** ==> results in **"6.7407E+21"**.
|
||||
The existing Arduino print library only supports printing of floats and
|
||||
doubles up to about 4E9 while the range of floats goes up to ~1E38.
|
||||
The smallest float values will often be printed as 0.00 while floats
|
||||
support down to about 1E-38 (subnormal even to 1E-45).
|
||||
Existing (AVR) library functions **dtostrf()** has no scientific notation
|
||||
and **dtostre()** is limited to 7 decimals. These latter two are faster.
|
||||
Values printed with **sci()** do look pretty in column output.
|
||||
Values printed with **sci()** do look often pretty in column output.
|
||||
|
||||
- **size_t sci(Stream &str, double value, uint8_t decimals)** as above.
|
||||
Prints directly to a stream, returning bytes printed.
|
||||
|
||||
- **char \* eng(double value, uint8_t decimals)** converts a float or double to a
|
||||
char array.
|
||||
@ -80,26 +89,27 @@ E.g. print(eng(f, 4)) ==> results in "6.7407E+21".
|
||||
Note the exponent created by **eng()** is always a multiple of 3.
|
||||
Values printed with **eng()** do not always look pretty in column output.
|
||||
This is due to the exponent power of 3. However its output translates easy to
|
||||
thousands, millions etc which are powers of 3.
|
||||
thousands, millions, billions, and millis, micros, nano etc which are powers of 3.
|
||||
|
||||
- **char \* scieng(double value, uint8_t decimals, uint8_t exponentMultiple)** converts a
|
||||
float or double to a char array.
|
||||
**sci()** and **eng()** use the same underlying function called **scieng()**
|
||||
as the initial code for converting was almost identical.
|
||||
Although not intended to be used directly, one may use it.
|
||||
Although not intended to be used directly, feel free to use it.
|
||||
The last parameter **exponentMultiple** defines where the exponent is a multiple of.
|
||||
For the **sci()** function this is 1, for the **eng()** function this is 3.
|
||||
The **scieng()** function works for multiples from 1..9 for the exponent.
|
||||
The usability of other values than 1 and 3 are not known.
|
||||
Personally I like the multiple of 2 as I get 2 orders of magnitude in the
|
||||
mantissa.
|
||||
mantissa. This is e.g. useful for temperature Celsius or percentages.
|
||||
|
||||
|
||||
#### toBytes()
|
||||
|
||||
- **char \* toBytes(double value, uint8_t decimals = 2)** makes from a big number
|
||||
representing an amount of bytes a shorter string usable for displaying.
|
||||
The number of decimals is max 3
|
||||
- **char \* toBytes(double value, uint8_t decimals = 2)** converts a big number
|
||||
representing an amount of bytes to a shorter string usable for displaying.
|
||||
The string uses official extensions.
|
||||
The number of decimals is max 3:
|
||||
Example 3.292.528 ==> "3.140 MB"
|
||||
|
||||
Value ranges supported are in steps of powers of 1024.
|
||||
@ -107,12 +117,13 @@ These will all be shown in UPPERCASE so KB, MB etc.
|
||||
|
||||
| Unit | abbrev. | size | Unit | abbrev. | size |
|
||||
|:-----------:|:---------:|:--------:|:------------:|:---------:|:--------:|
|
||||
| kilobytes | KB | 1024 | zettabytes | KB | 1024^7 |
|
||||
| megabytes | MB | 1024^2 | yottabytes | MB | 1024^8 |
|
||||
| gigabytes | GB | 1024^3 | xonaytes | GB | 1024^9 |
|
||||
| terabytes | TB | 1024^4 | wekabytes | TB | 1024^10 |
|
||||
| petabytes | PB | 1024^5 | vundabytes | PB | 1024^11 |
|
||||
| exabytes | EB | 1024^6 | udabytes | EB | 1024^12 |
|
||||
| bytes | B | 1024^0 | | | |
|
||||
| kilobytes | KB | 1024^1 | zettabytes | ZB | 1024^7 |
|
||||
| megabytes | MB | 1024^2 | yottabytes | YB | 1024^8 |
|
||||
| gigabytes | GB | 1024^3 | xonaytes | XB | 1024^9 |
|
||||
| terabytes | TB | 1024^4 | wekabytes | WB | 1024^10 |
|
||||
| petabytes | PB | 1024^5 | vundabytes | VB | 1024^11 |
|
||||
| exabytes | EB | 1024^6 | udabytes | UB | 1024^12 |
|
||||
|
||||
|
||||
Treda Byte is shortened as "TDB" and uses 2 chars to indicate the magnitude.
|
||||
@ -123,7 +134,7 @@ Should be big enough for some time.
|
||||
Note: max uint64_t 2^64 is in the order of exa or zetta bytes.
|
||||
|
||||
To have some support for the really big sizes the code uses lowercase for the next 8 levels:
|
||||
treda sorta rinta quexa pepta ocha nena minga luma (1024\^21 ~~ 10\^63)
|
||||
treda sorta rinta quexa pepta ocha nena minga luma (1024\^13 ~~ 1024\^21)
|
||||
To enable this patch the function in the **printHelpers.cpp** file.
|
||||
|
||||
|
||||
@ -132,7 +143,7 @@ To enable this patch the function in the **printHelpers.cpp** file.
|
||||
The default print() function of Arduino does not have leading zero's
|
||||
for **HEX** and **BIN**.
|
||||
This often causes a "broken" layout especially if one wants to print
|
||||
in columns or so.
|
||||
the output in columns or so.
|
||||
|
||||
To solve this the following functions are added that will generate a
|
||||
constant length char array.
|
||||
@ -151,6 +162,10 @@ Note: Data types not supported, must be cast to an supported type.
|
||||
Note: There is overlap between **hex(value)** and **print64(value, HEX)**.
|
||||
The latter does not produce the leading zero's or fixed length output.
|
||||
|
||||
Note: hex() does not print hex indicator like "0x" or "H" in front.
|
||||
|
||||
Note: bin() does not print bin indicator like "b" at the end.
|
||||
|
||||
|
||||
#### toRoman()
|
||||
|
||||
@ -188,6 +203,18 @@ Notes:
|
||||
"official" and extended numbers.
|
||||
- The number 4 is often written as IIII on clocks with Roman digits,
|
||||
although IV would be (more?) correct and therefore IV is used.
|
||||
The reason for IIII is that it is opposite of VIII giving a visual balance.
|
||||
|
||||
|
||||
#### Distance feet inch
|
||||
|
||||
Experimental 0.4.1
|
||||
|
||||
- **char \* printInch(float inch, uint16_t step = 16)** prints a float inch distance default in sixteenth ```a b/16```.
|
||||
The parameter step must be a power of 2 == 2, 4, 8, 16, 32, 64, 128.
|
||||
|
||||
- **char \* printFeet(float feet)** prints a float feet distance as
|
||||
``` a'b"``` e.g. 4.5 feet prints as ```4'6"```
|
||||
|
||||
|
||||
## Shared print buffer
|
||||
@ -230,6 +257,7 @@ When functions are added, the recommended minimum size might increase.
|
||||
|
||||
- documentation
|
||||
- improve readability of the code
|
||||
- em ==> exponentFactor?
|
||||
|
||||
|
||||
#### Could
|
||||
@ -239,15 +267,13 @@ When functions are added, the recommended minimum size might increase.
|
||||
- investigate thread safe version
|
||||
- pass char buffer as parameter (breaking)
|
||||
- could be the log10 pow version?
|
||||
- investigate distance print helpers.
|
||||
- feet(float cm) as 3'2" or 3-7/8 feet
|
||||
- inch(float cm) as 32"
|
||||
- yards(float meter),
|
||||
- miles(float kilometre)
|
||||
- optimize **char \* hex(uint8_t / uint16_t ...)**
|
||||
- make this library a .h file only?
|
||||
|
||||
|
||||
#### Wont
|
||||
|
||||
- add **oct()** along BIN, HEX
|
||||
- add **float()** as Arduino limits floats to "MAXLONG" by code.
|
||||
- use dtostrf() - is that portable?
|
||||
- use sci() or eng()
|
||||
@ -260,3 +286,4 @@ When functions are added, the recommended minimum size might increase.
|
||||
- **sci()** and **eng()**.
|
||||
- investigate sci() version based upon use of log()
|
||||
- done => see examples.
|
||||
|
||||
|
@ -0,0 +1,40 @@
|
||||
// FILE: print_inch_feet.ino
|
||||
// AUTHOR: Rob Tillaart
|
||||
// PURPOSE: demo program distance functions
|
||||
|
||||
|
||||
#include "printHelpers.h"
|
||||
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
Serial.println(__FILE__);
|
||||
Serial.print("PRINTHELPERS_VERSION: ");
|
||||
Serial.println(PRINTHELPERS_VERSION);
|
||||
|
||||
// test some random values
|
||||
for (float inch = 0; inch < 100; inch += 5.43)
|
||||
{
|
||||
Serial.print(inch, 2);
|
||||
Serial.print('\t');
|
||||
Serial.println(printInch(inch, 32));
|
||||
}
|
||||
Serial.println();
|
||||
|
||||
|
||||
for (float feet = 0; feet < 100; feet += 5.43)
|
||||
{
|
||||
Serial.print(feet, 2);
|
||||
Serial.print('\t');
|
||||
Serial.println(printFeet(feet));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// -- END OF FILE --
|
@ -0,0 +1,60 @@
|
||||
|
||||
Arduino UNO
|
||||
IDE 1.8.19
|
||||
|
||||
print_performance.ino
|
||||
PRINTHELPERS_VERSION: 0.4.1
|
||||
4
|
||||
4
|
||||
|
||||
Mass moon M = 7.34767309E+20
|
||||
Speed of light c = 2.99792458E+8
|
||||
Print E = Mc^2 = 6.6037592413026551656653076E+37
|
||||
|
||||
|
||||
|
||||
print64
|
||||
TIME: 22476
|
||||
660375892052148224
|
||||
|
||||
SCI
|
||||
TIME: 9232
|
||||
6.603759288787841E+17
|
||||
|
||||
ENG
|
||||
TIME: 7388
|
||||
660.375976562500000E+15
|
||||
|
||||
dtostrf
|
||||
TIME: 2468
|
||||
660375890000000000.000000000000000
|
||||
|
||||
dtostre
|
||||
TIME: 1452
|
||||
6.6037589e+17
|
||||
|
||||
toBytes
|
||||
TIME: 1980
|
||||
586.531 PB
|
||||
|
||||
hex
|
||||
TIME: 1304
|
||||
092A206000000000
|
||||
|
||||
bin
|
||||
TIME: 2464
|
||||
0000100100101010001000000110000000000000000000000000000000000000
|
||||
|
||||
toRoman
|
||||
TIME: 89352
|
||||
CMXCIX
|
||||
|
||||
printInch
|
||||
TIME: 177308
|
||||
999 0/16
|
||||
|
||||
printFeet
|
||||
TIME: 137448
|
||||
999"0'
|
||||
|
||||
done...
|
@ -162,6 +162,36 @@ void setup()
|
||||
Serial.println(b);
|
||||
delay(100);
|
||||
|
||||
|
||||
Serial.println();
|
||||
Serial.println("printInch");
|
||||
delay(100);
|
||||
start = micros();
|
||||
for (int i = 0; i < 1000; i++)
|
||||
{
|
||||
b = printInch(i);
|
||||
}
|
||||
stop = micros();
|
||||
Serial.print("TIME: ");
|
||||
Serial.println(stop - start);
|
||||
Serial.println(b);
|
||||
delay(100);
|
||||
|
||||
|
||||
Serial.println();
|
||||
Serial.println("printFeet");
|
||||
delay(100);
|
||||
start = micros();
|
||||
for (int i = 0; i < 1000; i++)
|
||||
{
|
||||
b = printFeet(i);
|
||||
}
|
||||
stop = micros();
|
||||
Serial.print("TIME: ");
|
||||
Serial.println(stop - start);
|
||||
Serial.println(b);
|
||||
delay(100);
|
||||
|
||||
Serial.println();
|
||||
Serial.println("done...");
|
||||
}
|
||||
|
@ -67,6 +67,16 @@ void setup()
|
||||
Serial.print("\t");
|
||||
Serial.println(scieng(E, 8, em));
|
||||
}
|
||||
Serial.println();
|
||||
|
||||
if (sizeof(double) == 8)
|
||||
{
|
||||
while (E < 1e308)
|
||||
{
|
||||
E *= 1e5;
|
||||
Serial.println(sci(E, 16));
|
||||
}
|
||||
}
|
||||
|
||||
Serial.println("\ndone...");
|
||||
}
|
||||
|
@ -45,6 +45,14 @@ void setup()
|
||||
Serial.println(b);
|
||||
delay(1000);
|
||||
|
||||
// for (int i = 1; i <= 5000; i++)
|
||||
// {
|
||||
// Serial.print(i);
|
||||
// Serial.print('\t');
|
||||
// Serial.println(toRoman(i));
|
||||
// }
|
||||
// delay(1000);
|
||||
|
||||
Serial.println("\ndone...");
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "printHelpers",
|
||||
"keywords": "Convert,int64,uint64,print,scientific,notation,toBytes,HEX,BIN,Roman",
|
||||
"description": "Arduino library to help printing. int64 and uint64 support base 10 (DEC) and 16 (HEX). Scientific notation of floats.",
|
||||
"description": "Arduino library to help printing. int64 and uint64 support base 10 (DEC) and 16 (HEX). Scientific notation of floats. Feet and inch.",
|
||||
"authors":
|
||||
[
|
||||
{
|
||||
@ -15,7 +15,7 @@
|
||||
"type": "git",
|
||||
"url": "https://github.com/RobTillaart/printHelpers"
|
||||
},
|
||||
"version": "0.4.0",
|
||||
"version": "0.4.1",
|
||||
"license": "MIT",
|
||||
"frameworks": "arduino",
|
||||
"platforms": "*",
|
||||
|
@ -1,9 +1,9 @@
|
||||
name=printHelpers
|
||||
version=0.4.0
|
||||
version=0.4.1
|
||||
author=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
sentence=Arduino library to help formatting data for printing. 64 bit integers (base 10 and 16). Engineering and scientific notation.
|
||||
paragraph=Supports 64 bit integers (base 10 and 16). Engineering and scientific notation. toBytes() for KB MB, HEX and BIN, Roman numbers.
|
||||
paragraph=Supports 64 bit integers (base 10 and 16). Engineering and scientific notation. toBytes() for KB MB, HEX and BIN, Roman numbers. Feet and inch.
|
||||
category=Other
|
||||
url=https://github.com/RobTillaart/printHelpers
|
||||
architectures=*
|
||||
|
@ -2,7 +2,7 @@
|
||||
// FILE: printHelpers.cpp
|
||||
// AUTHOR: Rob Tillaart
|
||||
// DATE: 2018-01-21
|
||||
// VERSION: 0.4.0
|
||||
// VERSION: 0.4.1
|
||||
// PUPROSE: Arduino library to help formatting for printing.
|
||||
// URL: https://github.com/RobTillaart/printHelpers
|
||||
|
||||
@ -134,7 +134,7 @@ char * print64(uint64_t value, uint8_t base)
|
||||
|
||||
// typical buffer size for 8 byte double is 22 bytes
|
||||
// 15 bytes mantissa, sign dot E-xxx
|
||||
// em = exponentMultiple.
|
||||
// em = exponentMultiple.
|
||||
char * scieng(double value, uint8_t decimals, uint8_t em)
|
||||
{
|
||||
char * buffer = __printbuffer;
|
||||
@ -258,9 +258,9 @@ char * sci(double value, uint8_t decimals)
|
||||
}
|
||||
|
||||
|
||||
void sci(Stream &str, double value, uint8_t decimals)
|
||||
size_t sci(Stream &str, double value, uint8_t decimals)
|
||||
{
|
||||
str.print(sci(value, decimals));
|
||||
return str.print(sci(value, decimals));
|
||||
}
|
||||
|
||||
|
||||
@ -277,7 +277,8 @@ void sci(Stream &str, double value, uint8_t decimals)
|
||||
// so code wise difficult and as it is seldom used, support stops there.
|
||||
//
|
||||
// To have some support the code uses lowercase for the next 8 levels
|
||||
// treda sorta rinta quexa pepta ocha nena minga luma (1024 ^21 ~~ 10^63)
|
||||
// treda sorta rinta quexa pepta ocha nena minga luma (1024 ^13 ~~ 1024^21)
|
||||
//
|
||||
char * toBytes(double value, uint8_t decimals)
|
||||
{
|
||||
char * buffer = __printbuffer;
|
||||
@ -417,7 +418,6 @@ char * bin(uint8_t value, uint8_t digits) { return bin((uint32_t) value, digits
|
||||
//
|
||||
// toRoman
|
||||
//
|
||||
// experimental
|
||||
// extended with 10K units generated with the same but lower case chars.
|
||||
// would expect a special char for 5000?
|
||||
// need investigation.
|
||||
@ -455,7 +455,7 @@ char * toRoman(uint32_t value)
|
||||
idx++;
|
||||
}
|
||||
// set chars to lower
|
||||
for (int i = 0; i < strlen(buffer); i++)
|
||||
for (uint16_t i = 0; i < strlen(buffer); i++)
|
||||
{
|
||||
buffer[i] = tolower(buffer[i]);
|
||||
}
|
||||
@ -476,6 +476,61 @@ char * toRoman(uint32_t value)
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Distances
|
||||
// Experimental
|
||||
|
||||
// step == 2,4,8,16,32,64,128,256 (default 16)
|
||||
char * printInch(float inch, uint16_t step)
|
||||
{
|
||||
char * buffer = __printbuffer;
|
||||
uint32_t whole = inch;
|
||||
uint8_t num = round((inch - whole) * step);
|
||||
if (num == step)
|
||||
{
|
||||
whole++;
|
||||
num = 0;
|
||||
}
|
||||
uint8_t den = step;
|
||||
// optional reduce
|
||||
while ((num > 0) && ((num & 1) == 0))
|
||||
{
|
||||
num >>= 1;
|
||||
den >>= 1;
|
||||
}
|
||||
|
||||
#if defined(ESP32)
|
||||
// ESP32 does not support %ld or ltoa()
|
||||
sprintf(buffer, "%d %d/%d", whole, num, den);
|
||||
#else
|
||||
sprintf(buffer, "%ld %d/%d", whole, num, den);
|
||||
#endif
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
||||
char * printFeet(float feet)
|
||||
{
|
||||
char * buffer = __printbuffer;
|
||||
uint32_t ft = feet;
|
||||
uint8_t inch = round((feet - ft) * 12);
|
||||
if (inch == 12)
|
||||
{
|
||||
ft++;
|
||||
inch = 0;
|
||||
}
|
||||
#if defined(ESP32)
|
||||
// ESP32 does not support %ld or ltoa()
|
||||
sprintf(buffer, "%d\"%d\'", ft, inch);
|
||||
#else
|
||||
sprintf(buffer, "%d\"%d\'", ft, inch);
|
||||
#endif
|
||||
sprintf(buffer, "%d\"%d\'", ft, inch);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
||||
// -- END OF FILE --
|
||||
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
// FILE: printHelpers.h
|
||||
// AUTHOR: Rob Tillaart
|
||||
// DATE: 2018-01-21
|
||||
// VERSION: 0.4.0
|
||||
// VERSION: 0.4.1
|
||||
// PUPROSE: Arduino library to help formatting for printing.
|
||||
// URL: https://github.com/RobTillaart/printHelpers
|
||||
|
||||
@ -12,7 +12,7 @@
|
||||
#include "stdlib.h"
|
||||
|
||||
|
||||
#define PRINTHELPERS_VERSION (F("0.4.0"))
|
||||
#define PRINTHELPERS_VERSION (F("0.4.1"))
|
||||
|
||||
|
||||
// global buffer used by all functions so no static buffer in every function
|
||||
@ -55,7 +55,7 @@ char * eng(double value, uint8_t decimals); // em == 3
|
||||
|
||||
char * sci(double value, uint8_t decimals); // em == 1
|
||||
|
||||
void sci(Stream &str, double value, uint8_t decimals);
|
||||
size_t sci(Stream &str, double value, uint8_t decimals);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
@ -103,9 +103,19 @@ char * bin(uint8_t value, uint8_t digits = 8);
|
||||
// toRoman()
|
||||
//
|
||||
// value should be in range 1..9999
|
||||
// values 10K-100M are experimental (see readme.md)
|
||||
// values 10K-100M are experimental in lower case (see readme.md)
|
||||
char * toRoman(uint32_t value);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Distances
|
||||
// Experimental
|
||||
//
|
||||
// step == 2,4,8,16,32,64,128,256 (default 16)
|
||||
char * printInch(float inch, uint16_t step = 16);
|
||||
char * printFeet(float feet);
|
||||
|
||||
|
||||
// -- END OF FILE --
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user