Sindbad~EG File Manager

Current Path : /home/beeson/public_html/WebMathXpert/
Upload File :
Current File : //home/beeson/public_html/WebMathXpert/TestForm.php

<?php
$problemtype = $TESTCONVERGENCE = 211;   // from probtype.h
$title = "Infinite Series"; 
$topic = 174;  // _sum_series
?> 
<!DOCTYPE html>
<?php
$serverAddress = 'localhost'; // Adjust the server address
$serverPort = 12349; // Adjust the server port
$timeout = 300; // Connection timeout in seconds,  long enough for debugging.
$startupDelay = 5; // Delay for server startup in seconds, if server is not already running

if (!(isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] == 'on' || 
   $_SERVER['HTTPS'] == 1) ||  
   isset($_SERVER['HTTP_X_FORWARDED_PROTO']) &&   
   $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https'))
{
   $redirect = 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
   header('HTTP/1.1 301 Moved Permanently');
   header('Location: ' . $redirect);
   exit();
}
if ($_SERVER['SERVER_NAME'] == 'localhost') { 
    $serverAddress = 'localhost';  
} else {
    $serverAddress = 'mathxpert.org'; 
}
session_start();
$sessionId = session_id();  // guaranteed not to contain a pipe character
ini_set('display_errors', 1);
error_reporting(E_ALL);
require("SendMessage.php");
$Series = isset($_POST["infiniteseries"]) ? $_POST["infiniteseries"] : '';

?>
<html>
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, maximum-scale=1.0, user-scalable=0">
	<style>
	/* Set a global font-family rule for all text elements.  Only Times New Roman actually works well.  */
	text {
		  # font-family: 'Times New Roman'; /*, 'Cambria Math', 'STIX Two Math', 'Latin Modern Math', 'TeX Gyre Termes Math'; */
		 }
	 svg text {
		font-family: 'Times New Roman';
		font-size: 16px;
		fill: black; 
		text-align: center;
	}
	/* Ensure Arial for button and tooltip text */
	.svg-button text, .svg-button svg text, .tooltip svg text{
		font-family: 'Arial';
  }
	/* Stacking form elements vertically */
	form {
		display: flex;
		flex-direction: column;
		align-items: flex-start; /* Align items to the start of the form */
		gap: 10px; /* Add some space between each element */
	}
	#formulaPrompt {
		margin-bottom: 5px;
	}
	input[type="text"] {
		width: 300px; /* Set the width of the text input */
	}
	#EntryFields {
		    display: flex;
		    align-items: center;
		}

		.function-entry {
		    display: flex;
		    align-items: center;
		}

		#expressionID {
			flex: 1; /* Allow input field to take up remaining space */
		}

		#arrowButton {
			background: none;
			border: none;
			padding: 0;
			margin-left: 10px; /* Add some spacing between the input and button */
			cursor: pointer;
		}

		#arrowButton img {
			display: block;
		}
 
	/* Tooltips  */  
	.tooltip {
		position: absolute;
		background-color: lightyellow; 
		border: 1px solid black;
		color: black;
		padding: 5px;
		border-radius: 3px;
		white-space: nowrap;
		z-index: 1000;
		display: none; /* Hide by default */ 
		font-size: 12px; /* Change the font size */
		font-family: Arial, sans-serif; 
	}

	.tooltip::before {
		content: '';
		position: absolute;
		top: -8px; /* Adjust based on the size of the triangle */
		left: 0px; /* Adjust based on desired position */
		border-width: 0 5px 10px 0px; /* Create a smaller yellow triangle pointing up */
		border-style: solid; 
		border-color: transparent transparent lightyellow transparent; /* Only the bottom part is visible */
	}

	.hidden {
		display: none;
	}
</style>
<title><?php echo($title) ?> </title>
<?php
	$language = $_GET['language'];  // has to come before the client-side validation script that needs it 
	$windowWidth = $_GET['windowWidth'];
	$windowHeight = $_GET['windowHeight'];
	$toolbarWidth = $_GET['toolbarWidth'];  // this needs to be passed to GraphDoc.php
	$graphWidth = $windowWidth - $toolbarWidth;
?>
<script>
	function fourArgs(input) {
		// Remove "sum(" from the start and ")" from the end
		input = input.trim().slice(4, -1);

		// Find the third comma from the end
		let commas = [];
		for (let i = input.length - 1; i >= 0; i--) {
			if (input[i] === ',') {
				commas.push(i);
			}
			// Stop after finding the third comma
			if (commas.length === 3)  
				break;
		}

		// If there are not exactly three commas, return null
		if (commas.length < 3) {
			return null;
		}

	// Extract the parts based on the found commas
	let thirdCommaIndex = commas[2];
	let beforeThirdComma = input.slice(0, thirdCommaIndex).trim();
	let rest = input.slice(thirdCommaIndex + 1).split(',').map(s => s.trim());

	// Ensure rest has exactly three parts (b, c, d)
	if (rest.length !== 3) {
	  return null;
	}

	// Resulting strings a, b, c, d
	return [beforeThirdComma, ...rest];
	}


	function validVariableName(input) {
		const greekLetters = ["alpha", "beta", "gamma", "delta", "omega", "epsilon", "mu", "lambda", "sigma", "theta", "phi", "rho", "psi", "tau", "nu"];
		if (/^[a-zA-Z]$/.test(input)) {
			return true;
		}
		return greekLetters.includes(input);
	}
	function validInteger(x) {
		// Trim whitespace and check if the string matches a valid integer format
		return /^\s*-?\d+\s*$/.test(x);
	}

	function validSeries(input) {  
		console.log("in validSeries with ", input);
		input = input.trim();
		if (!input.startsWith("sum")) {
			return 'alertseries';  // "Input should have the form sum(f,n,firstIndex,infinity)." 
		}  
		let parts = fourArgs(input); 
		if (parts == null) 
			return 'alertseries';
		let x = parts[1];
		// Ensure x is a valid variable name  
		let L = x.length; 
		console.log("in validSeries, parts is ", parts);
		if (!validVariableName(x)) {
			return 'alert5';   // second argument must be a variable name
		}  
		let lowerLimit = parts[2]; 
		//  Enforce that lowerLimit is a specific integer.  
		//  MathXpert rejects sum(1/n,n,m,infinity)  though in future it might accept it, assuming 0 < m 
		if(! validInteger(lowerLimit)) 
			return 'alertlower';
		let last = parts[3].trim(); 
		if (last !== "infinity") 
			return 'alertinfinity'; 
			//  there may be commas in the summand, e.g. series(log(x,4),x,0,1), so it's too hard to 
			//  isolate the args of series in Javascript--let the Engine do the parsing.
		return true;  // further invalid input will be rejected by the Engine 
	}

	// JavaScript function to validate the form before submission
	function validateForm(event) {
		// Get the value of the input field 
		let series = document.forms["formulaForm"]["infiniteseries"].value; 
		console.log("In validateForm with ", series); 
		let err = validSeries(series);  
				console.log("err is ", err);
		if(err !== true ){
			// Show an alert if validation failed 
			alert(translations["<?php echo $language; ?>"][err]);

			// Prevent the form from being submitted
			event.preventDefault();
			return false;
		} 
		return true; 
	}

	// Add the validation function to the form's submit event
	document.addEventListener('DOMContentLoaded', function() {
		document.getElementById("formulaForm").addEventListener("submit", validateForm);
	});
	document.addEventListener('DOMContentLoaded', function () {
		// Get the complexSelector element
		const complexSelector = document.getElementById('complexSelector');
		if (complexSelector) {
			// Set the value of the selector to match the current topic
			complexSelector.value = topic;
			// Trigger visual feedback by simulating focus
			complexSelector.focus(); // Apply focus styles (like turning green)
			console.log("Focused element after update:", document.activeElement);
		}
	});
</script>
<?php 
if (isset($_POST['topicField3'])){   // may have been set by ArrowButton.js 
	$topic = $_POST['topicField3'];
	// echo("topic = $topic"); 
}
?>
<script>
// global variables, changeable by complexSelector, passed by POST['complexSelector'] when Display is clicked
var topic = <?php echo($topic); ?>;
var problemtype = <?php echo($problemtype); ?>;
if (topic == 174) // _sum_series
	problemtype = 209;   // ADDSERIES
else
	problemtype = 211;   // TEST_CONVERGENCE 
</script>
</head>
<body>

<style>
    .function-entry {
        display: flex;
        align-items: center;
        margin-bottom: 10px;
    }

    .function-entry svg {
        margin-right: 10px;
    }

    #EntryFields {
        margin-bottom: 0px;
    }
	/* CSS to style the entry fields with a light green background */
	input[type="text"],
	input[type="number"],
	input[type="email"],
	textarea
	{
		background-color: #ccffcc; /* Light green background */
		border: 1px solid #ccc; /* Optional: Border styling */
		padding: 5px; /*  Padding for better spacing */
		border-radius: 4px; /*  Rounded corners */
	}
	
	select {
		background-color: #ccffcc; /* Light green */
	}
	

	/*  Style for focus state */
	input[type="text"]:focus,
	input[type="number"]:focus,
	input[type="email"]:focus,
	textarea:focus,
	select:focus {
		background-color: #b3ffb3; /* Slightly darker green when focused */
		outline: none; /* Remove default outline */
		border-color: #66cc66; /* Optional: Change border color on focus */
	}
	
	
	#svgContainer, #myForm {
	    display: block; /* Ensures each is on its line */
	    width: 100%; /* Adjusts width to the container */
	}

	#svgContainer {
		margin-bottom: 5px; 
		margin-top: 10px;
		background-color: lightblue;
		position:relative
		/* overflow: hidden;  Ensure the container wraps its content */
	}

	.add-function-container {
		display: flex;
		align-items: center; /* Align items vertically center */
		gap: 10px; /* Add some space between the button and label */
		margin-top: 10px; /* Add space above the container */
	}


</style>
<script src="TranslateEnterPages.js"></script>

<form action="<?php echo htmlspecialchars($_SERVER['PHP_SELF'] . '?' . $_SERVER['QUERY_STRING']); ?>" method="post" id="formulaForm">
	<svg id="enterseries" width="350" x="0" y="30" height="25">
		<text x="0" y="20">Series to evaluate or test for convergence:</text>
	</svg>
	<div id="EntryFields">		
		<div class="function-entry">
			<input type="text" name="infiniteseries"  id="infiniteseriesID" placeholder="sum(1/(n^2+n),n,2,infinity)", value="<?php echo ($Series); ?>" autofocus>
			<button
				id="arrowButton"
				class="svg-button"
				type="button"
				onClick="handleArrowClick(document.getElementById('infiniteseriesID'),problemtype,topic)"
			>
			<img src="images/drawn_bow_arrow_30px.png" alt="Arrow Icon" width="30" height="30">
			</button>
		</div>
	</div>
	<button type="submit" id="displayButton10" class="svg-button" style="background-color:transparent; border:none;">
		<svg width="80" height="30" id="display" style="position:relative; overflow:visible;" xmlns="http://www.w3.org/2000/svg">
			<!-- Background -->
			<rect width="80" height="30" fill="rgb(0,0,128)" />
			<!-- Text -->
			<text x="40" y="20" style="fill:white;" font-size="12" font-family="Arial" text-anchor="middle">Display</text>
		</svg>
	</button>	
	<input type="hidden" name="topicField3" value="<?php echo($topic); ?>" id="topicField3"> 
</form>

<!-- tooltip-container is used by Tooltips.js to put each tooltip text, one at a time, into it.  So it's empty now. -->
<div id="tooltip-container" class = "tooltip"></div>
<!-- put all needed tooltips here as <svg> elements.
	This pre-document file does not receive Tooltips from the Engine.  They must be written here.  
	But the text will be replaced from translateEnterPages if a translation is provided there. 
-->
<svg class="tooltip" id="tooltip-displayButton10" width="300" height="30" 
	style="display:none;
	position:absolute;
	left: 0; top: 0;
	xmlns="http://www.w3.org/2000/svg" 
>
	<text x = "0"  y="16" style="font-size:14px;fill:black;stroke:none;">Display the series in mathematical notation </text>
</svg>	
<svg class="tooltip" id="tooltip-solveNowButton" width="250" height="30" 
	style="display:none;
	position:absolute;
	left: 0; top: 0;
	xmlns="http://www.w3.org/2000/svg" 
>
	<text x = "0"  y="16" style="font-size:14px;fill:black;stroke:none;">Open a MathXpert calculation</text>
</svg>
</svg>	
<svg class="tooltip" id="tooltip-arrowButton" width="250" height="40" 
	style="display:none; position:absolute; left: 0; top: 0;"
	xmlns="http://www.w3.org/2000/svg" 
>
	<text x = "0"  y="16" style="font-size:14px;fill:black;stroke:none;">Shoots a sample problem into</text>
	<text x = "0"  y="35" style="font-size:14px;fill:black;stroke:none;">the entry field to the left</text>
</svg>
<?php
$clientSocket = createClientSocket($serverAddress, $serverPort, $timeout);
if ($_SERVER["REQUEST_METHOD"] === "POST") 
	{
		$Series = $_POST['infiniteseries'];
	
			// Now connect to the Engine
		$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
		if ($socket === false) 
			{
				echo "Socket creation failed: " . socket_strerror(socket_last_error()) . "<br>";
			} 
		else 
			{   
				socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, array("sec" => $timeout, "usec" => 0));
				$result = socket_connect($socket, $serverAddress, $serverPort);
				if ($result) 
					{
						if($topic ==  174) // _sum_series 
							$problemtype = 209;  // ADDSERIES
						else 
							$problemtype = 211;  // TEST_CONVERVENCE 
							
						$param = "\"$Series\"+$problemtype+$language+$graphWidth+$windowHeight+$topic+$toolbarWidth"; 
						$response = sendMessage($clientSocket,"setupAndCheckSymbol",$param);
						if ($response === false)
							{
								$errcode = socket_last_error($socket);
								$message = socket_strerror($errcode);
								echo "Socket_read error: $message<br>";
							}  
						else if (str_contains($response, "Error"))  // parseError or mathError 
							{ 
								?>
									<div id="svgContainer" >
										<?php  
										   // add the dynamically generated SVG,  of class "parserError" or "mathError"
											echo ($response);
												/*		More elaborately,  we could use Javascript to add $response to the DOM,
														then check whether the class is parserError, and if it is, put up
														an alert with the message;  otherwise echo it as here or just add it to 
														svgContainer. 
												*/  
										?>	 
									</div>  
									<?php
							}
						else
							{  
								?> 
									<div style="display:none;">
										<?php include 'ButtonDefinitions.svg'; ?>
									</div> 
									<div id="svgContainer" >	
											<?php  
											   // add the dynamically generated SVG, 
											   // which comes as an SVG element with id "parsedTerm" of class "termSVG"
												echo ($response);
											?>	 
									</div>   
									<form id="myForm" method="post" action="SymbolicDoc.php"> 
										<!-- the action element has no name as we don't need it posted, especially not with name "action", which causes a conflict --> 
										<input type="hidden" id="formAction" value=""> 
									   <label for="complexSelector" id="selector22Label" style="display:inline-block; margin-top:5px; margin-bottom:5px">What do you want to do?:</label>  
										<select id="complexSelector" class="selector" style="display:inline-block; margin-top:5px; margin-bottom:8px;" onchange="document.getElementById('topicField2').value = this.value;"> 
											<option value="174" class="selector-item" id="seriesEval">
												Try to evaluate the series
											</option>
											<option value="175" class="selector-item" id="integraltest">
											Integral test
											</option>
											<option value="176" class="selector-item" id="comparisontest">
												Comparison test
											</option>
											<option value="177" class="selector-item" id="rootorratiotest">
												Root test or ratio test
											</option>
										</select>  
										<button type="submit" name="solveNow" id="solveNowButton" class="svg-button" style="display:block; background-color:transparent; border:none;">
											<svg width="130" height="30" style="position:relative;overflow:visible;" xmlns="http://www.w3.org/2000/svg">
												<!-- Background -->
												<rect width="130" height="30" fill="rgb(0,0,128)" />
												<!-- Text -->
												<text x="65" y="20" style="fill:white;" font-size="12" font-family="Arial" text-anchor="middle" >Do the Math</text>
											</svg>
										</button> 
										<input type="hidden" name="widthField3" id="widthField2" value = <?php echo $windowWidth ?> > 
										<input type="hidden" name="heightField3" id="heightField2" value=<?php echo $windowHeight ?> > 
										<input type="hidden" name="toolbarwidthField" id="toolbarwidthField" value = <?php echo $toolbarWidth ?> > 
										<input type="hidden" name="language" id="language" value = <?php echo $language ?> >  
										<input type="hidden" name="topicField" value="<?php echo($topic); ?>" id="topicField2"> 
										</form>
								<?php 
							}
					} 
				else 
					{
						echo "Failed to connect to the MathXpert Engine: " . socket_strerror(socket_last_error()) . "<br>"; 
					}
			} 
	
	}
?>
    
<script src="MoveSvgElement.js"></script>
<script src="Tooltips.js"></script>
<script>
	function adjustFormPositionAfterSvgResizes() {
		var svgContainer = document.getElementById('svgContainer');
		var myForm = document.getElementById('myForm'); 
		if(myForm == null) 
			return;
		// Get the current height of the svgContainer 
		if(svgContainer)  // it doesn't exist until the Display form is processed
			var currentHeight = svgContainer.offsetHeight;

		// Adjust the form's margin to prevent overlap
		myForm.style.marginTop = (currentHeight + 20) + 'px'; // Adjust as needed for spacing
	}

</script>
<script>
	document.addEventListener('DOMContentLoaded', function() {
		setLanguage('<?php echo($language); ?>');
		moveSvgElementToContainer("parsedTerm", "svgContainer");  
		// Adjust the form position right after resizing the container
		adjustFormPositionAfterSvgResizes();
	 });
</script>
<script src="FetchMessage.js"></script>
<script src="arrowButton.js"> </script>
</body>
</html>


Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists