mirror of
https://github.com/Respect/Validation.git
synced 2024-06-09 09:12:17 +02:00
Create "SubdivisionCode" rule
This commit is contained in:
parent
28711d0a45
commit
6c9a0e7228
284
docs/SubdivisionCode.md
Normal file
284
docs/SubdivisionCode.md
Normal file
|
@ -0,0 +1,284 @@
|
||||||
|
# SubdivisionCode
|
||||||
|
|
||||||
|
- `v::subdivisionCode(string $countryCode)`
|
||||||
|
|
||||||
|
Validates subdivision country codes according to [ISO 3166-2][].
|
||||||
|
|
||||||
|
The `$countryCode` must be a country in [ISO 3166-1 alpha-2][] format.
|
||||||
|
|
||||||
|
```php
|
||||||
|
v::subdivisionCode('BR')->validate('SP'); //true
|
||||||
|
v::subdivisionCode('US')->validate('CA'); //true
|
||||||
|
```
|
||||||
|
|
||||||
|
This rule is case sensitive.
|
||||||
|
|
||||||
|
## Available country codes
|
||||||
|
|
||||||
|
- `AD`: Andorra
|
||||||
|
- `AE`: United Arab Emirates
|
||||||
|
- `AF`: Afghanistan
|
||||||
|
- `AG`: Antigua and Barbuda
|
||||||
|
- `AI`: Anguilla
|
||||||
|
- `AL`: Albania
|
||||||
|
- `AM`: Armenia
|
||||||
|
- `AN`: AN.html
|
||||||
|
- `AO`: Angola
|
||||||
|
- `AQ`: Antarctica
|
||||||
|
- `AR`: Argentina
|
||||||
|
- `AS`: American Samoa
|
||||||
|
- `AT`: Austria
|
||||||
|
- `AU`: Australia
|
||||||
|
- `AW`: Aruba
|
||||||
|
- `AX`: Åland
|
||||||
|
- `AZ`: Azerbaijan
|
||||||
|
- `BA`: Bosnia and Herzegovina
|
||||||
|
- `BB`: Barbados
|
||||||
|
- `BD`: Bangladesh
|
||||||
|
- `BE`: Belgium
|
||||||
|
- `BF`: Burkina Faso
|
||||||
|
- `BG`: Bulgaria
|
||||||
|
- `BH`: Bahrain
|
||||||
|
- `BI`: Burundi
|
||||||
|
- `BJ`: Benin
|
||||||
|
- `BL`: Saint Barthélemy
|
||||||
|
- `BM`: Bermuda
|
||||||
|
- `BN`: Brunei
|
||||||
|
- `BO`: Bolivia
|
||||||
|
- `BQ`: Bonaire
|
||||||
|
- `BR`: Brazil
|
||||||
|
- `BS`: Bahamas
|
||||||
|
- `BT`: Bhutan
|
||||||
|
- `BV`: Bouvet Island
|
||||||
|
- `BW`: Botswana
|
||||||
|
- `BY`: Belarus
|
||||||
|
- `BZ`: Belize
|
||||||
|
- `CA`: Canada
|
||||||
|
- `CC`: Cocos [Keeling] Islands
|
||||||
|
- `CD`: Democratic Republic of the Congo
|
||||||
|
- `CF`: Central African Republic
|
||||||
|
- `CG`: Republic of the Congo
|
||||||
|
- `CH`: Switzerland
|
||||||
|
- `CI`: Ivory Coast
|
||||||
|
- `CK`: Cook Islands
|
||||||
|
- `CL`: Chile
|
||||||
|
- `CM`: Cameroon
|
||||||
|
- `CN`: China
|
||||||
|
- `CO`: Colombia
|
||||||
|
- `CR`: Costa Rica
|
||||||
|
- `CS`: CS.html
|
||||||
|
- `CU`: Cuba
|
||||||
|
- `CV`: Cape Verde
|
||||||
|
- `CW`: Curacao
|
||||||
|
- `CX`: Christmas Island
|
||||||
|
- `CY`: Cyprus
|
||||||
|
- `CZ`: Czech Republic
|
||||||
|
- `DE`: Germany
|
||||||
|
- `DJ`: Djibouti
|
||||||
|
- `DK`: Denmark
|
||||||
|
- `DM`: Dominica
|
||||||
|
- `DO`: Dominican Republic
|
||||||
|
- `DZ`: Algeria
|
||||||
|
- `EC`: Ecuador
|
||||||
|
- `EE`: Estonia
|
||||||
|
- `EG`: Egypt
|
||||||
|
- `EH`: Western Sahara
|
||||||
|
- `ER`: Eritrea
|
||||||
|
- `ES`: Spain
|
||||||
|
- `ET`: Ethiopia
|
||||||
|
- `FI`: Finland
|
||||||
|
- `FJ`: Fiji
|
||||||
|
- `FK`: Falkland Islands
|
||||||
|
- `FM`: Micronesia
|
||||||
|
- `FO`: Faroe Islands
|
||||||
|
- `FR`: France
|
||||||
|
- `GA`: Gabon
|
||||||
|
- `GB`: United Kingdom
|
||||||
|
- `GD`: Grenada
|
||||||
|
- `GE`: Georgia
|
||||||
|
- `GF`: French Guiana
|
||||||
|
- `GG`: Guernsey
|
||||||
|
- `GH`: Ghana
|
||||||
|
- `GI`: Gibraltar
|
||||||
|
- `GL`: Greenland
|
||||||
|
- `GM`: Gambia
|
||||||
|
- `GN`: Guinea
|
||||||
|
- `GP`: Guadeloupe
|
||||||
|
- `GQ`: Equatorial Guinea
|
||||||
|
- `GR`: Greece
|
||||||
|
- `GS`: South Georgia and the South Sandwich Islands
|
||||||
|
- `GT`: Guatemala
|
||||||
|
- `GU`: Guam
|
||||||
|
- `GW`: Guinea-Bissau
|
||||||
|
- `GY`: Guyana
|
||||||
|
- `HK`: Hong Kong
|
||||||
|
- `HM`: Heard Island and McDonald Islands
|
||||||
|
- `HN`: Honduras
|
||||||
|
- `HR`: Croatia
|
||||||
|
- `HT`: Haiti
|
||||||
|
- `HU`: Hungary
|
||||||
|
- `ID`: Indonesia
|
||||||
|
- `IE`: Ireland
|
||||||
|
- `IL`: Israel
|
||||||
|
- `IM`: Isle of Man
|
||||||
|
- `IN`: India
|
||||||
|
- `IO`: British Indian Ocean Territory
|
||||||
|
- `IQ`: Iraq
|
||||||
|
- `IR`: Iran
|
||||||
|
- `IS`: Iceland
|
||||||
|
- `IT`: Italy
|
||||||
|
- `JE`: Jersey
|
||||||
|
- `JM`: Jamaica
|
||||||
|
- `JO`: Jordan
|
||||||
|
- `JP`: Japan
|
||||||
|
- `KE`: Kenya
|
||||||
|
- `KG`: Kyrgyzstan
|
||||||
|
- `KH`: Cambodia
|
||||||
|
- `KI`: Kiribati
|
||||||
|
- `KM`: Comoros
|
||||||
|
- `KN`: Saint Kitts and Nevis
|
||||||
|
- `KP`: North Korea
|
||||||
|
- `KR`: South Korea
|
||||||
|
- `KW`: Kuwait
|
||||||
|
- `KY`: Cayman Islands
|
||||||
|
- `KZ`: Kazakhstan
|
||||||
|
- `LA`: Laos
|
||||||
|
- `LB`: Lebanon
|
||||||
|
- `LC`: Saint Lucia
|
||||||
|
- `LI`: Liechtenstein
|
||||||
|
- `LK`: Sri Lanka
|
||||||
|
- `LR`: Liberia
|
||||||
|
- `LS`: Lesotho
|
||||||
|
- `LT`: Lithuania
|
||||||
|
- `LU`: Luxembourg
|
||||||
|
- `LV`: Latvia
|
||||||
|
- `LY`: Libya
|
||||||
|
- `MA`: Morocco
|
||||||
|
- `MC`: Monaco
|
||||||
|
- `MD`: Moldova
|
||||||
|
- `ME`: Montenegro
|
||||||
|
- `MF`: Saint Martin
|
||||||
|
- `MG`: Madagascar
|
||||||
|
- `MH`: Marshall Islands
|
||||||
|
- `MK`: Macedonia
|
||||||
|
- `ML`: Mali
|
||||||
|
- `MM`: Myanmar [Burma]
|
||||||
|
- `MN`: Mongolia
|
||||||
|
- `MO`: Macao
|
||||||
|
- `MP`: Northern Mariana Islands
|
||||||
|
- `MQ`: Martinique
|
||||||
|
- `MR`: Mauritania
|
||||||
|
- `MS`: Montserrat
|
||||||
|
- `MT`: Malta
|
||||||
|
- `MU`: Mauritius
|
||||||
|
- `MV`: Maldives
|
||||||
|
- `MW`: Malawi
|
||||||
|
- `MX`: Mexico
|
||||||
|
- `MY`: Malaysia
|
||||||
|
- `MZ`: Mozambique
|
||||||
|
- `NA`: Namibia
|
||||||
|
- `NC`: New Caledonia
|
||||||
|
- `NE`: Niger
|
||||||
|
- `NF`: Norfolk Island
|
||||||
|
- `NG`: Nigeria
|
||||||
|
- `NI`: Nicaragua
|
||||||
|
- `NL`: Netherlands
|
||||||
|
- `NO`: Norway
|
||||||
|
- `NP`: Nepal
|
||||||
|
- `NR`: Nauru
|
||||||
|
- `NU`: Niue
|
||||||
|
- `NZ`: New Zealand
|
||||||
|
- `OM`: Oman
|
||||||
|
- `PA`: Panama
|
||||||
|
- `PE`: Peru
|
||||||
|
- `PF`: French Polynesia
|
||||||
|
- `PG`: Papua New Guinea
|
||||||
|
- `PH`: Philippines
|
||||||
|
- `PK`: Pakistan
|
||||||
|
- `PL`: Poland
|
||||||
|
- `PM`: Saint Pierre and Miquelon
|
||||||
|
- `PN`: Pitcairn Islands
|
||||||
|
- `PR`: Puerto Rico
|
||||||
|
- `PS`: Palestine
|
||||||
|
- `PT`: Portugal
|
||||||
|
- `PW`: Palau
|
||||||
|
- `PY`: Paraguay
|
||||||
|
- `QA`: Qatar
|
||||||
|
- `RE`: Réunion
|
||||||
|
- `RO`: Romania
|
||||||
|
- `RS`: Serbia
|
||||||
|
- `RU`: Russia
|
||||||
|
- `RW`: Rwanda
|
||||||
|
- `SA`: Saudi Arabia
|
||||||
|
- `SB`: Solomon Islands
|
||||||
|
- `SC`: Seychelles
|
||||||
|
- `SD`: Sudan
|
||||||
|
- `SE`: Sweden
|
||||||
|
- `SG`: Singapore
|
||||||
|
- `SH`: Saint Helena
|
||||||
|
- `SI`: Slovenia
|
||||||
|
- `SJ`: Svalbard and Jan Mayen
|
||||||
|
- `SK`: Slovakia
|
||||||
|
- `SL`: Sierra Leone
|
||||||
|
- `SM`: San Marino
|
||||||
|
- `SN`: Senegal
|
||||||
|
- `SO`: Somalia
|
||||||
|
- `SR`: Suriname
|
||||||
|
- `SS`: South Sudan
|
||||||
|
- `ST`: São Tomé and Príncipe
|
||||||
|
- `SV`: El Salvador
|
||||||
|
- `SX`: Sint Maarten
|
||||||
|
- `SY`: Syria
|
||||||
|
- `SZ`: Swaziland
|
||||||
|
- `TC`: Turks and Caicos Islands
|
||||||
|
- `TD`: Chad
|
||||||
|
- `TF`: French Southern Territories
|
||||||
|
- `TG`: Togo
|
||||||
|
- `TH`: Thailand
|
||||||
|
- `TJ`: Tajikistan
|
||||||
|
- `TK`: Tokelau
|
||||||
|
- `TL`: East Timor
|
||||||
|
- `TM`: Turkmenistan
|
||||||
|
- `TN`: Tunisia
|
||||||
|
- `TO`: Tonga
|
||||||
|
- `TR`: Turkey
|
||||||
|
- `TT`: Trinidad and Tobago
|
||||||
|
- `TV`: Tuvalu
|
||||||
|
- `TW`: Taiwan
|
||||||
|
- `TZ`: Tanzania
|
||||||
|
- `UA`: Ukraine
|
||||||
|
- `UG`: Uganda
|
||||||
|
- `UM`: U.S. Minor Outlying Islands
|
||||||
|
- `US`: United States
|
||||||
|
- `UY`: Uruguay
|
||||||
|
- `UZ`: Uzbekistan
|
||||||
|
- `VA`: Vatican City
|
||||||
|
- `VC`: Saint Vincent and the Grenadines
|
||||||
|
- `VE`: Venezuela
|
||||||
|
- `VG`: British Virgin Islands
|
||||||
|
- `VI`: U.S. Virgin Islands
|
||||||
|
- `VN`: Vietnam
|
||||||
|
- `VU`: Vanuatu
|
||||||
|
- `WF`: Wallis and Futuna
|
||||||
|
- `WS`: Samoa
|
||||||
|
- `XK`: Kosovo
|
||||||
|
- `YE`: Yemen
|
||||||
|
- `YT`: Mayotte
|
||||||
|
- `ZA`: South Africa
|
||||||
|
- `ZM`: Zambia
|
||||||
|
- `ZW`: Zimbabwe
|
||||||
|
|
||||||
|
All data was extrated from [GeoNames][] which is licensed under a
|
||||||
|
[Creative Commons Attribution 3.0 License][].
|
||||||
|
|
||||||
|
***
|
||||||
|
See also:
|
||||||
|
|
||||||
|
* [CountryCode](CountryCode.md)
|
||||||
|
* [Tld](Tld.md)
|
||||||
|
|
||||||
|
|
||||||
|
[Creative Commons Attribution 3.0 License]: http://creativecommons.org/licenses/by/3.0 "Creative Commons Attribution 3.0 License"
|
||||||
|
[GeoNames]: http://www.geonames.org "GetNames"
|
||||||
|
[ISO 3166-1 alpha-2]: http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2 "ISO 3166-1 alpha-2"
|
||||||
|
[ISO 3166-2]: http://en.wikipedia.org/wiki/ISO_3166-2 "ISO 3166-2"
|
|
@ -126,6 +126,7 @@
|
||||||
|
|
||||||
* [CountryCode](CountryCode.md)
|
* [CountryCode](CountryCode.md)
|
||||||
* [PostalCode](PostalCode.md)
|
* [PostalCode](PostalCode.md)
|
||||||
|
* [SubdivisionCode](SubdivisionCode.md)
|
||||||
* [Tld](Tld.md)
|
* [Tld](Tld.md)
|
||||||
|
|
||||||
## Files
|
## Files
|
||||||
|
@ -263,6 +264,7 @@
|
||||||
* [Space](Space.md)
|
* [Space](Space.md)
|
||||||
* [StartsWith](StartsWith.md)
|
* [StartsWith](StartsWith.md)
|
||||||
* [String](String.md)
|
* [String](String.md)
|
||||||
|
* [SubdivisionCode](SubdivisionCode.md)
|
||||||
* [SymbolicLink](SymbolicLink.md)
|
* [SymbolicLink](SymbolicLink.md)
|
||||||
* [Tld](Tld.md)
|
* [Tld](Tld.md)
|
||||||
* [True](True.md)
|
* [True](True.md)
|
||||||
|
|
24
library/Exceptions/SubdivisionCodeException.php
Normal file
24
library/Exceptions/SubdivisionCodeException.php
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of Respect/Validation.
|
||||||
|
*
|
||||||
|
* (c) Alexandre Gomes Gaigalas <alexandre@gaigalas.net>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the "LICENSE.md"
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Respect\Validation\Exceptions;
|
||||||
|
|
||||||
|
class SubdivisionCodeException extends ValidationException
|
||||||
|
{
|
||||||
|
public static $defaultTemplates = array(
|
||||||
|
self::MODE_DEFAULT => array(
|
||||||
|
self::STANDARD => '{{name}} must be a valid subdivision code for {{countryCode}}',
|
||||||
|
),
|
||||||
|
self::MODE_NEGATIVE => array(
|
||||||
|
self::STANDARD => '{{name}} must not be a valid subdivision code for {{countryCode}}',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
37
library/Rules/SubdivisionCode.php
Normal file
37
library/Rules/SubdivisionCode.php
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of Respect/Validation.
|
||||||
|
*
|
||||||
|
* (c) Alexandre Gomes Gaigalas <alexandre@gaigalas.net>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the "LICENSE.md"
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Respect\Validation\Rules;
|
||||||
|
|
||||||
|
use Respect\Validation\Exceptions\ComponentException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates country subdivision codes according to ISO 3166-2.
|
||||||
|
*
|
||||||
|
* @link http://en.wikipedia.org/wiki/ISO_3166-2
|
||||||
|
* @link http://www.geonames.org/countries/
|
||||||
|
*/
|
||||||
|
class SubdivisionCode extends AbstractWrapper
|
||||||
|
{
|
||||||
|
public $countryCode;
|
||||||
|
|
||||||
|
public function __construct($countryCode)
|
||||||
|
{
|
||||||
|
$shortName = ucfirst(strtolower($countryCode)).'SubdivisionCode';
|
||||||
|
$className = __NAMESPACE__.'\\Locale\\'.$shortName;
|
||||||
|
if (!class_exists($className)) {
|
||||||
|
throw new ComponentException(sprintf('"%s" is not a valid countryCode for ISO 3166-2', $countryCode));
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->countryCode = $countryCode;
|
||||||
|
$this->validatable = new $className();
|
||||||
|
}
|
||||||
|
}
|
|
@ -110,6 +110,7 @@ use Respect\Validation\Rules\Key;
|
||||||
* @method static Validator space(string $additionalChars = null)
|
* @method static Validator space(string $additionalChars = null)
|
||||||
* @method static Validator startsWith(mixed $startValue, bool $identical = false)
|
* @method static Validator startsWith(mixed $startValue, bool $identical = false)
|
||||||
* @method static Validator string()
|
* @method static Validator string()
|
||||||
|
* @method static Validator subdivisionCode(string $countryCode)
|
||||||
* @method static Validator symbolicLink()
|
* @method static Validator symbolicLink()
|
||||||
* @method static Validator tld()
|
* @method static Validator tld()
|
||||||
* @method static Validator true()
|
* @method static Validator true()
|
||||||
|
|
|
@ -20,6 +20,10 @@
|
||||||
<filter>
|
<filter>
|
||||||
<whitelist processUncoveredFilesFromWhitelist="false">
|
<whitelist processUncoveredFilesFromWhitelist="false">
|
||||||
<directory>library/</directory>
|
<directory>library/</directory>
|
||||||
|
<exclude>
|
||||||
|
<directory suffix=".php">library/Exceptions/SubdivisionCode</directory>
|
||||||
|
<directory suffix=".php">library/Rules/SubdivisionCode</directory>
|
||||||
|
</exclude>
|
||||||
</whitelist>
|
</whitelist>
|
||||||
</filter>
|
</filter>
|
||||||
</phpunit>
|
</phpunit>
|
||||||
|
|
96
tests/Rules/SubdivisionCodeTest.php
Normal file
96
tests/Rules/SubdivisionCodeTest.php
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of Respect/Validation.
|
||||||
|
*
|
||||||
|
* (c) Alexandre Gomes Gaigalas <alexandre@gaigalas.net>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the "LICENSE.md"
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Respect\Validation\Rules;
|
||||||
|
|
||||||
|
use PHPUnit_Framework_TestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @covers Respect\Validation\Rules\SubdivisionCode
|
||||||
|
* @covers Respect\Validation\Exceptions\SubdivisionCodeException
|
||||||
|
*/
|
||||||
|
class SubdivisionCodeTest extends PHPUnit_Framework_TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @expectedException Respect\Validation\Exceptions\ComponentException
|
||||||
|
* @expectedExceptionMessage "whatever" is not a valid entry for ISO 3166-2
|
||||||
|
*/
|
||||||
|
public function testShouldThrowsExceptionWhenInvalidFormat()
|
||||||
|
{
|
||||||
|
new SubdivisionCode('whatever');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException Respect\Validation\Exceptions\ComponentException
|
||||||
|
* @expectedExceptionMessage "JK" is not a valid entry for ISO 3166-2
|
||||||
|
*/
|
||||||
|
public function testShouldNotAcceptWrongNamesOnConstructor()
|
||||||
|
{
|
||||||
|
new SubdivisionCode('JK');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testShouldDefineASubdivisionCodeFormatOnConstructor()
|
||||||
|
{
|
||||||
|
$countrySubdivision = new SubdivisionCode('US');
|
||||||
|
|
||||||
|
$this->assertEquals('US', $countrySubdivision->entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function providerForValidSubdivisionCodeInformation()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
array('AQ', null),
|
||||||
|
array('BR', 'SP'),
|
||||||
|
array('MV', '00'),
|
||||||
|
array('US', 'CA'),
|
||||||
|
array('YT', ''),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider providerForValidSubdivisionCodeInformation
|
||||||
|
*/
|
||||||
|
public function testShouldValidateValidSubdivisionCodeInformation($entry, $input)
|
||||||
|
{
|
||||||
|
$countrySubdivision = new SubdivisionCode($entry);
|
||||||
|
|
||||||
|
$this->assertTrue($countrySubdivision->validate($input));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function providerForInvalidSubdivisionCodeInformation()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
array('BR', 'CA'),
|
||||||
|
array('MV', 0),
|
||||||
|
array('US', 'CE'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider providerForInvalidSubdivisionCodeInformation
|
||||||
|
*/
|
||||||
|
public function testShouldNotValidateInvalidSubdivisionCodeInformation($entry, $input)
|
||||||
|
{
|
||||||
|
$countrySubdivision = new SubdivisionCode($entry);
|
||||||
|
|
||||||
|
$this->assertFalse($countrySubdivision->validate($input));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException Respect\Validation\Exceptions\SubdivisionCode\BrSubdivisionCodeException
|
||||||
|
* @expectedExceptionMessage "CA" must be a country subdivision of Brazil
|
||||||
|
*/
|
||||||
|
public function testShouldThrowsSubdivisionCodeException()
|
||||||
|
{
|
||||||
|
$countrySubdivision = new SubdivisionCode('BR');
|
||||||
|
$countrySubdivision->assert('CA');
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue