Jump to content
Latest News: (loading..)

Recommended Posts

This add-on will show a state drop down menu in "create account", address_book" and "checkout_new_address".

- When the customer first views the Create Account or Add Address Book Entry form, a default country is pre-selected
- If the default country has zones (states, provinces, etc.), a drop-down list for the zones is automatically displayed; if no zones are in the database, a normal text input field is shown instead
- If the customer changes the country, the form refreshes and the state field is updated according to the new country; any entries in other fields are preserved.

BS version only.

----------------------------------

Country State BS v3.0 - milerwan

Adding/editing some codes into states.php file to fix automatic display of entry_state field if not null
Javascript changes into catalog/includes/modules/ht_country_state_jquery.php file :
- Automatic display of entry_state field if not null
- Refresh logo alignment
- Removal complementary text which is useless
Language files updated next to the additional text removal
Add french language for form

And always no core change !

NB: We are never better served than by ourselves ;)

----------------------------------

Official thread here.

Link to the app : https://apps.oscommerce.com/UT1CL&country-state-selector-bs


Osc v2.3.4 BS "custom"

Share this post


Link to post
Share on other sites

@milerwan

1. the refresh/spinner icon is broken in 2.3.4.1 CE Frozen and newer BS versions. It needs update to fontawesome 5.

2. it seems your version is based on the older version 2.4.4 or older, not the newest version 2.4.5 uploaded by Demitri

Share this post


Link to post
Share on other sites
Posted (edited)
1 hour ago, raiwa said:

@milerwan,

1. the refresh/spinner icon is broken in 2.3.4.1 CE Frozen and newer BS versions. It needs update to fontawesome 5.

2. your version is based on the older version 2.4.4 or older, not the newest version 2.4.5 uploaded by Demitri

 

 

1. For those who has got 2.3.4.1 CE Frozen version and/or fontawesome 5 :

Edit includes/modules/header_tags/ht_country_state_jquery.php file and find this code :

            $oscTemplate->addBlock('<script>$(document).ready(function(){if($("#inputCountry").val()==""){$("#inputCountry").val('.STORE_COUNTRY.');}if($("#inputCountry").val()!=""){$("label[for=\'inputState\']+div").html(\'<i class="fa fa-refresh fa-spin fa-2x fa-fw" style="none:right; margin-top:-2px; margin-bottom:13px; margin-left:0px;"></i>\'),id_country=$("#inputCountry").val(),$.post("states.php",{country_id:id_country,state_name:sn,state_entry:se},function(a){$("label[for=\'inputState\']+div").html(a)})}});</script>' . "\n", $this->group);
          }

          $oscTemplate->addBlock('<script>if($("#inputState").val()!=""){var se=$("#inputState").val();}{var sn=$("#inputState").val();}$("#inputCountry").change(function(){$("label[for=\'inputState\'] + div").html(\'<i class="fa fa-refresh fa-spin fa-2x fa-fw" style="none:right; margin-top:-2px; margin-bottom:13px; margin-left:0px;"></i>\'),id_country=$("#inputCountry").val(),$.post("states.php",{country_id:id_country,state_name:sn,state_entry:se},function(a){$("label[for=\'inputState\'] + div").html(a)})});</script>' . "\n", $this->group);

And replace by this :

          if (MODULE_HEADER_TAGS_COUNTRY_STATE_JQUERY_DEFAULT_COUNTRY == 'True') {
            $oscTemplate->addBlock('<script>$(document).ready(function(){if($("#inputCountry").val()==""){$("#inputCountry").val('.STORE_COUNTRY.');}if($("#inputCountry").val()!=""){$("label[for=\'inputState\']+div").html(\'<i class="fas fa-spinner fa-spin fa-2x fa-fw" style="none:right; margin-top:3px; margin-bottom:6px; margin-left:0px;"></i>\'),id_country=$("#inputCountry").val(),$.post("states.php",{country_id:id_country,state_name:sn,state_entry:se},function(a){$("label[for=\'inputState\']+div").html(a)})}});</script>' . "\n", $this->group);
          }

          $oscTemplate->addBlock('<script>if($("#inputState").val()!=""){var se=$("#inputState").val();}{var sn=$("#inputState").val();}$("#inputCountry").change(function(){$("label[for=\'inputState\'] + div").html(\'<i class="fas fa-spinner fa-spin fa-2x fa-fw" style="none:right; margin-top:3px; margin-bottom:6px; margin-left:0px;"></i>\'),id_country=$("#inputCountry").val(),$.post("states.php",{country_id:id_country,state_name:sn,state_entry:se},function(a){$("label[for=\'inputState\'] + div").html(a)})});</script>' . "\n", $this->group);

 

2. The version of Demitri is useless :
- no need to change the checkbox selection for files
- no need to change the name of the files

That's my choice.
 

 

For information, here are the changes applied for v3.0 :

In state.php file (- deleted / + replaced) :

  require('includes/application_top.php');

-  $country_id = (isset($_POST['country_id']) ? $_POST['country_id'] : '');
+  $country_id = $_POST['country_id'];
  $state_name = (isset($_POST['state_name']) ? $_POST['state_name'] : '');
+  $state_entry = (isset($_POST['state_entry']) ? $_POST['state_entry'] : '');

  $check_query = tep_db_query("select count(*) as total from zones where zone_country_id = '" . (int)$country_id . "'");
  $check = tep_db_fetch_array($check_query);
  $entry_state_has_zones = ($check['total'] > 0);

  if ($entry_state_has_zones == true) {
    $zones_array = array();
    $zones_array[0] = array('id' => '', 'text' => PULL_DOWN_DEFAULT);
    $zones_query = tep_db_query("select zone_name from zones where zone_country_id = '" . (int)$country_id . "' order by zone_name");
    while ($zones_values = tep_db_fetch_array($zones_query)) {
      $zones_array[] = array('id' => $zones_values['zone_name'], 'text' => $zones_values['zone_name']);
    }
    echo tep_draw_pull_down_menu('state', $zones_array, $state_name, 'id="inputState" aria-describedby="atState"');
    echo FORM_REQUIRED_INPUT;
  } else {
-    echo tep_draw_input_field('state', NULL, 'id="inputState" placeholder="' . ENTRY_STATE_TEXT . '"');
+    echo tep_draw_input_field('state', (isset($country_id) ? tep_get_zone_name($country_id, $state_name, $state_entry) : ''), 'id="inputState" placeholder="' . ENTRY_STATE_TEXT . '"');
    echo FORM_REQUIRED_INPUT;
  }

 

In  includes/modules/header_tags/ht_country_state_jquery.php file :

          if (MODULE_HEADER_TAGS_COUNTRY_STATE_JQUERY_DEFAULT_COUNTRY == 'True') {
-            $oscTemplate->addBlock('<script>$(document).ready(function(){if($("#inputCountry").val()==""){$("#inputCountry").val('.STORE_COUNTRY.');}if($("#inputCountry").val()!=""){$("label[for=\'inputState\']+div").html(\''.MODULE_HEADER_TAGS_COUNTRY_STATE_JQUERY_TEXT. ' <i class="fa fa-refresh fa-spin fa-2x fa-fw"></i>\'),id_country=$("#inputCountry").val(),$.post("states.php",{country_id:id_country,state_name:ds},function(a){$("label[for=\'inputState\']+div").html(a)})}});</script>' . "\n", $this->group);
+            $oscTemplate->addBlock('<script>$(document).ready(function(){if($("#inputCountry").val()==""){$("#inputCountry").val('.STORE_COUNTRY.');}if($("#inputCountry").val()!=""){$("label[for=\'inputState\']+div").html(\'<i class="fa fa-refresh fa-spin fa-2x fa-fw" style="none:right; margin-top:-2px; margin-bottom:13px; margin-left:0px;"></i>\'),id_country=$("#inputCountry").val(),$.post("states.php",{country_id:id_country,state_name:sn,state_entry:se},function(a){$("label[for=\'inputState\']+div").html(a)})}});</script>' . "\n", $this->group);
          }

-          $oscTemplate->addBlock('<script>if($("#inputState").val()!=""){var ds=$("#inputState").val();}$("#inputCountry").change(function(){$("label[for=\'inputState\'] + div").html(\'<i class="fa fa-refresh fa-spin fa-2x fa-fw"></i>\'),id_country=$("#inputCountry").val(),$.post("states.php",{country_id:id_country,state_name:ds},function(a){$("label[for=\'inputState\'] + div").html(a)})});</script>' . "\n", $this->group);
+          $oscTemplate->addBlock('<script>if($("#inputState").val()!=""){var se=$("#inputState").val();}{var sn=$("#inputState").val();}$("#inputCountry").change(function(){$("label[for=\'inputState\'] + div").html(\'<i class="fa fa-refresh fa-spin fa-2x fa-fw" style="none:right; margin-top:-2px; margin-bottom:13px; margin-left:0px;"></i>\'),id_country=$("#inputCountry").val(),$.post("states.php",{country_id:id_country,state_name:sn,state_entry:se},function(a){$("label[for=\'inputState\'] + div").html(a)})});</script>' . "\n", $this->group);

 

As you can see I have modified javascript code and renamed "ds" variable to "sn" (for $state_name var, for better readability) and added a "se" variable (for $state_entry).
I have deleted the constant text (no need) and applied style to fix the break line.

Edited by milerwan

Osc v2.3.4 BS "custom"

Share this post


Link to post
Share on other sites

New update : https://apps.oscommerce.com/UT1CL&country-state-selector-bs

Country State BS v3.0.1 - milerwan

Apply name changes for module and files (from 2.4.5 by Demitry) as "jQuery" library is not use in this module (and therefore replaced by "Selector" to match the real name of the module) :
- Country/State jQuery -> Country/State Selector
- ht_country_state_jquery.php -> ht_country_state_selector.php
Cleaning some unnecessary codes into states.php file
Change icon "refresh" to "spinner" for better look with a new line adjustment (includes/modules/ht_country_state_selector.php)
Add fontawesome 5 compatibility for users of new 2.3.4.1 CE Frozen version and/or fontawesome 5 library in their "classic" 2.3.4 BS shop (separated folder to copy to overwrite "includes/modules/ht_country_state_selector.php" file


Osc v2.3.4 BS "custom"

Share this post


Link to post
Share on other sites
Posted (edited)
1 hour ago, raiwa said:

@milerwan. I believe there is still one glitch:

in ht module style "none:right; " seems to me doesn't exist. Otherwise good work :thumbsup:

Yes, strange thing I have forgotten to delete I think.

 

43 minutes ago, raiwa said:

@milerwan, the isset(variable) checks you removed are not unnecessary . The variables are not always defined. It is good coding praxis to check if variables are set.

In this point, I'm not agree.

1. When the code is activated, "$country_id / $_POST['country_id']" can't be blank.
If it is "$zones_query" or "tep_get_zone_name" function will return no result for example.

2. If you take a look on the "tep_get_zone_name" function, you will see that if no result for "$zones_query", then "$state_entry" will return :

////
// Returns the zone (State/Province) name
// TABLES: zones
  function tep_get_zone_name($country_id, $zone_id, $default_zone) {
    $zone_query = tep_db_query("select zone_name from " . TABLE_ZONES . " where zone_country_id = '" . (int)$country_id . "' and zone_id = '" . (int)$zone_id . "'");
    if (tep_db_num_rows($zone_query)) {
      $zone = tep_db_fetch_array($zone_query);
      return $zone['zone_name'];
    } else {
      return $default_zone;
    }
  }


At this point even if "$_POST['state_name']" or "$_POST['state_entry']" are blank, the isset is useless because it return same result.

3. If you use a condition with isset() to return same blank result, what is the point of using it?!?

Do you see what I mean ?

 

Edited by milerwan

Osc v2.3.4 BS "custom"

Share this post


Link to post
Share on other sites
Posted (edited)

even the result is the same, it produces a php ERROR UNDEFINED, because "$_POST['state_name']" or "$_POST['state_entry']" are not blank, they are undefined (not set)

blank, null and undefined or not set is not the same.

Thats the reason it is used in core address_book_details.php:

isset($entry['entry_country_id']) ? tep_get_zone_name($entry['entry_country_id'], $entry['entry_zone_id'], $entry['entry_state']) : ''

 

Edited by raiwa

Share this post


Link to post
Share on other sites
Posted (edited)
2 hours ago, raiwa said:

even the result is the same, it produces a php ERROR UNDEFINED, because "$_POST['state_name']" or "$_POST['state_entry']" are not blank, they are undefined (not set)

blank, null and undefined or not set is not the same.

Thats the reason it is used in core address_book_details.php:


isset($entry['entry_country_id']) ? tep_get_zone_name($entry['entry_country_id'], $entry['entry_zone_id'], $entry['entry_state']) : ''

 

1. If you take a look on registred data from address_book table, you will see that there is no NULL, only 0, number or blank possible.
All registred fields are already isset() compatible or blank, so no need of isset() in that case for $_POST variables in the begining of the script.

2. Take a look on the condition from state.php file :

  if ($entry_state_has_zones == true) {
    $zones_array = array();
    $zones_array[0] = array('id' => '', 'text' => PULL_DOWN_DEFAULT);
    $zones_query = tep_db_query("select zone_name from zones where zone_country_id = '" . (int)$country_id . "' order by zone_name");
    while ($zones_values = tep_db_fetch_array($zones_query)) {
      $zones_array[] = array('id' => $zones_values['zone_name'], 'text' => $zones_values['zone_name']);
    }
    echo tep_draw_pull_down_menu('state', $zones_array, $state_name, 'id="inputState" aria-describedby="atState"');
	echo FORM_REQUIRED_INPUT;
  } else {
    echo tep_draw_input_field('state', tep_get_zone_name($country_id, $state_name, $state_entry), 'id="inputState" placeholder="' . ENTRY_STATE_TEXT . '"');
    echo FORM_REQUIRED_INPUT;
  }

For "$entry_state_has_zones == true" (or false) could be, you must have upstream valid "$country_id / $_POST['country_id']".
So understand that "$country_id" variable couldn't be blank or NULL in that case.

Do you understand what I mean now ?

Edited by milerwan

Osc v2.3.4 BS "custom"

Share this post


Link to post
Share on other sites
Posted (edited)

With "tep_get_zone_name()" function, if variables ($country_id or $state_name) don't match with existing entries from ZONE table (or $state_name is blank), the condition returns "$state_entry" variable.

If "$state_entry" variable don't exist then you will have blank value in the "tep_draw_input_field" field.

if I followed your reasoning, you would like to have this kind of code :

(isset($state_entry) ? echo tep_draw_input_field('state', tep_get_zone_name($country_id, $state_name, $state_entry), 'id="inputState" placeholder="' . ENTRY_STATE_TEXT . '"') : echo tep_draw_input_field('state', NULL, 'id="inputState" placeholder="' . ENTRY_STATE_TEXT . '"'));

 

For me it is 100% useless. At no moment you can have an sql error so isset() condition is useless everywhere.

 

PS: Wait I test a thing and I tell you result...

I have tested to save address with original script "echo tep_draw_input_field('state', NULL, 'id="inputState" placeholder="' . ENTRY_STATE_TEXT . '"')" and there is always blank entry (for entry_state) in mysql registred data, never "NULL" syntax.

Edited by milerwan

Osc v2.3.4 BS "custom"

Share this post


Link to post
Share on other sites
Posted (edited)
21 minutes ago, milerwan said:

If "$state_entry" variable don't exist then you will have blank value in the "tep_draw_input_field" field.

If $state entry doesn't exist, it means it is not defined and php throws an undefined error.

As stated, it works but it is not good coding practice. That's all.

Edited by raiwa

Share this post


Link to post
Share on other sites
Just now, raiwa said:

If $state entry doesn't exist, it means it is not defined and php throws an undefined error.

As stated, it works but it is not good coding practice. That's all.

From mysql, I have manually checked NULL for "entry_state" and saved and no matter when I edit again the address from "address_book_process.php".
I think you point to a problem that does not exist in this case friend...


Osc v2.3.4 BS "custom"

Share this post


Link to post
Share on other sites
Posted (edited)
4 minutes ago, raiwa said:

nothing to do with what is in your database. A constant or variable must be defined before using it or it's a coding error.

What do you think why it is done like this in the core create account?

1. ???

2. You haven't read carefully my previous post :

 

Edited by milerwan

Osc v2.3.4 BS "custom"

Share this post


Link to post
Share on other sites

Ok, you're confusing the lines of conditions between those from "address_book_details.php" and "states.php".

Take a look and compare :
- address_book_details.php :

1a          if ($process == true) {
2a            if ($entry_state_has_zones == true) {
              $zones_array = array();
              $zones_query = tep_db_query("select zone_name from " . TABLE_ZONES . " where zone_country_id = '" . (int)$country . "' order by zone_name");
              while ($zones_values = tep_db_fetch_array($zones_query)) {
                $zones_array[] = array('id' => $zones_values['zone_name'], 'text' => $zones_values['zone_name']);
              }
              echo tep_draw_pull_down_menu('state', $zones_array, 0, 'id="inputState" aria-describedby="atState"');
              if (tep_not_null(ENTRY_STATE_TEXT)) echo '<span id="atState" class="help-block">' . ENTRY_STATE_TEXT . '</span>';
2b            } else {
              echo tep_draw_input_field('state', NULL, 'id="inputState" placeholder="' . ENTRY_STATE_TEXT . '"');
2            }
1b          } else {
            echo tep_draw_input_field('state', (isset($entry['entry_country_id']) ? tep_get_zone_name($entry['entry_country_id'], $entry['entry_zone_id'], $entry['entry_state']) : ''), 'id="inputState" placeholder="' . ENTRY_STATE_TEXT . '"');
1          }
		  echo FORM_REQUIRED_INPUT;

- states.php :

2a  if ($entry_state_has_zones == true) {
    $zones_array = array();
    $zones_array[0] = array('id' => '', 'text' => PULL_DOWN_DEFAULT);
    $zones_query = tep_db_query("select zone_name from zones where zone_country_id = '" . (int)$country_id . "' order by zone_name");
    while ($zones_values = tep_db_fetch_array($zones_query)) {
      $zones_array[] = array('id' => $zones_values['zone_name'], 'text' => $zones_values['zone_name']);
    }
    echo tep_draw_pull_down_menu('state', $zones_array, $state_name, 'id="inputState" aria-describedby="atState"');
	echo FORM_REQUIRED_INPUT;
2b  } else {
    echo tep_draw_input_field('state', tep_get_zone_name($country_id, $state_name, $state_entry), 'id="inputState" placeholder="' . ENTRY_STATE_TEXT . '"');
    echo FORM_REQUIRED_INPUT;
2  }

Now it's clearer or still not? :wink:


Osc v2.3.4 BS "custom"

Share this post


Link to post
Share on other sites

on address_book_process.php => add new address => change to a country which has no states: neither $_POST['state_entry'] nor $_POST['state_name'] is set.

if you change the country to "please select", $_POST['country_id'] is not set.

Maybe I miss something and you are right. But I wouldn't remove the isset checks without beeing 100% sure that they are not needed. Up to you. I only wanted to help.

 

Share this post


Link to post
Share on other sites

New update : https://apps.oscommerce.com/UT1CL&country-state-selector-bs

Country State BS v3.0.2 - milerwan

Cleaning some unnecessary javascript code into "includes/modules/ht_country_state_selector.php" file (my fault)
Cleaning some unnecessary php code (variable and function) into "states.php" file to reach genuine code

NB: The mountain gave birth to a mouse. ^_^'


Osc v2.3.4 BS "custom"

Share this post


Link to post
Share on other sites
Posted (edited)
If I do print_r($_POST) in address_book_process.php => new address, I get: Array ( [country_id] => 212 )  => $_POST[state_name] is not set! (212 is a country without states)
 
Ressource:

In PHP, a variable or array element which has never been set is different from one whose value is null; attempting to access such an unset value is a runtime error.

..............................................................................

It's also worth mentioning that as runtime errors go, a missing array index is considered a minor one (assigned the E_NOTICE level). If you change the error_reporting level so that notices are ignored, your original code will actually work as written, with the attempted array access returning null. But that's considered bad practice, especially for production code.

Edited by raiwa

Share this post


Link to post
Share on other sites
Posted (edited)

I am using this addon together with @Raiwa 's modular checkout & ship in cart estimator:

Just some minutes ago a customer bought virtual products and I noticed that there is no shipping or billing address in the order. When I open the order in the order editor, it crahes, as it seems because of the customer's state which contains a '  ! (Country: France , state: Val d'Oise )

 

1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'Oise' OR zone_code = 'Val d'Oise')' at line 1

select zone_id from zones where zone_country_id = '73' and (zone_name = 'Val d'Oise' OR zone_code = 'Val d'Oise')

 

I can't tell if this has to do with any of the addons involved here, or with 2.3.4.1 CE. What I can tell is that an older order with virtual products by the same customer from last year works and appears alright!

Edited by inra311

Share this post


Link to post
Share on other sites
7 minutes ago, inra311 said:

I am using this addon together with @Raiwa 's modular checkout & ship in cart estimator:

Just some minutes ago a customer bought virtual products and I noticed that there is no shipping or billing address in the order. When I open the order in the order editor, it crahes, as it seems because of the customer's state which contains a '  ! (Country: France , state: Val d'Oise )

 

1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'Oise' OR zone_code = 'Val d'Oise')' at line 1

select zone_id from zones where zone_country_id = '73' and (zone_name = 'Val d'Oise' OR zone_code = 'Val d'Oise')

 

I can't tell if this has to do with any of the addons involved here, or with 2.3.4.1 CE. What I can tell is that an older order with virtual products by the same customer from last year works and appears alright!

Hi,

The error you have is because oscommerce don't support state name entry with ' in (I'm French user and I've got the same issue regardless of the use of this module).
Edit the catalog of state names from admin, select "Lieux / taxes" -> "Zones" and modifiy "Val d'Oise" to "Val d Oise" (without coma) and save.
Like this you will not have the error anywhere even from Order Editor normally.


Osc v2.3.4 BS "custom"

Share this post


Link to post
Share on other sites
6 hours ago, raiwa said:
If I do print_r($_POST) in address_book_process.php => new address, I get: Array ( [country_id] => 212 )  => $_POST[state_name] is not set! (212 is a country without states)
 
Ressource:

In PHP, a variable or array element which has never been set is different from one whose value is null; attempting to access such an unset value is a runtime error.

..............................................................................

It's also worth mentioning that as runtime errors go, a missing array index is considered a minor one (assigned the E_NOTICE level). If you change the error_reporting level so that notices are ignored, your original code will actually work as written, with the attempted array access returning null. But that's considered bad practice, especially for production code.

You have made the change in "states.php" file, isn't it ?
could you see me the code please ?


Osc v2.3.4 BS "custom"

Share this post


Link to post
Share on other sites
Posted (edited)

I have tested your trick code but I haven't the same result as yours :

  if ($entry_state_has_zones == true) {
    $zones_array = array();
    $zones_array[0] = array('id' => '', 'text' => PULL_DOWN_DEFAULT);
    $zones_query = tep_db_query("select zone_name from zones where zone_country_id = '" . (int)$country_id . "' order by zone_name");
    while ($zones_values = tep_db_fetch_array($zones_query)) {
      $zones_array[] = array('id' => $zones_values['zone_name'], 'text' => $zones_values['zone_name']);
    }
    echo tep_draw_pull_down_menu('state', $zones_array, $state_name, 'id="inputState" aria-describedby="atState"');
  } else {
    echo tep_draw_input_field('state', $state_name, 'id="inputState" placeholder="' . ENTRY_STATE_TEXT . '"');
  }
  echo FORM_REQUIRED_INPUT;
  print_r ($_POST);


Here is 2 screenshots.


1. Result when editing an existing address ($state_name == '13' because already registred like this in db):
edit_address.jpg.93c2363836c26e722f477fe506f224e3.jpg

2. Result when create a new existing address ($state_name doesn't exist):new_address.jpg.6b4f8ae50377cbc6de5148cc49f96c2b.jpg

 

Does I have to see displayed "$_POST[state_name] is not set!" mention ?!?

Edited by milerwan

Osc v2.3.4 BS "custom"

Share this post


Link to post
Share on other sites

I don't know why it doesn't show the error. Maybe it's because the script is accessed via javascript? But if 'state_name' is not in the array listed, it is not set and doesn't exist.

Meanwhile it's always better to echo variables where they are used:

  require('includes/application_top.php');

  echo '$_POST' . print_r($_POST);
  $country_id = $_POST['country_id'];
  $state_name = $_POST['state_name'];

  $check_query = tep_db_query("select count(*) as total from zones where zone_country_id = '" . (int)$country_id . "'");

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×