Jump to content

jhsachs

Members
  • Posts

    135
  • Joined

  • Last visited

Everything posted by jhsachs

  1. If you've had good experiences with an all-in-one WAMP package, would you please recommend it? Context: I've installed WAMP piece by piece several times, but I'm looking for a more efficient method. Thus I tried an all-in-one package for my current project. I chose one that looked well finished and popular, but when I was done, MySQL didn't work. My preliminary efforts at diagnosing the problem just led me into deep water. Since my objective was to spend less time installing WAMP, not more, I posted a request for help in the package's forum with a description of what had happened and what I'd found. Over the weekend I got one reply. Its drift was, "If you had read the publicly available MySQL documentation, you would know..." The gist was that the problem isn't what I thought but I shouldn't expect any help figuring out what it is. Maybe I can fix the problem with a reasonable additional investment of time, and maybe not. I'd rather remove this package and install one which doesn't create problems, or if it does, they're easy to fix, or if they're not, the forum members are more helpful. Thus, I'm soliciting recommendations.
  2. I'm not sure which version of Apache is installed; phpinfo doesn't say, and I haven't had time to research it otherwise. If the version of Apache doesn't support SNI, replacing it is not an option. It's on a managed server, and neither my client nor I would be prepared to roll our own.
  3. If you have reason to believe that the problem is in .htaccess, certainly you need to see it. Here it is; I've done substitutions on the domain names to make them consistent with the OP. Options +FollowSymlinks RewriteEngine on rewritecond %{http_host} ^http://production\.com [nc] rewriterule ^(.*)$ http://www.production\.com/$1 [r=301,nc] rewritecond %{http_host} ^https://production\.com [nc] rewriterule ^(.*)$ https://www.production\.com/$1 [r=301,nc] rewritecond %{http_host} ^http://domain\.com [nc] rewriterule ^(.*)$ http://www.domain\.com/$1 [r=301,nc] rewritecond %{http_host} ^https://domain\.com [nc] rewriterule ^(.*)$ https://www.domain\.com/$1 [r=301,nc] ("domain.com" is the domain on which I'm having this problem, a domain used for QA. "production.com" is the corresponding production domain. The file contains references to both only so that I can use a single version of the .htaccess file in both.) The limitation of one certificate per domain sounds likely to be the problem, though. If so, I can eliminate it by moving the site to another domain name, which probably won't be a big deal. I'll contact the client to ask if I can use one of their parked names.
  4. I'm trying to set up a subdomain for the first time. Something is happening with the URL resolution that I don't understand. The directory structure looks like this: serverRoot home accountRoot subdomainRoot public_html (subdomain document root) include (subdomain's include files) public_html (domain document root) include (domain's include files) When I load subdomain.domain.com, it works. When I load http://subdomain.domain.com, it works. When I load https://subdomain.domain.com, I get an error. By fiddling with the source code, I've determined that the server is actually loading index.php from the root domain instead of the subdomain. The only cause I can think of for this is a rewrite rule, but I think I've eliminated that possibility. There are no rewrite rules that could match https://subdomain.domain.com. Furthermore, the rewrite rules for https and http are exactly equivalent, so any rule that affects one should affect the other. And finally, the effect of a rewrite rule should be visible in the URL shown in the browser's address bar, but it isn't changed. I'm looking for ideas here: what might be wrong?
  5. There was a bit more to it than that, but you got me pointed in the right direction. console.log is indeed useful. Here my debugged code. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> <title>A scrolling div</title> <link rel="stylesheet" href="FixedParts.css" type="text/css" /> <script type="text/javascript"> /** * Return the absolute x and y offsets of an object. * @return: [x_offset,y_offset] */ function findPos(obj) { var curleft = curtop = 0; if (obj.offsetParent) { // Add each new object's offsetLeft and offsetTop to curleft and curtop. do { curleft += obj.offsetLeft; curtop += obj.offsetTop; console.log( ' '+obj.nodeName+'='+obj.offsetTop+','+curtop ); // The loopends when we process the root object (with no parent). } while ( (obj=obj.offsetParent) ); return [curleft,curtop]; } } /** * Resize <div id='mainDiv'> when <body>'s resize event occurs. */ function resizeMainDiv() { var bodyHeight = document.body.offsetHeight; console.log('bodyHeight='+bodyHeight); var mainDiv = document.getElementById('mainDiv'); var mainDiv_xy = findPos(mainDiv); console.log('mainDiv_xy='+mainDiv_xy); var divHeight = bodyHeight - mainDiv_xy[1]; console.log('divHeight='+divHeight); mainDiv.style.height = divHeight+'px'; } </script> </head> <body bgcolor="#ffffff" onLoad='resizeMainDiv()' onResize='resizeMainDiv()'> <div id="mainContainer"> <div id="masthead"> <table width="820"> <tr> <td width="180" align="center"><strong>This is the heading!</strong></td> </tr> </table> <table width="100%"> <tr> <td> <ul class="glossymenu"> <li class="current">S o m e T a b s G o H e r e</li> </ul> </td> </tr> </table> </div> <table> <tr> <td> <div id="leftSidebar"> <div id="sectionLinks" bgcolor="white"> <div> <table width="156"> <tr><td align="center"> Some<br/> more<br/> links<br/> and<br/> some<br/> ads<br/> go<br/> here. </td></tr> </table> </div> </div> </div> </td> <td> <div class="bodyOuter"> <div class="bodyInner" id="mainDiv"> <h1 id="pageName" class="headers">This is where the text goes.</h1> <p><strong>There's</strong> lots and lots and lots and lots and lots and lots of text so it's so long it scrolls.</p> <p><strong>There's lots </strong>and lots and lots and lots and lots and lots of text so it's so long it scrolls.</p> <p><strong>There's lots and </strong>lots and lots and lots and lots and lots of text so it's so long it scrolls.</p> <p><strong>There's lots and lots </strong>and lots and lots and lots and lots of text so it's so long it scrolls.</p> <p><strong>There's lots and lots and </strong>lots and lots and lots and lots of text so it's so long it scrolls.</p> <p><strong>There's lots and lots and lots </strong>and lots and lots and lots of text so it's so long it scrolls.</p> <p><strong>There's lots and lots and lots and </strong>lots and lots and lots of text so it's so long it scrolls.</p> <p><strong>There's lots and lots and lots and lots </strong>and lots and lots of text so it's so long it scrolls.</p> <p><strong>There's lots and lots and lots and lots and </strong>lots and lots of text so it's so long it scrolls.</p> <br/> <p><strong>There's</strong> lots and lots and lots and lots and lots and lots of text so it's so long it scrolls.</p> <p><strong>There's lots </strong>and lots and lots and lots and lots and lots of text so it's so long it scrolls.</p> <p><strong>There's lots and </strong>lots and lots and lots and lots and lots of text so it's so long it scrolls.</p> <p><strong>There's lots and lots </strong>and lots and lots and lots and lots of text so it's so long it scrolls.</p> <p><strong>There's lots and lots and </strong>lots and lots and lots and lots of text so it's so long it scrolls.</p> <p><strong>There's lots and lots and lots </strong>and lots and lots and lots of text so it's so long it scrolls.</p> <p><strong>There's lots and lots and lots and </strong>lots and lots and lots of text so it's so long it scrolls.</p> <p><strong>There's lots and lots and lots and lots </strong>and lots and lots of text so it's so long it scrolls.</p> <p><strong>There's lots and lots and lots and lots and </strong>lots and lots of text so it's so long it scrolls.</p> <br/> <p><strong>There's</strong> lots and lots and lots and lots and lots and lots of text so it's so long it scrolls.</p> <p><strong>There's lots </strong>and lots and lots and lots and lots and lots of text so it's so long it scrolls.</p> <p><strong>There's lots and </strong>lots and lots and lots and lots and lots of text so it's so long it scrolls.</p> <p><strong>There's lots and lots </strong>and lots and lots and lots and lots of text so it's so long it scrolls.</p> <p><strong>There's lots and lots and </strong>lots and lots and lots and lots of text so it's so long it scrolls.</p> <p><strong>There's lots and lots and lots </strong>and lots and lots and lots of text so it's so long it scrolls.</p> <p><strong>There's lots and lots and lots and </strong>lots and lots and lots of text so it's so long it scrolls.</p> <p><strong>There's lots and lots and lots and lots </strong>and lots and lots of text so it's so long it scrolls.</p> <p><strong>There's lots and lots and lots and lots and </strong>lots and lots of text so it's so long it scrolls.</p> <br/> <p><strong>There's</strong> lots and lots and lots and lots and lots and lots of text so it's so long it scrolls.</p> <p><strong>There's lots </strong>and lots and lots and lots and lots and lots of text so it's so long it scrolls.</p> <p><strong>There's lots and </strong>lots and lots and lots and lots and lots of text so it's so long it scrolls.</p> <p><strong>There's lots and lots </strong>and lots and lots and lots and lots of text so it's so long it scrolls.</p> <p><strong>There's lots and lots and </strong>lots and lots and lots and lots of text so it's so long it scrolls.</p> <p><strong>There's lots and lots and lots </strong>and lots and lots and lots of text so it's so long it scrolls.</p> <p><strong>There's lots and lots and lots and </strong>lots and lots and lots of text so it's so long it scrolls.</p> <p><strong>There's lots and lots and lots and lots </strong>and lots and lots of text so it's so long it scrolls.</p> <p><strong>There's lots and lots and lots and lots and </strong>lots and lots of text so it's so long it scrolls.</p> <br/> <div align="center">There's some stuff after the text, but it's not very interesting.</div> <br/><br/> </div> </div> </td> </tr> </table> </div> </body> </html> I owe the findPos function to the nice folks at http://www.quirksmode.org/js/findpos.html.
  6. I'll look into console.log, which I'm not familiar with. It's always good to learn more about one's tools. But taking the alerts out is not going to help, because I put them in a (non-successful) attempt to diagnose the problem after I encountered it.
  7. Yes. Of course, when I don't set a breakpoint it doesn't do anything useful, and without the breakpoint I can't figure out why. Here's a simplified version of the code, which behaves the same way as the original. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> <title>A scrolling div</title> <link rel="stylesheet" href="FixedParts.css" type="text/css" /> <script type="text/javascript"> function resizeMainDiv() { alert ('start'); var mainDiv = getElementById('mainDiv'); alert ('mainDiv='+mainDiv); var divHeight = document.height - mainDiv.y; mainDiv.height = divHeight; } </script> </head> <body bgcolor="#ffffff" onResize='resizeMainDiv()'> <div id='MainDiv'> text </div> </body> </html> True, tonight... but next week it may not be! Seriously, I've been burned by upgrades often enough that I don't want anything to do with software that changes every time I turn my back. I'll upgrade the next time a new release contains a feature I want, or differs enough to create compatibility issues. Change for the sake of change doesn't appeal to me.
  8. I'm using Firebug with Firefox 10 under Windows 7. I'm trying to debug a simple JavaScript function that is called by the <body> tag's onResize event. I set a breakpoint at the first statement of the function and resized the window. I wanted Firebug to halt the function at the breakpoint. Instead, the entire system froze. I couldn't get Firefox or Firebug to respond. I was able to switch tasks by pressing Ctrl+Tab or Alt+Tab, but the cursor would not enter the task bar. The mouse pointer was fixed as a double-headed arrow (vertical or horizontal depending on how I tried to resize the window). I suspect this happened because Windows queued up multiple onResize events and Firebug halted the function while it was processing the first one, but I don't understand why that causes a problem -- or, more important, how to work around it. Any suggestions?
  9. I called it a "quirk," because I wasn't sure if it was a bug in MySQL or not. I alluded to a "bug" in my code, caused by the quirk. You're right, the documentation does describe this as correct behavior. I missed it because it's in the description of the return value rather than the description of the function. It appears that mysql_info will tell me the number of rows matched, although I have to pick the information out of a string that is written for human consumption. Not the most elegant solution possible, but far, far better than what I thought I'd have to deal with. I'll consider this solved.
  10. I've got a PHP function that many scripts use to perform MySQL queries. One of its parameters determines whether a query that matches no rows is considered an error. If the parameter is true and a query matches no rows, the function creates a log entry and kills the script. I've discovered a bug which appears to be based on an unexpected quirk in the mysql_affected_rows function: it appears to return the number of rows in which at least one column value was changed, rather than the number of rows that matched the WHERE condition. For example, if I execute a query like UPDATE xyz SET abc=1 WHERE recno=5 and a row with recno=5 exists but its value of abc is already 1, mysql_affected_rows returns 0, and my function thinks an error occurred. This is very inconvenient because I'm really trying to test for consistency errors: the absence of a row that should exist. I really couldn't care less if the value in the row is actually being changed. As far as I can see, there are only two airtight ways to fix this problem. One would be to pass the function two queries: one to test for the existence of the record, and another to perform the update. That's wrong in multiple ways: it's inefficient, it would require source code changes everywhere the function is called, and it would create a new source of bugs (writing the existence query incorrectly). The other way would be to parse the UPDATE query and construct an existence query from its table name and WHERE clause. I like a challenge as well as the next fellow, but I'm not prepared to add a SQL parser to my application. What I really want is a mysql_rows_matched function, but I can't find such a thing. Are there any other possibilities here?
  11. Teamviewer looks like it might be a useful tool here. I haven't tried installing it, but they appear to have made it really easy. One problem is the cost. A little research made it clear that my use would be considered commercial, and although non-commercial use is free, for commercial use it's pretty darned expensive. I came across another application called Camstudio, from the Camtasia people, which is open source and thus completely free. It doesn't have a collaboration function. It records a session on the user's computer which they could e-mail to me. That might work even better.
  12. I'm trying to debug a problem that a user can reproduce with fair regularity, but I can't reproduce at all. I need a tool that will tell me exactly what the user did in the browser to make the problem occur. I'm looking for recommended tools. I think these are all the requirements: It's very simple to install and use. The user will have to do this herself, and I can only help her by phone or email. It's very simple to remove when we're done using it. It operates only in the browser, and preferably only in a particular window or with a particular domain name. I don't want something that will capture passwords and bank account numbers! It's reasonably easy for me to interpret the results. Any common Windows browser is OK, but Firefox is preferred. What's available?
  13. Here's a problem for anyone who likes JavaScript puzzles and has too much time on their hands! For the sake of security, I wanted to pass all of a site's parameters via POST requests. This works fine as long as the design is limited to forms, but I was working with an existing site that has hundreds of links and dozens of buttons. I know it's possible to gin up a form with submit buttons that look like links, but the code is messy, and there were all sorts of situations that would have required special treatment; for example, buttons that contain images and links that span line breaks. I decided to solve the problem by coding links and buttons, and running a JavaScript function in the onclick event to move the URL and parameters into a hidden form, then submit the form. The idea was that a link like this... <a href="gerbils.php?wheel=yes">Gerbils!</a> ...would be recoded like this: <a onclick="return SetLoad(this);" href="gerbils.php?wheel=yes">Gerbils!</a> Every link would have to be changed, but the change would be simple and absolutely consistent. I tried it. It works. In Firefox 10. When I tried the fully "debugged" code in Internet Explorer 8 and Chrome 19, it failed in two different ways. IE appeared to execute the entire JavaScript function, then do a GET request as if the function had done nothing. Chrome wouldn't execute the function at all. At this point I decided to abandon the approach. I don't have experience debugging JavaScript in IE or Chrome, and a brief trial convinced me that in Chrome, at least, it would not be a walk in the woods. The technique I tried to implement seems elegant and useful, though... if it can be made to work in other browsers. That's the challenge. Whoever completes it will have my undying gratitude and a useful piece of code! Here's the code I've got: function SetLoad(id) { alert("We got here"); if ( typeof(id)=='string' ) { // This tag. var obj = document.getElementById(id); // id="x" onclick='return SetLoad("x")' } else if (id) { var obj = id; // onclick='return SetLoad(this);' } else { var obj = document.activeElement; // onclick='return SetLoad();' } if ( obj.tagName=='BUTTON' ) { // If it's a button var href = obj.value; // get its value } else { // else var href= obj.href; // it's an anchor; get its href. } var qPos = href.indexOf('?'); // Position of '?' var pars = ''; // Value of parameter string if any if (qPos>=0) { // If there is a '?' pars = href.substr(qPos+1); // par = the following substring href = href.substr(0,qPos); // href = the preceding substring } document.load.action = href; // Set the form's target document.load.params.value = pars; // Set the params field's value document.load.submit(); // Submit the form return false; } It operates on this form: <form name="load" method="POST" action="genX.php"> <?php passTokens() ?> <input type="hidden" name="params" value="xxxxxxxxxxx"/> </form> Each script that expects parameters must "unpack" them from the "params" parameter by calling this PHP function: /** * <p>Parse $_POST['params'] and replace it with its components.</p> * <p>This makes a script loaded by BodySuffix.inc's "load" form act like a conventionallyl loaded * script.</p> */ function parsePOST() { if ( !key_exists('params',$_POST) ) { return; } $params = $_POST['params']; if ( !isPOST('tokenS') || !isPOST('tokenP') || !isPOST('loadBy') ){ $msg = "tokenS, tokenP, or loadBy is missing:\n" . var_export($_POST,true); atrain_log(null,null,null,$msg); atrain_exit($msg); } $_POST = array( 'tokenS'=>$_POST['tokenS'], 'tokenP'=>$_POST['tokenP'], 'loadBy'=>$_POST['loadBy'] ); if ($params=='') { return; } foreach ( explode('&',$params) as $p ) { $pv = explode('=',$p); if ( count($pv)!=2) { $msg = "parsePOST ill-formed parameter: $params"; atrain_log(null,null,null,$msg); atrain_exit($msg); } $_POST[$pv[0]] = html_entity_decode($pv[1]); } }
  14. This is not really a client-side question, but it concerns HTTP, not HTML, so I think this is the best place for it. When the user clicks the Back button to reload an uncacheable page, is there a way to make the browser reload the page without displaying the "Page is expired" warning first? Background: my server-side code needs to have control over what happens when the user clicks the Back button, so the "Page is expired" warning is meaningless; there's no reason for the user ever to not reload the expired page. Thus the warning just makes the UI more difficult to use! Here's an example of how the problem comes up. The user's workflow normally goes from page A to B to C. The server side code enforces this. For example, if the user tries to go back from C to B, the server must decide whether to say "you can't do that" and reload C, or allow B to reload normally. or allow B to reload but omit some of the operations it normally performs. Therefore, B must be non-cacheable. In this case the user is doing something "wrong," even if the server decides to allow it; the "Page is expired" message is unnecessary but tolerable. But if the user goes from B to a Help page, then clicks the Back button to return to B, the operation is considered perfectly normal. Since B must not be cacheable, the server has to handle the Back operation again, but the "Page is expired" message should not appear; it will just delay the user and possibly make him think he can't get back to B when he really can.
  15. I see. The stuff I'm doing is quite different, at least currently. I'll probably incorporate Ajax into my project at some point, but when I do, it will be in the context of rather complex logic for which the debugger will still be an important tool.
  16. I think I understand -- debuggers don't lend themselves to direct application to the Ajax and SOAP calls themselves. It's not that they interfere with a debugger's usefulness in the other parts of a program.
  17. Good feedback so far. Dan, I know what Ajax and SOAP are, but I haven't worked with them as a programmer. Can you give me some insight into why they don't play well with debuggers?
  18. Do you use a debugger? If you don't, what debugging tools do you favor, and why? Whether you do or you don't, what's your impression of who uses debuggers and who doesn't? Background I'm working for a small company with a couple of programmers. I think of myself as a programmer, but I've been earning most of my income by other means for the past ten years or so. I'm trying to get back into programming now. I'm feeling somewhat uncomfortable because I expect to use a debugger, and our two "real" programmers never bothered installing one. No one has said anything, but I've got a feeling that they think I need training wheels. I'm wondering what's behind this. Am I just behind the times? (The other two guys are much younger than me. Their parents probably gave them their first personal computers about the time I bought my first house.) Or is this purely a matter of personal style?
  19. Thank you; SetLoad(this) makes sense, and works. JavaScript's scoping rules don't entirely make sense to me, but that may just be because I'm not used to running programs in a browser.
  20. I don't understand. What does "theTag" represent? Or if it's not intended to be a placeholder, where it is defined?
  21. Later... I think I know what the problem is, but I need advice to solve it. The misbehaving anchors contain <img> tags instead of text. When I use Firebug's "highlight the clicked element" feature, it highlights the <img> tag rather than the anchor tag. If I had a pointer to the <img> tag I believe I could get the anchor tag by getting its parent. But as I said, this points to the body, not the anchor or the <img>, so I can't use that.
  22. I've got an event handler for onclick which is called by a tag like <a onclick="return SetLoad();" href="..."> and it needs the value of href. This should be simple, right? When an event handler is called, I've read, this refers to the object associated with the event. In this case it should refer to the anchor tag that was clicked. But it isn't so. When Firebug stops execution at a breakpoint in the event function, its watch tab tells me that this refers to the Window object. As an alternative, I've been referring to document.activeElement. That seemed to work well, but now I've discovered a group of anchor tags for which it doesn't work. I see nothing different about them, but their document.activeElement refers to the page's body rather than the clicked anchor. I know I can find the anchor by defining an id for each anchor, passing it to SetLoad, and calling getElementById on it. I want to avoid that because there are hundreds of anchors on dozens of pages. It would take hours to code them all, and probably hours more to find and fix the occasional errors.
  23. DavidAM: that's a viable solution to the problem, and I think I could implement it without a great deal of rewriting, once I get the site working with the double-load solution. That's encouraging. Adam, you commented that while David's proposed solution would work, you'd never use it yourself. You didn't say anything about why you wouldn't use it, or what you'd do instead. Could you explain please? If David's solution has drawbacks, I want to understand them. PFM..., I really don't know what to make of your last post. I firmly agree with the principle you stated, but I don't see how it applies to the situation. Are you implying that the way the site behaves to the user should be determined by what is convenient to implement? I can't agree with that, apart from considering whether the desired behavior can be implemented at a cost that the client finds acceptable.
  24. I'm not sure how this thread got off the rails, but I'd like to do a reset. I originally asked a specific technical question: given that a page must allow users to load a new page by clicking a hyperlink, is there a way to pass the new page parameters via POST, rather than GET, without two round trips to the browser? Somehow we've gotten into a discussion of the site's user-facing behavior; That isn't useful, because I can't disclose all of the considerations that determined the present design, or even exactly what the design is. And even if it were useful, it's not what I need. I gather that the literal answer to my original question is probably "no." I'm hoping for a somewhat broader consideration of the problem: is there some technique that would give me the result I want with a reasonable amount of effort, even if it doesn't work the way I original intended? I wonder whether AJAX would be helpful here. I haven't worked with it before, so I don't have a good understanding of its capabilities.
  25. Here are some responses that should make the situation clearer. I may have more to offer when I get a chance to refer the code tonight. First, I'll explain what the site is for. It awards continuing education credits to users who take an on-line "class" and pass a test. I didn't disclose that in the OP because I was afraid it would complicate the situation rather than clarify it. Some the reasons why I need to solve this technical problem still won't make a lot of sense unless I disclose details of the site's internal operation, and obviously I can't do that. Ronnie Wood wrote: True, but not important. We aren't dealing with security here; we're just trying to prevent users from unintentionally destroying their own work. Few of our users have the skill to intercept a POST response, but the ones that do should also have the insight to recognize a token when they see one and understand the probable consequences if they try to hijack one. If they understand and still want to do it... well, OK. Some people have strange hobbies. I think I misrepresented the situation by referring to "saving work." There isn't any work to save, in the sense that there would be if a user were editing one document and wanted to edit a different one. If we offered saving work as an option, our users would just get confused when we tried to explain when (never mind why) they have to do it! I don't understand what session life has to do with the problem. (The session life is already set to 24 hours, and we get very few trouble reports that seem related to session expiry.) Batwimp wrote: I'm not sure what you want a sample of. I could easily provide a copy of the file I referred to as post.php. I could also prepare a set of sanitized pages that show how it works, but that would take some time, and I'd like to understand how it will help before I do it. PFMaBiSmAd wrote: Well, no. There are a number of reasons for that. The one that's simplest to explain is that when the user finishes taking a class she may want to return to the beginning of the workflow and take another one. If we don't clear the session variables then, she won't be able to do so.
×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.