'Home', 'link' => '/'], //['title' => 'Blog', 'link' => '//blog.flash.moe'], ['title' => 'Blog', 'link' => '//flash.moe/2020/?blog=1'], ['title' => 'Projects', 'link' => '/projects'], ['title' => 'Contact', 'link' => '/contact'], ['title' => 'Related', 'link' => '/related'], ['title' => 'Etcetera', 'link' => '/etc'], ['title' => 'Forum', 'link' => '//forum.flash.moe'], ]); define('FM_BGS', [ '/assets/headers/krk-000.jpg', '/assets/headers/krk-001.jpg', '/assets/headers/krk-002.jpg', '/assets/headers/krk-003.jpg', '/assets/headers/krk-004.jpg', '/assets/headers/krk-005.jpg', '/assets/headers/krk-006.jpg', '/assets/headers/krk-007.jpg', '/assets/headers/krk-008.jpg', '/assets/headers/mkt-000.jpg', '/assets/headers/mkt-001.jpg', '/assets/headers/mkt-002.jpg', '/assets/headers/mkt-003.jpg', '/assets/headers/mkt-004.jpg', '/assets/headers/mkt-005.jpg', '/assets/headers/mkt-006.jpg', '/assets/headers/mkt-007.jpg', '/assets/headers/mkt-008.jpg', '/assets/headers/mkt-009.jpg', '/assets/headers/mkt-010.jpg', '/assets/headers/mkt-011.jpg', '/assets/headers/mkt-012.jpg', '/assets/headers/mkt-013.jpg', '/assets/headers/mkt-014.jpg', '/assets/headers/mkt-015.jpg', '/assets/headers/mkt-016.jpg', '/assets/headers/mkt-017.jpg', '/assets/headers/mkt-018.jpg', '/assets/headers/mkt-019.jpg', '/assets/headers/mkt-020.jpg', '/assets/headers/mkt-021.jpg', '/assets/headers/mkt-022.jpg', '/assets/headers/mkt-023.jpg', '/assets/headers/mkt-024.jpg', '/assets/headers/mkt-025.jpg', '/assets/headers/mkt-026.jpg', '/assets/headers/mkt-027.jpg', '/assets/headers/mkt-028.jpg', '/assets/headers/mkt-029.jpg', '/assets/headers/mkt-030.jpg', '/assets/headers/mkt-031.jpg', '/assets/headers/mkt-032.jpg', '/assets/headers/mkt-033.jpg', '/assets/headers/mkt-034.jpg', '/assets/headers/mkt-035.jpg', '/assets/headers/mkt-036.jpg', '/assets/headers/mkt-037.jpg', '/assets/headers/mkt-038.jpg', '/assets/headers/mkt-039.jpg', '/assets/headers/mkt-040.jpg', '/assets/headers/mkt-041.jpg', '/assets/headers/mkt-042.jpg', '/assets/headers/mkt-043.jpg', '/assets/headers/mkt-044.jpg', '/assets/headers/mkt-045.jpg', '/assets/headers/mkt-046.jpg', '/assets/headers/mkt-047.jpg', '/assets/headers/mkt-048.jpg', '/assets/headers/mkt-049.jpg', '/assets/headers/mkt-050.jpg', '/assets/headers/mkt-051.jpg', '/assets/headers/mkt-052.jpg', '/assets/headers/mkt-053.jpg', '/assets/headers/mkt-054.jpg', '/assets/headers/mkt-055.jpg', '/assets/headers/mkt-056.jpg', '/assets/headers/mkt-057.jpg', '/assets/headers/mkt-058.jpg', '/assets/headers/mkt-059.jpg', '/assets/headers/mkt-060.jpg', '/assets/headers/mkt-061.jpg', '/assets/headers/mkt-062.jpg', '/assets/headers/mkt-063.jpg', ]); define('FM_FEET', [ 'if it ain\'t broke, i\'ll break it', ]); define('FM_ERRS' , [ 403 => [ 'code' => 403, 'title' => 'Access Denied', 'image' => '/assets/errors/403.jpg', 'desc' => 'You are not supposed to be here.', ], 404 => [ 'code' => 404, 'title' => 'Not Found', 'image' => '/assets/errors/404.jpg', 'desc' => 'Whatever you\'re looking for is no longer here, or might not have been here in the first place.', ], 405 => [ 'code' => 405, 'title' => 'Method Not Supported', 'image' => '/assets/errors/405.jpg', 'desc' => 'You\'re up to something, aren\'t you?', ], ]); function fm_component(string $name, array $vars = []) { extract($vars); require __DIR__ . '/../components/' . $name . '.php'; } function first_paragraph(string $text, string $delimiter = "\n"): string { $index = mb_strpos($text, $delimiter); return $index === false ? $text : mb_substr($text, 0, $index); } function time_elapsed(int $since, bool $full = false): string { $now = new DateTime; $since = new DateTime(date('c', $since)); $diff = $now->diff($since); $diff->w = floor($diff->d / 7); $diff->d -= $diff->w * 7; $string = [ 'y' => 'year', 'm' => 'month', 'w' => 'week', 'd' => 'day', 'h' => 'hour', 'i' => 'minute', 's' => 'second', ]; foreach($string as $key => &$value) { if($diff->{$key}) $value = $diff->{$key} . ' ' . $value . ($diff->{$key} > 1 ? 's' : ''); else unset($string[$key]); } if(!$full) $string = array_slice($string, 0, 1); return $string ? implode(', ', $string) . ' ago' : 'just now'; } function cache_output(string $name, int $lifetime, callable $callable) { $path = sys_get_temp_dir() . '/fm-' . $name . '.cache'; if(!is_file($path) || (filemtime($path) + $lifetime) < time()) file_put_contents($path, serialize($callable())); return unserialize(file_get_contents($path)); } set_include_path(realpath(__DIR__ . '/../lib/') . PATH_SEPARATOR . get_include_path()); spl_autoload_extensions('.php'); spl_autoload_register(); ob_start(); $reqMethod = filter_input(INPUT_SERVER, 'REQUEST_METHOD', FILTER_SANITIZE_STRING); $reqPath = '/' . trim(parse_url(filter_input(INPUT_SERVER, 'REQUEST_URI', FILTER_SANITIZE_STRING), PHP_URL_PATH), '/'); if(substr($reqPath, 0, 7) === '/error/') { $statusCode = intval(substr($reqPath, 7, 3)); } else { foreach(glob(__DIR__ . '/../pages/*.php') as $page) { $result = include_once $page; $statusCode = $result & 0xFFF; if(($result & FM_HIT) === FM_HIT) { if($statusCode >= 100 && $statusCode <= 999) http_response_code($statusCode); return; } if(($result & FM_ERR) === FM_ERR) break; } } $errorInfo = FM_ERRS[$statusCode ?? 404] ?? FM_ERRS[404]; http_response_code($errorInfo['code']); fm_component('header', ['title' => $errorInfo['title']]); ?>

<?=$errorInfo['image'];?>