ICU-2552 number of zeros
X-SVN-Rev: 13520
This commit is contained in:
parent
ed3bced160
commit
3f812b4d59
@ -104,6 +104,8 @@ UOBJECT_DEFINE_RTTI_IMPLEMENTATION(DecimalFormat)
|
||||
const int32_t DecimalFormat::kDoubleIntegerDigits = 309;
|
||||
const int32_t DecimalFormat::kDoubleFractionDigits = 340;
|
||||
|
||||
const int32_t DecimalFormat::kMaxScientificIntegerDigits = 8;
|
||||
|
||||
/**
|
||||
* These are the tags we expect to see in normal resource bundle files associated
|
||||
* with a locale.
|
||||
@ -612,15 +614,12 @@ DecimalFormat::format(int32_t number,
|
||||
|| number < (INT32_MIN / fMultiplier))))
|
||||
{
|
||||
digits.set(((double)number) * fMultiplier,
|
||||
fUseExponentialNotation ?
|
||||
getMinimumIntegerDigits() + getMaximumFractionDigits() : 0,
|
||||
precision(FALSE),
|
||||
!fUseExponentialNotation);
|
||||
}
|
||||
else
|
||||
{
|
||||
digits.set(number * fMultiplier,
|
||||
fUseExponentialNotation ?
|
||||
getMinimumIntegerDigits() + getMaximumFractionDigits() : 0);
|
||||
digits.set(number * fMultiplier, precision(TRUE));
|
||||
}
|
||||
|
||||
return subformat(appendTo, fieldPosition, digits, TRUE);
|
||||
@ -704,9 +703,7 @@ DecimalFormat::format( double number,
|
||||
DigitList digits;
|
||||
|
||||
// This detects negativity too.
|
||||
digits.set(number, fUseExponentialNotation ?
|
||||
getMinimumIntegerDigits() + getMaximumFractionDigits() :
|
||||
getMaximumFractionDigits(),
|
||||
digits.set(number, precision(FALSE),
|
||||
!fUseExponentialNotation);
|
||||
|
||||
return subformat(appendTo, fieldPosition, digits, FALSE);
|
||||
@ -802,6 +799,15 @@ DecimalFormat::subformat(UnicodeString& appendTo,
|
||||
}
|
||||
int32_t maxIntDig = getMaximumIntegerDigits();
|
||||
int32_t minIntDig = getMinimumIntegerDigits();
|
||||
if (fUseExponentialNotation && maxIntDig > kMaxScientificIntegerDigits) {
|
||||
maxIntDig = 1;
|
||||
if (maxIntDig < minIntDig) {
|
||||
maxIntDig = minIntDig;
|
||||
}
|
||||
}
|
||||
if (fUseExponentialNotation && maxIntDig > minIntDig) {
|
||||
minIntDig = 1;
|
||||
}
|
||||
|
||||
/* Per bug 4147706, DecimalFormat must respect the sign of numbers which
|
||||
* format as zero. This allows sensible computations and preserves
|
||||
@ -926,8 +932,14 @@ DecimalFormat::subformat(UnicodeString& appendTo,
|
||||
|
||||
DigitList expDigits;
|
||||
expDigits.set(exponent);
|
||||
for (i=expDigits.fDecimalAt; i<fMinExponentDigits; ++i)
|
||||
appendTo += (zero);
|
||||
{
|
||||
int expDig = fMinExponentDigits;
|
||||
if (fUseExponentialNotation && expDig < 1) {
|
||||
expDig = 1;
|
||||
}
|
||||
for (i=expDigits.fDecimalAt; i<expDig; ++i)
|
||||
appendTo += (zero);
|
||||
}
|
||||
for (i=0; i<expDigits.fDecimalAt; ++i)
|
||||
{
|
||||
UChar32 c = (UChar32)((i < expDigits.fCount) ?
|
||||
@ -2091,9 +2103,6 @@ UBool DecimalFormat::isScientificNotation() {
|
||||
*/
|
||||
void DecimalFormat::setScientificNotation(UBool useScientific) {
|
||||
fUseExponentialNotation = useScientific;
|
||||
if (fUseExponentialNotation && fMinExponentDigits < 1) {
|
||||
fMinExponentDigits = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2619,9 +2628,15 @@ DecimalFormat::toPattern(UnicodeString& result, UBool localized) const
|
||||
if (g > 0 && fGroupingSize2 > 0 && fGroupingSize2 != fGroupingSize) {
|
||||
g += fGroupingSize2;
|
||||
}
|
||||
int32_t maxIntDig = fUseExponentialNotation ? getMaximumIntegerDigits() :
|
||||
(uprv_max(uprv_max(g, getMinimumIntegerDigits()),
|
||||
roundingDecimalPos) + 1);
|
||||
int maxIntDig = getMaximumIntegerDigits();
|
||||
if (fUseExponentialNotation) {
|
||||
if (maxIntDig > kMaxScientificIntegerDigits) {
|
||||
maxIntDig = 1;
|
||||
}
|
||||
} else {
|
||||
maxIntDig = uprv_max(uprv_max(g, getMinimumIntegerDigits()),
|
||||
roundingDecimalPos) + 1;
|
||||
}
|
||||
for (i = maxIntDig; i > 0; --i) {
|
||||
if (!fUseExponentialNotation && i<maxIntDig &&
|
||||
isGroupingPosition(i)) {
|
||||
@ -3463,6 +3478,13 @@ void DecimalFormat::setCurrency(const UChar* theCurrency) {
|
||||
}
|
||||
}
|
||||
|
||||
int32_t
|
||||
DecimalFormat::precision(UBool isIntegral) const {
|
||||
return fUseExponentialNotation
|
||||
? getMinimumIntegerDigits() + getMaximumFractionDigits()
|
||||
: (isIntegral ? 0 : getMaximumFractionDigits());
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
||||
#endif /* #if !UCONFIG_NO_FORMATTING */
|
||||
|
@ -752,7 +752,11 @@ public:
|
||||
virtual UBool isScientificNotation(void);
|
||||
|
||||
/**
|
||||
* Set whether or not scientific notation is used.
|
||||
* Set whether or not scientific notation is used. When scientific notation
|
||||
* is used, the effective maximum number of integer digits is <= 8. If the
|
||||
* maximum number of integer digits is set to more than 8, the effective
|
||||
* maximum will be 1. This allows this call to generate a 'default' scientific
|
||||
* number format without additional changes.
|
||||
* @param useScientific TRUE if this object formats and parses scientific
|
||||
* notation
|
||||
* @see #isScientificNotation
|
||||
@ -1106,6 +1110,8 @@ public:
|
||||
private:
|
||||
DecimalFormat(); // default constructor not implemented
|
||||
|
||||
int32_t precision(UBool isIntegral) const;
|
||||
|
||||
/**
|
||||
* Do real work of constructing a new DecimalFormat.
|
||||
*/
|
||||
@ -1294,6 +1300,17 @@ protected:
|
||||
* @draft ICU 2.4
|
||||
*/
|
||||
static const int32_t kDoubleFractionDigits;
|
||||
|
||||
/**
|
||||
* When someone turns on scientific mode, we assume that more than this
|
||||
* number of digits is due to flipping from some other mode that didn't
|
||||
* restrict the maximum, and so we force 1 integer digit. We don't bother
|
||||
* to track and see if someone is using exponential notation with more than
|
||||
* this number, it wouldn't make sense anyway, and this is just to make sure
|
||||
* that someone turning on scientific mode with default settings doesn't
|
||||
* end up with lots of zeroes.
|
||||
*/
|
||||
static const int32_t kMaxScientificIntegerDigits;
|
||||
};
|
||||
|
||||
inline UnicodeString&
|
||||
|
@ -61,6 +61,9 @@ void NumberFormatTest::runIndexedTest( int32_t index, UBool exec, const char* &n
|
||||
CASE(20,TestSymbolsWithBadLocale);
|
||||
CASE(21,TestAdoptDecimalFormatSymbols);
|
||||
|
||||
CASE(22,TestScientific2);
|
||||
CASE(23,TestScientificGrouping);
|
||||
|
||||
default: name = ""; break;
|
||||
}
|
||||
}
|
||||
@ -146,7 +149,7 @@ NumberFormatTest::TestDigitList(void)
|
||||
list1.append('1');
|
||||
list1.fDecimalAt = 1;
|
||||
DigitList list2;
|
||||
list2.set(1);
|
||||
list2.set((int32_t)1);
|
||||
if (list1 != list2) {
|
||||
errln("digitlist append, operator!= or set failed ");
|
||||
}
|
||||
@ -334,6 +337,37 @@ NumberFormatTest::TestExponential(void)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
NumberFormatTest::TestScientific2() {
|
||||
// jb 2552
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
DecimalFormat* fmt = (DecimalFormat*)NumberFormat::createCurrencyInstance("en_US", status);
|
||||
if (U_SUCCESS(status)) {
|
||||
double num = 12.34;
|
||||
expect(*fmt, num, "$12.34");
|
||||
fmt->setScientificNotation(TRUE);
|
||||
expect(*fmt, num, "$1.23E1");
|
||||
fmt->setScientificNotation(FALSE);
|
||||
expect(*fmt, num, "$12.34");
|
||||
}
|
||||
delete fmt;
|
||||
}
|
||||
|
||||
void
|
||||
NumberFormatTest::TestScientificGrouping() {
|
||||
// jb 2552
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
DecimalFormat fmt("###.##E0",status);
|
||||
if (U_SUCCESS(status)) {
|
||||
expect(fmt, .01234, "12.3E-3");
|
||||
expect(fmt, .1234, "123E-3");
|
||||
expect(fmt, 1.234, "1.23E0");
|
||||
expect(fmt, 12.34, "12.3E0");
|
||||
expect(fmt, 123.4, "123E0");
|
||||
expect(fmt, 1234., "1.23E3");
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------
|
||||
|
||||
// Test the handling of quotes
|
||||
|
@ -75,6 +75,10 @@ class NumberFormatTest: public CalendarTimeZoneTest {
|
||||
|
||||
void TestScientific(void);
|
||||
|
||||
void TestScientific2(void);
|
||||
|
||||
void TestScientificGrouping(void);
|
||||
|
||||
void TestSurrogateSupport(void);
|
||||
|
||||
/**
|
||||
|
@ -4,8 +4,8 @@
|
||||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/dev/test/format/NumberFormatTest.java,v $
|
||||
* $Date: 2003/06/11 18:49:38 $
|
||||
* $Revision: 1.19 $
|
||||
* $Date: 2003/10/29 00:20:05 $
|
||||
* $Revision: 1.20 $
|
||||
*
|
||||
*****************************************************************************************
|
||||
*/
|
||||
@ -24,6 +24,7 @@ import com.ibm.icu.util.*;
|
||||
import java.math.BigInteger;
|
||||
import java.text.FieldPosition;
|
||||
import java.text.ParsePosition;
|
||||
import java.text.ParseException;
|
||||
import java.util.Locale;
|
||||
|
||||
public class NumberFormatTest extends com.ibm.icu.dev.test.TestFmwk {
|
||||
@ -173,6 +174,20 @@ public class NumberFormatTest extends com.ibm.icu.dev.test.TestFmwk {
|
||||
errln("FAIL: Expected a'b123");
|
||||
}
|
||||
|
||||
public void TestParseCurrencyTrailingSymbol() {
|
||||
// see sun bug 4709840
|
||||
NumberFormat fmt = NumberFormat.getCurrencyInstance(Locale.GERMANY);
|
||||
float val = 12345.67f;
|
||||
String str = fmt.format(val);
|
||||
logln("val: " + val + " str: " + str);
|
||||
try {
|
||||
Number num = fmt.parse(str);
|
||||
logln("num: " + num);
|
||||
} catch (ParseException e) {
|
||||
errln("parse of '" + str + "' threw exception: " + e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the handling of the currency symbol in patterns.
|
||||
**/
|
||||
@ -734,6 +749,28 @@ public class NumberFormatTest extends com.ibm.icu.dev.test.TestFmwk {
|
||||
}
|
||||
}
|
||||
|
||||
public void TestScientific2() {
|
||||
// jb 2552
|
||||
DecimalFormat fmt = (DecimalFormat)NumberFormat.getCurrencyInstance();
|
||||
Number num = new Double(12.34);
|
||||
expect(fmt, num, "$12.34");
|
||||
fmt.setScientificNotation(true);
|
||||
expect(fmt, num, "$1.23E1");
|
||||
fmt.setScientificNotation(false);
|
||||
expect(fmt, num, "$12.34");
|
||||
}
|
||||
|
||||
public void TestScientificGrouping() {
|
||||
// jb 2552
|
||||
DecimalFormat fmt = new DecimalFormat("###.##E0");
|
||||
expect(fmt, .01234, "12.3E-3");
|
||||
expect(fmt, .1234, "123E-3");
|
||||
expect(fmt, 1.234, "1.23E0");
|
||||
expect(fmt, 12.34, "12.3E0");
|
||||
expect(fmt, 123.4, "123E0");
|
||||
expect(fmt, 1234, "1.23E3");
|
||||
}
|
||||
|
||||
// additional coverage tests
|
||||
|
||||
// sigh, can't have static inner classes, why not?
|
||||
|
@ -5,8 +5,8 @@
|
||||
*******************************************************************************
|
||||
*
|
||||
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/text/DecimalFormat.java,v $
|
||||
* $Date: 2003/09/12 10:31:16 $
|
||||
* $Revision: 1.36 $
|
||||
* $Date: 2003/10/29 00:20:03 $
|
||||
* $Revision: 1.37 $
|
||||
*
|
||||
*****************************************************************************************
|
||||
*/
|
||||
@ -616,11 +616,7 @@ public class DecimalFormat extends NumberFormat {
|
||||
// At this point we are guaranteed a nonnegative finite
|
||||
// number.
|
||||
synchronized(digitList) {
|
||||
digitList.set(number, useExponentialNotation ?
|
||||
getMinimumIntegerDigits() + getMaximumFractionDigits() :
|
||||
getMaximumFractionDigits(),
|
||||
!useExponentialNotation);
|
||||
|
||||
digitList.set(number, precision(false), !useExponentialNotation);
|
||||
return subformat(result, fieldPosition, isNegative, false);
|
||||
}
|
||||
}
|
||||
@ -729,9 +725,7 @@ public class DecimalFormat extends NumberFormat {
|
||||
|
||||
number *= multiplier;
|
||||
synchronized(digitList) {
|
||||
digitList.set(number, useExponentialNotation ?
|
||||
getMinimumIntegerDigits() + getMaximumFractionDigits() : 0);
|
||||
|
||||
digitList.set(number, precision(true));
|
||||
return subformat(result, fieldPosition, isNegative, true);
|
||||
}
|
||||
}
|
||||
@ -756,9 +750,7 @@ public class DecimalFormat extends NumberFormat {
|
||||
// At this point we are guaranteed a nonnegative finite
|
||||
// number.
|
||||
synchronized(digitList) {
|
||||
digitList.set(number, useExponentialNotation ?
|
||||
getMinimumIntegerDigits() + getMaximumFractionDigits() : 0);
|
||||
|
||||
digitList.set(number, precision(true));
|
||||
return subformat(result, fieldPosition, number.signum() < 0, false);
|
||||
}
|
||||
}
|
||||
@ -782,15 +774,11 @@ public class DecimalFormat extends NumberFormat {
|
||||
// At this point we are guaranteed a nonnegative finite
|
||||
// number.
|
||||
synchronized(digitList) {
|
||||
digitList.set(number, useExponentialNotation ?
|
||||
getMinimumIntegerDigits() + getMaximumFractionDigits() :
|
||||
getMaximumFractionDigits(),
|
||||
!useExponentialNotation);
|
||||
digitList.set(number, precision(false), !useExponentialNotation);
|
||||
return subformat(result, fieldPosition, number.signum() < 0, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* <strong><font face=helvetica color=red>NEW</font></strong>
|
||||
* Format a BigDecimal number.
|
||||
@ -817,10 +805,7 @@ public class DecimalFormat extends NumberFormat {
|
||||
// At this point we are guaranteed a nonnegative finite
|
||||
// number.
|
||||
synchronized(digitList) {
|
||||
digitList.set(number, useExponentialNotation ?
|
||||
getMinimumIntegerDigits() + getMaximumFractionDigits() :
|
||||
getMaximumFractionDigits(),
|
||||
!useExponentialNotation);
|
||||
digitList.set(number, precision(false), !useExponentialNotation);
|
||||
return subformat(result, fieldPosition, number.signum() < 0, false);
|
||||
}
|
||||
}
|
||||
@ -847,6 +832,23 @@ public class DecimalFormat extends NumberFormat {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the number of digits to show.
|
||||
*/
|
||||
private int precision(boolean isIntegral) {
|
||||
int maxIntDig = getMaximumIntegerDigits();
|
||||
int minIntDig = getMinimumIntegerDigits();
|
||||
if (useExponentialNotation && maxIntDig > MAX_SCIENTIFIC_INTEGER_DIGITS) {
|
||||
maxIntDig = 1;
|
||||
if (maxIntDig < minIntDig) {
|
||||
maxIntDig = minIntDig;
|
||||
}
|
||||
}
|
||||
return useExponentialNotation
|
||||
? getMinimumIntegerDigits() + getMaximumFractionDigits()
|
||||
: (isIntegral ? 0 : getMaximumFractionDigits());
|
||||
}
|
||||
|
||||
/**
|
||||
* Complete the formatting of a finite number. On entry, the digitList must
|
||||
* be filled in with the correct digits.
|
||||
@ -877,6 +879,15 @@ public class DecimalFormat extends NumberFormat {
|
||||
symbols.getDecimalSeparator();
|
||||
int maxIntDig = getMaximumIntegerDigits();
|
||||
int minIntDig = getMinimumIntegerDigits();
|
||||
if (useExponentialNotation && maxIntDig > MAX_SCIENTIFIC_INTEGER_DIGITS) {
|
||||
maxIntDig = 1;
|
||||
if (maxIntDig < minIntDig) {
|
||||
maxIntDig = minIntDig;
|
||||
}
|
||||
}
|
||||
if (useExponentialNotation && maxIntDig > minIntDig) {
|
||||
minIntDig = 1;
|
||||
}
|
||||
|
||||
/* Per bug 4147706, DecimalFormat must respect the sign of numbers which
|
||||
* format as zero. This allows sensible computations and preserves
|
||||
@ -997,7 +1008,13 @@ public class DecimalFormat extends NumberFormat {
|
||||
result.append(symbols.getPlusSign());
|
||||
}
|
||||
digitList.set(exponent);
|
||||
for (i=digitList.decimalAt; i<minExponentDigits; ++i) result.append(zero);
|
||||
{
|
||||
int expDig = minExponentDigits;
|
||||
if (useExponentialNotation && expDig < 1) {
|
||||
expDig = 1;
|
||||
}
|
||||
for (i=digitList.decimalAt; i<expDig; ++i) result.append(zero);
|
||||
}
|
||||
for (i=0; i<digitList.decimalAt; ++i)
|
||||
{
|
||||
result.append((i < digitList.count) ?
|
||||
@ -2155,7 +2172,11 @@ public class DecimalFormat extends NumberFormat {
|
||||
|
||||
/**
|
||||
* <strong><font face=helvetica color=red>NEW</font></strong>
|
||||
* Set whether or not scientific notation is used.
|
||||
* Set whether or not scientific notation is used. When scientific notation
|
||||
* is used, the effective maximum number of integer digits is <= 8. If the
|
||||
* maximum number of integer digits is set to more than 8, the effective
|
||||
* maximum will be 1. This allows this call to generate a 'default' scientific
|
||||
* number format without additional changes.
|
||||
* @param useScientific true if this object formats and parses scientific
|
||||
* notation
|
||||
* @see #isScientificNotation
|
||||
@ -2167,9 +2188,6 @@ public class DecimalFormat extends NumberFormat {
|
||||
*/
|
||||
public void setScientificNotation(boolean useScientific) {
|
||||
useExponentialNotation = useScientific;
|
||||
if (useExponentialNotation && minExponentDigits < 1) {
|
||||
minExponentDigits = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2387,6 +2405,25 @@ public class DecimalFormat extends NumberFormat {
|
||||
&& symbols.equals(other.symbols));
|
||||
}
|
||||
|
||||
// protected void handleToString(StringBuffer buf) {
|
||||
// super.handleToString(buf);
|
||||
// buf.append("\nposPrefixPattern: '" + posPrefixPattern + "'\n");
|
||||
// buf.append("positivePrefix: '" + positivePrefix + "'\n");
|
||||
// buf.append("posSuffixPattern: '" + posSuffixPattern + "'\n");
|
||||
// buf.append("positiveSuffix: '" + positiveSuffix + "'\n");
|
||||
// buf.append("negPrefixPattern: '" + Utility.format1ForSource(negPrefixPattern) + "'\n");
|
||||
// buf.append("negativePrefix: '" + Utility.format1ForSource(negativePrefix) + "'\n");
|
||||
// buf.append("negSuffixPattern: '" + negSuffixPattern + "'\n");
|
||||
// buf.append("negativeSuffix: '" + negativeSuffix + "'\n");
|
||||
// buf.append("multiplier: '" + multiplier + "'\n");
|
||||
// buf.append("groupingSize: '" + groupingSize + "'\n");
|
||||
// buf.append("groupingSize2: '" + groupingSize2 + "'\n");
|
||||
// buf.append("decimalSeparatorAlwaysShown: '" + decimalSeparatorAlwaysShown + "'\n");
|
||||
// buf.append("useExponentialNotation: '" + useExponentialNotation + "'\n");
|
||||
// buf.append("minExponentDigits: '" + minExponentDigits + "'\n");
|
||||
// buf.append("symbols: '" + symbols + "'");
|
||||
// }
|
||||
|
||||
/**
|
||||
* Overrides hashCode
|
||||
* @stable ICU 2.0
|
||||
@ -2718,9 +2755,15 @@ public class DecimalFormat extends NumberFormat {
|
||||
if (g > 0 && groupingSize2 > 0 && groupingSize2 != groupingSize) {
|
||||
g += groupingSize2;
|
||||
}
|
||||
int maxIntDig = useExponentialNotation ? getMaximumIntegerDigits() :
|
||||
(Math.max(Math.max(g, getMinimumIntegerDigits()),
|
||||
int maxIntDig = getMaximumIntegerDigits();
|
||||
if (useExponentialNotation) {
|
||||
if (maxIntDig > MAX_SCIENTIFIC_INTEGER_DIGITS) {
|
||||
maxIntDig = 1;
|
||||
}
|
||||
} else {
|
||||
maxIntDig = (Math.max(Math.max(g, getMinimumIntegerDigits()),
|
||||
roundingDecimalPos) + 1);
|
||||
}
|
||||
for (i = maxIntDig; i > 0; --i) {
|
||||
if (!useExponentialNotation && i<maxIntDig &&
|
||||
isGroupingPosition(i)) {
|
||||
@ -3845,7 +3888,18 @@ public class DecimalFormat extends NumberFormat {
|
||||
*/
|
||||
static final int DOUBLE_INTEGER_DIGITS = 309;
|
||||
static final int DOUBLE_FRACTION_DIGITS = 340;
|
||||
|
||||
|
||||
/**
|
||||
* When someone turns on scientific mode, we assume that more than this
|
||||
* number of digits is due to flipping from some other mode that didn't
|
||||
* restrict the maximum, and so we force 1 integer digit. We don't bother
|
||||
* to track and see if someone is using exponential notation with more than
|
||||
* this number, it wouldn't make sense anyway, and this is just to make sure
|
||||
* that someone turning on scientific mode with default settings doesn't
|
||||
* end up with lots of zeroes.
|
||||
*/
|
||||
static final int MAX_SCIENTIFIC_INTEGER_DIGITS = 8;
|
||||
|
||||
// Proclaim JDK 1.1 serial compatibility.
|
||||
static final long serialVersionUID = 864413376551465018L;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user