diff --git a/.gitignore b/.gitignore index 4c66d00..8a142a2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ vendor/ .idea/ +.phpunit.result.cache \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index bab13b5..71bcb65 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ All notable changes to the wrapper will be documented in this file. - Updated guzzle from `6.x|7.x` to `^9` - Minor changes in the readme - Updated the phpunit.xml configuration file +- Changed the response base pagination into a Pagination class see Issue:#23 ### Added - Added support for PHP 8.0 - Added the `disableFreeSan` field for requests. @@ -19,6 +20,7 @@ All notable changes to the wrapper will be documented in this file. - Dropped support for all versions below PHP 7.4 - Removed functions previously marked deprecated - Removed deprecated RequestDCV class +- Removed EncryptionEverywhere support ## [2.0.1] diff --git a/readme.md b/readme.md index 1d682a2..f428d30 100644 --- a/readme.md +++ b/readme.md @@ -24,6 +24,11 @@ And updated via composer update xolphin/xolphin-api-php ``` +### Upgrade guide: from v2.x to v3.x +- Access pagination attributes from `$response->getPagination()->{{method}};` +- Remove all EE (EncryptionEverywhere) blocks from your code, it has finally been removed. +- Make sure you enforce the right types since we enforce strict-typing now. + ### Upgrade guide from v1.8.3 to v2.x Update your `xolphin/xolphin-api-php` dependency to `^2.0` in your `composer.json` file. @@ -170,22 +175,6 @@ foreach($notes as $note){ $client->requests->sendSectigoSAEmail(1234, 'mail@example.com', RequestLanguage::ENGLISH); ``` -#### Request an "Encryption Everywhere" certificate - -```php -$request = $this->_client->requests->createEE(); -$request->setCsr(''); -$request->setApproverEmail('email@example.com'); -$request->setApproverFirstName('FirstName'); -$request->setApproverLastName('SecondName'); -$request->setApproverPhone('+12345678901'); -$request->setDcvType(DCVTypes::FILE_VALIDATION); -// if you just want to validate -$request->setValidate(true); - -$response = $client->requests->sendEE($request); -``` - ### Certificate #### Certificates list and expirations diff --git a/src/Endpoints/CertificatesEndpoint.php b/src/Endpoints/CertificatesEndpoint.php index d87c9f4..f33f729 100644 --- a/src/Endpoints/CertificatesEndpoint.php +++ b/src/Endpoints/CertificatesEndpoint.php @@ -44,11 +44,13 @@ public function all(): array $result = new Certificates($this->client->get('certificates', ['page' => 1])); if (!$result->isError()) { $certificates = $result->certificates; - while ($result->page < $result->pages) { - $result = new Certificates($this->client->get('certificates', ['page' => $result->page + 1])); + while ($result->getPagination()->getPage() < $result->getPagination()->getPages()) { + $result = new Certificates($this->client->get('certificates', ['page' => $result->getPagination()->getPage() + 1])); + if ($result->isError()) { break; } + $certificates = array_merge($certificates, $result->certificates); } } diff --git a/src/Endpoints/InvoicesEndpoint.php b/src/Endpoints/InvoicesEndpoint.php index 4c6262a..f106ad4 100644 --- a/src/Endpoints/InvoicesEndpoint.php +++ b/src/Endpoints/InvoicesEndpoint.php @@ -40,11 +40,13 @@ public function all(): array $result = new Invoices($this->client->get('invoices', ['page' => 1])); if (!$result->isError()) { $invoices = $result->invoices; - while ($result->page < $result->pages) { - $result = new Invoices($this->client->get('invoices', ['page' => $result->page + 1])); + while ($result->getPagination()->getPage() < $result->getPagination()->getPages()) { + $result = new Invoices($this->client->get('invoices', ['page' => $result->getPagination()->getPage() + 1])); + if ($result->isError()) { break; } + $invoices = array_merge($invoices, $result->invoices); } } diff --git a/src/Endpoints/RequestsEndpoint.php b/src/Endpoints/RequestsEndpoint.php index fa0912c..ce2278d 100644 --- a/src/Endpoints/RequestsEndpoint.php +++ b/src/Endpoints/RequestsEndpoint.php @@ -10,11 +10,9 @@ use Xolphin\Client; use Xolphin\Exceptions\XolphinRequestException; use Xolphin\Requests\CertificateRequest; -use Xolphin\Requests\RequestEERequest; use Xolphin\Responses\Base; use Xolphin\Responses\Notes; use Xolphin\Responses\Request; -use Xolphin\Responses\RequestEE; use Xolphin\Responses\Requests; use Xolphin\Responses\ValidationCalls; @@ -46,11 +44,13 @@ public function all(): array $result = new Requests($this->client->get('requests', ['page' => 1])); if (!$result->isError()) { $requests = $result->requests; - while ($result->page < $result->pages) { - $result = new Requests($this->client->get('requests', ['page' => $result->page + 1])); + while ($result->getPagination()->getPage() < $result->getPagination()->getPages()) { + $result = new Requests($this->client->get('requests', ['page' => $result->getPagination()->getPage() + 1])); + if ($result->isError()) { break; } + $requests = array_merge($requests, $result->requests); } } @@ -81,24 +81,6 @@ public function send(CertificateRequest $request): Request return new Request($this->client->post('requests', $request->getApiRequestBody())); } - /** - * @return RequestEERequest - */ - public function createEE(): RequestEERequest - { - return new RequestEERequest(); - } - - /** - * @param RequestEERequest $request - * @return RequestEE - * @throws XolphinRequestException|GuzzleException - */ - public function sendEE(RequestEERequest $request): RequestEE - { - return new RequestEE($this->client->post('requests/ee', $request->getApiRequestBody())); - } - /** * @param int $id * @return Request diff --git a/src/Endpoints/SupportEndpoint.php b/src/Endpoints/SupportEndpoint.php index aa7e8b0..dd2ebfb 100644 --- a/src/Endpoints/SupportEndpoint.php +++ b/src/Endpoints/SupportEndpoint.php @@ -59,11 +59,13 @@ public function products(): array $result = new Products($this->client->get('products', ['page' => 1])); if (!$result->isError()) { $products = $result->products; - while ($result->page < $result->pages) { - $result = new Products($this->client->get('products', ['page' => $result->page + 1])); + while ($result->getPagination()->getPage() < $result->getPagination()->getPages()) { + $result = new Products($this->client->get('products', ['page' => $result->getPagination()->getPage() + 1])); + if ($result->isError()) { break; } + $products = array_merge($products, $result->products); } } diff --git a/src/Requests/RequestEERequest.php b/src/Requests/RequestEERequest.php deleted file mode 100644 index cee3a7e..0000000 --- a/src/Requests/RequestEERequest.php +++ /dev/null @@ -1,206 +0,0 @@ -csr; - } - - /** - * @return string - */ - public function getApproverEmail(): string - { - return $this->approverEmail; - } - - /** - * @return string - */ - public function getApproverFirstName(): string - { - return $this->approverFirstName; - } - - /** - * @return string - */ - public function getApproverLastName(): string - { - return $this->approverLastName; - } - - /** - * @return string - */ - public function getApproverPhone(): string - { - return $this->approverPhone; - } - - /** - * @return string - */ - public function getDcvType(): string - { - return $this->dcvType; - } - - /** - * @return array - */ - public function getSubjectAlternativeNames(): array - { - return $this->subjectAlternativeNames; - } - - /** - * @param string $csr - * @return RequestEERequest - */ - public function setCsr(string $csr): RequestEERequest - { - $this->csr = $csr; - return $this; - } - - /** - * @param string $approverEmail - * @return RequestEERequest - */ - public function setApproverEmail(string $approverEmail): RequestEERequest - { - $this->approverEmail = $approverEmail; - return $this; - } - - /** - * @param string $approverFirstName - * @return RequestEERequest - */ - public function setApproverFirstName(string $approverFirstName): RequestEERequest - { - $this->approverFirstName = $approverFirstName; - return $this; - } - - /** - * @param string $approverLastName - * @return RequestEERequest - */ - public function setApproverLastName(string $approverLastName): RequestEERequest - { - $this->approverLastName = $approverLastName; - return $this; - } - - /** - * @param string $approverPhone - * @return RequestEERequest - */ - public function setApproverPhone(string $approverPhone): RequestEERequest - { - $this->approverPhone = $approverPhone; - return $this; - } - - /** - * @param string[] $subjectAlternativeNames - * @return RequestEERequest - */ - public function setSubjectAlternativeNames(array $subjectAlternativeNames): RequestEERequest - { - $this->subjectAlternativeNames = $subjectAlternativeNames; - return $this; - } - - /** - * @param bool $validate - * @return RequestEERequest - */ - public function setValidate(bool $validate): RequestEERequest - { - $this->validate = $validate; - return $this; - } - - /** - * @param string $dcvType use one of the following: EMAIL_VALIDATION, FILE_VALIDATION, DNS_VALIDATION - * @return RequestEERequest - */ - public function setDcvType(string $dcvType): RequestEERequest - { - $this->dcvType = $dcvType; - return $this; - } - - /** - * @return bool - */ - public function isValidate(): bool - { - return $this->validate; - } - - /** - * Array representation - * - * @return array - */ - public function getApiRequestBody(): array - { - $result = [ - 'csr' => $this->csr, - 'approverEmail' => $this->approverEmail, - 'approverFirstName' => $this->approverFirstName, - 'approverLastName' => $this->approverLastName, - 'approverPhone' => $this->approverPhone, - 'dcvType' => $this->dcvType, - 'validate' => $this->validate, - ]; - - if (!empty($this->subjectAlternativeNames)) { - $result['subjectAlternativeNames'] = implode(',', $this->subjectAlternativeNames); - } - - return $result; - } -} \ No newline at end of file diff --git a/src/Responses/Base.php b/src/Responses/Base.php index 0fab783..201169d 100644 --- a/src/Responses/Base.php +++ b/src/Responses/Base.php @@ -6,17 +6,7 @@ class Base { - /** @var int */ - public int $page; - - /** @var int */ - public int $limit; - - /** @var int */ - public int $pages; - - /** @var int */ - public int $total; + private ?Pagination $pagination; /** @var object */ protected $_embedded; @@ -27,7 +17,6 @@ class Base /** @var mixed */ private $errors; - /** * BaseResponse constructor. * @param object $data @@ -40,18 +29,26 @@ public function __construct($data) if (isset($data->errors)) { $this->errors = $data->errors; } - if (isset($data->page)) { - $this->page = $data->page; - } - if (isset($data->limit)) { - $this->limit = $data->limit; - } - if (isset($data->pages)) { - $this->pages = $data->pages; - } - if (isset($data->total)) { - $this->total = $data->total; + + if (isset($data->page) || isset($data->limit) || isset($data->pages) || isset($data->total)) { + $this->pagination = new Pagination(); + + if (isset($data->page)) { + $this->pagination->setpage((int) $data->page); + } + if (isset($data->limit)) { + $this->pagination->setLimit((int) $data->limit); + } + if (isset($data->pages)) { + $this->pagination->setPages((int) $data->pages); + } + if (isset($data->total)) { + $this->pagination->setTotal((int) $data->total); + } + } else { + $this->pagination = null; } + if (isset($data->_embedded)) { $this->_embedded = $data->_embedded; } @@ -66,15 +63,6 @@ public function isError(): bool return !empty($this->errors); } - /** - * @return string - * @deprecated use getMessage() instead - */ - public function getErrorMessage(): string - { - return $this->message; - } - /** * Error about current request * Not null when response code != 200 @@ -92,4 +80,12 @@ public function getErrorData() { return $this->errors; } + + /** + * @return Pagination|null + */ + public function getPagination(): ?Pagination + { + return $this->pagination; + } } diff --git a/src/Responses/CSR.php b/src/Responses/CSR.php index a868c78..5499cf4 100644 --- a/src/Responses/CSR.php +++ b/src/Responses/CSR.php @@ -43,7 +43,7 @@ public function __construct($data) $this->type = $data->type; } if (isset($data->size)) { - $this->size = $data->size; + $this->size = (int) $data->size; } if (isset($data->company)) { $this->company = $data->company; diff --git a/src/Responses/Certificate.php b/src/Responses/Certificate.php index 49f54b8..2ce4ddf 100644 --- a/src/Responses/Certificate.php +++ b/src/Responses/Certificate.php @@ -47,7 +47,7 @@ function __construct($data) if (!$this->isError()) { if (isset($data->id)) { - $this->id = $data->id; + $this->id = (int) $data->id; } if (isset($data->domainName)) { $this->domainName = $data->domainName; @@ -65,10 +65,10 @@ function __construct($data) $this->company = $data->company; } if (isset($data->customerId)) { - $this->customerId = $data->customerId; + $this->customerId = (int) $data->customerId; } if (isset($data->valid)) { - $this->valid = $data->valid; + $this->valid = (bool) $data->valid; } if (isset($data->_embedded->product)) { diff --git a/src/Responses/Invoice.php b/src/Responses/Invoice.php index 4f28594..3ca135b 100644 --- a/src/Responses/Invoice.php +++ b/src/Responses/Invoice.php @@ -53,28 +53,28 @@ function __construct($data) if (!$this->isError()) { if (isset($data->id)) { - $this->id = $data->id; + $this->id = (int) $data->id; } if (isset($data->currency)) { $this->currency = $data->currency; } if (isset($data->amount)) { - $this->amount = $data->amount; + $this->amount = (float) $data->amount; } if (isset($data->tax)) { - $this->tax = $data->tax; + $this->tax = (float) $data->tax; } if (isset($data->invoiceNr)) { - $this->invoiceNr = $data->invoiceNr; + $this->invoiceNr = (int) $data->invoiceNr; } if (isset($data->amountPaid)) { - $this->amountPaid = $data->amountPaid; + $this->amountPaid = (float) $data->amountPaid; } if (isset($data->status)) { $this->status = $data->status; } if (isset($data->total)) { - $this->total = $data->total; + $this->total = (float) $data->total; } if (isset($data->date_created)) { $this->dateCreated = new DateTime($data->date_created); diff --git a/src/Responses/Note.php b/src/Responses/Note.php index 2aec95d..6079d33 100644 --- a/src/Responses/Note.php +++ b/src/Responses/Note.php @@ -43,7 +43,7 @@ function __construct($data) parent::__construct($data); if (isset($data->id)) { - $this->id = $data->id; + $this->id = (int) $data->id; } if (isset($data->contact)) { $this->contact = $data->contact; diff --git a/src/Responses/Pagination.php b/src/Responses/Pagination.php new file mode 100644 index 0000000..66a6386 --- /dev/null +++ b/src/Responses/Pagination.php @@ -0,0 +1,85 @@ +page; + } + + /** + * @param int $page + * @return Pagination + */ + public function setPage(int $page): Pagination + { + $this->page = $page; + return $this; + } + + /** + * @return int + */ + public function getLimit(): int + { + return $this->limit; + } + + /** + * @param int $limit + * @return Pagination + */ + public function setLimit(int $limit): Pagination + { + $this->limit = $limit; + return $this; + } + + /** + * @return int + */ + public function getPages(): int + { + return $this->pages; + } + + /** + * @param int $pages + * @return Pagination + */ + public function setPages(int $pages): Pagination + { + $this->pages = $pages; + return $this; + } + + /** + * @return int + */ + public function getTotal(): int + { + return $this->total; + } + + /** + * @param int $total + * @return Pagination + */ + public function setTotal(int $total): Pagination + { + $this->total = $total; + return $this; + } +} diff --git a/src/Responses/Product.php b/src/Responses/Product.php index 30dc3e6..c9f202f 100644 --- a/src/Responses/Product.php +++ b/src/Responses/Product.php @@ -40,7 +40,7 @@ public function __construct($data) if (!$this->isError()) { if (isset($data->id)) { - $this->id = $data->id; + $this->id = (int) $data->id; } if (isset($data->brand)) { $this->brand = $data->brand; @@ -55,10 +55,10 @@ public function __construct($data) $this->validation = $data->validation; } if (isset($data->includedDomains)) { - $this->includeDomains = $data->includedDomains; + $this->includeDomains = (int) $data->includedDomains; } if (isset($data->maxDomains)) { - $this->maxDomains = $data->maxDomains; + $this->maxDomains = (int) $data->maxDomains; } if (!empty($data->prices)) { diff --git a/src/Responses/ProductPrice.php b/src/Responses/ProductPrice.php index e907ebd..42f96ea 100644 --- a/src/Responses/ProductPrice.php +++ b/src/Responses/ProductPrice.php @@ -25,16 +25,16 @@ class ProductPrice public function __construct($data) { if (isset($data->years)) { - $this->years = (int)$data->years; + $this->years = (int) $data->years; } if (isset($data->price)) { - $this->price = (float)$data->price; + $this->price = (float) $data->price; } if (isset($data->extraPrice)) { - $this->priceExtra = (float)$data->extraPrice; + $this->priceExtra = (float) $data->extraPrice; } if (isset($data->extraPriceWildcard)) { - $this->priceExtraWildcard = (float)$data->extraPriceWildcard; + $this->priceExtraWildcard = (float) $data->extraPriceWildcard; } } } diff --git a/src/Responses/Request.php b/src/Responses/Request.php index 027bd84..55a8b6c 100644 --- a/src/Responses/Request.php +++ b/src/Responses/Request.php @@ -63,8 +63,8 @@ class Request extends Base /** @var string */ public string $approverPhone; - /** @var string */ - public string $kvk; + /** @var string|null */ + public ?string $kvk = null; /** @var Product */ public Product $product; @@ -89,7 +89,7 @@ function __construct($data) if (!$this->isError()) { if (isset($data->id)) { - $this->id = $data->id; + $this->id = (int) $data->id; } if (isset($data->domainName)) { $this->domainName = $data->domainName; @@ -98,7 +98,7 @@ function __construct($data) $this->subjectAlternativeNames = $data->subjectAlternativeNames; } if (isset($data->years)) { - $this->years = $data->years; + $this->years = (int) $data->years; } if (isset($data->company)) { $this->company = $data->company; @@ -143,10 +143,10 @@ function __construct($data) $this->kvk = $data->kvk; } if (isset($data->requiresAction)) { - $this->requiresAction = $data->requiresAction; + $this->requiresAction = (bool) $data->requiresAction; } if (isset($data->brandValidation)) { - $this->brandValidation = $data->brandValidation; + $this->brandValidation = (bool) $data->brandValidation; } if (!empty($data->validations)) { diff --git a/src/Responses/RequestEE.php b/src/Responses/RequestEE.php deleted file mode 100644 index 27b15b8..0000000 --- a/src/Responses/RequestEE.php +++ /dev/null @@ -1,44 +0,0 @@ -id)) { - $this->id = $data->id; - } - if (isset($data->dateOrdered)) { - $this->dateOrdered = $data->dateOrdered; - } - if (isset($data->crt)) { - $this->crt = $data->crt; - } - if (isset($data->pkcs7)) { - $this->pkcs7 = $data->pkcs7; - } - } -} diff --git a/src/Responses/RequestValidation.php b/src/Responses/RequestValidation.php index ccd35b4..ea14011 100644 --- a/src/Responses/RequestValidation.php +++ b/src/Responses/RequestValidation.php @@ -25,13 +25,13 @@ class RequestValidation public function __construct($data) { if (isset($data->status)) { - $this->status = (bool)$data->status; + $this->status = (bool) $data->status; } if (isset($data->statusDetail)) { - $this->statusDetail = (int)$data->statusDetail; + $this->statusDetail = (int) $data->statusDetail; } if (isset($data->statusMessage)) { - $this->statusMessage = (string)$data->statusMessage; + $this->statusMessage = (string) $data->statusMessage; } if (!empty($data->domains)) { diff --git a/src/Responses/RequestValidationDomain.php b/src/Responses/RequestValidationDomain.php index dee98ac..df097ab 100644 --- a/src/Responses/RequestValidationDomain.php +++ b/src/Responses/RequestValidationDomain.php @@ -48,10 +48,10 @@ public function __construct($data) $this->domain = $data->domain; } if (isset($data->status)) { - $this->status = $data->status; + $this->status = (bool) $data->status; } if (isset($data->statusDetail)) { - $this->statusDetail = $data->statusDetail; + $this->statusDetail = (int) $data->statusDetail; } if (isset($data->statusMessage)) { $this->statusMessage = $data->statusMessage; diff --git a/src/Responses/SSLCheck.php b/src/Responses/SSLCheck.php index 424d408..17342cb 100644 --- a/src/Responses/SSLCheck.php +++ b/src/Responses/SSLCheck.php @@ -15,7 +15,7 @@ class SSLCheck extends Base public bool $passed; /** @var stdClass */ - public stdClass $tests; + public $tests; /** @var string */ public string $fullJsonResult; @@ -33,7 +33,7 @@ public function __construct($data) $this->ifaceName = $data->ifaceName; } if (isset($data->passed)) { - $this->passed = $data->passed; + $this->passed = (bool) $data->passed; } if (isset($data->tests)) { $this->tests = $data->tests; diff --git a/src/Responses/ValidationCall.php b/src/Responses/ValidationCall.php index 0450990..92ba17d 100644 --- a/src/Responses/ValidationCall.php +++ b/src/Responses/ValidationCall.php @@ -28,7 +28,7 @@ public function __construct($data) parent::__construct($data); if (isset($data->requestId)) { - $this->requestId = $data->requestId; + $this->requestId = (int) $data->requestId; } if (isset($data->date)) { $this->date = (new DateTime($data->date)); diff --git a/tests/Endpoint/CertificateTest.php b/tests/Endpoint/CertificateTest.php index 87c6c53..81070f5 100644 --- a/tests/Endpoint/CertificateTest.php +++ b/tests/Endpoint/CertificateTest.php @@ -1,4 +1,5 @@ certificates->all(); } - } diff --git a/tests/Endpoint/InvoiceTest.php b/tests/Endpoint/InvoiceTest.php index 933ff10..3c128ec 100644 --- a/tests/Endpoint/InvoiceTest.php +++ b/tests/Endpoint/InvoiceTest.php @@ -1,4 +1,5 @@ assertNull($request->kvk); } - /** * @description "Retry DCV" */ @@ -80,10 +78,7 @@ public function testScheduleValidationCallSuccess() $this->assertNull($request->getErrorData()); $this->assertEquals('The phone call has successfully been scheduled.', $request->getMessage()); $this->assertInstanceOf(Base::class, $request); - $this->assertNull($request->page); - $this->assertNull($request->pages); - $this->assertNull($request->total); - $this->assertNull($request->limit); + $this->assertNull($request->getPagination()); } /** diff --git a/tests/Endpoint/SupportTest.php b/tests/Endpoint/SupportTest.php index 74aa1da..ff07136 100644 --- a/tests/Endpoint/SupportTest.php +++ b/tests/Endpoint/SupportTest.php @@ -1,4 +1,5 @@ assertEquals('hostmaster@sslcertificaten.nl', @$approverEmails[2]); $this->assertEquals('postmaster@sslcertificaten.nl', @$approverEmails[3]); $this->assertEquals('webmaster@sslcertificaten.nl', @$approverEmails[4]); - $this->assertEquals('info@xolphin.nl', @$approverEmails[5]); + $this->assertEquals('domainadmin@sectigo.com', @$approverEmails[5]); } /** diff --git a/tests/Requests/RequestEERequestTest.php b/tests/Requests/RequestEERequestTest.php deleted file mode 100644 index f2cb127..0000000 --- a/tests/Requests/RequestEERequestTest.php +++ /dev/null @@ -1,77 +0,0 @@ - [ - [ - 'csr' => $csr, - 'dcvType' => DCVTypes::DNS_VALIDATION, - 'subjectAlternativeNames' => 'xolphin.nl,xolphin.com,xolphin.net', - 'approverFirstName' => 'John', - 'approverLastName' => 'Doe', - 'approverEmail' => 'johndoe@xolphin.nl', - 'approverPhone' => '+316123456789', - 'validate' => true - ], - (new RequestEERequest()) - ->setCsr($csr) - ->setApproverEmail('johndoe@xolphin.nl') - ->setApproverFirstName('John') - ->setApproverLastName('Doe') - ->setApproverPhone('+316123456789') - ->setSubjectAlternativeNames([ - 'xolphin.nl', - 'xolphin.com', - 'xolphin.net' - ]) - ->setValidate(true) - ->setDcvType(DCVTypes::DNS_VALIDATION) - ], - ]; - } - - /** - * @dataProvider getApiRequestBodyDataProvider - */ - public function testGetApiRequestBody(array $expectedResults, RequestEERequest $RequestEERequest): void - { - $actualResults = $RequestEERequest->getApiRequestBody(); - - $this->assertEquals( - $expectedResults, - $actualResults - ); - } -} \ No newline at end of file