diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..62c3e2b
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,7 @@
+protected/FWCodeHydrater
+protected/src/secret_php_files
+protected/src/aes
+protected/src/aeskeys.php
+protected/keydata
+*.swp
+*.log
diff --git a/protected/cli/makeLicense.php b/protected/cli/makeLicense.php
new file mode 100644
index 0000000..d669306
--- /dev/null
+++ b/protected/cli/makeLicense.php
@@ -0,0 +1,40 @@
+format(DateTime::ATOM));
+
+$license_maker = new MakeLicense();
+
+define("PWD1", $license_maker->makePassword());
+define("PWD2", $license_maker->makePassword());
+
+const Array_For_Files = [
+ BaseDir. "/src/aes/main.aes" =>
+ [ "feature" => "testing", "enabled" => true, "expires" => EXPIRES_DATE, "password" => PWD1 ],
+ BaseDir. "/src/aes/config.aes" =>
+ [ "feature" => "junk", "enabled" => false, "password" => PWD2 ],
+];
+
+const ALLOWED_DOMAINS = ["localhost", "sub.example.org"];
+const PrivatePEM = BaseDir."/keydata/private.pem";
+const PublicPEM = BaseDir."/keydata/public.pem";
+const AESKeysFile = BaseDir."/src/aeskeys.php";
+const LicenseFile = BaseDir."/keydata/license.json";
+
+
+$license_maker->generateLicense(
+ Array_For_Files,
+ ALLOWED_DOMAINS,
+ PrivatePEM,
+ PublicPEM,
+ AESKeysFile,
+ LicenseFile
+);
+
+/**
+ * use stars for unlimited access for domains and expires dates if desired!
+ */
\ No newline at end of file
diff --git a/protected/logs/error_log.txt b/protected/logs/error_log.txt
new file mode 100644
index 0000000..0058aab
--- /dev/null
+++ b/protected/logs/error_log.txt
@@ -0,0 +1,3 @@
+[2025-07-23 16:53:30] [WARNING] HydraterLicense\KeyGenerator::generatePublicKey(/var/www/ProjectCodeHydrater/protected/keydata/private.pem): Failed to open stream: No such file or directory in /var/www/ProjectCodeHydrater/protected/cli/makeLicense.php on line 109
+[2025-07-23 16:53:30] [WARNING] file_get_contents(/var/www/ProjectCodeHydrater/protected/keydata/private.pem): Failed to open stream: No such file or directory in /var/www/ProjectCodeHydrater/protected/cli/makeLicense.php on line 114
+[2025-07-23 16:53:30] [WARNING] openssl_sign(): Supplied key param cannot be coerced into a private key in /var/www/ProjectCodeHydrater/protected/cli/makeLicense.php on line 118
diff --git a/protected/src/errors.php b/protected/src/errors.php
new file mode 100644
index 0000000..341eb35
--- /dev/null
+++ b/protected/src/errors.php
@@ -0,0 +1,119 @@
+ "\033[31m", // red
+ 'warning' => "\033[33m", // yellow
+ 'notice' => "\033[36m", // cyan
+ 'reset' => "\033[0m" // reset
+ ];
+ $color = $colors[$type] ?? $colors['error'];
+ return $color . $message . $colors['reset'] . PHP_EOL;
+ } else {
+ // Web HTML formatting
+ $styles = [
+ 'error' => 'color:red;',
+ 'warning' => 'color:orange;',
+ 'notice' => 'color:blue;'
+ ];
+ $style = $styles[$type] ?? $styles['error'];
+ return "
$message
";
+ }
+}
+
+// Custom error handler
+set_error_handler(function($errno, $errstr, $errfile, $errline) {
+ // Skip if error reporting is turned off
+ if (!(error_reporting() & $errno)) {
+ return false;
+ }
+
+ $errorTypes = [
+ E_ERROR => ['ERROR', 'error'],
+ E_WARNING => ['WARNING', 'warning'],
+ E_PARSE => ['PARSE ERROR', 'error'],
+ E_NOTICE => ['NOTICE', 'notice'],
+ E_CORE_ERROR => ['CORE ERROR', 'error'],
+ E_CORE_WARNING => ['CORE WARNING', 'warning'],
+ E_COMPILE_ERROR => ['COMPILE ERROR', 'error'],
+ E_COMPILE_WARNING => ['COMPILE WARNING', 'warning'],
+ E_USER_ERROR => ['USER ERROR', 'error'],
+ E_USER_WARNING => ['USER WARNING', 'warning'],
+ E_USER_NOTICE => ['USER NOTICE', 'notice'],
+ E_STRICT => ['STRICT', 'notice'],
+ E_RECOVERABLE_ERROR=> ['RECOVERABLE ERROR', 'error'],
+ E_DEPRECATED => ['DEPRECATED', 'warning'],
+ E_USER_DEPRECATED => ['USER DEPRECATED', 'warning']
+ ];
+
+ $errorInfo = $errorTypes[$errno] ?? ['UNKNOWN', 'error'];
+ $errorType = $errorInfo[0];
+ $errorCategory = $errorInfo[1];
+
+ $logMessage = date('[Y-m-d H:i:s]') . " [$errorType] $errstr in $errfile on line $errline" . PHP_EOL;
+ $displayMessage = "$errorType: $errstr in $errfile on line $errline";
+
+ // Log to file
+ file_put_contents(LOG_FILE, $logMessage, FILE_APPEND);
+
+ // Display in development environment
+ if (ENVIRONMENT === 'development') {
+ echo formatMessage($displayMessage, $errorCategory);
+ }
+
+ // Prevent PHP's default error handler
+ return true;
+});
+
+// Handle exceptions
+set_exception_handler(function($e) {
+ $logMessage = date('[Y-m-d H:i:s]') . " [EXCEPTION] " . $e->getMessage() .
+ " in " . $e->getFile() . " on line " . $e->getLine() . PHP_EOL;
+ $displayMessage = "UNCAUGHT EXCEPTION: " . $e->getMessage() . " in " . $e->getFile() . " on line " . $e->getLine();
+
+ file_put_contents(LOG_FILE, $logMessage, FILE_APPEND);
+
+ if (ENVIRONMENT === 'development') {
+ echo formatMessage($displayMessage, 'error');
+ } else {
+ // In production, show user-friendly message
+ echo PHP_SAPI === 'cli'
+ ? "An error occurred. Our team has been notified." . PHP_EOL
+ : "An error occurred. Our team has been notified.";
+ }
+});
+
+// Handle fatal errors
+register_shutdown_function(function() {
+ $error = error_get_last();
+ if ($error && in_array($error['type'], [E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR])) {
+ $logMessage = date('[Y-m-d H:i:s]') . " [FATAL] {$error['message']} in {$error['file']} on line {$error['line']}" . PHP_EOL;
+ $displayMessage = "FATAL ERROR: {$error['message']} in {$error['file']} on line {$error['line']}";
+
+ file_put_contents(LOG_FILE, $logMessage, FILE_APPEND);
+
+ if (ENVIRONMENT === 'development') {
+ echo formatMessage($displayMessage, 'error');
+ }
+ }
+});
+
+// Test the error handler (uncomment to test)
+// trigger_error("This is a test warning", E_USER_WARNING);
+// throw new Exception("This is a test exception");
+// nonexistentFunction(); // Will trigger a fatal error in shutdown handler
\ No newline at end of file
diff --git a/protected/src/extrasBooter.php b/protected/src/extrasBooter.php
new file mode 100644
index 0000000..2cc95d7
--- /dev/null
+++ b/protected/src/extrasBooter.php
@@ -0,0 +1,20 @@
+
+ * @copyright (c) 2025, Robert Strutts
+ * @license MIT
+ */
+
+use HydraterBootloader\LicenseVerifier;
+
+define("BaseDir", dirname(__DIR__));
+
+const PublicPEM = BaseDir."/keydata/public.pem";
+const AESKeysFile = BaseDir."/src/aeskeys.php";
+const LicenseFile = BaseDir."/keydata/license.json";
+
+$verifier = new LicenseVerifier();
+$verifier->tryEnabledItem(LicenseFile, AESKeysFile, "testing", PublicPEM);