Bladeren bron

Add files via upload

Capitan Cloud 11 maanden geleden
bovenliggende
commit
27af8f70c5

+ 186 - 0
Private/classes/fivemode/fivemode/class.cookie.inc

@@ -0,0 +1,186 @@
+<?php
+
+/**
+ * Copyright (c) 2016, 2024, 5 Mode
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither 5 Mode nor the names of its contributors 
+ *       may be used to endorse or promote products derived from this software 
+ *       without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * class.cookie.inc
+ * 
+ * Cookie class.
+ *
+ * @author Daniele Bonini <my25mb@aol.com>
+ * @copyrights (c) 2016, 2024, 5 Mode 
+ * @license https://opensource.org/licenses/BSD-3-Clause 
+ */
+
+namespace fivemode\fivemode;
+
+/**
+ * Cookie
+ *
+ * Cookie class
+ *
+ * @package  Cookie
+ * @author   Daniele Bonini <my25mb@aol.com>
+ * @version  2.0
+ * @access   public
+ */
+final class Cookie {
+  
+  const EXPIRE_ONEDAY = 86400;
+  const EXPIRE_SEVENDAYS = 604800;
+  const EXPIRE_THIRTYDAYS = 2592000;
+  const EXPIRE_SIXMONTHS = 15768000;
+  const EXPIRE_ONEYEAR = 31536000;
+  const EXPIRE_LIFETIME = -1;
+
+  /**
+   * Default constructor
+   * 
+   * @return void
+   */
+  private function __construct()
+  {
+  }
+  
+  /**
+   * Check if the given cookie exists
+   *
+   * @param string $name the name of the cookie
+   * @return bool if the given cookie exist, true/false
+   */
+  static public function exists(string $name): bool
+  {
+    return isset($_COOKIE[COOKIE_PREFIX . $name]);
+  }
+
+  /**
+   * Check if the given cookie is empty
+   *
+   * @param string $name the name of the cookie
+   * @return bool if the given cookie is empty, true/false
+   */
+  static public function isEmpty(string $name): bool
+  {
+    if (!self::exists($name)) {
+      return true;
+    }
+    return empty($_COOKIE[COOKIE_PREFIX . $name]);
+  }
+
+  /**
+   * Get the value of the given cookie
+   *
+   * @param string $name the name of the cookie
+   * @param string $default the default value
+   * @return string the value of the cookie
+   */
+  static public function get(string $name, string $default = ""): string
+  {
+    return (self::exists($name) ? $_COOKIE[COOKIE_PREFIX . $name] : $default);
+  }
+
+  /**
+   * Set the value of a given cookie
+   * 
+   * @param string $name the name of the cookie
+   * @param string $value the value
+   * @param mixed $expire the expiration time
+   * @param string $path the path
+   * @param mixed $domain the domain
+   * @return bool if the cookie has been successfully set, true/false
+   */
+  static public function set(string $name, string $value, ?int $expire = self::EXPIRE_ONEYEAR, string $path = "/", $domain = false): bool
+  {
+    $retval = false;
+    
+    settype($subdomain, "string");
+    
+    if (!headers_sent())
+    {
+      if ($domain === false) {
+        //$domain = $_SERVER['HTTP_HOST'];
+        $domain = $_SERVER['HTTP_HOST'];
+        $domain = str_replace("www.", PHP_STR, strtolower($domain));
+        $isSubdomain = isSubdomainHost($subdomain);
+        if ($isSubdomain) {
+          $domain = str_replace($subdomain . ".", PHP_STR, $domain);
+        }
+      }
+      
+      if ($expire === self::EXPIRE_LIFETIME) {
+        $expire = PHP_INT_MAX;
+      } elseif (is_numeric($expire)) {
+        $expire = time() + $expire;
+      } else {
+        $expire = strtotime($expire);
+      }
+      
+      $retval = @setcookie(COOKIE_PREFIX . $name, $value, $expire, $path, $domain, false, true);
+      if ($retval) {
+        $_COOKIE[COOKIE_PREFIX . $name] = $value;
+      }
+    }
+    
+    return $retval;
+  }
+
+  /**
+   * Delete the given cookie
+   *
+   * @param string $name the name of the cookie
+   * @param string $path the path of the cookie
+   * @param mixed $domain the domain of the cookie
+   * @return bool if the cookie has been successfully deleted, true/false
+   */
+  static public function delete(string $name, string $path = "/", $domain = false): bool
+  {
+    $retval = false;
+    
+    settype($subdomain, "string");
+    
+    if (!headers_sent())
+    {
+      if (self::exists($name)) {
+        
+        if ($domain === false) {
+          //$domain = $_SERVER['HTTP_HOST'];
+          $domain = $_SERVER['HTTP_HOST'];
+          $domain = str_replace("www.", PHP_STR, strtolower($domain));
+          $isSubdomain = isSubdomainHost($subdomain);
+          if ($isSubdomain) {
+            $domain = str_replace($subdomain . ".", PHP_STR, $domain);
+          }
+        }
+
+        $retval = @setcookie(COOKIE_PREFIX . $name, "", time() - 3600, $path, $domain, false, true);
+
+        unset($_COOKIE[COOKIE_PREFIX . $name]);
+      }
+    }
+    
+    return $retval;
+  }
+}

+ 346 - 0
Private/classes/fivemode/fivemode/class.page.inc

@@ -0,0 +1,346 @@
+<?php
+
+/**
+ * Copyright (c) 2016, 2024, 5 Mode
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither 5 Mode nor the names of its contributors 
+ *       may be used to endorse or promote products derived from this software 
+ *       without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * class.page.inc
+ * 
+ * Page class.
+ *
+ * @author Daniele Bonini <my25mb@aol.com>
+ * @copyrights (c) 2016, 2024, 5 Mode 
+ * @license https://opensource.org/licenses/BSD-3-Clause 
+ */
+
+namespace fivemode\fivemode;
+
+/**
+ * Page
+ *
+ * Page class
+ *
+ * @package  Page
+ * @author   Daniele Bonini <my25mb@aol.com>
+ * @version  2.0
+ * @access   public
+ */
+final class Page 
+{
+  
+  const URL_OUTPUT_RAW = 1;
+  const URL_OUTPUT_FORMATTED = 2;
+  const URL_OUTPUT_TEXT = 3;
+  
+  /**
+   * Default constructor
+   * 
+   * @return void
+   */
+  private function __construct()
+  {
+  }
+  
+  /**
+   * The buffer for the javascript of page footer
+   *  
+   * @access private
+   * @var Array
+   */
+  private static $aFooterJSBuffer = Array2::PHP_EMPTY;
+  
+  /**
+   * Add the given javascript code to the page buffer
+   * 
+   * @param string $JScode the JS code to add in the page footer
+   */
+  public static function addToJSBuffer(string $JScode): void
+  {
+    self::$aFooterJSBuffer[] = $JScode;
+  }
+
+  /**
+   * Clear the page buffer for the javascript code
+   */
+  public static function clearJSBuffer(): void 
+  {
+    self::$aFooterJSBuffer = Array2::PHP_EMPTY;
+  }
+
+  /**
+   * Display the content of the page buffer for the javascript code
+   */
+  public static function displayJSBuffer(): void
+  {
+    foreach(self::$aFooterJSBuffer as $JScode) {
+      echo $JScode . PHP_EOL. PHP_EOL;
+    }  
+  }
+  
+  /**
+   * Enable the links of the given text
+   * 
+   * @param string $text the text being parsed for links
+   * @return the text with enabled links
+   */
+  public static function enableEmailLinks(string $text, bool $masked): string
+  {
+    settype($text, "string");
+    settype($masked, "boolean");
+    
+    $callable_masked = function($aResults) {
+      $result = implode(PHP_STR, $aResults); 
+      return "<a href='mailto:$result'>" . mb_strrichr($result, "@", true) . "@.." . mb_strrichr($result, ".", false) . "</a>";
+    };
+
+    $callable_unmasked = function($aResults) {
+      $result = implode(PHP_STR, $aResults); 
+      return "<a href='mailto:$result'>$result</a>";
+    };
+
+    $regexPattern = "/(([A-Za-z0-9]+_+)|([A-Za-z0-9]+\-+)|([A-Za-z0-9]+\.+)|([A-Za-z0-9]+\++))*[A-Za-z0-9]+@((\w+\-+)|(\w+\.))*\w{1,63}\.[a-zA-Z]{2,6}/";
+    
+    if ($masked) {
+      $callable = $callable_masked;
+    } else {
+      $callable = $callable_unmasked;
+    } 
+    
+    return preg_replace_callback($regexPattern, $callable, $text);
+  }  
+
+  /**
+   * Enable the links of the given text
+   * 
+   * @param string $text the text being parsed for links
+   * @return the text with enabled links
+   */
+  public static function enableLinks(string $text): string
+  {
+    //return preg_replace("/(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,8})([\/\w \.-]*)$/", "\\0&nbsp;<a href='\\0' target=\"_blank\">[#1]</a>", $text);
+    return preg_replace("/(https?:\/\/)([\da-z\.-]+)\.([a-z\.]{2,8})(\/?.+)?$/", "<span style='color:darkgray; background:#E0E0E0;'>\\0&nbsp;[&nbsp;<a href='\\0' target=\"_blank\" style=\"font-size: large;\">@</a>&nbsp;]</span>", $text);
+  }  
+  
+  /**
+   * Enable the links of the given text
+   * 
+   * @param string $text the text being parsed for links
+   * @return the text with enabled links
+   */
+  public static function getFirstEnabledLink(string $text, bool $formatted = true): string
+  {
+    $matches = [];
+    $bDFLTLINK = false;
+    //return preg_replace("/(https?:\/\/)([\da-z\.-]+)\.([a-z\.]{2,8})(\/?.+)?$/", "<span style='color:darkgray; background:#E0E0E0;'>\\0&nbsp;[&nbsp;<a href='\\0' target=\"_blank\" style=\"font-size: large;\">@</a>&nbsp;]</span>", $text);
+    //$preg_retval = preg_match("/(https?:\/\/[\da-z\.-]+\.[a-z\.]{2,8}(\/?.+)?)$/", $text, $matches);
+    $preg_retval = preg_match("/((https?:\/\/)?[\w\.-]+\.[a-z\.]{2,8}(\/?.+)?)$/", $text, $matches);
+    if ($preg_retval>=1) {
+      //return preg_replace("/^(https?:\/\/)(([\da-z\.-]+)\.([a-z\.]{2,8}))(\/?[.]+)?$/", "<a class='link-image' href='\\0' target='_blank'>\\2</a>", $matches[1]);
+      $url = $matches[1];
+    } else {
+      //return preg_replace("/^(https?:\/\/)(([\da-z\.-]+)\.([a-z\.]{2,8}))(\/?[.]+)?$/", "<a class='link-image' href='\\0' target='_blank'>\\2</a>", ENGINE_DFLTLINK);
+      $url = ENGINE_DFLTLINK;
+    }  
+
+    if (mb_stripos1($url, ENGINE_DFLTLINK)) {
+      $bDFLTLINK = true;
+    }  
+    
+    $url = str_replace(PHP_TILDE, PHP_SLASH, $url);
+    
+    $urlText = preg_replace("/(https?:\/\/)(([\da-z\.-]+)\.([a-z\.]{2,8}))(\/?.+)?$/", "\\2", $url);
+    
+    if ($formatted) {
+      /*
+      if ($bDFLTLINK) { 
+        return "[AD]&nbsp;<a class='link-image' href='http://" . $url . "' target='_blank'>" . (mb_strlen($urlText)<=26 ? $urlText : left($urlText, 10) . ".." . right($urlText, 14)) . "</a>";
+      } else {  
+        return "<a class='link-image' href='http://" . $url . "' target='_blank'>" . (mb_strlen($urlText)<=26 ? $urlText : left($urlText, 10) . ".." . right($urlText, 14)) . "</a>";
+      } */
+      
+      if ($bDFLTLINK) { 
+        return "[AD]&nbsp;<a class='link-image' onclick='openLink(\"http://" . $url . "\",\"_blank\")'>" . (mb_strlen($urlText)<=26 ? $urlText : left($urlText, 10) . ".." . right($urlText, 14)) . "</a>";
+      } else {  
+        return "<a class='link-image' onclick='openLink(\"http://" . $url . "\",\"_blank\")'>" . (mb_strlen($urlText)<=26 ? $urlText : left($urlText, 10) . ".." . right($urlText, 14)) . "</a>";
+      }  
+      
+    } else {
+      return $urlText; 
+    }  
+  }
+  
+  /**
+   * Get the gallery url
+   * 
+   * @param string $desc the text being parsed for links
+   * @param int $output the kind of output
+   * @return the text with enabled links
+   */
+  public static function getGalleryUrl(string $desc, int $output = self::URL_OUTPUT_FORMATTED): string
+  {
+    $matches = [];
+    $bDFLTLINK = false;
+
+    $preg_retval = preg_match("/((https?:\/\/)?[\w\.-]+\.[a-z\.]{2,8}(\/?.+)?)$/", $desc, $matches);
+    if ($preg_retval>=1) {
+      $url = $matches[1];
+    } else {
+      $url = ENGINE_DFLTLINK;
+    }  
+
+    if ($output === self::URL_OUTPUT_RAW) {
+      return $url;      
+    }
+    
+    if (mb_stripos1($url, ENGINE_DFLTLINK)) {
+      $bDFLTLINK = true;
+    }  
+    
+    $url = str_replace(PHP_TILDE, PHP_SLASH, $url);
+    
+    $urlText = preg_replace("/(https?:\/\/)(([\da-z\.-]+)\.([a-z\.]{2,8}))(\/?.+)?$/", "\\2", $url);
+    
+    if ($output === self::URL_OUTPUT_FORMATTED) {
+      
+      if ($bDFLTLINK) { 
+        return "[AD]&nbsp;<a class='link-image' onclick='openLink(\"http://" . $url . "\",\"_blank\")'>" . (mb_strlen($urlText)<=26 ? $urlText : left($urlText, 10) . ".." . right($urlText, 14)) . "</a>";
+      } else {  
+        return "<a class='link-image' onclick='openLink(\"http://" . $url . "\",\"_blank\")'>" . (mb_strlen($urlText)<=26 ? $urlText : left($urlText, 10) . ".." . right($urlText, 14)) . "</a>";
+      }  
+      
+    } else {
+      return $urlText; 
+    }  
+  }
+  
+  
+  /**
+   * Encode any HTML of a given string
+   * 
+   * @param string $s the string to encode
+   * @param bool $withBR keep the BR tag, true/false
+   * @return string the string encoded
+   */
+  public static function HTMLencode(?string $s, bool $withBR = false): string 
+  {
+    if (!isset($s)) {
+      return PHP_STR;
+    }
+    
+    $s = str_ireplace("&#39;", "'", $s); 
+    $s = str_ireplace("&#34;", "\"", $s);
+    $s = str_ireplace("\\n", chr(10), $s);
+    $s = htmlspecialchars($s, ENT_QUOTES |ENT_IGNORE | ENT_HTML5, "UTF-8");
+    
+    if ($withBR) {
+      $s = str_ireplace(chr(10), PHP_BR, $s);
+    }  
+    
+    return $s;
+  }
+  
+  /**
+   * Set headers to no cache
+   * 
+   * @param integer $interval the interval in seconds
+   */
+  public static function setNoCacheHeaders(): void 
+  {
+    // Backwards Compatibility for HTTP/1.0 clients
+    header("Expires: 0");
+    header("Pragma: no-cache");
+    // HTTP/1.1 support
+    header("Cache-Control: no-cache,no-store,max-age=0,s-maxage=0,must-revalidate");
+  }
+  
+  /**
+   * Set headers to private cache
+   * 
+   * @param integer $interval the interval in seconds
+   */
+  public static function setPrivateCacheHeaders(int $interval = 300): void
+  {
+    $now = time();
+    $pretty_lmtime = gmdate("D, d M Y H:i:s", $now) . " GMT";
+    $pretty_extime = gmdate("D, d M Y H:i:s", $now + $interval) . " GMT";
+    // Backwards Compatibility for HTTP/1.0 clients
+    header("Last Modified: $pretty_lmtime");
+    header("Expires: $pretty_extime");
+    header("Pragma: ");
+    // HTTP/1.1 support
+    header("Cache-Control: private,max-age=$interval,s-maxage=0");
+  }
+  
+  /**
+   * Set headers to public cache
+   * 
+   * @param integer $interval the interval in seconds
+   */
+  public static function setPublicCacheHeaders(int $interval = 300): void
+  {
+    $now = time();
+    $pretty_lmtime = gmdate("D, d M Y H:i:s", $now) . " GMT";
+    $pretty_extime = gmdate("D, d M Y H:i:s", $now + $interval) . " GMT";
+    // Backwards Compatibility for HTTP/1.0 clients
+    header("Last Modified: $pretty_lmtime");
+    header("Expires: $pretty_extime");
+    header("Pragma: ");
+    // HTTP/1.1 support
+    header("Cache-Control: public,max-age=$interval");
+  }
+  
+  /** 
+   * Make a redirect
+   * 
+   * @param string $newUrl the url to redirect to
+   */
+  public static function redirect(string $newUrl): void  
+  {
+    if (headers_sent()) {
+      echo("<script>window.location.replace('" . $newUrl . "');</script>");
+    } else {
+      header("HTTP/1.0 302 Redirect");
+      header('Location: ' . $newUrl);
+    } 
+    exit();
+  }
+
+  /** 
+   * Make a permanent redirect
+   * 
+   * @param string $newUrl the url to redirect to
+   */
+  public static function redirectPerm(string $newUrl): void  
+  {
+    if (headers_sent()) {
+      echo("<script>window.location.replace('" . $newUrl . "');</script>");
+    } else {
+      header("HTTP/1.0 301 Moved Permanently");
+      header('Location: ' . $newUrl);
+    } 
+    exit();
+  }
+  
+}

+ 70 - 0
Private/classes/fivemode/fivemode/class.puffi.inc

@@ -0,0 +1,70 @@
+<?php
+
+/**
+ * Copyright 2021, 2026 5 Mode
+ *
+ * This file is part of GrandePuffo.
+ *
+ * GrandePuffo is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GrandePuffo is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.  
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GrandePuffo. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * class.puffi.inc
+ * 
+ * Puffi class.
+ *
+ * @author Daniele Bonini <my25mb@has.im>
+ * @copyrights (c) 2016, 2026, 5 Mode
+ **/
+
+namespace fivemode\fivemode;
+
+/**
+ * Puffi
+ *
+ * Puffi class
+ *
+ * @package  Puffi
+ * @author   Daniele Bonini <my25mb@has.im>
+ * @version  1.0
+ * @access   public
+ */
+final class Puffi {
+  
+  static private $counter = -1;
+  
+  /**
+   * Default constructor
+   * 
+   * @return void
+   */
+  private function __construct()
+  {
+  }
+
+  static public function getcounter(): int
+  {
+    return self::$counter+1;
+  }
+      
+  /**
+   * Check if the given cookie exists
+   *
+   * @param string $name the name of the cookie
+   * @return bool if the given cookie exist, true/false
+   */
+  static public function getres(string $sha, int $mycounter): string
+  {
+    //self::$counter++;
+    return constant("ROUTING_RES" . $mycounter);
+  }
+}

+ 180 - 0
Private/config/config.inc.sample

@@ -0,0 +1,180 @@
+<?php
+
+/**
+ * Copyright 2021, 2026 5 Mode
+ *
+ * This file is part of Grande Puffo.
+ *
+ * GrandePuffo is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GrandePuffo is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.  
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GrandePuffo. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * config.inc
+ * 
+ * Configuration settings.
+ *
+ * @author Daniele Bonini <my25mb@has.im>
+ * @copyrights (c) 2016, 2026, 5 Mode
+  */
+
+define('DEBUG', true);
+
+define('APP_NAME', "GrandePuffo");
+define('APP_HOST', "grandepuffo.org");
+define('APP_PATH', "/path/to/GrandePuffo");
+define('APP_PRIVATE_PATH', "/path/to/GrandePuffo/Private");
+define('APP_PUBLIC_PATH', "/path/to/GrandePuffo/Public");
+define('APP_SECRETS_FOLDER',"scr");
+define('APP_ROUTE_PATH', "/path/to/GrandePuffo/Private/routes");
+define('APP_ERROR_PATH', "/path/to/GrandePuffo/Private/error");
+define('APP_LICENSE', <<<LICENSETEXT
+Copyright 2021, 2024 5 Mode
+
+This file is part of GrandePuffo.
+
+GrandePuffo is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+GrandePuffo is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.  
+ 
+You should have received a copy of the GNU General Public License
+along with GrandePuffo. If not, see <https://www.gnu.org/licenses/>.
+LICENSETEXT
+);
+
+define('COOKIE_PREFIX', "GRANDEP_");
+define('COOKIE_PATH', "/");
+define('COOKIE_DOMAIN', "grandepuffo.org");
+define('COOKIE_EXPIRE', 86400); // One day
+
+define('ROUTING_RES0', "/res/topbanner1.png");
+define('ROUTING_RES1', "/res/logo.png");
+define('ROUTING_RES2', "/res/sidebanner3.png");
+define('ROUTING_RES3', "/res/scriplet1.js");
+define('ROUTING_RES4', "/res/pix5.png");
+
+$CONFIG = [
+  'DEBUG' => true,
+
+  'APP' => [
+      'NAME' => "GrandePuffo",
+      'HOST' => "grandepuffo.org",
+      'PATH' => "/path/to/GrandePuffo/Public",
+      'PRIVATE_PATH' => "/path/to/GrandePuffo/Private",
+      'PUBLIC_PATH' => "/path/to/GrandePuffo/Public",
+      'SECRETS_FOLDER' => "scr",
+      'ROUTE_PATH' => "/path/to/GrandePuffo/Private/routes",
+      'ERROR_PATH' => "/path/to/GrandePuffo/Private/error",
+      'LICENSE' => <<<LICENSETEXT
+Copyright 2021, 2024 5 Mode
+
+This file is part of GrandePuffo.
+
+GrandePuffo is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+GrandePuffo is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.  
+ 
+You should have received a copy of the GNU General Public License
+along with GrandePuffo. If not, see <https://www.gnu.org/licenses/>.
+LICENSETEXT
+             
+            ],
+            
+  'COOKIE' => [            
+      'PREFIX', "GRANDEP_",
+      'PATH', "/",
+      'DOMAIN', "grandepuffo.org",
+      'EXPIRE', 86400
+            ]         
+];
+
+$ROUTING = [
+
+    'RES_ROUTER_PREFIX' => [
+        0 => [1000000, 1199999],
+        1 => [1200000, 1399999],
+        2 => [1400000, 1599999]
+      ],
+
+    'RES_ROUTER' => [
+        0 => "idxpage1img.php",
+        1 => "idxpage1html.php",
+        2 => "idxpage1js.php"
+      ],
+
+    'RES_PASSWORD' => [
+        0 => "res_password1",
+        1 => "res_password2",
+        2 => "res_password3",
+        3 => "res_password4",
+        4 => "res_password5"
+    ],
+
+    'RES_SALT' => [
+        0 => "res_salt1",
+        1 => "res_salt2",
+        2 => "res_salt3",
+        3 => "res_salt4",
+        4 => "res_salt5"
+    ],
+
+    'RES' => [
+        0 => "/res/topbanner1.png",
+        1 => "/res/logo.png",
+        2 => "/res/sidebanner3.png",
+        3 => "/res/scriplet1.js",
+        4 => "/res/pix5.png"
+    ],
+
+    'RES_TYPE' => [
+        0 => "image",
+        1 => "image",
+        2 => "image",
+        3 => "script",
+        4 => "image"
+    ],
+
+    'RES_DISPLAIED_SHA' => [
+        0 => "d1493e2ef9cdeaa559bbf49c5865bd4777eec2117186db53b0698b7d2105ca10",
+        1 => "ba78c55eae177c8e6749fa6aded78757ccfb10c85121cb4fbbb76b9ce3ef4db2",
+        2 => "100977ab07dc32e7fa389ccc8555a0e08b62ee052149cf00e706fa08275fcc53",
+        3 => "b0586a9e50b39f16f0584948f1574cf9ccce0194b71c95b5a624cf906d0d6b06",
+        4 => "3121b07e1fabb8751fbd1c8957281f6cbfefeb391de5da072c00ecd0b6577be1"
+    ],
+
+    'RES_SHA' => [
+        0 => "d1493e2ef9cdeaa559bbf49c5865bd4777eec2117186db53b0698b7d2105ca10",
+        1 => "ba78c55eae177c8e6749fa6aded78757ccfb10c85121cb4fbbb76b9ce3ef4db2",
+        2 => "100977ab07dc32e7fa389ccc8555a0e08b62ee052149cf00e706fa08275fcc53",
+        3 => "b0586a9e50b39f16f0584948f1574cf9ccce0194b71c95b5a624cf906d0d6b06",
+        4 => "3121b07e1fabb8751fbd1c8957281f6cbfefeb391de5da072c00ecd0b6577be1"
+    ],
+
+    'WEBPAGE_ELEMENT' => [
+        0 => "funnyctrl1",
+        1 => "funnyctrl2",
+        2 => "funnyctrl3",
+        3 => "funnyctrl4",
+        4 => "funnyctrl5"
+    ]
+];

+ 70 - 0
Private/config/const.php.inc

@@ -0,0 +1,70 @@
+<?php
+
+/**
+ * Copyright 2021, 2026 5 Mode
+ *
+ * This file is part of Grande Puffo.
+ *
+ * GrandePuffo is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GrandePuffo is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.  
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GrandePuffo. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * const.php.inc
+ * 
+ * Additional PHP constants.
+ *
+ * @author Daniele Bonini <my25mb@has.im>
+ * @copyrights (c) 2016, 2026 5 Mode
+  */
+
+if (!defined("PHP_BR")) {
+  define('PHP_BR', "<br>");
+}
+if (!defined("PHP_CN")) {
+  define('PHP_CN', "zh-CN");
+}
+if (!defined("PHP_EN")) {
+  define('PHP_EN', "en-US");
+}
+if (!defined("PHP_ES")) {
+  define('PHP_ES', "es-ES");
+}
+if (!defined("PHP_FR")) {
+  define('PHP_FR', "fr-FR");
+}
+if (!defined("PHP_HYPHEN")) {
+  define('PHP_HYPHEN', "-");
+}
+if (!defined("PHP_IT")) {
+  define('PHP_IT', "it-IT");
+}
+if (!defined("PHP_PIPE")) {
+  define('PHP_PIPE', "|");
+}
+if (!defined("PHP_SLASH")) {
+  define('PHP_SLASH', "/");
+}
+if (!defined("PHP_SPACE")) {
+  define('PHP_SPACE', " ");
+}
+if (!defined("PHP_STR")) {
+  define('PHP_STR', "");
+}
+if (!defined("PHP_TILDE")) {
+  define('PHP_TILDE', "~");
+}
+if (!defined("PHP_UNDERSCORE")) {
+  define('PHP_UNDERSCORE', "_");
+}
+if (!defined("PHP_EXE_NAME")) {
+  define('PHP_EXE_NAME',"php-8.2");
+}

+ 194 - 0
Private/core/init.inc

@@ -0,0 +1,194 @@
+<?php
+
+/**
+ * Copyright 2021, 2026 5 Mode
+ *
+ * This file is part of GrandePuffo.
+ *
+ * GrandePuffo is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GrandePuffo is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.  
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GrandePuffo. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * init.inc
+ * 
+ * Initialization file.
+ *
+ * @author Daniele Bonini <my25mb@has.im>
+ * @copyrights (c) 2016, 2026 5 Mode   
+ */
+
+use fivemode\fivemode\Page;
+
+error_reporting(E_ALL & ~ (E_WARNING | E_NOTICE | E_STRICT | E_DEPRECATED));  
+ini_set('display_startup_errors',1);  
+ini_set('display_errors',1);  
+ini_set('log_errors',1); 
+
+
+// CONFIGURATION
+define("CONFIG_PATH", __DIR__ . DIRECTORY_SEPARATOR . ".." . DIRECTORY_SEPARATOR . "config");
+
+require CONFIG_PATH . DIRECTORY_SEPARATOR . "config.inc";
+require CONFIG_PATH . DIRECTORY_SEPARATOR . "const.php.inc";
+
+mb_internal_encoding("UTF-8");
+
+
+// AUTOLOADER
+
+define("CLASSES_PATH", __DIR__ . DIRECTORY_SEPARATOR . ".." . DIRECTORY_SEPARATOR . "classes");
+define("INTERFACES_PATH", __DIR__ . DIRECTORY_SEPARATOR . ".." . DIRECTORY_SEPARATOR . "interfaces");
+
+/**
+ * Autoloader.
+ * 
+ * @param string $construct the name of the construct to load
+ */
+function autoloader($construct) {
+  
+  // For third-party libraries, eg. Pear
+  if (!defined("PHP_INCLUDE_PATH")) {
+    define("PHP_INCLUDE_PATH", ini_get("include_path"));
+  }
+  
+  $constructParts = explode('\\', $construct);
+  
+  // estrapolate the path from the construct name
+  $count = count($constructParts);
+  if ($count>1) {
+    $i = 0;
+    $constructPath = $constructParts[0];
+    for ($i=1; $i<($count-1); $i++) {
+      $constructPath .= DIRECTORY_SEPARATOR . $constructParts[$i];
+    }
+    $construct = $constructParts[$i];
+  }
+  
+  if (!stripos($construct, "interface")) {
+    // if it is a class
+  
+    switch ($construct) {
+      case "special_case":
+        $incPath = PHP_INCLUDE_PATH . DIRECTORY_SEPARATOR . "path/to/special_case.php";
+        break;
+      case "QRcode":
+        $incPath = CLASSES_PATH . DIRECTORY_SEPARATOR . "phpqrcode/qrlib.php";
+        //echo "incPath = $incPath" . PHP_BR;
+        break;
+      default:
+      
+        if (isset($constructPath)) {
+          $incPath = CLASSES_PATH . DIRECTORY_SEPARATOR . $constructPath . DIRECTORY_SEPARATOR . "class." . strtolower($construct) . ".inc";
+        } else {
+          $incPath = CLASSES_PATH . DIRECTORY_SEPARATOR . "class." . strtolower($construct) . ".inc";
+        }
+        
+        break;
+    }
+    
+  } else {
+    // if it is an interface
+    if (isset($constructPath)) {
+      $incPath = INTERFACES_PATH . DIRECTORY_SEPARATOR  . $constructPath . DIRECTORY_SEPARATOR . strtolower($construct) . ".inc";
+    } else {
+      $incPath = INTERFACES_PATH . DIRECTORY_SEPARATOR . strtolower($construct) . ".inc";
+    }  
+  }
+  
+  if (is_readable($incPath)) {
+    //echo "$incPath is readable" . PHP_BR;
+    require $incPath;
+  }
+  
+}
+spl_autoload_register("autoloader", true, true);
+
+
+// FUNCTIONS
+
+define("FUNCTIONS_PATH", __DIR__.DIRECTORY_SEPARATOR."..".DIRECTORY_SEPARATOR."functions");
+
+require FUNCTIONS_PATH . DIRECTORY_SEPARATOR . "func.string.inc";
+require FUNCTIONS_PATH . DIRECTORY_SEPARATOR . "func.app.inc";
+require FUNCTIONS_PATH . DIRECTORY_SEPARATOR . "func.various.inc";
+require FUNCTIONS_PATH . DIRECTORY_SEPARATOR . "func.file.inc";
+require FUNCTIONS_PATH . DIRECTORY_SEPARATOR . "func.filter.inc";
+require FUNCTIONS_PATH . DIRECTORY_SEPARATOR . "func.array.inc";
+require FUNCTIONS_PATH . DIRECTORY_SEPARATOR . "func.routing.inc";
+
+// ERROR HANDLING AND LOGGING
+
+//if (DEBUG) {
+  error_reporting(E_ALL | E_STRICT);  
+  ini_set('display_startup_errors',1);  
+  ini_set('display_errors',1);
+  ini_set('log_errors',1); 
+//} else {
+//  error_reporting(E_ALL & ~ (E_WARNING | E_NOTICE | E_STRICT | E_DEPRECATED));  
+//  ini_set('display_startup_errors',0);  
+//  ini_set('display_errors',0);  
+//  ini_set('log_errors',1); 
+//}
+
+// HEADERS
+
+Page::setNoCacheHeaders();
+
+
+
+// SHUTDOWN 
+
+/**
+ * Shutdown callback.
+ * 
+ * @return void
+ */
+function shutdownCallback() {
+  
+  //Err::setLogOnlyHandlers();
+
+  //if (Cache::issetInstance()) {  
+    //For non-persistent connections only
+    //$cache = &Cache::getInstance();
+    //$cache->close();
+
+    //Cache::unsetInstance();
+  //}
+  
+}
+register_shutdown_function("shutdownCallback");
+
+
+// ERROR PARAMETERS
+
+//errNo
+//define("ERR_NO", substr(filter_input1(INPUT_GET, "errNo", FILTER_SANITIZE_MD5TOKEN), 0, 100));
+//if (ERR_NO!==PHP_STR && !filter_var1(ERR_NO, FILTER_VALIDATE_ERRNO)) {
+//  Err::trigger_error1(ERR::ERR_ERR, "Invalid error number: " . ERR_NO, __FILE__, __LINE__);
+//}
+
+//errKey
+//define("ERR_KEY", array_search(ERR_NO, Err::$A_ERR_NO));
+
+//errMsg
+//define("ERR_MSG", substr(filter_input1(INPUT_GET, "errMsg", FILTER_SANITIZE_ERRMSG), 0, 200));
+
+//errScript
+//define("ERR_SCRIPT", substr(filter_input(INPUT_GET, "errScript", FILTER_SANITIZE_STRING), 0, 255));
+
+//errLine
+//define("ERR_LINE",  substr(filter_input(INPUT_GET, "errLine", FILTER_SANITIZE_NUMBER_INT), 0, 5));
+
+//errStack
+//define("ERR_STACK", substr(filter_input1(INPUT_GET, "errStack", FILTER_SANITIZE_STRING_WITHBR), 0, 2000));
+
+?>

+ 55 - 0
Private/error/err-401.php

@@ -0,0 +1,55 @@
+<?php
+
+/**
+ * Copyright 2021, 2026 5 Mode
+ *
+ * This file is part of GrandePuffo.
+ *
+ * GrandePuffo is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GrandePuffo is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.  
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GrandePuffo. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * err-401.php
+ * 
+ * Unauthorized 401 error page.
+ *
+ * @author Daniele Bonini <my25mb@has.im>
+ * @copyrights (c) 2016, 2026 5 Mode
+ */
+
+?>
+
+<?php //require APP_SCRIPT_PATH . "/header.php";?>
+
+
+    <div class="content-area">
+
+      <div class="col-xs-12 col-sm-12 col-md-12 col-lg-12">
+
+        <div class="box-centrd box-centrd-align-cent" style="width: 100%;">
+
+          <div align="center" style="width: 100%;">
+            <!--<img src="res/logo3.png" border="0">-->
+            <br><br>
+            <div style="width:100%; padding: 7%,0;"><h3>Unauthorized. 为授权. No autorizado. Non autorisé. Non autorizzato.</h3></div>
+          </div>
+
+        </div>  
+          
+        <br>
+        
+      </div>
+
+    </div>  
+
+
+<?php //require APP_SCRIPT_PATH . "/footer.php";?>

+ 63 - 0
Private/error/err-404.php

@@ -0,0 +1,63 @@
+<?php
+
+/**
+ * Copyright 2021, 2026 5 Mode
+ *
+ * This file is part of GrandePuffo.
+ *
+ * GrandePuffo is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GrandePuffo is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.  
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GrandePuffo. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * err-404.php
+ * 
+ * Page Not Found. 404 error page.
+ *
+ * @author Daniele Bonini <my25mb@has.im>
+ * @copyrights (c) 2016, 2026 5 Mode
+ */
+
+?>
+
+<?php //require APP_SCRIPT_PATH . "/header.php";?>
+
+
+    <div class="content-area">
+
+      <div class="col-xs-12 col-sm-12 col-md-12 col-lg-12">
+
+        <div class="box-centrd box-centrd-align-cent" style="width: 100%;">
+
+          <br><br>
+
+          <div class="spacer"><br><br><br><br></div>          
+          
+          <div align="center" style="width: 100%;">
+            <!--<img src="res/logo3.png" border="0">-->
+            <br><br>
+            <div style="width:100%; padding-left: 7%; padding-right: 7%;"><h3>Page not found. 找不到网页. Página no encontrada. Page non trouvée. Pagina non trovata.</h3></div>
+          </div>
+          
+          <div class="spacer-fixed" style="clear:both;"><br><br><br><br><br></div>
+
+          <div class="spacer" style="clear:both;"><br><br><br><br><br><br><br><br><br><br></div>
+
+        </div>  
+          
+        <br>
+
+      </div>
+
+    </div>  
+ 
+
+<?php //require APP_SCRIPT_PATH . "/footer.php";?>

+ 55 - 0
Private/error/err-502.php

@@ -0,0 +1,55 @@
+<?php
+
+/**
+ * Copyright 2021, 2026 5 Mode
+ *
+ * This file is part of GrandePuffo.
+ *
+ * GrandePuffo is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GrandePuffo is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.  
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GrandePuffo. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * err-502.php
+ * 
+ * Unauthorized 502 error page.
+ *
+ * @author Daniele Bonini <my25mb@has.im>
+ * @copyrights (c) 2016, 2026 5 Mode
+ */
+
+?>
+
+<?php //require APP_SCRIPT_PATH . "/header.php";?>
+
+
+    <div class="content-area">
+
+      <div class="col-xs-12 col-sm-12 col-md-12 col-lg-12">
+
+        <div class="box-centrd box-centrd-align-cent" style="width: 100%;">
+
+          <div align="center" style="width: 100%;">
+            <!--<img src="res/logo3.png" border="0">-->
+            <br><br>
+            <div style="width:100%; padding: 7%,0;"><h3>Unauthorized. 为授权. No autorizado. Non autorisé. Non autorizzato.</h3></div>
+          </div>
+
+        </div>  
+          
+        <br>
+        
+      </div>
+
+    </div>  
+
+
+<?php //require APP_SCRIPT_PATH . "/footer.php";?>

+ 80 - 0
Private/functions/func.app.inc

@@ -0,0 +1,80 @@
+<?php
+
+/**
+ * Copyright 2021, 2026 5 Mode
+ *
+ * This file is part of SqueePF.
+ *
+ * SqueePF is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SqueePF is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.  
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with SqueePF. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * func.app.inc
+ * 
+ * App related functions.
+ *
+ * @author Daniele Bonini <my25mb@has.im>
+ * @copyrights (c) 2016, 2026 5 Mode    
+ */
+
+use fivemode\fivemode\Config;
+
+
+/**
+ * Retrieve the list of the app hosts 
+ * 
+ * @return array the hosts array
+ */
+function getHostsArray(): array {
+  $reta = [];
+  $reta[] = APP_HOST;
+  $i = 2;
+  while (true && $i<=10) {
+    if (defined("APP_HOST" . $i)) {
+      $reta[] = Config::get("APP/HOST" . $i);
+    } else {
+      break;
+    }  
+    $i++;
+  }
+  return $reta;
+}
+
+
+/**
+ * 
+ * @return string
+ */
+function getQRCodeUri(string $styleTag): string {
+  
+  $retval = PHP_STR;
+  
+  $serverName = strtolower($_SERVER['HTTP_HOST']);
+  
+  if (mb_stripos1($serverName, "5mode.com") || mb_stripos1($serverName, "localhost")) {
+    $retval = "qrcode_5mode" . $styleTag . ".png";
+  }
+  
+  return $retval; 
+}
+
+
+function isSubdomainHost(string &$subdomain) {
+  $hostname = str_replace("www.", PHP_STR, strtolower($_SERVER['HTTP_HOST']));    
+  $ipos = mb_stripos($hostname, ".");
+  $subdomain = left($hostname, $ipos);
+  $noSubdomain = false;
+  if (($subdomain==="grandepuffo.doggy")) {
+    $noSubdomain = true;
+  }
+  return !$noSubdomain;
+}

+ 167 - 0
Private/functions/func.array.inc

@@ -0,0 +1,167 @@
+<?php
+
+/**
+ * Copyright 2021, 2026 5 Mode
+ *
+ * This file is part of SqueePF.
+ *
+ * SqueePF is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SqueePF is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.  
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with SqueePF. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * func.array.inc
+ * 
+ * Array related functions.
+ *
+ * @author Daniele Bonini <my25mb@has.im>
+ * @copyrights (c) 2016, 2026, 5 Mode     
+ */
+
+/**
+ * Fix multiple file uploaded array ($_FILE)
+ * 
+ * @param array $f the $_FILE array
+ * @return array the array fixed
+ */
+function fixMultipleFileUpload(&$f): array
+{
+    $files = array();
+    $count = count($f['name']);
+    $keys = array_keys($f);
+   
+    for($i=0;$i<$count;$i++)
+    {
+        foreach($keys as $key)
+        {
+            $files[$i][$key] = $f[$key][$i];
+        }
+    }
+    return $files;
+}
+
+/**
+ * Count the non zero elements of the given array
+ * 
+ * @param array $array
+ */
+function count_nonzeros(& $array): int 
+{
+  return count(array_filter($array));
+}  
+  
+/**
+ * Count the dimensions of the given array
+ * 
+ * @param array $array
+ * @return int the dimensions of the array
+ */
+function array_dim(array $array): int
+{
+  if (is_array(reset($array))) {
+    $retval = array_dim(reset($array)) + 1;
+  } else {
+    $retval = 1;
+  }
+
+  return $retval;
+}
+
+/**
+ * Filter false array entries replacing them with nulls
+ * 
+ * @param array $array array to filter
+ * @return array the resulting array
+ */
+function array_filter_tonull(array $array): array 
+{
+  foreach($array as & $val) {
+    if (!$val) {
+      $val = null;
+    }
+  }
+  return $array;
+}
+
+/**
+ * Return the values from a single column in the input array 
+ * filtered for value between $min and $max..
+ * 
+ * @param array $array the array being filtered
+ * @param string $column the column to filter on
+ * @param mixed $min the min val of column
+ * @param mixed $max the max val of column
+ * @return array the filtered array
+ */
+function array_numcolumn(& $array, string $column, int $min = 0, int $max = 99999999999): array 
+{
+  $GLOBALS['min'] = $min;
+  $GLOBALS['max'] = $max;
+  $array = array_filter(array_column($array, $column), function($val) {
+    if ($val>=$GLOBALS['min'] && $val<=$GLOBALS['max']) {
+      return true;
+    } else {
+      return false;
+    }
+  });
+  return $array;
+}
+
+/**
+ * Count the keys of a given array
+ * 
+ * @param array $array
+ * @return int the number of keys
+ */
+function array_keys_count(& $array): int
+{
+  return count(array_keys($array));
+}
+
+/**
+ * Append a value to the right of array until the given length
+ * 
+ * @param array $array array to pad
+ * @param mixed $val the value to the append to the array
+ * @param int $len the final length of the padded array
+ * @return void
+ */
+function array_rpad(& $array, $val, int $newlen): void 
+{
+  $i=count($array);
+  if ($i>=$newlen) {
+    return;
+  }
+  while($i<$newlen) {
+    $array[] = $val; 
+    $i++;
+  }
+}
+
+/**
+ * Searches the array for a given value and returns the corresponding key if successful
+ * otherwise null, result safe (not 0)
+ * 
+ * @param mixed $needle the value to search 
+ * @param array $array the array being searched
+ * @return mixed the key associated to the value, or null
+ */
+function array_search2($needle, & $array) 
+{
+  $retval = null;
+  foreach ($array as $key => $value) {
+    if ($value === $needle) {
+      $retval = $key;
+      break;
+    }
+  }
+  return $retval;
+}

+ 65 - 0
Private/functions/func.file.inc

@@ -0,0 +1,65 @@
+<?php
+
+/**
+ * Copyright 2021, 2026 5 Mode
+ *
+ * This file is part of SqueePF.
+ *
+ * SqueePF is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SqueePF is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.  
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with SqueePF. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * func.file.inc
+ * 
+ * String related functions.
+ *
+ * @author Daniele Bonini <my25mb@has.im>
+ * @copyrights (c) 2016, 2026 5 Mode
+ */
+
+/**
+ * Copy a source file
+ * 
+ * @param string $sourceFilePath the file to copy
+ * @param string $destFilePath the destination file
+ * @return void
+ */
+function cp(string $sourceFilePath, string $destFilePath): void 
+{
+  if (is_readable($sourceFilePath)) {
+      $dataLength = 999000;
+      $hsfile = fopen($sourceFilePath, "r");
+      $hdfile = fopen($destFilePath, "w");
+      while ($data = fread($hsfile, $dataLength)) {
+        fwrite($hdfile, $data);
+      }
+      fclose($hsfile);
+      fclose($hdfile);
+   }   
+}
+
+
+/**
+ * Get a new temp file path
+ * 
+ * @param string $tempResRoot the root path
+ * @return string the new tmp file path
+ */
+function getNewTmpFileName(string $tempResRoot, string $ext): string
+{
+    chdir($tempResRoot);
+    $tmpFileName = "tmp". mt_rand(1000000000, 9999999999) . ".$ext";
+    while (is_readable($tmpFileName)) {
+       $tmpFileName = "tmp". mp_rand(1000000000, 9999999999) . ".$ext";
+    }
+    return $tempResRoot . DIRECTORY_SEPARATOR . $tmpFileName;
+}

+ 300 - 0
Private/functions/func.filter.inc

@@ -0,0 +1,300 @@
+<?php
+
+/**
+ * Copyright 2021, 2026 5 Mode
+ *
+ * This file is part of SqueePF.
+ *
+ * SqueePF is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SqueePF is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.  
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with SqueePF. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * func-filter.inc
+ * 
+ * Custom filtering functions.
+ *
+ * @author Daniele Bonini <my25mb@has.im>
+ * @copyrights (c) 2016, 2026 5 Mode
+ */
+
+use fivemode\fivemode\Err;
+use fivemode\fivemode\ErrUtil;
+
+
+// Validate / sanitize a given string
+define("FILTER_SANITIZE_BOOLEAN", 1);
+define("FILTER_SANITIZE_ERRMSG", 2);
+define("FILTER_SANITIZE_FILENAME", 3);
+define("FILTER_SANITIZE_FILENAME_WITH_SPACE", 4);
+define("FILTER_SANITIZE_FILEPATH", 5);
+define("FILTER_SANITIZE_IMAGENAME", 6);
+define("FILTER_SANITIZE_LANGUAGE", 7);
+define("FILTER_SANITIZE_KEY", 8);
+define("FILTER_SANITIZE_MD5TOKEN", 9);
+define("FILTER_SANITIZE_Q", 10);
+define("FILTER_SANITIZE_QM", 11);
+define("FILTER_SANITIZE_SCRIPTNAME", 12);
+define("FILTER_SANITIZE_SHA2TOKEN", 13);
+define("FILTER_SANITIZE_STRING_WITHBR", 14);
+define("FILTER_SANITIZE_TAG", 15);
+define("FILTER_SANITIZE_TAGS", 16);
+define("FILTER_SANITIZE_URL1", 17);
+define("FILTER_SANITIZE_USERNAME", 18);
+define("FILTER_SANITIZE_FILEPATH_LESS", 19);
+define("FILTER_CLEAN_LANDINGPAGE", 100);
+define("FILTER_VALIDATE_ERRNO", 200);
+define("FILTER_VALIDATE_IMAGENAME", 201);
+define("FILTER_VALIDATE_LANGUAGE", 202);
+define("FILTER_VALIDATE_SHA2TOKEN", 203);
+define("FILTER_VALIDATE_MD5TOKEN", 204);
+define("FILTER_VALIDATE_REFID", 205);
+define("FILTER_VALIDATE_USERNAME", 206);
+define("FILTER_VALIDATE_TIMEWINDOW", 207);
+
+
+/**
+ * Sanitize a given variable
+ * 
+ * @param string $string the string to check
+ * @param integer $filter the type of filter to apply
+ * @param mixed $param (optional) for various purpose
+ * @return mixed the string filtered, a boolean if the string is validate
+ */
+function filter_var1(string $string, int $filter, $param = null) {
+  if ($string=="") {
+    return $string;
+  }  
+  switch ($filter) {
+    case FILTER_SANITIZE_BOOLEAN:
+      return preg_replace("/[^0-1]/iu", "", $string);
+    case FILTER_SANITIZE_ERRMSG:
+      return str_replace(chr(10)," ", str_replace(chr(13)," ",filter_var($string, FILTER_SANITIZE_STRING, FILTER_FLAG_ENCODE_HIGH | FILTER_FLAG_STRIP_BACKTICK)));
+    case FILTER_SANITIZE_FILENAME:
+      return preg_replace("/[^\w\-.]/iu", "", $string);
+    case FILTER_SANITIZE_FILENAME_WITH_SPACE:
+      return preg_replace("/[^\w\-. ]/iu", "", $string);
+    case FILTER_SANITIZE_FILEPATH:
+      return preg_replace("/[^A-Za-z0-9-_.\/]/", "", $string);
+    case FILTER_SANITIZE_IMAGENAME:
+      return str_replace("_", "", preg_replace("/[^\w\- ]/iu", "", $string));
+    case FILTER_SANITIZE_KEY:
+      return preg_replace("/[^A-Za-z0-9-_]/", "", $string);
+    case FILTER_SANITIZE_LANGUAGE:
+      return preg_replace("/[^A-Za-z\-]/", "", $string);      
+    case FILTER_SANITIZE_MD5TOKEN:
+      return preg_replace("/[^A-Za-z0-9]/", "", $string);
+    case FILTER_SANITIZE_Q:
+      return trim(preg_replace("/[^\w\-: ]/iu", "", $string));
+    case FILTER_SANITIZE_QM:
+      return trim(preg_replace("/[^\w\.\-: ]/iu", "", $string));      
+    case FILTER_SANITIZE_SCRIPTNAME:
+      return preg_replace("/[^A-Za-z0-9-_]/", "", $string);
+    case FILTER_SANITIZE_SHA2TOKEN:
+      return preg_replace("/[^A-Za-z0-9]/", "", $string);
+    case FILTER_SANITIZE_STRING_WITHBR:
+      return str_replace("&NewLine;", "<br>", filter_var(str_replace("<br>", "&NewLine;", isset1($string,"")), FILTER_SANITIZE_STRING));
+    case FILTER_SANITIZE_TAG:
+      return preg_replace("/[^\w\-]/iu", "", $string);
+    case FILTER_SANITIZE_TAGS:
+      return preg_replace("/[^\w\- ]/iu", "", $string);
+    case FILTER_SANITIZE_URL1:
+      return preg_replace("/[^\w\-]/iu", "", $string);
+    case FILTER_SANITIZE_USERNAME:
+      return preg_replace("/[^\w\-]/", "", $string);
+    case FILTER_SANITIZE_FILEPATH_LESS:
+      $s = $string;
+      $s = str_replace("../", PHP_STR, $s);
+      $s = str_replace("..", PHP_STR, $s);
+      $s = str_replace("/", PHP_STR, $s);
+      $s = str_replace("*", PHP_STR, $s);
+      $s = str_replace("?", PHP_STR, $s);
+      $s = str_replace("%", PHP_STR, $s);
+      return trim_word($s, ['../', '..', '/', '*', '?', '%', '.']);
+    case FILTER_CLEAN_LANDINGPAGE:
+      $posLandingPage = strpos($string, "lndp");
+      $i = strpos($string, "&");
+      if ($posLandingPage===false) {
+        return $string;
+      }  
+      if ($i===false) {
+        return "";
+      } else {
+        return substr($string, $i+1); 
+      }
+      break;
+    case FILTER_VALIDATE_ERRNO:
+      if (preg_match("/^[0-9]+?$/", $string)) {
+        return true;
+      } else {
+        if (preg_match("/^([a-zA-Z0-9]{32})?$/", $string) && ErrUtil::isValidError($string)) {
+          return true;
+        } else {
+          return false;
+        }
+      }
+    case FILTER_VALIDATE_IMAGENAME:
+      return (mb_strlen($string)>=3 && mb_strlen($string)<=50 && preg_match("/^[\w\- ]+?$/iu", $string) && !stripos($string,"_"));
+    case FILTER_VALIDATE_LANGUAGE:
+      return preg_match("/^([a-z]{2}\-[A-Z]{2})?$/", $string);
+    case FILTER_VALIDATE_REFID:
+      if (!filter_var($string, FILTER_VALIDATE_INT)) {
+        return false;
+      } 
+      if (hash("sha256", $string . APP_SALT, false) != $param) {
+        return false;
+      }
+      return true;
+    case FILTER_VALIDATE_SHA2TOKEN:
+      return preg_match("/^([a-zA-Z0-9]{64})?$/", $string);
+    case FILTER_VALIDATE_MD5TOKEN:
+      return preg_match("/^([a-zA-Z0-9]{32})?$/", $string);      
+    case FILTER_VALIDATE_USERNAME:
+      return (strlen($string)>=3 && strlen($string)<=20 && preg_match("/^[\w\-]+?$/", $string));
+    case FILTER_VALIDATE_TIMEWINDOW:
+      return (strlen($string)===2 && preg_match("/^[0-9][d|w]$/", $string));
+    default:
+      Err::trigger_error1(ERR::ERR_GENERAL, "filter_var1: $filter filter: not implemented", __FILE__, __LINE__);
+      break;
+  }
+}  
+
+//INPUT_POST
+//INPUT_GET
+//INPUT_COOKIE
+//INPUT_ENV
+//INPUT_SERVER
+//INPUT_SESSION
+//INPUT_REQUEST
+
+/**
+ * Sanitize a given input string
+ * 
+ * @param integer $inputType the type of input INPUT_POST, INPUT_GET, etc.
+ * @param string $key the key of the input
+ * @param integer $filter the type of filter to apply
+ * @param mixed $param (optional) for various purpose
+ * @return mixed the string filtered, a boolean if the string is validate
+ */
+function filter_input1(int $inputType, string $key, int $filter, $param = null) {
+  
+  $input = array();  
+  switch ($inputType) {
+    case INPUT_POST:
+      $input =& $_POST;
+      break;
+    case INPUT_GET:
+      $input =& $_GET;
+      break;
+    default:
+      Err::trigger_error1(ERR::ERR_GENERAL, "filter_input1: $inputType inputType: not implemented", __FILE__, __LINE__);
+      break;
+  }
+  
+  if (!isset($input[$key])) {
+    return null;
+  }
+  
+  switch ($filter) {
+    case FILTER_SANITIZE_BOOLEAN:
+      return preg_replace("/[^0-1]/iu", "", $input[$key]);
+    case FILTER_SANITIZE_ERRMSG:
+      return str_replace(chr(10)," ", str_replace(chr(13)," ",filter_var($input[$key], FILTER_SANITIZE_STRING, FILTER_FLAG_ENCODE_HIGH | FILTER_FLAG_STRIP_BACKTICK)));
+    case FILTER_SANITIZE_Q:
+      return trim(preg_replace("/[^\w\-: ]/iu", "", $input[$key]));
+    case FILTER_SANITIZE_QM:
+      return trim(preg_replace("/[^\w\.\-: ]/iu", "", $input[$key]));  
+    case FILTER_SANITIZE_MD5TOKEN:
+      return preg_replace("/[^A-Za-z0-9]/", "", $input[$key]);
+    case FILTER_SANITIZE_FILENAME:
+      return preg_replace("/[^\w\-.]/iu", "", $input[$key]);
+    case FILTER_SANITIZE_FILENAME_WITH_SPACE:
+      return preg_replace("/[^\w\-. ]/iu", "", $input[$key]);
+    case FILTER_SANITIZE_FILEPATH:
+      return preg_replace("/[^A-Za-z0-9-_.\/]/", "", $input[$key]);
+    case FILTER_SANITIZE_IMAGENAME:
+      return str_replace("_", "", preg_replace("/[^\w\- ]/iu", "", $input[$key]));      
+    case FILTER_SANITIZE_KEY:
+      return preg_replace("/[^A-Za-z0-9-_]/", "", $input[$key]);
+    case FILTER_SANITIZE_LANGUAGE:
+      return preg_replace("/[^A-Za-z\-]/", "", $input[$key]);      
+    case FILTER_SANITIZE_SCRIPTNAME:
+      return preg_replace("/[^A-Za-z0-9-_]/", "", $input[$key]);
+    case FILTER_SANITIZE_SHA2TOKEN:
+      return preg_replace("/[^A-Za-z0-9]/", "", $input[$key]);
+    case FILTER_SANITIZE_STRING_WITHBR:
+      return str_replace("&NewLine;", "<br>", filter_var(str_replace("<br>", "&NewLine;", isset1($input[$key],"")), FILTER_SANITIZE_STRING));
+    case FILTER_SANITIZE_TAG:
+      return preg_replace("/[^\w\-]/iu", "", $input[$key]);
+    case FILTER_SANITIZE_TAGS:
+      return preg_replace("/[^\w\- ]/iu", "", $input[$key]);
+    case FILTER_SANITIZE_URL1:
+      return preg_replace("/[^\w\-]/iu", "", $input[$key]);
+    case FILTER_SANITIZE_USERNAME:
+      return preg_replace("/[^\w\-]/", "", $input[$key]);
+    case FILTER_SANITIZE_FILEPATH_LESS:
+      $s = $input[$key];
+      $s = str_replace("../", PHP_STR, $s);
+      $s = str_replace("..", PHP_STR, $s);
+      $s = str_replace("/", PHP_STR, $s);
+      $s = str_replace("*", PHP_STR, $s);
+      $s = str_replace("?", PHP_STR, $s);
+      $s = str_replace("%", PHP_STR, $s);
+      return trim_word($s, ['../', '..', '/', '*', '?', '%', '.']);
+    case FILTER_CLEAN_LANDINGPAGE:
+      $posLandingPage = strpos($input[$key], "lndp");
+      $i = strpos($input[$key], "&");
+      if ($posLandingPage===false) {
+        return $input[$key];
+      }  
+      if ($i===false) {
+        return "";
+      } else {
+        return substr($input[$key], $i+1); 
+      }
+      break;
+    case FILTER_VALIDATE_ERRNO:
+      if (preg_match("/^[0-9]+?$/", $input[$key])) {
+        return true;
+      } else {
+        if (preg_match("/^([a-zA-Z0-9]{32})?$/", $input[$key]) && ErrUtil::isValidError($string)) {
+          return true;
+        } else {
+          return false;
+        }
+      }
+    case FILTER_VALIDATE_IMAGENAME:
+      return (mb_strlen($input[$key])>=3 && mb_strlen($input[$key])<=50 && preg_match("/^[\w\- ]+?$/iu", $input[$key]) && !stripos($input[$key], "_"));
+    case FILTER_VALIDATE_LANGUAGE:
+      return preg_match("/^([a-z]{2}\-[A-Z]{2})?$/", $input[$key]);
+    case FILTER_VALIDATE_REFID:
+      if (!filter_var($input[$key], FILTER_VALIDATE_INT)) {
+        return false;
+      } 
+      if (hash("sha256", $input[$key] . APP_SALT, false) != $param) {
+        return false;
+      }
+      return true;
+    case FILTER_VALIDATE_SHA2TOKEN:
+      return preg_match("/^([a-zA-Z0-9]{64})?$/", $input[$key]);
+    case FILTER_VALIDATE_MD5TOKEN:
+      return preg_match("/^([a-zA-Z0-9]{32})?$/", $input[$key]);  
+    case FILTER_VALIDATE_USERNAME:
+      return (strlen($input[$key])>=3 && strlen($input[$key])<=20 && preg_match("/^[\w\-]+?$/", $input[$key]));
+    case FILTER_VALIDATE_TIMEWINDOW:
+      return (strlen($input[$key])===2 && preg_match("/^[0-9][d|w]$/", $input[$key]));
+    default:
+      Err::trigger_error1(ERR::ERR_GENERAL, "filter_var1: $filter filter: not implemented", __FILE__, __LINE__);
+      break;
+  }
+}
+
+?>

+ 81 - 0
Private/functions/func.routing.inc

@@ -0,0 +1,81 @@
+<?php
+
+/**
+ * Copyright 2021, 2026 5 Mode
+ *
+ * This file is part of GrandePuffo.
+ *
+ * GrandePuffo is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GrandePuffo is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.  
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GrandePuffo. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * func.string.inc
+ * 
+ * String related functions.
+ *
+ * @author Daniele Bonini <my25mb@has.im>
+ * @copyrights (c) 2016, 2026 5 Mode
+ */
+
+
+function genTmpRes(string $myRes, string $myTmpResPath): void
+{
+  cp($myRes,$myTmpResPath);
+  if (is_readable($myTmpResPath)) {
+    chmod($myTmpResPath, 0655);  
+  }  
+}
+
+
+function getRes(string $displaiedSha): int
+{
+    global $ROUTING;
+
+    //echo("displaiedSha=$displaiedSha");
+    $tot = count($ROUTING['RES_PASSWORD'])-1;
+    $i=0;
+    while ($i<=$tot) {
+      //echo("#$i=".hash("sha256", $ROUTING['RES_PASSWORD'][$i] . $ROUTING['RES_SALT'][$i])."<br>");
+      if (hash("sha256", $ROUTING['RES_PASSWORD'][$i] . $ROUTING['RES_SALT'][$i]) === $displaiedSha) {
+        return $i; 
+      }
+      $i++;
+    } 
+}
+
+
+function getResIndex(string $myPrefix):  string
+{
+    global $ROUTING;
+ 
+    $i=0;
+    foreach($ROUTING['RES_ROUTER_PREFIX'] as $prefix) {
+      if ($prefix[0]>=$myPrefix && $myPrefix<=$prefix[1]) {
+        return $i;
+      }
+      $i++;
+    }
+}
+      
+                  
+function getResRouter(string $myPrefix):  string
+{
+    global $ROUTING;
+ 
+    $i=0;
+    foreach($ROUTING['RES_ROUTER_PREFIX'] as $prefix) {
+      if ($prefix[0]>=$myPrefix && $myPrefix<=$prefix[1]) {
+        return $ROUTING['RES_ROUTER'][$i];
+      }
+      $i++;
+    }
+}

+ 586 - 0
Private/functions/func.string.inc

@@ -0,0 +1,586 @@
+<?php
+
+/**
+ * Copyright 2021, 2026 5 Mode
+ *
+ * This file is part of SqueePF.
+ *
+ * SqueePF is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SqueePF is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.  
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with SqueePF. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * func.string.inc
+ * 
+ * String related functions.
+ *
+ * @author Daniele Bonini <my25mb@has.im>
+ * @copyrights (c) 2016, 2026 5 Mode
+ */
+
+
+/**
+ * Check if the given word is a contraction 
+ * 
+ * @param string $w the word being checked
+ * @return bool if the word is a contraction, true/false
+ */
+function is_contraction(?string $w): bool 
+{
+  $retval = false;
+  if (!isset($w)) {
+    return $retval;
+  }
+  if ($w === mb_strtoupper($w)) {
+    $retval = true;
+  }
+  return $retval;
+}
+
+/**
+ * Check if the passed word is a given name 
+ * 
+ * @param string $w the word being checked
+ * @return bool if the word is a given name, true/false
+ */
+function is_givenName(?string $w): bool 
+{
+  $retval = false;
+  if (!isset($w)) {
+    return $retval;
+  }
+  if (is_ucfirst($w) && !is_contraction($w)) {
+    $retval = true;
+  }
+  return $retval;
+}
+
+
+/**
+ * Check if the given string start with a capital letter
+ * 
+ * @param string $s the string being checked
+ * @return bool if the string starts with a capital letter , true/false
+ */
+function is_ucfirst(?string $s): bool 
+{
+  $retval = false;
+  if (!isset($s)) {
+    return $retval;
+  }
+  if (ucfirst(mb_substr($s,0,1)) === mb_substr($s,0,1)) {
+    $retval = true;
+  }
+  return $retval;
+}
+
+/**
+ * Check if the letter is a vowel
+ * 
+ * @param char $letter the letter to check
+ * @return bool if the letter is vowel, true/false
+ */
+function is_vowel(string $letter): bool 
+{
+  $vowels = ['a','e','i','o','u'];
+  return in_array($letter, $vowels);
+}
+
+/**
+ * Check if the given url is a valid Facebook page
+ * 
+ * Eg:
+ * http://facebook.com/mrdanielebeta                                   
+ * http://facebook.com/pg/makeiteasyforabird
+ * 
+ * @param string $url the url to check
+ * @return bool if the url is Facebook url, true/false
+ */
+function isFacebookUrl(string $url): bool 
+{
+  $retval=false;
+  $maxLength = 60;
+  if (strlen($url)>60) {
+    return $retval;    
+  }
+  $url= strtolower($url);
+  $pattern1 = "/^http(s)?\:\/\/(www\.)?facebook\.com\/[\w\.]+$/";
+  $pattern2 = "/^http(s)?\:\/\/(www\.)?facebook\.com\/pg\/[\w\.]+$/";
+  if (preg_match($pattern1, $url) || preg_match($pattern2, $url)) {
+    $retval=true;
+  } else {
+    $retval=false;
+  }  
+  return $retval;
+}  
+
+/**
+ * Check if the given url is a valid domain url
+ * 
+ * Eg:
+ * http://danielebonini.com
+  * 
+ * @param string $url the url to check
+ * @return bool if the url is a valid domain url, true/false
+ */
+function isUrl(string $url): bool
+{
+  $retval=false;
+  $maxLength = 45;
+  if (strlen($url)>45) {
+    return $retval;    
+  }
+  $url= strtolower($url);
+  $pattern1 = "/^http(s)?\:\/\/(www\.)?\w+\.\w+$/";
+  $pattern2 = "/^http(s)?\:\/\/(www\.)?\w+\.\w+.\w+$/";
+  if (preg_match($pattern1, $url) || preg_match($pattern2, $url)) {
+    $retval=true;
+  } else {
+    $retval=false;
+  }  
+  return $retval;
+}  
+
+/**
+ * Check if the given url is a valid Youtube page
+ * 
+ * Eg:
+ * http://youtube.com/watch?v=eeerwr24334 
+ * 
+ * @param string $url the url to check
+ * @return bool if the url is Youtube url, true/false
+ */
+function isYoutubeUrl(string $url): bool 
+{
+  $retval=false;
+  $maxLength = 50;
+  if (strlen($url)>50) {
+    return $retval;    
+  }
+  $url= strtolower($url);
+  $pattern1 = "/^http(s)?\:\/\/(www\.)?youtube\.com\/watch\?v\=[\w]+$/";
+  if (preg_match($pattern1, $url)) {
+    $retval=true;
+  } else {
+    $retval=false;
+  }  
+  return $retval;
+}  
+
+/**
+ * Test if a word is of a latin language
+ * 
+ * @param string  $word the string to test
+ * @return bool  if $word is of a latin language, true/false
+ */
+function isLatinLang(string $word): bool 
+{
+  
+  //$char = mb_substr($word, 0, 1);
+  //return !preg_match("/[\x{31C0}-\x{31EF}\x{3300}-\x{33FF}\x{3400}-\x{4DBF}\x{4E00}-\x{9FFF}\x{F900}-\x{FAFF}\x{FE30}-\x{FE4F}]{1}/u", $char);
+  
+  $isNonLatinLang = preg_match("/^[\w-]+[\x{31C0}-\x{31EF}\x{3300}-\x{33FF}\x{3400}-\x{4DBF}\x{4E00}-\x{9FFF}\x{F900}-\x{FAFF}\x{FE30}-\x{FE4F}]+$/u", $word) ||
+                    preg_match("/^[\x{31C0}-\x{31EF}\x{3300}-\x{33FF}\x{3400}-\x{4DBF}\x{4E00}-\x{9FFF}\x{F900}-\x{FAFF}\x{FE30}-\x{FE4F}]+$/u", $word) ||
+                    preg_match("/^[\x{31C0}-\x{31EF}\x{3300}-\x{33FF}\x{3400}-\x{4DBF}\x{4E00}-\x{9FFF}\x{F900}-\x{FAFF}\x{FE30}-\x{FE4F}]+[\w-]+$/u", $word) ||
+                    preg_match("/^[\w-]+[\x{31C0}-\x{31EF}\x{3300}-\x{33FF}\x{3400}-\x{4DBF}\x{4E00}-\x{9FFF}\x{F900}-\x{FAFF}\x{FE30}-\x{FE4F}]+[\w-]+$/u", $word);
+  
+  return !$isNonLatinLang;
+}
+
+function json_decode_from_db(string $json, bool $assoc = false) 
+{
+  $temp = $json;
+  $temp = str_replace('\"', '"', $temp);
+  $temp = str_replace("\'", "'", $temp);
+  $temp = str_replace("\\\\", "\\", $temp);
+  
+  return json_decode($temp, $assoc);
+}
+
+/**
+ * Left cut the given string for the specified length 
+ * 
+ * @param string $string the string being cut on the left
+ * @param int $length the length of the substring to return
+ * @return string the resulting substring    
+ */
+function left(?string $string, int $length): string 
+{
+  if (!isset($string) || $string === PHP_STR) {
+    return PHP_STR;
+  }
+  return mb_substr($string, 0, $length);
+}
+
+/**
+ * Right cut the given string for the specified length 
+ * 
+ * @param string $string the string being cut on the right
+ * @param int $length the length of the substring to return
+ * @return string the resulting substring    
+ */
+function right(?string $string, int $length): string 
+{
+  if (!isset($string) || $string === PHP_STR) {
+    return PHP_STR;
+  }  
+  return mb_substr($string, mb_strlen($string) - $length);
+}
+
+/**
+ * Get the left word of the given sentence 
+ * 
+ * @param string $phrase  the sentence being processed
+ * @return string the first word    
+ */
+function leftWord(?string $phrase): string 
+{
+  if (isset1($phrase, PHP_STR)===PHP_STR) {
+    return PHP_STR;
+  }  
+
+  $aWords = explode(PHP_SPACE, $phrase);
+  return $aWords[0]; 
+}
+
+/**
+ * Get the right word of the given sentence 
+ * 
+ * @param string $phrase  the sentence being processed
+ * @return string the last word    
+ */
+function rightWord(?string $phrase): string 
+{
+  if (isset1($phrase, PHP_STR)===PHP_STR) {
+    return PHP_STR;
+  }  
+
+  $aWords = explode(PHP_SPACE, $phrase);
+  return $aWords[count($aWords)-1];
+}
+
+
+/**
+ * Return the number of words of the given phrase
+ * 
+ * @param string $phrase
+ * @return int the number of words of the phrase
+ */
+function mb_str_word_count(string $phrase): int 
+{
+  $aWords = explode(PHP_SPACE, $phrase);
+  return count($aWords);
+}
+
+/**
+ * Finds the position of first occurrence of a string within another, 
+ * result safe (excluding 0), case insensitive
+ * 
+ * @param string $string the string being searched
+ * @param string $needle the string searched
+ * @param int $offset the position in string to start the search 
+ * @return mixed the position of the needle or False
+ */
+function mb_stripos1(string $string, string $needle, int $offset = 0) 
+{
+  return mb_stripos(PHP_TILDE . $string, $needle, $offset);
+}  
+
+/**
+ * Normalize the case of the given text 
+ * 
+ * @param string $text text to case normalize
+ * @return string the normalized text
+ */
+function str_case_normalize(?string $text): string 
+{
+  $retval = $text;
+  
+  if (!isset($text) || $text === PHP_STR) {
+    return $retval;
+  }
+  
+  $aWords = explode(PHP_SPACE, $text);
+  
+  foreach($aWords as & $word) {
+    if (strtoupper(substr($word,0,1)) === substr($word,0,1)) {
+      $word = ucfirst(strtolower($word));
+    } else {  
+      $word = strtolower($word);
+    }  
+  }
+    
+  $retval = implode(" ", $aWords);
+  
+  return $retval;
+}  
+
+/**
+ * Clean a phase removing repeated spaces and trimming it  
+ * 
+ * @param string $string the string being cleaned
+ * @return string the cleaned string
+ */
+function str_cleanphrase(string $string): string 
+{
+  //return trim(str_replace("  ", PHP_SPACE, str_replace("  ", PHP_SPACE, $string)));
+  
+  //hypen
+  $retval = str_replace(" -", PHP_HYPHEN, $string);
+  $retval = str_replace("- ", PHP_HYPHEN, $retval);
+  $retval = ltrim($retval, PHP_HYPHEN);
+  $retval = rtrim($retval, PHP_HYPHEN);
+  //space
+  $retval = trim(str_replace("  ", PHP_SPACE, str_replace("  ", PHP_SPACE, $retval)));
+  
+  return $retval;
+}  
+
+/**
+ * Clean a phase removing repeated spaces and trimming it  
+ * 
+ * @param string $string the string being cleaned
+ * @return string the cleaned string
+ */
+function str_cleanphrase_M(string $string): string 
+{
+  //return trim(str_replace("  ", PHP_SPACE, str_replace("  ", PHP_SPACE, $string)));
+  
+  //hypen
+  $retval = str_replace(" -", PHP_HYPHEN, $string);
+  $retval = str_replace("- ", PHP_HYPHEN, $retval);
+  $retval = ltrim($retval, PHP_HYPHEN);
+  $retval = rtrim($retval, PHP_HYPHEN);
+  //axterix
+  //$retval = trim(str_replace("**", "*", str_replace("**", "*", $retval)));
+  $retval = str_replace("*", PHP_SPACE, $retval);
+  //space
+  $retval = trim(str_replace("  ", PHP_SPACE, str_replace("  ", PHP_SPACE, $retval)));
+  
+  return $retval;
+}  
+
+/**
+ * Clean a phase removing the plurals  
+ * 
+ * @param string $string the string being cleaned
+ * @return string the cleaned string
+ */
+function str_cleanplurals(string $string): string 
+{
+  $aWords = explode(PHP_SPACE, $string);
+  
+  foreach($aWords as &$word) {
+    if (right($word,3)==="ies") {
+      $word = left($word, strlen($word)-3) . "y";
+    }  
+    if (right($word,3)==="hes" || right($word,3)==="xes") {
+      $word = left($word, strlen($word)-2);
+    }  
+    if (right($word,2)==="es") {
+      $word = left($word, strlen($word)-2) . "e";
+    }  
+    if (right($word,2)!=="ss" && right($word,1)==="s") {
+      $word = left($word, strlen($word)-1);
+    }  
+  }
+  
+  return implode(PHP_SPACE, $aWords);
+}  
+
+/**
+ * Break the given phrase by a word separator
+ * 
+ * @param string $phrase the phrase being broken
+ * @param string $word_separetor the word at which beginning break the phrase
+ * @param string $retFirstPart the resulting broken first part of the phrase 
+ * @param string $retReminder the remaining part of the phrase
+ * @return void
+ */
+function str_phrasebrk(string $phrase, string $word_separetor, & $retFirstPart, & $retRemainder = null): void 
+{
+  $phrase = PHP_SPACE . $phrase . PHP_SPACE;
+  $i = mb_stripos1($phrase, PHP_SPACE . $word_separetor . PHP_SPACE);
+  if ($i) {
+    $retFirstPart = trim(mb_substr($phrase, 0, $i));
+    if (isset($retRemainder)) {
+      $retRemainder = trim(mb_substr($phrase, $i));
+    }
+  } else {  
+    $retFirstPart = trim($phrase);
+    if (isset($retRemainder)) {
+      $retRemainder = PHP_STR;
+    }     
+  }
+}
+
+/**
+ * Return the given needle only if not already present in string
+ * 
+ * @param string $string
+ * @param string $needle
+ * @return string
+ */
+function str_place(string $string, string $needle): string  
+{
+   if (mb_stripos(PHP_TILDE . $string, $needle)) {
+     return PHP_STR;
+   } else {
+     return $needle;
+   }
+}
+
+/**
+ * Replace a pattern in the given string
+ * 
+ * @param string $needle the pattern searched for
+ * @param string $replace the replacement
+ * @param string $string the string being searched
+ * @param int $replacements the number of replacements to perform
+ * @return string the replaced string
+ */
+function str_replace1(string $needle, string $replace, ?string $string, int $replacements = 1): string 
+{
+  if (!isset($string) || $replacements === 0) {
+    return $string;
+  }
+  
+  if ($replacements < 0 ) {
+    $string = implode(PHP_SPACE, array_reverse(explode(PHP_SPACE, $string)));
+    $replace = implode(PHP_SPACE, array_reverse(explode(PHP_SPACE, $replace)));
+    $string = preg_replace("/$needle/i", $replace, $string, abs($replacements));
+    $string = implode(PHP_SPACE, array_reverse(explode(PHP_SPACE, $string)));
+  } else {
+    $string = preg_replace("/$needle/i", $replace, $string, abs($replacements));
+  }
+  
+  return $string;
+}
+
+/**
+ * Reverse the words in the given phrase
+ * 
+ * @param string $string the string being reversed
+ * @return string the resulting reversed string
+ */
+function str_phrase_reverse(string $string): string 
+{
+  settype($aWords, "array");
+  $aWords = explode(PHP_SPACE, $string);
+  $aWords = array_reverse($aWords);
+  return implode(PHP_SPACE, $aWords);
+}
+
+/**
+ * Finds the position of the first occurance of a word 
+ * in the given string, result safe (excluding 0), case insensitive
+ * 
+ * @param string $phrase the phrase being searched
+ * @param string $word the searched word
+ * @param int $offset the position in string to start the search 
+ * @return mixed the position of the searched word, otherwise false 
+ */
+function str_wordipos(string $phrase, string $word, int $offset = 0) 
+{
+  if ($offset<0) {
+    $offset=0;
+  }
+  $word = strtolower($word);
+  $phrase = strtolower($phrase);
+  $aWords = explode(" ", $phrase);
+  $max = count($aWords) - 1;
+  $i = $offset; 
+  while ($i <= $max) {
+    $word2 = $aWords[$i];
+    if ($word === $word2) {
+      return $i + 1;
+    }
+    $i++;
+  }
+  return false;
+}
+
+/**
+ * Remove duplicate words from a phrase
+ * 
+ * @param string $phrase the string being processed
+ * @param bool $removeRightMost if remove the right-most duplicates, true/false
+ * @return string the resulting string
+ */
+function str_word_unique(string $phrase, bool $removeRightMost = true) 
+{
+  settype($aWords, "array");
+  $aWords = explode(PHP_SPACE, $phrase);
+  if ($removeRightMost) {
+    // Remove right-most duplicates from the given string..
+    $aWords = array_unique($aWords);
+  } else {
+    // Remove left-most duplicates from the given string..
+    $aWords = array_reverse($aWords);
+    $aWords = array_unique($aWords);
+    $aWords = array_reverse($aWords);
+  }  
+  return implode(PHP_SPACE, $aWords);
+}  
+
+/**
+ * Short words by the given char limit
+ * 
+ * @param string $phrase the phrase being parsed 
+ * @param int $wordLength the word limit to set
+ * @return string  the resulting phrase
+ */
+function str_word_length(string $phrase, int $wordLength): string 
+{
+  $aWords = explode(PHP_SPACE, $phrase);
+  foreach($aWords as & $word) {
+    $word = mb_substr($word, 0, $wordLength);
+  }
+  return implode(PHP_SPACE, $aWords);
+}
+
+/**
+ * Right trim a word from the given string
+ * 
+ * @param string $phrase the string being trimmed
+ * @param array $aWords the words to remove
+ * @return string the resulting right trimmed phrase 
+ */
+function rtrim_word(string $phrase, array $aWords): string 
+{
+  $retval = PHP_SPACE . $phrase . PHP_SPACE;
+  
+  foreach ($aWords as $word) {
+    if (right($retval, mb_strlen($word) + 2) === (PHP_SPACE . $word . PHP_SPACE)) {
+      $retval = left($retval, mb_strlen($retval) - (mb_strlen($word) + 1));
+    }  
+  }  
+  
+  return str_cleanphrase($retval);
+}
+
+/**
+ * Trim a word from the given string
+ * 
+ * @param string $phrase the string being trimmed
+ * @param array $aWords the words to remove
+ * @return string the resulting trimmed phrase 
+ */
+function trim_word(string $phrase, array $aWords) {
+
+  $retval = PHP_SPACE . $phrase . PHP_SPACE;
+  
+  foreach ($aWords as $word) {
+    $retval = str_ireplace(PHP_SPACE . $word . PHP_SPACE, PHP_SPACE, $retval);
+  }  
+  
+  return str_cleanphrase($retval);
+}

+ 129 - 0
Private/functions/func.various.inc

@@ -0,0 +1,129 @@
+<?php
+
+/**
+ * Copyright 2021, 2026 5 Mode
+ *
+ * This file is part of SqueePF.
+ *
+ * SqueePF is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * SqueePF is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.  
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with SqueePF. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * func.various.inc
+ * 
+ * Functions of various kind.
+ *
+ * @author Daniele Bonini <my25mb@has.im>
+ * @copyrights (c) 2016, 2026 5 Mode
+ */
+
+/**
+ * Replacement for echo with debug checking
+ * 
+ * @param boolean $debug_var a debug value, if true the echo will be executed 
+ * @param list $args a variable argument list
+ * @return void
+ */
+function echo_ifdebug(bool $debug_var, ...$args): void 
+{
+  if (!DEBUG || !$debug_var) {
+    return;
+  }
+  foreach($args as $arg) {
+    echo $arg;
+  }
+}
+
+function getResource(string $string, string $destLocale = "EN"): string
+{
+  
+  global $LOCALE;
+  
+  if ($destLocale === "EN") {
+    return $string; 
+  }    
+
+  if ($LOCALE[$destLocale]["Monday"]==PHP_STR) {
+    return $string; 
+  }    
+
+  return str_ireplace(array_keys($LOCALE[$destLocale]),array_values($LOCALE[$destLocale]), $string);
+}
+
+
+/**
+ * Get an integer result for a division
+ * 
+ * @param mixed $a first operand
+ * @param mixed $b second operand
+ * @return int the integer result
+ */
+function intdiv_1($a, $b): int 
+{
+  return ($a - $a % $b) / $b;
+}
+
+/**
+ * Check if the number is odd
+ * 
+ * @param mixed $a first operand
+ * @return bool if the number is odd, true/false
+ */
+function is_odd($a): bool 
+{
+  return ($a % 2) > 0;
+}
+
+/**
+ * Check if the number is pair
+ * 
+ * @param mixed $a first operand
+ * @return bool if the number is pair, true/false
+ */
+function is_pair($a): bool
+{
+  return ($a % 2) === 0;
+}
+
+
+/**
+ * Check if a variable is set with a default return
+ * 
+ * @param mixed $var the variable to check
+ * @param mixed $default the default value
+ * @return mixed the return value
+ */
+function isset1(&$var, $default=false) 
+{
+  if (isset($var)) {
+    return $var;
+  } else {
+    return $default;
+  }
+}
+
+/**
+ * Replacement for var_dump with debug checking
+ * 
+ * @param boolean $debug_var a debug value, if true the var_dump will be executed 
+ * @param list $args a variable argument list
+ * @return void
+ */
+function var_dump_ifdebug(bool $debug_var, ...$args): void 
+{
+  if (!DEBUG || !$debug_var) {
+    return;
+  }
+  foreach($args as $arg) {
+    var_dump($arg);
+  }
+}

+ 0 - 0
Private/log/empty


+ 45 - 0
Private/routes/page/page.php

@@ -0,0 +1,45 @@
+<?php
+
+/**
+ * Copyright 2021, 2026 5 Mode
+ *
+ * This file is part of GrandePuffo.
+ *
+ * GrandePuffo is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GrandePuffo is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.  
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GrandePuffo. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * page.php
+ * 
+ * The Page.
+ *
+ * @author Daniele Bonini <my25mb@has.im>
+ * @copyrights (c) 2016, 2026 5 Mode     
+ */
+
+$myPrefix= mt_rand(1000000, 1199999);
+$myImageSha = "ba78c55eae177c8e6749fa6aded78757ccfb10c85121cb4fbbb76b9ce3ef4db2";
+
+?>
+
+<html>
+<head>
+<link src="style1.css" type="text/css">
+</head>
+<body>
+<img src='/<?PHP echo($myPrefix.$myImageSha);?>'>
+<img src='/<?PHP echo($myPrefix.$myImageSha);?>'>
+<img src='/<?PHP echo($myPrefix.$myImageSha);?>'>
+<img src='/<?PHP echo($myPrefix.$myImageSha);?>'>
+<img src='/<?PHP echo($myPrefix.$myImageSha);?>'>
+</body>
+</html>

+ 25 - 0
Private/templates/Licenses/license-GrandePuffo.txt

@@ -0,0 +1,25 @@
+/**
+ * Copyright 2021, 2026 5 Mode
+ *
+ * This file is part of GrandePuffo.
+ *
+ * GrandePuffo is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GrandePuffo is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.  
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GrandePuffo. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * fileName.php
+ * 
+ * Description of the file.
+ *
+ * @author Daniele Bonini <my25mb@has.im>
+ * @copyrights (c) 2016, 2026, 5 Mode
+ */

+ 0 - 0
Private/upload/empty


+ 5 - 0
Public/css/style1.css

@@ -0,0 +1,5 @@
+body {
+   background-color: #FFFFFF;
+   font-size: 11px;
+   color: lightgreen;
+}

+ 121 - 0
Public/idxpage1img.php

@@ -0,0 +1,121 @@
+<?php
+
+/**
+ * Copyright 2021, 2026 5 Mode
+ *
+ * This file is part of GrandePuffo.
+ *
+ * GrandePuffo is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GrandePuffo is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.  
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GrandePuffo. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * mrouter.php
+ * 
+ * The main router.
+ *
+ * @author Daniele Bonini <my25mb@has.im>
+ * @copyrights (c) 2016, 2026 5 Mode     
+ */
+
+use fivemode\fivemode\Cookie;
+use fivemode\fivemode\Puffi;
+
+
+// FUNCTION AND VARIABLE DECLARATIONS
+
+// Cookie reset..
+function resetCookies() {
+    Cookie::set($mySha, "0", Cookie::EXPIRE_ONEDAY, "/", APP_HOST);
+    Cookie::set($mySha."0", "", Cookie::EXPIRE_ONEDAY, "/", APP_HOST);
+    Cookie::set($mySha."1", "", Cookie::EXPIRE_ONEDAY, "/", APP_HOST);
+    Cookie::set($mySha."2", "", Cookie::EXPIRE_ONEDAY, "/", APP_HOST);
+    Cookie::set($mySha."3", "", Cookie::EXPIRE_ONEDAY, "/", APP_HOST);
+    Cookie::set($mySha."4", "", Cookie::EXPIRE_ONEDAY, "/", APP_HOST);
+}
+
+// Increment image instance counter..
+function setCookieCounter() {
+
+    // set iteraction counter..    
+
+   global $ROUTING;
+   global $myShaCounter;
+   global $mySha;
+
+   while(true) {
+      $myShaCounter++;    
+
+      if (!defined("ROUTING_RES".$myShaCounter)) {
+         Cookie::set($mySha, 0, Cookie::EXPIRE_ONEDAY, "/", APP_HOST);  
+         break;
+      }  
+                                                         
+      if ($ROUTING['RES_TYPE'][$myShaCounter]==="image") {
+          Cookie::set($mySha, $myShaCounter, Cookie::EXPIRE_ONEDAY, "/", APP_HOST);
+          break;
+      }
+  }
+}
+
+$myTmpResPath = "";
+
+
+// PARAMETERS VALIDATION
+
+
+//$myDisplaiedSha = substr($url,7,strlen($url)-11);
+$myDisplaiedSha = substr($url,7,strlen($url));
+
+$myResIdx=getRes($myDisplaiedSha);
+// echo("**".$myResIdx."**");
+$mySha = $ROUTING['RES_SHA'][$myResIdx]; 
+
+$myShaCounter = Cookie::get($mySha, 0);
+//echo("**".$myShaCounter."**");
+ 
+$myResType = $ROUTING['RES_TYPE'][$myShaCounter];
+// echo("**".$myResType."**");
+  
+if ($myResType==="image") {
+
+      //$mySha = $ROUTING['RES_SHA'][$myResIdx];
+      $myPageElementID = $ROUTING['WEBPAGE_ELEMENT'][$myShaCounter];
+      $myRes = Puffi::getres($mySha,$myShaCounter); 
+      //echo("--".$myRes."--");
+      $cookiePath = Cookie::get($mySha.$myShaCounter, PHP_STR);
+
+      if ( $cookiePath !== $cookiePath) {
+
+        $myTmpResPath = $cookiePath;
+        $myTmpResRelPath = substr($myTmpResPath, strlen(APP_PUBLIC_PATH));
+
+      } else { 
+
+        $myTmpResRoot = APP_PUBLIC_PATH . DIRECTORY_SEPARATOR . "tmpres";
+
+        $myTmpResPath = getNewTmpFileName($myTmpResRoot, pathinfo($myRes, PATHINFO_EXTENSION));
+        $myTmpResRelPath = substr($myTmpResPath, strlen(APP_PUBLIC_PATH));
+        
+        genTmpRes(APP_PUBLIC_PATH . DIRECTORY_SEPARATOR . $myRes, $myTmpResPath);
+
+        Cookie::set($mySha.$myShaCounter, $myTmpResPath, Cookie::EXPIRE_ONEDAY, "/", APP_HOST);
+
+      }
+
+}
+
+if (is_readable($myTmpResPath)) {
+    $filecont = file_get_contents($myTmpResPath);
+    echo($filecont);
+}
+
+setCookieCounter();

+ 61 - 0
Public/index.php

@@ -0,0 +1,61 @@
+<?php
+
+/**
+ * Copyright 2021, 2026 5 Mode
+ *
+ * This file is part of GrandePuffo.
+ *
+ * GrandePuffo is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GrandePuffo is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.  
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GrandePuffo. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * index.php
+ * 
+ * The index file.
+ *
+ * @author Daniele Bonini <my25mb@has.im>
+ * @copyrights (c) 2016, 2026 5 Mode     
+ */
+
+require "../Private/core/init.inc";
+
+
+// FUNCTION AND VARIABLE DECLARATIONS
+
+
+// PARAMETERS VALIDATION
+
+$url = filter_input(INPUT_GET, "url")??"";
+$url = strip_tags($url);
+$url = strtolower(trim(substr($url, 0, 300), "/"));
+
+switch ($url) {
+  case "":
+  case "page":
+
+    $scriptPath = APP_ROUTE_PATH . "/page";
+    define("ROUTE_NAME", "page");
+    define("ROUTE_FILENAME", "page.php");   
+                              
+    break;         
+                        
+  default:
+    $scriptPath = APP_ERROR_PATH;
+    define("ROUTE_NAME", "err-404");
+    define("ROUTE_FILENAME", "err-404.php");  
+}
+
+if (ROUTE_NAME==="err-404") {
+  header("HTTP/1.1 404 Not Found");
+}  
+
+require $scriptPath . "/" . ROUTE_FILENAME;

File diff suppressed because it is too large
+ 1 - 0
Public/js/jquery-3.6.0.min.js


+ 65 - 0
Public/mrouter.php

@@ -0,0 +1,65 @@
+<?php
+
+/**
+ * Copyright 2021, 2026 5 Mode
+ *
+ * This file is part of GrandePuffo.
+ *
+ * GrandePuffo is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GrandePuffo is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.  
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with GrandePuffo. If not, see <https://www.gnu.org/licenses/>.
+ *
+ * mrouter.php
+ * 
+ * The main router.
+ *
+ * @author Daniele Bonini <my25mb@has.im>
+ * @copyrights (c) 2016, 2026 5 Mode     
+ */
+
+require "../Private/core/init.inc";
+
+
+// FUNCTION AND VARIABLE DECLARATIONS
+
+
+// PARAMETERS VALIDATION
+
+$url = filter_input(INPUT_GET, "url")??"";
+$url = strip_tags($url);
+$url = strtolower(trim(substr($url, 0, 300), "/"));
+
+$rndPrefix = substr($url, 0, 6);
+
+$myResRouter = getResRouter($rndPrefix);
+
+if ($myResRouter !== PHP_STR) {
+
+    $scriptPath = APP_ROUTE_PATH;
+    define("ROUTE_NAME", "router");
+    define("ROUTE_FILENAME", $myResRouter );  
+  
+    header("Content-Type: image/png");
+        
+    require(APP_PUBLIC_PATH . "/$myResRouter");
+    
+} else {
+    $scriptPath = APP_ERROR_PATH;
+    define("ROUTE_NAME", "err-404");
+    define("ROUTE_FILENAME", "err-404.php");  
+    
+    if (ROUTE_NAME==="err-404") {
+      header("HTTP/1.1 404 Not Found");
+    }  
+          
+    require $scriptPath . "/" . ROUTE_FILENAME;
+}

BIN
Public/res/logo.png


BIN
Public/res/pix5.png


BIN
Public/res/sidebanner3.png


BIN
Public/res/topbanner1.png


Some files were not shown because too many files changed in this diff