Sindbad~EG File Manager
<?php
$problemtype = $POWERSERIES = 210; // from probtype.h
$title = "Power Series";
$topic = 179; // _power_series2; needs to be the default shown in the selector
?>
<!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");
$function = isset($_POST["function"]) ? $_POST["function"] : '';
?>
<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 validfunction(input) {
return true; // invalid input will be rejected by the Engine, we don't try to do it here
}
// JavaScript function to validate the form before submission
function validateForm(event) {
// Get the value of the input field
const series = document.forms["formulaForm"]["function"].value;
console.log("In validateForm with ", series);
let err = validfunction(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;
}
</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['selector32'] when Display is clicked
var topic = <?php echo($topic); ?>;
var problemtype = <?php echo($problemtype); ?>;
</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 */
}
/* 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="enterpowerseries" width="400" x="0" y="30" height="25">
<text x="0" y="20">Function to expand in a power series:</text>
</svg>
<div id="EntryFields">
<div class="function-entry">
<input type="text" name="function" id="functionID" placeholder="x^2 ln(1-x)", value="<?php echo htmlspecialchars($function); ?>" autofocus>
<button
id="arrowButton"
class="svg-button"
type="button"
onClick="handleArrowClick(document.getElementById('functionID'),problemtype,topic)"
>
<img src="images/drawn_bow_arrow_30px.png" alt="Arrow Icon" width="30" height="30">
</button>
</div>
</div>
<button type="submit" id="displayButton9" 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-displayButton9" 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 function 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")
{
$function = $_POST['function'];
// 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)
{
$param = "\"$function\"+$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="selector32" id="selector32Label" style="display:inline-block; margin-top:5px; margin-bottom:5px">What do you want to do?:</label>
<select id="selector32" class="selector" style="display:inline-block; margin-top:5px; margin-bottom:8px;"
onchange="document.getElementById('topicField2').value = this.value; document.getElementById('topicField2').setAttribute('value', this.value);"
>
<option value="179" class="selector-item" id="power_series2">
Use simple power series to find other series
</option>
<option value="178" class="selector-item" id="power_series">
Derive simple power series
</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>
// Add the validation function to the form's submit event
document.addEventListener('DOMContentLoaded', function() {
document.getElementById("formulaForm").addEventListener("submit", validateForm);
console.log(document.forms["formulaForm"]);
});
document.addEventListener('DOMContentLoaded', function () {
// Get the complexSelector element
const complexSelector = document.getElementById('selector32');
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>
<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