41 Commits
1.1.2 ... 2.3.0

Author SHA1 Message Date
6109c2dd2f added fonts 2024-12-17 15:02:07 +07:00
9f375114ef deleted spaces 2024-12-17 14:25:47 +07:00
f8f6119ef6 added dynamic load css 2024-12-17 14:25:10 +07:00
9ef52e1dfc "javascript" to "js" 2024-12-17 14:22:47 +07:00
d3775bf96d some syntax errors 2024-12-16 23:23:46 +07:00
510a80665b added "/themes/default/" 2024-12-16 23:21:31 +07:00
e805fe9e76 fixed for core.html 2024-12-16 23:21:10 +07:00
2c29d0c842 added "/themes/default/" 2024-12-16 23:18:03 +07:00
93311f1857 getGlobal to getGlobals() 2024-12-16 22:47:43 +07:00
b86e856fe7 views\manager to views\templater 2024-12-16 22:44:36 +07:00
a893aa6b5a $minimal to $core 2024-12-16 22:42:08 +07:00
321c28a53e ${REPO_OWNER}\${REPO_NAME}\models\enumerations\language 2024-12-16 22:23:31 +07:00
9b958b6a88 $$router to $$core 2024-12-16 20:01:33 +07:00
24fcef43f7 PUBLIC to INDEX lol 2024-12-16 20:00:20 +07:00
c9e5cb3762 mirzaev\minimal\http\enumerations\content 2024-12-16 19:50:07 +07:00
2c6ed07ded {{ theme }} to "default" back 2024-12-16 18:33:58 +07:00
96388c220e any type instead fixed "module" 2024-12-16 18:25:49 +07:00
c2cba489d1 added dynamic load javascript 2024-12-16 18:23:15 +07:00
aad0a5a051 forget about it 2024-12-16 18:16:53 +07:00
8159f6866d created main.html 2024-12-16 18:15:28 +07:00
9dccb451f6 added aside.html 2024-12-16 18:13:59 +07:00
9f3b87c1ed created aside.html 2024-12-16 18:13:16 +07:00
e0845e2ef1 added colors.css 2024-12-16 17:08:39 +07:00
5c0f1815c0 created colors.css 2024-12-16 17:07:28 +07:00
6a4cfb8e2f deleted EOL 2024-12-16 17:05:44 +07:00
7ddf05ead3 Обновить author/project/system/public/css/themes/default/system.css 2024-12-16 17:04:53 +07:00
b6d2725848 separated 2024-12-16 17:04:30 +07:00
3a2e102e11 created footer.css 2024-12-16 17:04:01 +07:00
3aa8936fc5 created aside.css 2024-12-16 17:03:32 +07:00
3af08b07ed created header.css 2024-12-16 17:03:13 +07:00
4f4d31b64a created system.css 2024-12-16 17:02:39 +07:00
c0515a4171 separating main.css 2024-12-16 16:59:26 +07:00
02d1350982 {{ theme }} 2024-12-16 16:54:55 +07:00
37ae0546fd INDEX to PUBLIC 2024-12-16 15:52:52 +07:00
0510dca375 removed dublicate 2024-12-16 15:52:20 +07:00
2b3f624199 resolved #1 2024-12-15 22:16:01 +07:00
0843fd83a5 PHP 8.4 + MINIMAL 3.2.0 + many improvements 2024-12-15 00:20:44 +03:00
7f7cdced69 Обновить composer.json 2024-09-08 15:37:23 +07:00
04f8b49075 added other directories to indexing 2024-01-11 06:52:03 +07:00
a634e1b7c1 composer script fix 2024-01-11 06:17:52 +07:00
56f27f6f62 composer fix and installer fix 2024-01-11 05:58:38 +07:00
144 changed files with 1419 additions and 617 deletions

2
.gitea/template Normal file → Executable file
View File

@@ -1 +1 @@
*
**

0
.gitignore vendored Normal file → Executable file
View File

107
author/project/system/controllers/core.php Normal file → Executable file
View File

@@ -5,89 +5,112 @@ declare(strict_types=1);
namespace ${REPO_OWNER}\${REPO_NAME}\controllers;
// Files of the project
use ${REPO_OWNER}\${REPO_NAME}\views\manager,
use ${REPO_OWNER}\${REPO_NAME}\views\templater,
${REPO_OWNER}\${REPO_NAME}\models\core as models,
${REPO_OWNER}\${REPO_NAME}\models\account_model as account,
${REPO_OWNER}\${REPO_NAME}\models\session_model as session;
// Library for ArangoDB
use ArangoDBClient\Document as _document;
${REPO_OWNER}\${REPO_NAME}\models\session,
${REPO_OWNER}\${REPO_NAME}\models\enumerations\language;
// Framework for PHP
use mirzaev\minimal\controller;
use mirzaev\minimal\core as minimal,
mirzaev\minimal\controller,
mirzaev\minimal\http\response,
mirzaev\minimal\http\enumerations\status;
/**
* Core of controllers
* Controllers core
*
* @package ${REPO_OWNER}\${REPO_NAME}\controllers
* @author ${REPO_OWNER} < mail >
*
* @param session $$session Instance of the session
* @param language $$language Language
* @param response $$response Response
* @param array $$errors Registry of errors
*
* @method void __construct(minimal $$minimal, bool $$initialize) Constructor
*
* @license http://www.wtfpl.net/ Do What The Fuck You Want To Public License
* @author ${REPO_OWNER} <mail@domain.zone>
*/
class core extends controller
{
/**
* Postfix for name of controllers files
* Session
*
* @var session|null $$session Instance of the session
*/
final public const POSTFIX = '';
protected readonly session $$session;
/**
* Instance of a session
* Language
*
* @var language $$language Language
*/
protected readonly session $session;
protected language $$language = language::en;
/**
* Instance of an account
* Response
*
* @see https://wiki.php.net/rfc/property-hooks (find a table about backed and virtual hooks)
*
* @var response $$response Response
*/
protected readonly ?account $account;
protected response $$response {
// Read
get => $$this->response ??= $$this->request->response();
}
/**
* Registry of errors
* Errors
*
* @var array $$errors Registry of errors
*/
protected array $errors = [
protected array $$errors = [
'session' => [],
'account' => []
];
/**
* Constructor of an instance
* Constructor
*
* @param bool $initialize Initialize a controller?
* @param minimal $$core Instance of the MINIMAL
* @param bool $$initialize Initialize a controller?
*
* @return void
*/
public function __construct(bool $initialize = true)
public function __construct(minimal $$core, bool $$initialize = true)
{
// Blocking requests from CloudFlare (better to write this blocking into nginx config file)
if ($_SERVER['HTTP_USER_AGENT'] === 'nginx-ssl early hints') return;
if (isset($$_SERVER['HTTP_USER_AGENT']) && $$_SERVER['HTTP_USER_AGENT'] === 'nginx-ssl early hints') return status::bruh->label;
// For the extends system
parent::__construct($initialize);
parent::__construct(core: $$core);
if ($initialize) {
// Initializing is requested
if ($$initialize) {
// Requestet initializing
// Initializing of models core (connect to ArangoDB...)
// Initializing core of the models
new models();
// Initializing of the date until which the session will be active
$expires = strtotime('+1 week');
$$expires = strtotime('+1 week');
// Initializing of default value of hash of the session
$_COOKIE["session"] ??= null;
$$_COOKIE["session"] ??= null;
// Initializing of session
$this->session = new session($_COOKIE["session"], $expires, $this->errors['session']);
$$this->session = new session($$_COOKIE["session"], $$expires, $$this->errors['session']);
// Handle a problems with initializing a session
if (!empty($this->errors['session'])) die;
else if ($_COOKIE["session"] !== $this->session->hash) {
if (!empty($$this->errors['session'])) die;
else if ($$_COOKIE["session"] !== $$this->session->hash) {
// Hash of the session is changed (implies that the session has expired and recreated)
// Write a new hash of the session to cookies
setcookie(
'session',
$this->session->hash,
$$this->session->hash,
[
'expires' => $expires,
'expires' => $$expires,
'path' => '/',
'secure' => true,
'httponly' => true,
@@ -97,25 +120,7 @@ class core extends controller
}
// Initializing of preprocessor of views
$this->view = new templater($this->session);
$$this->view = new templater($$this->session);
}
}
/**
* Check of initialization
*
* Checks whether a property is initialized in a document instance from ArangoDB
*
* @param string $name Name of the property from ArangoDB
*
* @return bool The property is initialized?
*/
public function __isset(string $name): bool
{
// Check of initialization of the property and exit (success)
return match ($name) {
default => isset($this->{$name})
};
}
}

54
author/project/system/controllers/index.php Normal file → Executable file
View File

@@ -7,24 +7,62 @@ namespace ${REPO_OWNER}\${REPO_NAME}\controllers;
// Files of the project
use ${REPO_OWNER}\${REPO_NAME}\controllers\core;
// Framework for PHP
use mirzaev\minimal\http\enumerations\content,
mirzaev\minimal\http\enumerations\status;
/**
* Index controller
* Index
*
* @package ${REPO_OWNER}\${REPO_NAME}\controllers
* @author ${REPO_OWNER} < mail >
*
* @param array $$errors Registry of errors
*
* @method null index() Main page
*
* @license http://www.wtfpl.net/ Do What The Fuck You Want To Public License
* @author ${REPO_OWNER} <mail@domain.zone>
*/
final class index extends core
{
/**
* Render the main page
* Errors
*
* @param array $parameters Parameters of the request (POST + GET)
* @var array $$errors Registry of errors
*/
public function index(array $parameters = []): ?string
protected array $$errors = [
'session' => []
];
/**
* Main page
*
* @return null
*/
public function index(): null
{
// Exit (success)
if ($_SERVER['REQUEST_METHOD'] === 'GET') return $this->view->render(DIRECTORY_SEPARATOR . 'index.html');
else if ($_SERVER['REQUEST_METHOD'] === 'POST') return $main;
if (str_contains($$this->request->headers['accept'], content::any->value)) {
// Request for any response
// Render page
$$page = $$this->view->render('index.html');
// Sending response
$$this->response
->start()
->clean()
->sse()
->write($$page)
->validate($$this->request)
?->body()
->end();
// Deinitializing rendered page
unset($$page);
// Exit (success)
return null;
}
// Exit (fail)
return null;

301
author/project/system/models/core.php Normal file → Executable file
View File

@@ -5,14 +5,15 @@ declare(strict_types=1);
namespace ${REPO_OWNER}\${REPO_NAME}\models;
// Framework for PHP
use mirzaev\minimal\model;
use mirzaev\minimal\model,
mirzaev\minimal\http\enumerations\status;
// Framework for ArangoDB
use mirzaev\arangodb\connection as arangodb,
mirzaev\arangodb\collection,
mirzaev\arangodb\document;
// Libraries for ArangoDB
// Library for ArangoDB
use ArangoDBClient\Document as _document,
ArangoDBClient\DocumentHandler as _document_handler;
@@ -20,114 +21,131 @@ use ArangoDBClient\Document as _document,
use exception;
/**
* Core of models
* Models core
*
* @package ${REPO_OWNER}\${REPO_NAME}\controllers
* @author ${REPO_OWNER} < mail >
* @package ${REPO_OWNER}\${REPO_NAME}\models
*
* @param public ARANGODB Path to the file with ArangoDB session connection data
* @param arangodb $$arangodb Instance of the ArangoDB session
*
* @method void __construct(bool $$initialize, ?arangodb $$arangodb) Constructor
* @method _document|static|array|null read(string $$filter, string $$sort, int $$amount, int $$page, string $$return, array $$parameters, array &$$errors) Read document from ArangoDB
*
* @license http://www.wtfpl.net/ Do What The Fuck You Want To Public License
* @author ${REPO_OWNER} <mail@domain.zone>
*/
class core extends model
{
/**
* Postfix for name of models files
*/
final public const POSTFIX = '';
/**
* Path to the file with settings of connecting to the ArangoDB
*/
final public const ARANGODB = '../settings/arangodb.php';
/**
* Instance of the session of ArangoDB
*/
protected static arangodb $arangodb;
/**
* Name of the collection in ArangoDB
*/
public const COLLECTION = 'THIS_COLLECTION_SHOULD_NOT_EXIST_REPLACE_IT_IN_THE_MODEL';
/**
* Constructor of an instance
* ArangoDB connection daa
*
* @param bool $initialize Initialize a model?
* @param ?arangodb $arangodb Instance of a session of ArangoDB
* @var string ARANGODB Path to the file with ArangoDB session connection data
*/
final public const string ARANGODB = __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'settings' . DIRECTORY_SEPARATOR . 'arangodb.php';
/**
* ArangoDB
*
* @var arangodb $$arangodb Instance of the ArangoDB session
*/
protected static arangodb $$arangodb;
/**
* Constructor
*
* @param bool $$initialize Initialize a model?
* @param ?arangodb $$arangodb Instance of the ArangoDB session
*
* @return void
*/
public function __construct(bool $initialize = true, ?arangodb $arangodb = null)
public function __construct(bool $$initialize = true, ?arangodb $$arangodb = null)
{
// For the extends system
parent::__construct($initialize);
parent::__construct($$initialize);
if ($initialize) {
if ($$initialize) {
// Initializing is requested
if (isset($arangodb)) {
// Recieved an instance of a session of ArangoDB
// Write an instance of a session of ArangoDB to the property
$this->__set('arangodb', $arangodb);
} else {
// Not recieved an instance of a session of ArangoDB
// Initializing of an instance of a session of ArangoDB
$this->__get('arangodb');
}
// Writing an instance of a session of ArangoDB to the property
self::$$arangodb = $$arangodb ?? new arangodb(require static::ARANGODB);
}
}
/**
* Read from ArangoDB
* Read document from ArangoDB
*
* @param string $filter Expression for filtering (AQL)
* @param string $sort Expression for sorting (AQL)
* @param int $amount Amount of documents for collect
* @param int $page Page
* @param string $return Expression describing the parameters to return (AQL)
* @param array &$errors The registry on errors
* @param string $$filter Expression for filtering (AQL)
* @param string $$sort Expression for sorting (AQL)
* @param int $$amount Amount of documents for collect
* @param int $$page Page
* @param string $$return Expression describing the parameters to return (AQL)
* @param array $$parameters Binded parameters for placeholders ['placeholder' => parameter]
* @param array &$$errors Registry of errors
*
* @return _document|array|null An array of instances of documents from ArangoDB, if they are found
* @return mixed An array of instances of documents from ArangoDB, if they are found
*/
public static function read(
string $filter = '',
string $sort = 'd.created DESC, d._key DESC',
int $amount = 1,
int $page = 1,
string $return = 'd',
array &$errors = []
): _document|array|null {
public static function _read(
string $$filter = '',
string $$sort = 'd.created DESC, d._key DESC',
int $$amount = 1,
int $$page = 1,
string $$return = 'd',
array $$parameters = [],
array &$$errors = []
): _document|static|array|null {
try {
if (collection::init(static::$arangodb->session, static::COLLECTION)) {
if (collection::initialize(static::COLLECTION, static::TYPE)) {
// Initialized the collection
// Read from ArangoDB and exit (success)
return collection::search(
static::$arangodb->session,
// Read from ArangoDB
$$result = collection::execute(
sprintf(
<<<'AQL'
FOR d IN %s
FOR d IN @@collection
%s
%s
LIMIT %d, %d
LIMIT @offset, @amount
RETURN %s
AQL,
static::COLLECTION,
empty($filter) ? '' : "FILTER $filter",
empty($sort) ? '' : "SORT $sort",
--$page <= 0 ? 0 : $amount * $page,
$amount,
$return
)
empty($$filter) ? '' : "FILTER $$filter",
empty($$sort) ? '' : "SORT $$sort",
empty($$return) ? 'd' : $$return
),
[
'@collection' => static::COLLECTION,
'offset' => --$$page <= 0 ? 0 : $$page * $$amount,
'amount' => $$amount
] + $$parameters,
errors: $$errors
);
} else throw new exception('Failed to initialize the collection');
} catch (exception $e) {
// Write to the registry of errors
$errors[] = [
'text' => $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine(),
'stack' => $e->getTrace()
if ($$amount === 1 && $$result instanceof _document) {
// Received only 1 document and @todo rebuild
// Initializing the object
$$object = new static;
if (method_exists($$object, '__document')) {
// Object can implement a document from ArangoDB
// Writing the instance of document from ArangoDB to the implement object
$$object->__document($$result);
// Exit (success)
return $$object;
}
}
// Exit (success)
return $$result;
} else throw new exception('Failed to initialize ' . static::TYPE . ' collection: ' . static::COLLECTION);
} catch (exception $$e) {
// Writing to registry of errors
$$errors[] = [
'text' => $$e->getMessage(),
'file' => $$e->getFile(),
'line' => $$e->getLine(),
'stack' => $$e->getTrace()
];
}
@@ -135,154 +153,77 @@ class core extends model
return null;
}
/**
* Delete from ArangoDB
*
* @param _document $instance Instance of the document from ArangoDB
* @param array &$errors The registry on errors
*
* @return bool Deleted from ArangoDB without errors?
*/
public static function delete(_document $instance, array &$errors = []): bool
{
try {
if (collection::init(static::$arangodb->session, static::COLLECTION)) {
// Initialized the collection
// Delete from ArangoDB and exit (success)
return (new _document_handler(static::$arangodb->session))->remove($instance);
} else throw new exception('Failed to initialize the collection');
} catch (exception $e) {
// Write to the registry of errors
$errors[] = [
'text' => $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine(),
'stack' => $e->getTrace()
];
}
// Exit (fail)
return false;
}
/**
* Update in ArangoDB
*
* @param _document $instance Instance of the document from ArangoDB
*
* @return bool Writed to ArangoDB without errors?
*/
public static function update(_document $instance): bool
{
// Update in ArangoDB and exit (success)
return document::update(static::$arangodb->session, $instance);
}
/**
* Write
*
* @param string $name Name of the property
* @param mixed $value Value of the property
* @param string $$name Name of the property
* @param mixed $$value Value of the property
*
* @return void
*/
public function __set(string $name, mixed $value = null): void
public function __set(string $$name, mixed $$value = null): void
{
match ($name) {
'arangodb' => (function () use ($value) {
if ($this->__isset('arangodb')) {
// Is alredy initialized
// Exit (fail)
throw new exception('Forbidden to reinitialize the session of ArangoDB ($this::$arangodb)', 500);
} else {
// Is not already initialized
if ($value instanceof arangodb) {
// Recieved an appropriate value
// Write the property and exit (success)
self::$arangodb = $value;
} else {
// Recieved an inappropriate value
// Exit (fail)
throw new exception('Session of ArangoDB ($this::$arangodb) is need to be mirzaev\arangodb\connection', 500);
}
}
match ($$name) {
'arangodb' => (function () use ($$value) {
if (isset(static::$$arangodb)) throw new exception('Forbidden to reinitialize the ArangoDB session($$this::$$arangodb)', status::internal_server_error->value);
else if ($$value instanceof arangodb) self::$$arangodb = $$value;
else throw new exception('Session of connection to ArangoDB ($$this::$$arangodb) is need to be mirzaev\arangodb\connection', status::internal_server_error->value);
})(),
default => parent::__set($name, $value)
default => parent::__set($$name, $$value)
};
}
/**
* Read
*
* @param string $name Name of the property
* @param string $$name Name of the property
*
* @return mixed Content of the property, if they are found
*/
public function __get(string $name): mixed
public function __get(string $$name): mixed
{
return match ($name) {
'arangodb' => (function () {
try {
if (!$this->__isset('arangodb')) {
// Is not initialized
// Initializing of a default value from settings
$this->__set('arangodb', new arangodb(require static::ARANGODB));
}
// Exit (success)
return self::$arangodb;
} catch (exception) {
// Exit (fail)
return null;
}
})(),
default => parent::__get($name)
return match ($$name) {
default => parent::__get($$name)
};
}
/**
* Delete
*
* @param string $name Name of the property
* @param string $$name Name of the property
*
* @return void
*/
public function __unset(string $name): void
public function __unset(string $$name): void
{
// Deleting a property and exit (success)
parent::__unset($name);
parent::__unset($$name);
}
/**
* Check of initialization
*
* @param string $name Name of the property
* @param string $$name Name of the property
*
* @return bool The property is initialized?
*/
public function __isset(string $name): bool
public function __isset(string $$name): bool
{
// Check of initialization of the property and exit (success)
return parent::__isset($name);
return parent::__isset($$name);
}
/**
* Call a static property or method
*
* @param string $name Name of the property or the method
* @param array $arguments Arguments for the method
* @param string $$name Name of the property or the method
* @param array $$arguments Arguments for the method
*/
public static function __callStatic(string $name, array $arguments): mixed
public static function __callStatic(string $$name, array $$arguments): mixed
{
match ($name) {
return match ($$name) {
'arangodb' => (new static)->__get('arangodb'),
default => throw new exception("Not found: $name", 500)
default => throw new exception("Not found: $$name", 500)
};
}
}

View File

@@ -0,0 +1,50 @@
<?php
declare(strict_types=1);
namespace ${REPO_OWNER}\${REPO_NAME}\models\enumerations;
/**
* Language
*
* Types of languages by ISO 639-1 standart
*
* @package ${REPO_OWNER}\${REPO_NAME}\models\enumerations
*
* @license http://www.wtfpl.net/ Do What The Fuck You Want To Public License
* @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy>
* @author ${REPO_OWNER} <mail@domain.zone>
*/
enum language
{
case en;
case ru;
/**
* Label
*
* Initialize label of the language
*
* @param language|null $$language Language into which to translate
*
* @return string Translated label of the language
*
* @todo
* 1. More languages
* 2. Cases???
*/
public function label(?language $$language = language::en): string
{
// Exit (success)
return match ($$this) {
language::en => match ($$language) {
language::en => 'English',
language::ru => 'Английский'
},
language::ru => match ($$language) {
language::en => 'Russian',
language::ru => 'Русский'
}
};
}
}

View File

@@ -0,0 +1,21 @@
<?php
declare(strict_types=1);
namespace ${REPO_OWNER}\${REPO_NAME}\models\enumerations;
/**
* Session
*
* Types of session verification
*
* @package ${REPO_OWNER}\${REPO_NAME}\models\enumerations
*
* @license http://www.wtfpl.net/ Do What The Fuck You Want To Public License
* @author ${REPO_OWNER} <mail@domain.zone>
*/
enum session
{
case hash_only;
case hash_else_address;
}

View File

@@ -0,0 +1,31 @@
<?php
declare(strict_types=1);
namespace ${REPO_OWNER}\${REPO_NAME}\models\interfaces;
// Framework for ArangoDB
use mirzaev\arangodb\enumerations\collection\type;
/**
* Collection
*
* Interface for implementing a collection from ArangoDB
*
* @package ${REPO_OWNER}\${REPO_NAME}\models\interfaces
*
* @license http://www.wtfpl.net/ Do What The Fuck You Want To Public License
* @author ${REPO_OWNER} <mail@domain.zone>
*/
interface collection
{
/**
* Name of the collection in ArangoDB
*/
public const string COLLECTION = 'THIS_COLLECTION_SHOULD_NOT_EXIST';
/**
* Type of the collection in ArangoDB
*/
public const type TYPE = type::document;
}

View File

@@ -0,0 +1,81 @@
<?php
declare(strict_types=1);
namespace ${REPO_OWNER}\${REPO_NAME}\models\interfaces;
// Library для ArangoDB
use ArangoDBClient\Document as _document;
/**
* Document
*
* Interface for implementing a document instance from ArangoDB
*
* @param _document $$document An instance of the ArangoDB document from ArangoDB (protected readonly)
*
* @package ${REPO_OWNER}\${REPO_NAME}\models\interfaces
*
* @license http://www.wtfpl.net/ Do What The Fuck You Want To Public License
* @author ${REPO_OWNER} <mail@domain.zone>
*/
interface document
{
/**
* Write
*
* Write a property into an instance of the ArangoDB document
*
* @param string $$name Name of the property
* @param mixed $$value Content of the property
*
* @return void
*/
public function __set(string $$name, mixed $$value = null): void;
/**
* Read
*
* Read a property from an instance of the ArangoDB docuemnt
*
* @param string $$name Name of the property
*
* @return mixed Content of the property
*/
public function __get(string $$name): mixed;
/**
* Delete
*
* Deinitialize the property in an instance of the ArangoDB document
*
* @param string $$name Name of the property
*
* @return void
*/
public function __unset(string $$name): void;
/**
* Check of initialization
*
* Check of initialization of the property into an instance of the ArangoDB document
*
* @param string $$name Name of the property
*
* @return bool The property is initialized?
*/
public function __isset(string $$name): bool;
/**
* Execute a method
*
* Execute a method from an instance of the ArangoDB document
*
* @param string $$name Name of the method
* @param array $$arguments Arguments for the method
*
* @return mixed Result of execution of the method
*/
public function __call(string $$name, array $$arguments = []): mixed;
}

363
author/project/system/models/session.php Normal file → Executable file
View File

@@ -5,8 +5,13 @@ declare(strict_types=1);
namespace ${REPO_OWNER}\${REPO_NAME}\models;
// Files of the project
use mirzaev\ebala\models\account,
mirzaev\ebala\models\traits\status;
use ${REPO_OWNER}\${REPO_NAME}\models\traits\status,
${REPO_OWNER}\${REPO_NAME}\models\traits\buffer,
${REPO_OWNER}\${REPO_NAME}\models\traits\document as document_trait,
${REPO_OWNER}\${REPO_NAME}\models\interfaces\document as document_interface,
${REPO_OWNER}\${REPO_NAME}\models\interfaces\collection as collection_interface,
${REPO_OWNER}\${REPO_NAME}\models\enumerations\session as verification,
${REPO_OWNER}\${REPO_NAME}\models\enumerations\language;
// Framework for ArangoDB
use mirzaev\arangodb\collection,
@@ -19,258 +24,210 @@ use ArangoDBClient\Document as _document;
use exception;
/**
* Model of session
* Session model
*
* @package ${REPO_OWNER}\${REPO_NAME}\controllers
* @author ${REPO_OWNER} < mail >
* @package ${REPO_OWNER}\${REPO_NAME}\models
*
* @param string COLLECTION Name of the collection in ArangoDB
* @param verification VERIFICATION Type of session verification
*
* @method void __construct(?string $$hash, ?int $$expires, array &$$errors) Constructor
* @method document|null hash(string $$hash, array &$$errors) Search by hash
* @method document|null address(string $$address, array &$$errors) Search by IP-address
*
* @license http://www.wtfpl.net/ Do What The Fuck You Want To Public License
* @author ${REPO_OWNER} <mail@domain.zone>
*/
final class session extends core
final class session extends core implements document_interface, collection_interface
{
/**
* Name of the collection in ArangoDB
*/
final public const COLLECTION = 'session';
use status, document_trait, buffer, cart {
buffer::write as write;
cart::initialize as cart;
}
/**
* An instance of the ArangoDB document from ArangoDB
* Collection name
*
* @var string COLLECTION Name of the collection in ArangoDB
*/
protected readonly _document $document;
final public const string COLLECTION = 'session';
/**
* Constructor of an instance
*
* Initialize of a session and write them to the $this->document property
*
* @param ?string $hash Hash of the session in ArangoDB
* @param ?int $expires Date of expiring of the session (used for creating a new session)
* @param array &$errors Registry of errors
*
* @return static instance of the ArangoDB document of session
* Session verification type
*
* @var verification VERIFICATION Type of session verification
*/
public function __construct(?string $hash = null, ?int $expires = null, array &$errors = [])
final public const verification VERIFICATION = verification::hash_else_address;
/**
* Constructor
*
* Initialize session and write into the $$this->document property
*
* @param ?string $$hash Hash of the session in ArangoDB
* @param ?int $$expires Date of expiring of the session (used for creating a new session)
* @param array &$$errors Registry of errors
*
* @return void
*/
public function __construct(?string $$hash = null, ?int $$expires = null, array &$$errors = [])
{
try {
if (collection::init(static::$arangodb->session, self::COLLECTION)) {
if (collection::initialize(static::COLLECTION, static::TYPE, errors: $$errors)) {
// Initialized the collection
if ($this->search($hash, $errors)) {
// Found an instance of the ArangoDB document of session and received a session hash
if (isset($$hash) && $$document = $$this->hash($$hash, errors: $$errors)) {
// Found the instance of the ArangoDB document of session and received a session hash
// Writing document instance of the session from ArangoDB to the property of the implementing object
$$this->__document($$document);
} else if (static::VERIFICATION === verification::hash_else_address && $$document = $$this->address($$_SERVER['REMOTE_ADDR'], errors: $$errors)) {
// Found the instance of the ArangoDB document of session and received a session hash
// Writing document instance of the session from ArangoDB to the property of the implementing object
$$this->__document($$document);
} else {
// Not found an instance of the ArangoDB document of session
// Not found the instance of the ArangoDB document of session
// Initializing a new session and write they into ArangoDB
$_id = document::write($this::$arangodb->session, self::COLLECTION, [
'active' => true,
'expires' => $expires ?? time() + 604800,
'ip' => $_SERVER['REMOTE_ADDR'],
'x-forwarded-for' => $_SERVER['HTTP_X_FORWARDED_FOR'] ?? null,
'referer' => $_SERVER['HTTP_REFERER'] ?? null,
'useragent' => $_SERVER['HTTP_USER_AGENT'] ?? null
]);
$$_id = document::write(
static::COLLECTION,
[
'active' => true,
'expires' => $$expires ?? time() + 604800,
'address' => $$_SERVER['REMOTE_ADDR'],
'x-forwarded-for' => $$_SERVER['HTTP_X_FORWARDED_FOR'] ?? null,
'referer' => $$_SERVER['HTTP_REFERER'] ?? null,
'useragent' => $$_SERVER['HTTP_USER_AGENT'] ?? null
]
);
if ($session = collection::search($this::$arangodb->session, sprintf(
<<<AQL
FOR d IN %s
FILTER d._id == '%s' && d.expires > %d && d.active == true
if ($$session = collection::execute(
<<<'AQL'
FOR d IN @@collection
FILTER d._id == @_id && d.expires > @time && d.active == true
RETURN d
AQL,
self::COLLECTION,
$_id,
time()
))) {
// Found an instance of just created new session
[
'@collection' => static::COLLECTION,
'_id' => $$_id,
'time' => time()
],
errors: $$errors
)) {
// Found the instance of just created new session
// Generate a hash and write into an instance of the ArangoDB document of session property
$session->hash = sodium_bin2hex(sodium_crypto_generichash($_id));
// Generating a hash and write into the instance of the ArangoDB document of session property
$$session->hash = sodium_bin2hex(sodium_crypto_generichash($$_id));
if (document::update($this::$arangodb->session, $session)) {
// Is writed update
if (document::update($$session, errors: $$errors)) {
// Writed to ArangoDB
// Write instance of the ArangoDB document of session into property and exit (success)
$this->document = $session;
} else throw new exception('Could not write the session data');
} else throw new exception('Could not create or find just created session');
// Writing instance of the session document from ArangoDB to the property of the implementing object
$$this->__document($$session);
} else throw new exception('Failed to write the session data');
} else throw new exception('Failed to create or find just created session');
}
} else throw new exception('Could not initialize the collection');
} catch (exception $e) {
// Write to the registry of errors
$errors[] = [
'text' => $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine(),
'stack' => $e->getTrace()
} else throw new exception('Failed to initialize ' . static::TYPE . ' collection: ' . static::COLLECTION);
} catch (exception $$e) {
// Writing to the registry of errors
$$errors[] = [
'text' => $$e->getMessage(),
'file' => $$e->getFile(),
'line' => $$e->getLine(),
'stack' => $$e->getTrace()
];
}
}
/**
* Search
* Search by hash
*
* Search for the session in ArangoDB by hash and write they into $this->document property if they are found
* Search for the session in ArangoDB by hash
*
* @param ?string $hash Hash of the session in ArangoDB
* @param array &$errors Registry of errors
* @param string $$hash Hash of the session in ArangoDB
* @param array &$$errors Registry of errors
*
* @return static instance of the ArangoDB document of session
* @return _document|null instance of document of the session in ArangoDB
*/
public function search(?string $hash, array &$errors = []): bool
public static function hash(string $$hash, array &$$errors = []): ?_document
{
try {
if (isset($hash)) {
// Recieved a hash
if (collection::initialize(static::COLLECTION, static::TYPE, errors: $$errors)) {
// Collection initialized
// Search the session data in ArangoDB
$_document = $session = collection::search($this::$arangodb->session, sprintf(
<<<AQL
FOR d IN %s
FILTER d.hash == '%s' && d.expires > %d && d.active == true
return collection::execute(
<<<'AQL'
FOR d IN @@collection
FILTER d.hash == @hash && d.expires > @time && d.active == true
RETURN d
AQL,
self::COLLECTION,
$hash,
time()
));
if ($_document instanceof _document) {
// An instance of the ArangoDB document of session is found
// Write the session data to the property
$this->document = $_document;
// Exit (success)
return true;
}
}
} catch (exception $e) {
// Write to the registry of errors
$errors[] = [
'text' => $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine(),
'stack' => $e->getTrace()
AQL,
[
'@collection' => static::COLLECTION,
'hash' => $$hash,
'time' => time()
],
errors: $$errors
);
} else throw new exception('Failed to initialize ' . static::TYPE . ' collection: ' . static::COLLECTION);
} catch (exception $$e) {
// Writing to the registry of errors
$$errors[] = [
'text' => $$e->getMessage(),
'file' => $$e->getFile(),
'line' => $$e->getLine(),
'stack' => $$e->getTrace()
];
}
// Exit (fail)
return false;
return null;
}
/**
* Write to buffer of the session
* Search by IP-address
*
* @param array $data Data for merging
* @param array &$errors Registry of errors
* Search for the session in ArangoDB by IP-address
*
* @return bool Is data has written into the session buffer?
* @param string $$address IP-address writed to the session in ArangoDB
* @param array &$$errors Registry of errors
*
* @return _document|null instance of document of the session in ArangoDB
*/
public function write(array $data, array &$errors = []): bool
public static function address(string $$address, array &$$errors = []): ?_document
{
try {
if (collection::init($this::$arangodb->session, self::COLLECTION)) {
// Initialized the collection
if (collection::initialize(static::COLLECTION, static::TYPE, errors: $$errors)) {
// Collection initialized
// An instance of the ArangoDB document of session is initialized?
if (!isset($this->document)) throw new exception('An instance of the ArangoDB document of session is not initialized');
// Write data into buffwer of an instance of the ArangoDB document of session
$this->document->buffer = array_replace_recursive(
$this->document->buffer ?? [],
[$_SERVER['INTERFACE'] => array_replace_recursive($this->document->buffer[$_SERVER['INTERFACE']] ?? [], $data)]
// Search the session data in ArangoDB
return collection::execute(
<<<'AQL'
FOR d IN @@collection
FILTER d.address == @address && d.expires > @time && d.active == true
SORT d.updated DESC
LIMIT 1
RETURN d
AQL,
[
'@collection' => static::COLLECTION,
'address' => $$address,
'time' => time()
],
errors: $$errors
);
// Write to ArangoDB and exit (success)
return document::update($this::$arangodb->session, $this->document) ? true : throw new exception('Не удалось записать данные в буфер сессии');
} else throw new exception('Could not initialize the collection');
} catch (exception $e) {
// Write to the registry of errors
$errors[] = [
'text' => $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine(),
'stack' => $e->getTrace()
} else throw new exception('Failed to initialize ' . static::TYPE . ' collection: ' . static::COLLECTION);
} catch (exception $$e) {
// Writing to the registry of errors
$$errors[] = [
'text' => $$e->getMessage(),
'file' => $$e->getFile(),
'line' => $$e->getLine(),
'stack' => $$e->getTrace()
];
}
return false;
}
/**
* Write
*
* Write a property into an instance of the ArangoDB document
*
* @param string $name Name of the property
* @param mixed $value Content of the property
*
* @return void
*/
public function __set(string $name, mixed $value = null): void
{
// Write to the property into an instance of the ArangoDB document and exit (success)
$this->document->{$name} = $value;
}
/**
* Read
*
* Read a property from an instance of the ArangoDB docuemnt
*
* @param string $name Name of the property
*
* @return mixed Content of the property
*/
public function __get(string $name): mixed
{
// Read a property from an instance of the ArangoDB document and exit (success)
return match ($name) {
'arangodb' => $this::$arangodb,
default => $this->document->{$name}
};
}
/**
* Delete
*
* Deinitialize the property in an instance of the ArangoDB document
*
* @param string $name Name of the property
*
* @return void
*/
public function __unset(string $name): void
{
// Delete the property in an instance of the ArangoDB document and exit (success)
unset($this->document->{$name});
}
/**
* Check of initialization
*
* Check of initialization of the property into an instance of the ArangoDB document
*
* @param string $name Name of the property
*
* @return bool The property is initialized?
*/
public function __isset(string $name): bool
{
// Check of initializatio nof the property and exit (success)
return isset($this->document->{$name});
}
/**
* Execute a method
*
* Execute a method from an instance of the ArangoDB document
*
* @param string $name Name of the method
* @param array $arguments Arguments for the method
*
* @return mixed Result of execution of the method
*/
public function __call(string $name, array $arguments = []): mixed
{
// Execute the method and exit (success)
if (method_exists($this->document, $name)) return $this->document->{$name}($arguments);
}
}
// Exit (fail)
return null;
}}

View File

@@ -0,0 +1,84 @@
<?php
declare(strict_types=1);
namespace ${REPO_OWNER}\${REPO_NAME}\models\traits;
// Files of the project
use ${REPO_OWNER}\${REPO_NAME}\models\traits\document as document_trait,
${REPO_OWNER}\${REPO_NAME}\models\interfaces\document as document_interface,
${REPO_OWNER}\${REPO_NAME}\models\interfaces\collection as collection_interface,
${REPO_OWNER}\${REPO_NAME}\models\enumerations\language;
// Library for ArangoDB
use ArangoDBClient\Document as _document;
// Framework for ArangoDB
use mirzaev\arangodb\collection,
mirzaev\arangodb\document;
// Built-in libraries
use exception;
/**
* Buffer
*
* Storage of data in the document from ArangoDB
*
* @uses document
* @uses document_interface
* @uses collection_interface
*
* @param static COLLECTION Name of the collection in ArangoDB
* @param static TYPE Type of the collection in ArangoDB
*
* @package ${REPO_OWNER}\${REPO_NAME}\models\traits
*
* @license http://www.wtfpl.net/ Do What The Fuck You Want To Public License
* @author ${REPO_OWNER} <mail@domain.zone>
*/
trait buffer
{
/**
* Write to buffer of the document
*
* @param array $$data Data for writing (merge)
* @param array &$$errors Registry of errors
*
* @return bool Is data has written into the document from ArangoDB?
*/
public function write(array $$data, array &$$errors = []): bool
{
try {
if (collection::initialize(static::COLLECTION, static::TYPE, errors: $$errors)) {
// Initialized the collection
// Is the instance of the document from ArangoDB are initialized?
if (!isset($$this->document)) throw new exception('The instance of the sessoin document from ArangoDB is not initialized');
// Writing data into buffer of the instance of the document from ArangoDB
$$this->document->buffer = array_replace_recursive($$this->document->buffer ?? [], $$data);
// Is the buffer of the instance of the document from ArangoDB exceed 10 megabytes?
if (mb_strlen(json_encode($$this->document->buffer)) > 10485760) throw new exception('The buffer size exceeds 10 megabytes');
// Serializing parameters
if ($$this->document->language instanceof language) $$this->document->language = $$this->document->language->name;
// Writing to ArangoDB and exit (success)
return document::update($$this->document, errors: $$errors);
} else throw new exception('Failed to initialize ' . static::TYPE . ' collection: ' . static::COLLECTION);
} catch (exception $$e) {
// Writing to the registry of errors
$$errors[] = [
'text' => $$e->getMessage(),
'file' => $$e->getFile(),
'line' => $$e->getLine(),
'stack' => $$e->getTrace()
];
}
// Exit (fail)
return false;
}
}

View File

@@ -0,0 +1,206 @@
<?php
declare(strict_types=1);
namespace ${REPO_OWNER}\${REPO_NAME}\models\traits;
// Files of the project
use ${REPO_OWNER}\${REPO_NAME}\models\interfaces\document as document_interface,
${REPO_OWNER}\${REPO_NAME}\models\interfaces\collection as collection_interface,
${REPO_OWNER}\${REPO_NAME}\models\connect;
// Library для ArangoDB
use ArangoDBClient\Document as _document;
// Framework for ArangoDB
use mirzaev\arangodb\connection as arangodb,
mirzaev\arangodb\document as framework_document,
mirzaev\arangodb\collection;
// Built-in libraries
use exception;
/**
* Trait for implementing a document instance from ArangoDB
*
* @uses document_interface
*
* @var protected readonly _document|null $$document An instance of the ArangoDB document
*
* @package ${REPO_OWNER}\${REPO_NAME}\models\traits
*
* @license http://www.wtfpl.net/ Do What The Fuck You Want To Public License
* @author ${REPO_OWNER} <mail@domain.zone>
*/
trait document
{
/**
* Document
*
* @var _document $$document An instance of the document from ArangoDB
*/
protected readonly _document $$document;
/**
* Constructor
*
* @param bool $$initialize Initialize a model?
* @param ?arangodb $$arangodb Instance of a session of ArangoDB
* @param _document|null|false $$document An instance of the ArangoDB document
*
* @return void
*/
public function __construct(
bool $$initialize = true,
?arangodb $$arangodb = null,
_document|null|false $$document = false
) {
// For the extends system
parent::__construct($$initialize, $$arangodb);
// Writing to the property
if ($$document instanceof _document) $$this->__document($$document);
else if ($$document === null) throw new exception('Failed to initialize an instance of the document from ArangoDB');
}
/**
* Write or read document
*
* @param _document|null $$document Instance of document from ArangoDB
*
* @return _document|null Instance of document from ArangoDB
*/
public function __document(?_document $$document = null): ?_document
{
// Writing a property storing a document instance to ArangoDB
if ($$document) $$this->document ??= $$document;
// Read a property storing a document instance to ArangoDB and exit (success)
return $$this->document ?? null;
}
/**
* Connect
*
* @param collecton_interface $$document Document
* @param array &$$errors Registry of errors
*
* @return string|null The identifier of the created edge of the "connect" collection, if created
*/
public function connect(collection_interface $$document, array &$$errors = []): ?string
{
try {
if (collection::initialize(static::COLLECTION, static::TYPE, errors: $$errors)) {
if (collection::initialize(connect::COLLECTION, connect::TYPE, errors: $$errors)) {
if (collection::initialize($$document::COLLECTION, $$document::TYPE, errors: $$errors)) {
// Initialized collections
if ($$this->document instanceof _document) {
// Initialized instance of the document from ArangoDB
// Writing document and exit (success)
return framework_document::write(
connect::COLLECTION,
[
'_from' => $$document->getId(),
'_to' => $$this->document->getId()
],
errors: $$errors
);
} else throw new exception('The instance of the document from ArangoDB is not initialized');
} else throw new exception('Failed to initialize ' . $$document::TYPE . ' collection: ' . $$document::COLLECTION);
} else throw new exception('Failed to initialize ' . connect::TYPE . ' collection: ' . connect::COLLECTION);
} else throw new exception('Failed to initialize ' . static::TYPE . ' collection: ' . static::COLLECTION);
} catch (exception $$e) {
// Writing to the registry of errors
$$errors[] = [
'text' => $$e->getMessage(),
'file' => $$e->getFile(),
'line' => $$e->getLine(),
'stack' => $$e->getTrace()
];
}
// Exit (fail)
return null;
}
/**
* Write
*
* Write a property into an instance of the ArangoDB document
*
* @param string $$name Name of the property
* @param mixed $$value Content of the property
*
* @return void
*/
public function __set(string $$name, mixed $$value = null): void
{
// Writing to the property into an instance of the ArangoDB document and exit (success)
$$this->document->{$$name} = $$value;
}
/**
* Read
*
* Read a property from an instance of the ArangoDB docuemnt
*
* @param string $$name Name of the property
*
* @return mixed Content of the property
*/
public function __get(string $$name): mixed
{
// Read a property from an instance of the ArangoDB document and exit (success)
return match ($$name) {
default => $$this->document->{$$name}
};
}
/**
* Delete
*
* Deinitialize the property in an instance of the ArangoDB document
*
* @param string $$name Name of the property
*
* @return void
*/
public function __unset(string $$name): void
{
// Delete the property in an instance of the ArangoDB document and exit (success)
unset($$this->document->{$$name});
}
/**
* Check of initialization
*
* Check of initialization of the property into an instance of the ArangoDB document
*
* @param string $$name Name of the property
*
* @return bool The property is initialized?
*/
public function __isset(string $$name): bool
{
// Check of initializatio nof the property and exit (success)
return isset($$this->document->{$$name});
}
/**
* Execute a method
*
* Execute a method from an instance of the ArangoDB document
*
* @param string $$name Name of the method
* @param array $$arguments Arguments for the method
*
* @return mixed Result of execution of the method
*/
public function __call(string $$name, array $$arguments = []): mixed
{
// Execute the method and exit (success)
return method_exists($$this->document, $$name) ? $$this->document->{$$name}($$arguments) ?? null : null;
}
}

View File

@@ -0,0 +1,66 @@
<?php
declare(strict_types=1);
namespace ${REPO_OWNER}\${REPO_NAME}\models\traits;
// Built-in libraries
use exception;
/**
* Files
*
* Trait with files handlers
*
* @method static void delete(string $$directory, array &$$errors)
*
* @package ${REPO_OWNER}\${REPO_NAME}\models\traits
*
* @license http://www.wtfpl.net/ Do What The Fuck You Want To Public License
* @author ${REPO_OWNER} <mail@domain.zone>
*/
trait files
{
/**
* Delete
*
* Delete files recursively
*
* @param string $$directory Directory
* @param array &$$errors Registry of errors
*
* @return void
*/
private static function delete(string $$directory, array &$$errors = []): void
{
try {
if (file_exists($$directory)) {
// Directory exists
// Deleting descendant files and directories (enter to the recursion)
foreach (scandir($$directory) as $$file) {
if ($$file === '.' || $$file === '..') continue;
else if (is_dir("$$directory/$$file")) static::delete("$$directory/$$file", $$errors);
else unlink("$$directory/$$file");
}
// Deleting the directory
rmdir($$directory);
// Exit (success)
return;
} else throw new exception('Directory does not exist');
} catch (exception $$e) {
// Writing to the registry of errors
$$errors[] = [
'text' => $$e->getMessage(),
'file' => $$e->getFile(),
'line' => $$e->getLine(),
'stack' => $$e->getTrace()
];
}
// Exit (fail)
return;
}
}

42
author/project/system/models/traits/status.php Normal file → Executable file
View File

@@ -4,37 +4,51 @@ declare(strict_types=1);
namespace ${REPO_OWNER}\${REPO_NAME}\models\traits;
// Files of the project
use ${REPO_OWNER}\${REPO_NAME}\models\traits\document as document_trait,
${REPO_OWNER}\${REPO_NAME}\models\interfaces\document as document_interface;
// Built-in libraries
use exception;
/**
* Trait fo initialization of a status
* Status (DUMB SHIT)
*
* Trait for initialization of a status
*
* @uses document_trait
* @uses document_interface
*
* @method bool|null status(array &$$errors) Check document by its status
*
* @package ${REPO_OWNER}\${REPO_NAME}\models\traits
*
* @author ${REPO_OWNER} < mail >
* @license http://www.wtfpl.net/ Do What The Fuck You Want To Public License
* @author ${REPO_OWNER} <mail@domain.zone>
*/
trait status
{
/**
* Initialize of a status
* Status
*
* @param array &$errors Registry of errors
* Check document by its status
*
* @return ?bool Status, if they are found
* @param array &$$errors Registry of errors
*
* @return ?bool Status, if found
*/
public function status(array &$errors = []): ?bool
public function status(array &$$errors = []): ?bool
{
try {
// Read from ArangoDB and exit (success)
return $this->document->active ?? false;
} catch (exception $e) {
// Write to the registry of errors
$errors[] = [
'text' => $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine(),
'stack' => $e->getTrace()
return $$this->document->active ?? false;
} catch (exception $$e) {
// Writing to the registry of errors
$$errors[] = [
'text' => $$e->getMessage(),
'file' => $$e->getFile(),
'line' => $$e->getLine(),
'stack' => $$e->getTrace()
];
}

View File

@@ -0,0 +1,34 @@
@font-face {
font-family: 'DejaVu';
src: url("/fonts/dejavu/DejaVuLGCSans-ExtraLight.ttf");
font-weight: 200;
font-style: normal;
}
@font-face {
font-family: 'DejaVu';
src: url("/fonts/dejavu/DejaVuLGCSans.ttf");
font-weight: 400;
font-style: normal;
}
@font-face {
font-family: 'DejaVu';
src: url("/fonts/dejavu/DejaVuLGCSans-Oblique.ttf");
font-weight: 400;
font-style: italic;
}
@font-face {
font-family: 'DejaVu';
src: url("/fonts/dejavu/DejaVuLGCSans-Bold.ttf");
font-weight: 500;
font-style: normal;
}
@font-face {
font-family: 'DejaVu';
src: url("/fonts/dejavu/DejaVuLGCSans-BoldOblique.ttf");
font-weight: 500;
font-style: italic;
}

View File

@@ -0,0 +1,139 @@
@font-face {
font-family: 'Fira';
src: url('/fonts/fira/FiraSans-Hair.woff2') format('woff2'), url('/fonts/fira/FiraSans-Hair.woff') format('woff');
font-weight: 100;
font-style: normal;
}
@font-face {
font-family: 'Fira';
src: url('/fonts/fira/FiraSans-HairItalic.woff2') format('woff2'), url('/fonts/fira/FiraSans-HairItalic.woff') format('woff');
font-weight: 100;
font-style: italic;
}
@font-face {
font-family: 'Fira';
src: url('/fonts/fira/FiraSans-UltraLight.woff2') format('woff2'), url('/fonts/fira/FiraSans-UltraLight.woff') format('woff');
font-weight: 200;
font-style: normal;
}
@font-face {
font-family: 'Fira';
src: url('/fonts/fira/FiraSans-UltraLightItalic.woff2') format('woff2'), url('/fonts/fira/FiraSans-UltraLightItalic.woff') format('woff');
font-weight: 200;
font-style: italic;
}
@font-face {
font-family: 'Fira';
src: url('/fonts/fira/FiraSans-Light.woff2') format('woff2'), url('/fonts/fira/FiraSans-Light.woff') format('woff');
font-weight: 300;
font-style: normal;
}
@font-face {
font-family: 'Fira';
src: url('/fonts/fira/FiraSans-LightItalic.woff2') format('woff2'), url('/fonts/fira/FiraSans-LightItalic.woff') format('woff');
font-weight: 300;
font-style: italic;
}
@font-face {
font-family: 'Fira';
src: url('/fonts/fira/FiraSans-Regular.woff2') format('woff2'), url('/fonts/fira/FiraSans-Regular.woff') format('woff');
font-weight: 400;
font-style: normal;
}
@font-face {
font-family: 'Fira';
src: url('/fonts/fira/FiraSans-Italic.woff2') format('woff2'), url('/fonts/fira/FiraSans-Italic.woff') format('woff');
font-weight: 400;
font-style: italic;
}
@font-face {
font-family: 'Fira';
src: url('/fonts/fira/FiraMono-Medium.woff2') format('woff2'), url('/fonts/fira/FiraMono-Medium.woff') format('woff');
font-weight: 500;
font-style: normal;
}
@font-face {
font-family: 'Fira';
src: url('/fonts/fira/FiraSans-MediumItalic.woff2') format('woff2'), url('/fonts/fira/FiraSans-MediumItalic.woff') format('woff');
font-weight: 500;
font-style: italic;
}
@font-face {
font-family: 'Fira';
src: url('/fonts/fira/FiraSans-SemiBold.woff2') format('woff2'), url('/fonts/fira/FiraSans-SemiBold.woff') format('woff');
font-weight: 600;
font-style: normal;
}
@font-face {
font-family: 'Fira';
src: url('/fonts/fira/FiraSans-SemiBoldItalic.woff2') format('woff2'), url('/fonts/fira/FiraSans-SemiBoldItalic.woff') format('woff');
font-weight: 600;
font-style: italic;
}
@font-face {
font-family: 'Fira';
src: url('/fonts/fira/FiraSans-Bold.woff2') format('woff2'), url('/fonts/fira/FiraSans-Bold.woff') format('woff');
font-weight: 700;
font-style: normal;
}
@font-face {
font-family: 'Fira';
src: url('/fonts/fira/FiraSans-BoldItalic.woff2') format('woff2'), url('/fonts/fira/FiraSans-BoldItalic.woff') format('woff');
font-weight: 700;
font-style: italic;
}
@font-face {
font-family: 'Fira';
src: url('/fonts/fira/FiraSans-ExtraBold.woff2') format('woff2'), url('/fonts/fira/FiraSans-ExtraBold.woff') format('woff');
font-weight: 800;
font-style: normal;
}
@font-face {
font-family: 'Fira';
src: url('/fonts/fira/FiraSans-ExtraBoldItalic.woff2') format('woff2'), url('/fonts/fira/FiraSans-ExtraBoldItalic.woff') format('woff');
font-weight: 800;
font-style: italic;
}
@font-face {
font-family: 'Fira';
src: url('/fonts/fira/FiraSans-Heavy.woff2') format('woff2'), url('/fonts/fira/FiraSans-Heavy.woff') format('woff');
font-weight: 900;
font-style: normal;
}
@font-face {
font-family: 'Fira';
src: url('/fonts/fira/FiraSans-HeavyItalic.woff2') format('woff2'), url('/fonts/fira/FiraSans-HeavyItalic.woff') format('woff');
font-weight: 900;
font-style: italic;
}
@font-face {
font-family: 'Fira' Mono;
src: url('/fonts/fira/FiraMono-Regular.woff2') format('woff2'), url('/fonts/fira/FiraMono-Regular.woff') format('woff');
font-weight: 400;
font-style: normal;
}
@font-face {
font-family: 'Fira' Mono;
src: url('/fonts/fira/FiraMono-Bold.woff2') format('woff2'), url('/fonts/fira/FiraMono-Bold.woff') format('woff');
font-weight: 600;
font-style: normal;
}

View File

@@ -0,0 +1,31 @@
@font-face {
font-family: 'Hack';
src: url('/fonts/hack/hack-regular.woff2?sha=3114f1256') format('woff2'), url('/fonts/hack/hack-regular.woff?sha=3114f1256') format('woff');
font-weight: 400;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Hack';
src: url('/fonts/hack/hack-bold.woff2?sha=3114f1256') format('woff2'), url('/fonts/hack/hack-bold.woff?sha=3114f1256') format('woff');
font-weight: 700;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Hack';
src: url('/fonts/hack/hack-italic.woff2?sha=3114f1256') format('woff2'), url('/fonts/hack/hack-italic.woff?sha=3114f1256') format('woff');
font-weight: 400;
font-style: italic;
font-display: swap;
}
@font-face {
font-family: 'Hack';
src: url('/fonts/hack/hack-bolditalic.woff2?sha=3114f1256') format('woff2'), url('/fonts/hack/hack-bolditalic.woff?sha=3114f1256') format('woff');
font-weight: 700;
font-style: italic;
font-display: swap;
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

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