Initial upload of the control panel

This commit is contained in:
Pinga 2023-08-07 13:14:05 +03:00
parent f21bd93fbc
commit 7eab26586c
791 changed files with 312718 additions and 0 deletions

3
cp/README.md Normal file
View file

@ -0,0 +1,3 @@
composer update
Move env-sample to .env and configure.

306
cp/app/Auth/Auth.php Normal file
View file

@ -0,0 +1,306 @@
<?php
namespace App\Auth;
use App\Lib\Mail;
use Pinga\Auth\ConfirmationRequestNotFound;
use Pinga\Auth\EmailNotVerifiedException;
use Pinga\Auth\InvalidEmailException;
use Pinga\Auth\InvalidPasswordException;
use Pinga\Auth\InvalidSelectorTokenPairException;
use Pinga\Auth\NotLoggedInException;
use Pinga\Auth\ResetDisabledException;
use Pinga\Auth\TokenExpiredException;
use Pinga\Auth\TooManyRequestsException;
use Pinga\Auth\UserAlreadyExistsException;
/**
* Auth
*
* @author Hezekiah O. <support@hezecom.com>
*/
class Auth
{
static protected $auth;
/**
* Auth constructor.
*/
public function __construct()
{
self::$auth = auth();
}
/**
* @param $email
* @param $username
* @param $password
* @param array $info
* @return int
* @throws \Pinga\Auth\AuthError
*/
public static function create($email, $username, $password, $info=[]){
$auth = self::$auth;
try {
$userId = $auth->register($email, $username, $password, function ($selector, $token) use ($email, $username) {
$link = url('verify.email',[],['selector'=>urlencode($selector),'token'=>urlencode($token)]);
$message = file_get_contents(__DIR__.'/../../resources/views/auth/mail/confirm-email.html');
$message = str_replace(['{link}','{app_name}'],[$link,envi('APP_NAME')],$message);
$subject = 'Email Verification';
$from = ['email'=>envi('MAIL_FROM_ADDRESS'), 'name'=>envi('APP_NAME')];
$to = ['email'=>$email, 'name'=>$username];
// send message
Mail::send($subject, $message, $from, $to);
});
//$auth->admin()->addRoleForUserById($userId, Role::ADMIN);
return $userId;
}
catch (InvalidEmailException $e) {
redirect()->route('register')->with('error','Invalid email address');
}
catch (InvalidPasswordException $e) {
redirect()->route('register')->with('error','Invalid password');
}
catch (UserAlreadyExistsException $e) {
redirect()->route('register')->with('error','User already exists test');
}
catch (TooManyRequestsException $e) {
redirect()->route('register')->with('error','Too many requests, try again later');
}
}
/**
* @param $selector
* @param $token
* @throws \Pinga\Auth\AuthError
*/
public static function verifyEmail($selector, $token){
$auth = self::$auth;
try {
$auth->confirmEmail($selector, $token);
//echo 'Email address has been verified';
redirect()->route('login')->with('success','Email address has been verified');
}
catch (InvalidSelectorTokenPairException $e) {
redirect()->route('login')->with('error','Invalid token');
}
catch (TokenExpiredException $e) {
redirect()->route('login')->with('error','Token expired');
}
catch (UserAlreadyExistsException $e) {
redirect()->route('login')->with('error','Email address already exists');
}
catch (TooManyRequestsException $e) {
redirect()->route('login')->with('error','Too many requests, try again later.');
}
}
/**
* Re-sending confirmation requests
* @param $email
*/
public static function ResendVerification($email){
$auth = self::$auth;
try {
$auth->resendConfirmationForEmail($email, function ($selector, $token) use ($email) {
$link = url('verify.email',[],['selector'=>urlencode($selector),'token'=>urlencode($token)]);
$message = file_get_contents(__DIR__.'/../../resources/views/auth/mail/confirm-email.html');
$message = str_replace(['{link}','{app_name}'],[$link,envi('APP_NAME')],$message);
$subject = 'Email Verification';
$from = ['email'=>envi('MAIL_FROM_ADDRESS'), 'name'=>envi('MAIL_FROM_NAME')];
$to = ['email'=>$email, 'name'=>''];
// send message
Mail::send($subject, $message, $from, $to);
});
redirect()->route('login')->with('success','We have sent you another email. Please follow the link to verify your email.');
}
catch (ConfirmationRequestNotFound $e) {
redirect()->route('login')->with('error','No earlier request found that could be re-sent.');
}
catch (TooManyRequestsException $e) {
redirect()->route('login')->with('error','Too many requests, try again later');
}
}
/**
* @param $email
* @param $password
* @param null $remember
* @throws \Pinga\Auth\AttemptCancelledException
* @throws \Pinga\Auth\AuthError
*/
public static function login($email, $password, $remember=null){
$auth = self::$auth;
try {
if ($remember !='') {
// keep logged in for one year
$rememberDuration = (int) (60 * 60 * 24 * 365.25);
}
else {
// do not keep logged in after session ends
$rememberDuration = null;
}
$auth->login($email, $password,$rememberDuration);
return true;
}
catch (InvalidEmailException $e) {
redirect()->route('login')->with('error','Wrong email address');
}
catch (InvalidPasswordException $e) {
redirect()->route('login')->with('error','Wrong password');
}
catch (EmailNotVerifiedException $e) {
redirect()->route('login')->with('error','Email not verified');
die('Email not verified');
}
catch (TooManyRequestsException $e) {
redirect()->route('login')->with('error','Too many requests');
}
}
/**
* Reset Password 1 of 3
* @param $email
* @throws \Pinga\Auth\AuthError
*/
public static function forgotPassword($email){
$auth = self::$auth;
try {
$auth->forgotPassword($email, function ($selector, $token) use ($email) {
$link = url('reset.password',[],['selector'=>urlencode($selector),'token'=>urlencode($token)]);
$message = file_get_contents(__DIR__.'/../../resources/views/auth/mail/reset-password.html');
$message = str_replace(['{link}','{app_name}'],[$link,envi('APP_NAME')],$message);
$subject = 'Reset Password';
$from = ['email'=>envi('MAIL_FROM_ADDRESS'), 'name'=>envi('MAIL_FROM_NAME')];
$to = ['email'=>$email, 'name'=>''];
// send message
Mail::send($subject, $message, $from, $to);
});
redirect()->route('forgot.password')->with('success','A password reset link has been sent to your email.');
}
catch (InvalidEmailException $e) {
redirect()->route('forgot.password')->with('error','Invalid email address');
}
catch (EmailNotVerifiedException $e) {
redirect()->route('forgot.password')->with('error','Email not verified');
}
catch (ResetDisabledException $e) {
redirect()->route('forgot.password')->with('error','Password reset is disabled');
}
catch (TooManyRequestsException $e) {
redirect()->route('forgot.password')->with('error','Too many requests, try again later');
}
}
/**
* Reset Password 2 of 3
* @param $selector
* @param $token
* @throws \Pinga\Auth\AuthError
*/
public static function resetPasswordVerify($selector, $token){
$auth = self::$auth;
try {
$auth->canResetPasswordOrThrow($selector, $token);
redirect()->route('update.password',[],['selector'=>urlencode($selector),'token'=>urlencode($token)]);
}
catch (InvalidSelectorTokenPairException $e) {
redirect()->route('forgot.password')->with('error','Invalid token');
}
catch (TokenExpiredException $e) {
redirect()->route('forgot.password')->with('error','Token expired');
}
catch (ResetDisabledException $e) {
redirect()->route('forgot.password')->with('error','Password reset is disabled');
}
catch (TooManyRequestsException $e) {
redirect()->route('forgot.password')->with('error','Too many requests, try again later');
}
}
/**
* Reset Password 3 of 3
* @param $selector
* @param $token
* @param $password
* @throws \Pinga\Auth\AuthError
*/
public static function resetPasswordUpdate($selector, $token, $password){
$auth = self::$auth;
try {
$auth->resetPassword($selector, $token, $password);
redirect()->route('login')->with('success','Password has been reset');
}
catch (InvalidSelectorTokenPairException $e) {
redirect()->route('update.password',[],['selector'=>urlencode($selector),'token'=>urlencode($token)])->with('error','Invalid token');
}
catch (TokenExpiredException $e) {
redirect()->route('update.password',[],['selector'=>urlencode($selector),'token'=>urlencode($token)])->with('error','Token expired');
}
catch (ResetDisabledException $e) {
redirect()->route('update.password',[],['selector'=>urlencode($selector),'token'=>urlencode($token)])->with('error','Password reset is disabled');
}
catch (InvalidPasswordException $e) {
redirect()->route('update.password',[],['selector'=>urlencode($selector),'token'=>urlencode($token)])->with('error','Invalid password');
}
catch (TooManyRequestsException $e) {
redirect()->route('login')->with('error','Too many requests, try again later');
}
}
/**
* Changing the current users password when logged in only
* @param $oldPassword
* @param $newPassword
* @throws \Pinga\Auth\AuthError
*/
public static function changeCurrentPassword($oldPassword, $newPassword){
$auth = self::$auth;
try {
$auth->changePassword($oldPassword, $newPassword);
redirect()->route('profile')->with('success','Password has been changed');
}
catch (NotLoggedInException $e) {
redirect()->route('profile')->with('error','You are not logged in');
}
catch (InvalidPasswordException $e) {
redirect()->route('profile')->with('error','Your old password do not match');
}
catch (TooManyRequestsException $e) {
redirect()->route('profile')->with('error','Too many requests, try again later');
}
}
/**
* @throws \Pinga\Auth\AuthError
*/
public static function logout(){
return self::$auth->logOut();
}
/**
* @return bool
*/
public function isLogin(){
if (self::$auth->isLoggedIn()) {
return true;
}
else {
return false;
}
}
/**
* @return array
*/
public function user(){
$auth = self::$auth;
$info = [
'id' => $auth->getUserId(),
'email' => $auth->getEmail(),
'username' => $auth->getUsername(),
'ip' => $auth->getIpAddress()
];
return $info;
}
}

View file

@ -0,0 +1,117 @@
<?php
namespace App\Controllers\Auth;
use App\Auth\Auth;
use App\Controllers\Controller;
use Respect\Validation\Validator as v;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
/**
* AuthController
*
* @author Hezekiah O. <support@hezecom.com>
*/
class AuthController extends Controller
{
/**
* @param Request $request
* @param Response $response
* @return mixed
* @throws \DI\DependencyException
* @throws \DI\NotFoundException
*/
public function createRegister(Request $request, Response $response){
return view($response,'auth/register.twig');
}
/**
* @param Request $request
* @param Response $response
* @return Response
* @throws \DI\DependencyException
* @throws \DI\NotFoundException
* @throws \Pinga\Auth\AuthError
*/
public function register(Request $request, Response $response){
$validation = $this->validator->validate($request, [
'email' => v::noWhitespace()->notEmpty()->email(),
'username' => v::noWhitespace()->notEmpty()->alnum(),
'password' => v::notEmpty()->stringType()->length(8),
]);
if ($validation->failed()) {
redirect()->route('register');
//or
//return $response->withHeader('Location', route('register'));
}
$data = $request->getParsedBody();
$auth =Auth::create($data['email'],$data['password'],$data['username']);
if($auth) {
$msg = '<a href="'.route('verify.email.resend',[],['email'=>$data['email']]).'">Resend email</a>';
flash('success', 'We have send you a verification link to '.$data['email'].' <br>'.$msg);
return $response->withHeader('Location', route('login'));
}
}
/**
* @param Request $request
* @param Response $response
*/
public function verifyEmailResend(Request $request, Response $response){
$data = $request->getQueryParams();
Auth::ResendVerification($data['email']);
}
/**
* @param Request $request
* @param Response $response
* @throws \Pinga\Auth\AuthError
*/
public function verifyEmail(Request $request, Response $response){
//confirm email
$data = $request->getQueryParams();
Auth::verifyEmail($data['selector'], $data['token']);
}
/**
* @param Request $request
* @param Response $response
* @return mixed
* @throws \DI\DependencyException
* @throws \DI\NotFoundException
*/
public function createLogin(Request $request, Response $response){
return view($response,'auth/login.twig');
}
/**
* @param Request $request
* @param Response $response
* @throws \Pinga\Auth\AttemptCancelledException
* @throws \Pinga\Auth\AuthError
*/
public function login(Request $request, Response $response){
$data = $request->getParsedBody();
if(isset($data['remember'])){
$remember = $data['remember'];
}else{
$remember = null;
}
$login = Auth::login($data['email'], $data['password'], $remember);
if($login===true)
redirect()->route('home');
}
/**
* @throws \Pinga\Auth\AuthError
*/
public function logout()
{
Auth::logout();
redirect()->route('login');
}
}

View file

@ -0,0 +1,101 @@
<?php
namespace App\Controllers\Auth;
use App\Auth\Auth;
use App\Controllers\Controller;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Respect\Validation\Validator as v;
/**
* PasswordController
*
* @author Hezekiah O. <support@hezecom.com>
*/
class PasswordController extends Controller
{
/**
* @param Request $request
* @param Response $response
* @return mixed
* @throws \DI\DependencyException
* @throws \DI\NotFoundException
*/
public function createForgotPassword(Request $request, Response $response){
return view($response,'auth/password/forgot-password.twig');
}
/**
* @param Request $request
* @param Response $response
* @throws \Pinga\Auth\AuthError
*/
public function forgotPassword(Request $request, Response $response){
$data = $request->getParsedBody();
Auth::forgotPassword($data['email']);
}
/**
* @param Request $request
* @param Response $response
* @throws \Pinga\Auth\AuthError
*/
public function resetPassword(Request $request, Response $response){
$data = $request->getQueryParams();
Auth::resetPasswordVerify($data['selector'], $data['token']);
}
/**
* @param Request $request
* @param Response $response
* @return mixed
* @throws \DI\DependencyException
* @throws \DI\NotFoundException
*/
public function createUpdatePassword(Request $request, Response $response){
$data = $request->getQueryParams();
$selector = $data['selector'];
$token = $data['token'];
return view($response,'auth/password/update-password.twig', compact('selector','token'));
}
/**
* @param Request $request
* @param Response $response
* @throws \Pinga\Auth\AuthError
*/
public function updatePassword(Request $request, Response $response){
$data = $request->getParsedBody();
$validation = $this->validator->validate($request, [
'password' => v::notEmpty()->stringType()->length(8),
'password2' => v::notEmpty(),
]);
if ($validation->failed()) {
redirect()->route('update.password',[],['selector'=>urlencode($data['selector']),'token'=>urlencode($data['token'])]);
}
elseif (!v::equals($data['password'])->validate($data['password2'])) {
redirect()->route('update.password',[],['selector'=>urlencode($data['selector']),'token'=>urlencode($data['token'])])->with('error','The password do not match.');
}
Auth::resetPasswordUpdate($data['selector'], $data['token'], $data['password']);
}
/**
* @param Request $request
* @param Response $response
* @throws \Pinga\Auth\AuthError
*/
public function changePassword(Request $request, Response $response){
$data = $request->getParsedBody();
$validation = $this->validator->validate($request, [
'old_password' => v::notEmpty(),
'new_password' => v::notEmpty()->stringType()->length(8),
]);
if ($validation->failed()) {
redirect()->route('profile');
}
Auth::changeCurrentPassword($data['old_password'], $data['new_password']);
}
}

View file

@ -0,0 +1,27 @@
<?php
namespace App\Controllers;
use DI\Container;
/**
* Controller
*
* @author Hezekiah O. <support@hezecom.com>
*/
class Controller
{
protected $container;
public function __construct(Container $container)
{
$this->container = $container;
}
public function __get($property)
{
if ($this->container->get($property)) {
return $this->container->get($property);
}
}
}

View file

@ -0,0 +1,47 @@
<?php
namespace App\Controllers;
use App\Models\User;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Container\ContainerInterface;
class HomeController extends Controller
{
public function index(Request $request, Response $response)
{
return view($response,'index.twig');
}
public function dashboard(Request $request, Response $response)
{
$userModel = new User($this->container->get('db'));
$users = $userModel->getAllUsers();
return view($response,'admin/dashboard/index.twig', compact('users'));
}
public function mode(Request $request, Response $response)
{
if ($_SESSION['_screen_mode'] == 'dark') {
$_SESSION['_screen_mode'] = 'light';
} else {
$_SESSION['_screen_mode'] = 'dark';
}
$referer = $request->getHeaderLine('Referer');
if (!empty($referer)) {
return $response->withHeader('Location', $referer)->withStatus(302);
}
return $response->withHeader('Location', '/dashboard')->withStatus(302);
}
public function avatar(Request $request, Response $response)
{
$avatar = new \LasseRafn\InitialAvatarGenerator\InitialAvatar();
$stream = $avatar->name($_SESSION['auth_username'])->length(2)->fontSize(0.5)->size(96)->background('#206bc4')->color('#fff')->generate()->stream('png', 100);
$psr17Factory = new \Nyholm\Psr7\Factory\Psr17Factory();
$psrResponse = $psr17Factory->createResponse(200)->withBody($stream);
return $psrResponse;
}
}

View file

@ -0,0 +1,112 @@
<?php
namespace App\Controllers;
use App\Models\User;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Container\ContainerInterface;
class ProfileController extends Controller
{
public function profile(Request $request, Response $response)
{
$username = $_SESSION['auth_username'];
$email = $_SESSION['auth_email'];
$status = $_SESSION['auth_status'];
if ($status == 0) {
$status = "Confirmed";
} else {
$status = "Unknown";
}
$roles = $_SESSION['auth_roles'];
if ($roles == 0) {
$role = "Admin";
} else {
$role = "Unknown";
}
return view($response,'admin/profile/profile.twig',['email' => $email, 'username' => $username, 'status' => $status, 'role' => $role]);
}
public function notifications(Request $request, Response $response)
{
$username = $_SESSION['auth_username'];
$email = $_SESSION['auth_email'];
$status = $_SESSION['auth_status'];
if ($status == 0) {
$status = "Confirmed";
} else {
$status = "Unknown";
}
$roles = $_SESSION['auth_roles'];
if ($roles == 0) {
$role = "Admin";
} else {
$role = "Unknown";
}
return view($response,'admin/profile/notifications.twig',['email' => $email, 'username' => $username, 'status' => $status, 'role' => $role]);
}
public function security(Request $request, Response $response)
{
$username = $_SESSION['auth_username'];
$email = $_SESSION['auth_email'];
$status = $_SESSION['auth_status'];
if ($status == 0) {
$status = "Confirmed";
} else {
$status = "Unknown";
}
$roles = $_SESSION['auth_roles'];
if ($roles == 0) {
$role = "Admin";
} else {
$role = "Unknown";
}
return view($response,'admin/profile/security.twig',['email' => $email, 'username' => $username, 'status' => $status, 'role' => $role]);
}
public function plans(Request $request, Response $response)
{
$username = $_SESSION['auth_username'];
$email = $_SESSION['auth_email'];
$status = $_SESSION['auth_status'];
if ($status == 0) {
$status = "Confirmed";
} else {
$status = "Unknown";
}
$roles = $_SESSION['auth_roles'];
if ($roles == 0) {
$role = "Admin";
} else {
$role = "Unknown";
}
return view($response,'admin/profile/plans.twig',['email' => $email, 'username' => $username, 'status' => $status, 'role' => $role]);
}
public function invoices(Request $request, Response $response)
{
$username = $_SESSION['auth_username'];
$email = $_SESSION['auth_email'];
$status = $_SESSION['auth_status'];
if ($status == 0) {
$status = "Confirmed";
} else {
$status = "Unknown";
}
$roles = $_SESSION['auth_roles'];
if ($roles == 0) {
$role = "Admin";
} else {
$role = "Unknown";
}
return view($response,'admin/profile/invoices.twig',['email' => $email, 'username' => $username, 'status' => $status, 'role' => $role]);
}
}

18
cp/app/Lib/Config.php Normal file
View file

@ -0,0 +1,18 @@
<?php namespace App\Lib;
/**
* Config
*
* @author Hezekiah O. <support@hezecom.com>
*/
class Config
{
private static $config;
public static function get($key, $default = null)
{
if (is_null(self::$config)) {
self::$config = require_once(__DIR__ . '/../../config/app.php');
}
return !empty(self::$config[$key]) ? self::$config[$key] : $default;
}
}

79
cp/app/Lib/Logger.php Normal file
View file

@ -0,0 +1,79 @@
<?php namespace App\Lib;
use Monolog\ErrorHandler;
use Monolog\Handler\StreamHandler;
use Whoops\Handler\PrettyPageHandler;
use Whoops\Run;
/**
* Logger
*
* @author Hezekiah O. <support@hezecom.com>
*/
class Logger extends \Monolog\Logger
{
private static $loggers = [];
/**
* Logger constructor.
* @param string $key
* @param null $config
* @throws \Exception
*/
public function __construct($key = "app", $config = null)
{
parent::__construct($key);
if (empty($config)) {
$LOG_PATH = '/tmp/slim';
$config = [
'logFile' => "{$LOG_PATH}/{$key}.log",
'logLevel' => \Monolog\Logger::DEBUG
];
}
$this->pushHandler(new StreamHandler($config['logFile'], $config['logLevel']));
}
/**
* @param string $key
* @param null $config
* @return mixed
*/
public static function getInstance($key = "app", $config = null)
{
if (empty(self::$loggers[$key])) {
self::$loggers[$key] = new Logger($key, $config);
}
return self::$loggers[$key];
}
/**
* Output error bate on environment
*/
public static function systemLogs($enable = true)
{
$LOG_PATH = '/tmp/slim';
$appEnv = envi('APP_ENV') ?? 'local';
if($enable) {
// output pretty html error
self::htmlError();
}else {
// Error Log to file
self::$loggers['error'] = new Logger('errors');
self::$loggers['error']->pushHandler(new StreamHandler("{$LOG_PATH}/errors.log"));
ErrorHandler::register(self::$loggers['error']);
}
}
/**
* Display pretty html formatted errors during development
*/
public static function htmlError(){
$run = new Run;
$run->pushHandler(new PrettyPageHandler);
$run->register();
}
}

49
cp/app/Lib/Mail.php Normal file
View file

@ -0,0 +1,49 @@
<?php namespace App\Lib;
use PHPMailer\PHPMailer\Exception;
use PHPMailer\PHPMailer\PHPMailer;
/**
* Mail
*
* @author Hezekiah O. <support@hezecom.com>
*/
class Mail
{
public static function send($subject, $body, $from=[], $to=[], $info=[])
{
$mail = new PHPMailer(true);
try {
$mail->SMTPDebug = 0;
if(envi('MAIL_DRIVER')=='smtp') {
$mail->isSMTP();
$mail->Host = envi('MAIL_HOST');
$mail->SMTPAuth = true;
$mail->Username = envi('MAIL_USERNAME');
$mail->Password = envi('MAIL_PASSWORD');
$mail->SMTPSecure = envi('MAIL_ENCRYPTION');
$mail->Port = envi('MAIL_PORT');
}
elseif(envi('MAIL_DRIVER')=='sendmail') {
$mail->isSendmail();
}
else{
$mail->isMail();
}
$mail->setFrom($from['email'], $from['name']);
$mail->addAddress($to['email'], $to['name']);
//$mail->addAttachment('path/to/invoice1.pdf', 'invoice1.pdf');
$mail->isHTML(true);
$mail->Subject = $subject;
$mail->Body = $body;
//$mail->AltBody = 'This is the body in plain text for non-HTML mail clients';
$mail->send();
//echo 'Message has been sent';
return false;
} catch (Exception $e) {
echo "Message could not be sent. Mailer Error: {$mail->ErrorInfo}";
}
}
}

68
cp/app/Lib/Redirect.php Normal file
View file

@ -0,0 +1,68 @@
<?php namespace App\Lib;
/**
* Redirect
*
* @author Hezekiah O. <support@hezecom.com>
*/
class Redirect
{
protected $name;
protected $status;
public function __construct($name=null,$status =301)
{
$this->name = $name;
$this->status = $status;
}
public function __destruct()
{
$this->redirect();
}
public function to($name,$status =301)
{
$this->name = $name;
$this->status = $status;
return $this;
}
public function route($name, $params1 =[], $params2=[],$status =301)
{
$this->name = route($name,$params1,$params2);
$this->status = $status;
return $this;
}
public function with($type, $message)
{
flash($type, $message);
return $this;
}
public function redirect()
{
if (getenv('SWOOLE_ENABLED')) {
// Running in Swoole
if (!$this->response->isSent()) {
$this->response = $this->response
->withHeader('Location', $this->name)
->withStatus($this->status);
} else {
$this->response->getBody()->write(
sprintf('<script>window.location.replace("%s");</script>', $this->name)
);
}
return $this->response;
} else {
// Running in nginx/caddy/etc
if (headers_sent() === false) {
header('Location: ' . $this->name, true, $this->status);
exit;
}
exit('window.location.replace("' . $this->name . '");');
}
}
}

37
cp/app/Lib/Validator.php Normal file
View file

@ -0,0 +1,37 @@
<?php
namespace App\Lib;
use Respect\Validation\Validator as Respect;
use Respect\Validation\Exceptions\NestedValidationException;
/**
* Validator
*
* @author Hezekiah O. <support@hezecom.com>
*/
class Validator
{
protected $errors;
public function validate($request, array $rules)
{
$data = $request->getParsedBody();
foreach ($rules as $field => $rule) {
$fieldName = str_replace('_',' ',$field);
try {
$rule->setName(ucfirst($fieldName))->assert($data[$field]);
} catch (NestedValidationException $e) {
$this->errors[$field] = $e->getMessages();
}
}
$_SESSION['errors'] = $this->errors;
return $this;
}
public function failed()
{
return !empty($this->errors);
}
}

View file

@ -0,0 +1,24 @@
<?php
namespace App\Middleware;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Server\RequestHandlerInterface as RequestHandler;
/**
* AuthMiddleware
*
* @author Hezekiah O. <support@hezecom.com>
*/
class AuthMiddleware extends Middleware
{
public function __invoke(Request $request, RequestHandler $handler)
{
if(! $this->container->get('auth')->isLogin()) {
return redirect()->route('login')->with('error', 'Access denied, you need to login.');
}
$response = $handler->handle($request);
return $response;
}
}

View file

@ -0,0 +1,29 @@
<?php
namespace App\Middleware;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Server\RequestHandlerInterface as RequestHandler;
/**
* CsrfViewMiddleware
*
* @author Hezekiah O. <support@hezecom.com>
*/
class CsrfViewMiddleware extends Middleware
{
public function __invoke(Request $request, RequestHandler $handler)
{
$this->container->get('view')->getEnvironment()->addGlobal('csrf', [
'field' => '
<input type="hidden" name="'. $this->container->get('csrf')->getTokenNameKey() .'"
value="'. $this->container->get('csrf')->getTokenName() .'">
<input type="hidden" name="'. $this->container->get('csrf')->getTokenValueKey() .'"
value="'. $this->container->get('csrf')->getTokenValue() .'">
',
]);
$response = $handler->handle($request);
return $response;
}
}

View file

@ -0,0 +1,22 @@
<?php
namespace App\Middleware;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Server\RequestHandlerInterface as RequestHandler;
/**
* GuestMiddleware
*
* @author Hezekiah O. <support@hezecom.com>
*/
class GuestMiddleware extends Middleware
{
public function __invoke(Request $request, RequestHandler $handler)
{
$response = $handler->handle($request);
if($this->container->get('auth')->isLogin()) {
return redirect()->route('home');
}
return $response;
}
}

View file

@ -0,0 +1,20 @@
<?php
namespace App\Middleware;
use DI\Container;
/**
* Middleware
*
* @author Hezekiah O. <support@hezecom.com>
*/
class Middleware
{
protected $container;
public function __construct(Container $container)
{
$this->container = $container;
}
}

View file

@ -0,0 +1,21 @@
<?php
namespace App\Middleware;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Server\RequestHandlerInterface as RequestHandler;
/**
* OldInputMiddleware
*
* @author Hezekiah O. <support@hezecom.com>
*/
class OldInputMiddleware extends Middleware
{
public function __invoke(Request $request, RequestHandler $handler)
{
$this->container->get('view')->getEnvironment()->addGlobal('old', isset($_SESSION['old']) ? $_SESSION['old'] : '');
$_SESSION['old'] = $request->getParsedBody();
$response = $handler->handle($request);
return $response;
}
}

View file

@ -0,0 +1,22 @@
<?php
namespace App\Middleware;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Server\RequestHandlerInterface as RequestHandler;
/**
* ValidationErrorsMiddleware
*
* @author Hezekiah O. <support@hezecom.com>
*/
class ValidationErrorsMiddleware extends Middleware
{
public function __invoke(Request $request, RequestHandler $handler)
{
$this->container->get('view')->getEnvironment()->addGlobal('errors', isset($_SESSION['errors']) ? $_SESSION['errors'] : '');
unset($_SESSION['errors']);
$response = $handler->handle($request);
return $response;
}
}

50
cp/app/Models/User.php Normal file
View file

@ -0,0 +1,50 @@
<?php
namespace App\Models;
use Pinga\Db\PdoDatabase;
class User
{
private $db;
public function __construct(PdoDatabase $db)
{
$this->db = $db;
}
public function getAllUsers()
{
return $this->db->select('SELECT * FROM users');
}
public function getUserById($id)
{
return $this->db->select('SELECT * FROM users WHERE id = ?', [$id])->fetch();
}
public function createUser($username, $email, $password)
{
$hashedPassword = password_hash($password, PASSWORD_DEFAULT);
$this->db->insert('INSERT INTO users (username, email, password) VALUES (?, ?, ?)', [$username, $email, $hashedPassword]);
return $this->db->lastInsertId();
}
public function updateUser($id, $username, $email, $password)
{
$hashedPassword = password_hash($password, PASSWORD_DEFAULT);
$this->db->update('UPDATE users SET username = ?, email = ?, password = ? WHERE id = ?', [$username, $email, $hashedPassword, $id]);
return true;
}
public function deleteUser($id)
{
$this->db->delete('DELETE FROM users WHERE id = ?', [$id]);
return true;
}
}

94
cp/bin/createModel.php Normal file
View file

@ -0,0 +1,94 @@
<?php
use Delight\Db\PdoDatabase;
// Include the Delight-IM/db package
require_once __DIR__ . '/../vendor/autoload.php';
// Get the table name from the user input
$tableName = readline('Enter table name: ');
// Connect to the database using the PDO driver
$db = new PdoDatabase('mysql:host=localhost;dbname=my_database;charset=utf8mb4', 'my_username', 'my_password');
// Get the column names and types for the specified table
$columnData = $db->select('DESCRIBE ' . $tableName);
// Create the class name based on the table name (e.g. "users" -> "User")
$className = ucwords($tableName, '_');
// Generate the PHP code for the CRUD model based on the column data
$modelCode = <<<PHP
namespace App\Models;
use Delight\Db\PdoDatabase;
class $className
{
private PdoDatabase \$db;
public function __construct(PdoDatabase \$db)
{
\$this->db = \$db;
}
public function getAll$className()
{
return \$this->db->select('SELECT * FROM $tableName');
}
public function get$classNameById(\$id)
{
return \$this->db->select('SELECT * FROM $tableName WHERE id = ?', [\$id])->fetch();
}
public function create$className(${
implode(', ', array_map(function ($column) {
return '$' . $column['Field'];
}, $columnData))
})
{
${implode("\n ", array_map(function ($column) {
return '$' . $column['Field'] . ' = $this->db->quote($' . $column['Field'] . ');';
}, $columnData))}
\$this->db->insert('INSERT INTO $tableName (${implode(', ', array_map(function ($column) {
return $column['Field'];
}, $columnData))}) VALUES (${implode(', ', array_map(function ($column) {
return '$' . $column['Field'];
}, $columnData))})');
return \$this->db->lastInsertId();
}
public function update$className(\$id${implode(', ', array_map(function ($column) {
return ', $' . $column['Field'];
}, $columnData))})
{
${implode("\n ", array_map(function ($column) {
return '$' . $column['Field'] . ' = $this->db->quote($' . $column['Field'] . ');';
}, $columnData))}
\$this->db->update('UPDATE $tableName SET ${implode(', ', array_map(function ($column) {
return $column['Field'] . ' = $' . $column['Field'];
}, $columnData))} WHERE id = ?', array_merge([\$id], array_map(function ($column) {
return '$' . $column['Field'];
}, $columnData)));
return true;
}
public function delete$className(\$id)
{
\$this->db->delete('DELETE FROM $tableName WHERE id = ?', [\$id]);
return true;
}
}
PHP;
// Save the generated PHP code to a file
file_put_contents(__DIR__ . "/app/Models/$className.php", $modelCode);
// Output a success message
echo "CRUD model for table '$tableName' generated successfully.\n";

72
cp/bin/installDB.php Normal file
View file

@ -0,0 +1,72 @@
<?php
// Database type
$dbType = 'mysql';
// Database credentials
$host = 'localhost';
$username = 'your_mysql_username';
$password = 'your_mysql_password';
try {
// Connect to database
if ($dbType == 'mysql') {
$pdo = new PDO("mysql:host=$host", $username, $password);
} elseif ($dbType == 'postgresql') {
$pdo = new PDO("pgsql:host=$host", $username, $password);
} elseif ($dbType == 'sqlite') {
$pdo = new PDO("sqlite:host=$host");
}
// Set PDO attributes
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// New database details
$newDatabaseName = 'new_database_name';
$newDatabaseUsername = 'new_database_username';
$newDatabasePassword = 'new_database_password';
// Create new database
if ($dbType == 'mysql') {
$pdo->exec("CREATE DATABASE `$newDatabaseName`");
} elseif ($dbType == 'postgresql') {
$pdo->exec("CREATE DATABASE $newDatabaseName");
} elseif ($dbType == 'sqlite') {
$pdo->exec("CREATE DATABASE $newDatabaseName");
}
echo "Created new database '$newDatabaseName'\n";
// Create new user with access to the new database
if ($dbType == 'mysql') {
$pdo->exec("CREATE USER '$newDatabaseUsername'@'localhost' IDENTIFIED BY '$newDatabasePassword'");
$pdo->exec("GRANT ALL PRIVILEGES ON `$newDatabaseName`.* TO '$newDatabaseUsername'@'localhost'");
} elseif ($dbType == 'postgresql') {
$pdo->exec("CREATE USER $newDatabaseUsername WITH PASSWORD '$newDatabasePassword'");
$pdo->exec("GRANT ALL PRIVILEGES ON DATABASE $newDatabaseName TO $newDatabaseUsername");
} elseif ($dbType == 'sqlite') {
// SQLite doesn't have users and privileges, so skip this step
}
echo "Created new user '$newDatabaseUsername'\n";
echo "Granted all privileges to user '$newDatabaseUsername' on database '$newDatabaseName'\n";
// Connect to the new database as the new user
if ($dbType == 'mysql') {
$pdo = new PDO("mysql:host=$host;dbname=$newDatabaseName", $newDatabaseUsername, $newDatabasePassword);
} elseif ($dbType == 'postgresql') {
$pdo = new PDO("pgsql:host=$host;dbname=$newDatabaseName", $newDatabaseUsername, $newDatabasePassword);
} elseif ($dbType == 'sqlite') {
$pdo = new PDO("sqlite:$newDatabaseName");
}
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// Path to SQL file to import
$sqlFile = '/path/to/sql/file.sql';
// Import SQL file
$sql = file_get_contents($sqlFile);
$pdo->exec($sql);
echo "Imported SQL file '$sqlFile' into database '$newDatabaseName'\n";
} catch (PDOException $e) {
echo $e->getMessage();
}

203
cp/bin/swoole.php Normal file
View file

@ -0,0 +1,203 @@
<?php
use Imefisto\PsrSwoole\ServerRequest as PsrRequest;
use Imefisto\PsrSwoole\ResponseMerger;
use Nyholm\Psr7\Factory\Psr17Factory;
use Swoole\Http\Request;
use Swoole\Http\Response;
use Chubbyphp\StaticFile\StaticFileMiddleware;
use Psr\Http\Message\StreamFactoryInterface;
use App\Lib\Logger;
use DI\Container;
use Slim\Csrf\Guard;
use Slim\Factory\AppFactory;
use Slim\Handlers\Strategies\RequestResponseArgs;
use Slim\Views\Twig;
use Slim\Views\TwigMiddleware;
use Twig\TwigFunction;
if (session_status() == PHP_SESSION_NONE) {
session_start();
}
require __DIR__ . '/../vendor/autoload.php';
require __DIR__ . '/../bootstrap/helper.php';
try {
Dotenv\Dotenv::createImmutable(__DIR__. '/../')->load();
} catch (\Dotenv\Exception\InvalidPathException $e) {
//
}
//Enable error display in details when APP_ENV=local
if(envi('APP_ENV')=='local') {
Logger::systemLogs(true);
}else{
Logger::systemLogs(false);
}
$container = new Container();
// Set container to create App with on AppFactory
AppFactory::setContainer($container);
/**
* Create your slim app
*/
$app = AppFactory::create();
$responseFactory = $app->getResponseFactory();
$routeCollector = $app->getRouteCollector();
$routeCollector->setDefaultInvocationStrategy(new RequestResponseArgs());
$routeParser = $app->getRouteCollector()->getRouteParser();
require_once __DIR__ . '/../bootstrap/database.php';
$container->set('router', function () use ($routeParser) {
return $routeParser;
});
$container->set('db', function () use ($db) {
return $db;
});
$container->set('pdo', function () use ($pdo) {
return $pdo;
});
$container->set('auth', function() {
return new \App\Auth\Auth;
});
$container->set('flash', function() {
return new \Slim\Flash\Messages;
});
$container->set('view', function ($container) {
$view = Twig::create(__DIR__ . '/../resources/views', [
'cache' => false,
]);
$view->getEnvironment()->addGlobal('auth', [
'isLogin' => $container->get('auth')->isLogin(),
'user' => $container->get('auth')->user(),
]);
$view->getEnvironment()->addGlobal('flash', $container->get('flash'));
$view->getEnvironment()->addGlobal('screen_mode', $_SESSION['_screen_mode']);
//route
$route = new TwigFunction('route', function ($name) {
return route($name);
});
$view->getEnvironment()->addFunction($route);
// Define the route_is function
$routeIs = new \Twig\TwigFunction('route_is', function ($routeName) {
return strpos($_SERVER['REQUEST_URI'], $routeName) !== false;
});
$view->getEnvironment()->addFunction($routeIs);
//assets
$assets = new TwigFunction('assets', function ($location) {
return assets($location);
});
$view->getEnvironment()->addFunction($assets);
//Pagination
$pagination = new TwigFunction("links", function ($object) {
});
$view->getEnvironment()->addFunction($pagination);
return $view;
});
$app->add(TwigMiddleware::createFromContainer($app));
$container->set('validator', function ($container) {
return new App\Lib\Validator;
});
$container->set('csrf', function($container) use ($responseFactory) {
return new Guard($responseFactory);
});
$app->add(new \App\Middleware\ValidationErrorsMiddleware($container));
$app->add(new \App\Middleware\OldInputMiddleware($container));
$app->add(new \App\Middleware\CsrfViewMiddleware($container));
$app->add('csrf');
$app->setBasePath(routePath());
$uriFactory = new Psr17Factory;
$streamFactory = new Psr17Factory;
//$responseFactory = new Psr17Factory;
$uploadedFileFactory = new Psr17Factory;
$responseMerger = new ResponseMerger;
$app->add(new StaticFileMiddleware(
$responseFactory,
$streamFactory,
__DIR__ . '/../public'
));
require __DIR__ . '/../routes/web.php';
$http = new Swoole\Http\Server("0.0.0.0", 3000);
$http->set([
'worker_num' => swoole_cpu_num() * 2,
'enable_coroutine' => true,
'log_file' => '/tmp/sw'
]);
$http->on(
'request',
function (
Request $swooleRequest,
Response $swooleResponse
) use (
$uriFactory,
$streamFactory,
$uploadedFileFactory,
$responseFactory,
$responseMerger,
$app
) {
/**
* create psr request from swoole request
*/
$psrRequest = new PsrRequest(
$swooleRequest,
$uriFactory,
$streamFactory,
$uploadedFileFactory
);
// Check if the request path matches a static file path
if (preg_match('#^/assets/.*#', $psrRequest->getUri()->getPath())) {
// If the request path matches a static file path, pass the request off to the StaticFile middleware
$psrResponse = $app->handle($psrRequest, new Response());
} else {
// If the request path does not match a static file path, process the request with Slim
$psrResponse = $app->handle($psrRequest);
}
/**
* merge your psr response with swoole response
*/
$response = $responseMerger->toSwoole(
$psrResponse,
$swooleResponse
);
if ($response->isWritable()) {
$response->end();
} else {
// throw a generic exception
throw new RuntimeException('HTTP response is not available');
}
}
);
$http->start();

123
cp/bootstrap/app.php Normal file
View file

@ -0,0 +1,123 @@
<?php
use App\Lib\Logger;
use DI\Container;
use Slim\Csrf\Guard;
use Slim\Factory\AppFactory;
use Slim\Handlers\Strategies\RequestResponseArgs;
use Slim\Views\Twig;
use Slim\Views\TwigMiddleware;
use Twig\TwigFunction;
if (session_status() == PHP_SESSION_NONE) {
session_start();
}
require __DIR__ . '/../vendor/autoload.php';
require __DIR__ . '/helper.php';
try {
Dotenv\Dotenv::createImmutable(__DIR__. '/../')->load();
} catch (\Dotenv\Exception\InvalidPathException $e) {
//
}
//Enable error display in details when APP_ENV=local
if(envi('APP_ENV')=='local') {
Logger::systemLogs(true);
}else{
Logger::systemLogs(false);
}
$container = new Container();
// Set container to create App with on AppFactory
AppFactory::setContainer($container);
$app = AppFactory::create();
$responseFactory = $app->getResponseFactory();
$routeCollector = $app->getRouteCollector();
$routeCollector->setDefaultInvocationStrategy(new RequestResponseArgs());
$routeParser = $app->getRouteCollector()->getRouteParser();
require_once __DIR__ . '/database.php';
$container->set('router', function () use ($routeParser) {
return $routeParser;
});
$container->set('db', function () use ($db) {
return $db;
});
$container->set('pdo', function () use ($pdo) {
return $pdo;
});
$container->set('auth', function() {
return new \App\Auth\Auth;
});
$container->set('flash', function() {
return new \Slim\Flash\Messages;
});
$container->set('view', function ($container) {
$view = Twig::create(__DIR__ . '/../resources/views', [
'cache' => false,
]);
$view->getEnvironment()->addGlobal('auth', [
'isLogin' => $container->get('auth')->isLogin(),
'user' => $container->get('auth')->user(),
]);
$view->getEnvironment()->addGlobal('flash', $container->get('flash'));
if (isset($_SESSION['_screen_mode'])) {
$view->getEnvironment()->addGlobal('screen_mode', $_SESSION['_screen_mode']);
} else {
$view->getEnvironment()->addGlobal('screen_mode', 'light');
}
//route
$route = new TwigFunction('route', function ($name) {
return route($name);
});
$view->getEnvironment()->addFunction($route);
// Define the route_is function
$routeIs = new \Twig\TwigFunction('route_is', function ($routeName) {
return strpos($_SERVER['REQUEST_URI'], $routeName) !== false;
});
$view->getEnvironment()->addFunction($routeIs);
//assets
$assets = new TwigFunction('assets', function ($location) {
return assets($location);
});
$view->getEnvironment()->addFunction($assets);
//Pagination
$pagination = new TwigFunction("links", function ($object) {
});
$view->getEnvironment()->addFunction($pagination);
return $view;
});
$app->add(TwigMiddleware::createFromContainer($app));
$container->set('validator', function ($container) {
return new App\Lib\Validator;
});
$container->set('csrf', function($container) use ($responseFactory) {
return new Guard($responseFactory);
});
$app->add(new \App\Middleware\ValidationErrorsMiddleware($container));
$app->add(new \App\Middleware\OldInputMiddleware($container));
$app->add(new \App\Middleware\CsrfViewMiddleware($container));
$app->add('csrf');
$app->setBasePath(routePath());
require __DIR__ . '/../routes/web.php';

28
cp/bootstrap/database.php Normal file
View file

@ -0,0 +1,28 @@
<?php
$config = config('connections');
// MySQL Connection
if (config('default') == 'mysql') {
$pdo = new \PDO($config['mysql']['driver'].':dbname='.$config['mysql']['database'].';host='.$config['mysql']['host'].';charset='.$config['mysql']['charset'].'', $config['mysql']['username'], $config['mysql']['password']);
$db = \Pinga\Db\PdoDatabase::fromPdo($pdo);
}
// SQLite Connection
elseif (config('default') == 'sqlite') {
$pdo = new PDO($config['sqlite']['driver'].":".$config['sqlite']['driver']);
$db = \Pinga\Db\PdoDatabase::fromPdo($pdo);
}
// PostgreSQL Connection
elseif (config('default') == 'pgsql') {
$pdo = new \PDO($config['pgsql']['driver'].':dbname='.$config['pgsql']['database'].';host='.$config['pgsql']['host'].';charset='.$config['pgsql']['charset'].'', $config['pgsql']['username'], $config['pgsql']['password']);
$db = \Pinga\Db\PdoDatabase::fromPdo($pdo);
}
// SQL Server Connection
elseif (config('default') == 'sqlsrv') {
$pdo = new PDO($config['sqlsrv']['driver']."sqlsrv:server=".$config['sqlsrv']['host'].";".$config['sqlsrv']['database'], $config['sqlsrv']['username'], $config['sqlsrv']['password']);
$db = \Pinga\Db\PdoDatabase::fromPdo($pdo);
}
// MySQL Connection as default
else{
$pdo = new \PDO($config['mysql']['driver'].':dbname='.$config['mysql']['database'].';host='.$config['mysql']['host'].';charset='.$config['mysql']['charset'].'', $config['mysql']['username'], $config['mysql']['password']);
$db = \Pinga\Db\PdoDatabase::fromPdo($pdo);
}

169
cp/bootstrap/helper.php Normal file
View file

@ -0,0 +1,169 @@
<?php
/**
* Helper functions
* @author Hezekiah O. <support@hezecom.com>
*/
use Pinga\Auth\Auth;
/**
* @return mixed|string|string[]
*/
function routePath() {
if (isset($_SERVER['REQUEST_URI'])) {
$scriptDir = str_replace('\\', '/', dirname($_SERVER['SCRIPT_NAME']));
$uri = (string) parse_url('http://a' . $_SERVER['REQUEST_URI'], PHP_URL_PATH);
if (stripos($uri, $_SERVER['SCRIPT_NAME']) === 0) {
return $_SERVER['SCRIPT_NAME'];
}
if ($scriptDir !== '/' && stripos($uri, $scriptDir) === 0) {
return $scriptDir;
}
}
return '';
}
/**
* @param $key
* @param null $default
* @return mixed|null
*/
function config($key, $default=null){
return \App\Lib\Config::get($key, $default);
}
/**
* @param $var
* @return mixed
*/
function envi($var, $default=null)
{
if(isset($_ENV[$var])){
return $_ENV[$var];
}
return $default;
}
/**
* Start session
*/
function startSession(){
if (session_status() == PHP_SESSION_NONE) {
session_start();
}
}
/**
* @param $var
* @return mixed
*/
function session($var){
if (isset($_SESSION[$var])) {
return $_SESSION[$var];
}
}
/**
* Global PDO connection
* @return \DI\|mixed|PDO
* @throws \DI\DependencyException
* @throws \DI\NotFoundException
*/
function pdo(){
global $container;
return $container->get('pdo');
}
/**
* @return Auth
*/
function auth(){
$db = pdo();
$auth = new Auth($db);
return $auth;
}
/**
* @param $name
* @param array $params1
* @param array $params2
* @return mixed
* @throws \DI\DependencyException
* @throws \DI\NotFoundException
*/
function route($name, $params1 =[], $params2=[]){
global $container;
return $container->get('router')->urlFor($name,$params1,$params2);
}
/**
* @param string $dir
* @return string
*/
function baseUrl(){
$root = "";
$root .= !empty($_SERVER['HTTPS']) ? 'https' : 'http';
$root .= '://' . $_SERVER['HTTP_HOST'];
return $root;
}
/**
* @param string|null $name
* @return string
*/
function url($url=null, $params1 =[], $params2=[]){
if($url){
return baseUrl().route($url,$params1,$params2);
}
return baseUrl();
}
/**
* @param $resp
* @param $page
* @param array $arr
* @return mixed
* @throws \DI\DependencyException
* @throws \DI\NotFoundException
*/
function view($resp, $page, $arr=[]){
global $container;
return $container->get('view')->render($resp, $page, $arr);
}
/**
* @param $type
* @param $message
* @return mixed
* @throws \DI\DependencyException
* @throws \DI\NotFoundException
*/
function flash($type, $message){
global $container;
return $container->get('flash')->addMessage($type, $message);
}
/**
* @return \App\Lib\Redirect
*/
function redirect()
{
return new \App\Lib\Redirect();
}
/**
* @param $location
* @return string
*/
function assets($location){
return url().dirname($_SERVER["REQUEST_URI"]).'/'.$location;
}
/**
* @param $data
* @return mixed
*/
function toArray($data){
return json_decode(json_encode($data), true);
}

39
cp/composer.json Normal file
View file

@ -0,0 +1,39 @@
{
"name": "pinga/pinga-panel",
"description": "Pinga Framework Boilerplate",
"type": "project",
"keywords": ["slim", "slim 4", "skeleton", "authentication", "template", "orm","pinga"],
"homepage": "https://github.com/getpinga/pinga-panel",
"license": "MIT",
"authors": [
{
"name": "Taras Kondratyuk",
"email": "tk@gepinga.com"
}
],
"require": {
"php": "^8.1",
"ext-pdo": "*",
"slim/slim": "4.11.0",
"slim/twig-view": "^3.3.0",
"monolog/monolog": "^3.3.1",
"respect/validation": "^2.2.4",
"slim/csrf": "^1.3",
"slim/flash": "^0.4",
"vlucas/phpdotenv": "^5.5",
"php-di/php-di": "^7.0.2",
"nyholm/psr7": "^1.5",
"nyholm/psr7-server": "^1.0",
"pinga/auth": "^0.1.1",
"phpmailer/phpmailer": "^6.7.1",
"filp/whoops": "^2.14.6",
"imefisto/psr-swoole-native": "^1.1",
"chubbyphp/chubbyphp-static-file": "^1.2",
"lasserafn/php-initial-avatar-generator": "^4.2"
},
"autoload": {
"psr-4": {
"App\\": "app/"
}
}
}

72
cp/config/app.php Normal file
View file

@ -0,0 +1,72 @@
<?php
require __DIR__.'/../vendor/autoload.php';
use Dotenv\Dotenv;
$dotenv = Dotenv::createImmutable(__DIR__);
if (file_exists(__DIR__.'/.env')) {
$dotenv->load();
}
return [
'env' => $_ENV['APP_ENV'] ?? 'production',
'name' => $_ENV['APP_NAME'] ?? 'Hezecom',
'url' => $_ENV['APP_URL'] ?? 'http://localhost',
'timezone' => $_ENV['TIME_ZONE'] ?? 'UTC',
'default' => $_ENV['DB_DRIVER'] ?? 'mysql',
'connections' => [
'mysql' => [
'driver' => 'mysql',
'host' => $_ENV['DB_HOST'] ?? '127.0.0.1',
'port' => $_ENV['DB_PORT'] ?? '3306',
'database' => $_ENV['DB_DATABASE'] ?? 'forge',
'username' => $_ENV['DB_USERNAME'] ?? 'forge',
'password' => $_ENV['DB_PASSWORD'] ?? '',
'unix_socket' => $_ENV['DB_SOCKET'] ?? '',
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'strict' => true,
'engine' => null,
],
'sqlite' => [
'driver' => 'sqlite',
'database' => $_ENV['DB_DATABASE'] ?? __DIR__.'/database.sqlite',
'prefix' => '',
],
'pgsql' => [
'driver' => 'pgsql',
'host' => $_ENV['DB_HOST'] ?? '127.0.0.1',
'port' => $_ENV['DB_PORT'] ?? '5432',
'database' => $_ENV['DB_DATABASE'] ?? 'forge',
'username' => $_ENV['DB_USERNAME'] ?? 'forge',
'password' => $_ENV['DB_PASSWORD'] ?? '',
'charset' => 'utf8',
'prefix' => '',
'schema' => 'public',
'sslmode' => 'prefer',
],
'sqlsrv' => [
'driver' => 'sqlsrv',
'host' => $_ENV['DB_HOST'] ?? 'localhost',
'port' => $_ENV['DB_PORT'] ?? '1433',
'database' => $_ENV['DB_DATABASE'] ?? 'forge',
'username' => $_ENV['DB_USERNAME'] ?? 'forge',
'password' => $_ENV['DB_PASSWORD'] ?? '',
'charset' => 'utf8',
'prefix' => '',
],
],
'mail' => [
'driver' => $_ENV['MAIL_DRIVER'] ?? 'smtp',
'host' => $_ENV['MAIL_HOST'] ?? 'smtp.mailgun.org',
'port' => $_ENV['MAIL_PORT'] ?? 587,
'username' => $_ENV['MAIL_USERNAME'] ?? '',
'password' => $_ENV['MAIL_PASSWORD'] ?? '',
'encryption' => $_ENV['MAIL_ENCRYPTION'] ?? 'tls',
'from' => [
'address' => $_ENV['MAIL_FROM_ADDRESS'] ?? 'hello@example.com',
'name' => $_ENV['MAIL_FROM_NAME'] ?? 'Example',
],
],
];

21
cp/env-sample Normal file
View file

@ -0,0 +1,21 @@
APP_NAME='StarterApp'
APP_ENV=public
APP_URL=http://localhost
DB_DRIVER=mysql
DB_HOST=localhost
DB_DATABASE=pinglet
DB_USERNAME=root
DB_PASSWORD=
DB_PORT=3306
#mailer settings (Driver= smtp or sendmail or mail)
MAIL_DRIVER=smtp
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=username
MAIL_PASSWORD=password
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS='example@domain.com'
MAIL_FROM_NAME='Example'

0
cp/logs/errors.log Normal file
View file

16
cp/phpunit.xml Normal file
View file

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="bootstrap/app.php"
colors="true"
verbose="true"
stopOnFailure="false">
<testsuites>
<testsuite name="Test suite">
<directory>tests</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory suffix=".php">app/</directory>
</whitelist>
</filter>
</phpunit>

View file

@ -0,0 +1,301 @@
/*!
* Tabler v1.0.0-beta16 (https://tabler.io)
* @version 1.0.0-beta16
* @link https://tabler.io
* Copyright 2018-2022 The Tabler Authors
* Copyright 2018-2022 codecalm.net Paweł Kuna
* Licensed under MIT (https://github.com/tabler/tabler/blob/master/LICENSE)
*/
pre.highlight,
.highlight pre {
max-height: 30rem;
margin: 1.5rem 0;
overflow: auto;
border-radius: var(--tblr-border-radius);
}
pre.highlight::-webkit-scrollbar,
.highlight pre::-webkit-scrollbar {
width: 0.5rem;
height: 0.5rem;
-webkit-transition: background 0.3s;
transition: background 0.3s;
}
@media (prefers-reduced-motion: reduce) {
pre.highlight::-webkit-scrollbar,
.highlight pre::-webkit-scrollbar {
-webkit-transition: none;
transition: none;
}
}
pre.highlight::-webkit-scrollbar-thumb,
.highlight pre::-webkit-scrollbar-thumb {
border-radius: 5px;
background: rgba(var(--tblr-light-rgb), 0.16);
}
pre.highlight::-webkit-scrollbar-track,
.highlight pre::-webkit-scrollbar-track {
background: rgba(var(--tblr-light-rgb), 0.06);
}
pre.highlight:hover::-webkit-scrollbar-thumb,
.highlight pre:hover::-webkit-scrollbar-thumb {
background: rgba(var(--tblr-light-rgb), 0.32);
}
pre.highlight::-webkit-scrollbar-corner,
.highlight pre::-webkit-scrollbar-corner {
background: transparent;
}
.highlight {
margin: 0;
}
.highlight code > * {
margin: 0 !important;
padding: 0 !important;
}
.highlight .c, .highlight .c1 {
color: #a0aec0;
}
.highlight .nt, .highlight .nc, .highlight .nx {
color: #ff8383;
}
.highlight .na, .highlight .p {
color: #ffe484;
}
.highlight .s, .highlight .dl, .highlight .s2 {
color: #b5f4a5;
}
.highlight .k {
color: #93ddfd;
}
.highlight .s1, .highlight .mi {
color: #d9a9ff;
}
.example {
padding: 2rem;
margin: 1rem 0 2rem;
border: var(--tblr-border-width) var(--tblr-border-style) var(--tblr-border-color);
border-radius: 3px 3px 0 0;
position: relative;
min-height: 12rem;
display: flex;
align-items: center;
overflow-x: auto;
}
.example-centered {
justify-content: center;
}
.example-centered .example-content {
flex: 0 auto;
}
.example-content {
font-size: 0.875rem;
line-height: 1.4285714286;
color: #1d273b;
flex: 1;
max-width: 100%;
}
.example-content .page-header {
margin-bottom: 0;
}
.example-bg {
background: #f1f5f9;
}
.example-code {
margin: 2rem 0;
border: var(--tblr-border-width) var(--tblr-border-style) var(--tblr-border-color);
border-top: none;
}
.example-code pre {
margin: 0;
border: 0;
border-radius: 0 0 3px 3px;
}
.example + .example-code {
margin-top: -2rem;
}
.example-column {
margin: 0 auto;
}
.example-column > .card:last-of-type {
margin-bottom: 0;
}
.example-column-1 {
max-width: 26rem;
}
.example-column-2 {
max-width: 52rem;
}
.example-modal-backdrop {
background: #1d273b;
opacity: 0.24;
position: absolute;
width: 100%;
left: 0;
top: 0;
height: 100%;
border-radius: 2px 2px 0 0;
}
@media not print {
.theme-dark .example {
background-color: #1a2234;
border-color: #243049;
}
.theme-dark .example-content {
color: #f8fafc;
}
.theme-dark .example-code {
border-color: #243049;
border-top: none;
}
}
@media not print {
@media (prefers-color-scheme: dark) {
.theme-dark-auto .example {
background-color: #1a2234;
border-color: #243049;
}
.theme-dark-auto .example-content {
color: #f8fafc;
}
.theme-dark-auto .example-code {
border-color: #243049;
border-top: none;
}
}
}
.card-sponsor {
background: #dbe7f6 no-repeat center/100% 100%;
border-color: #548ed2;
min-height: 316px;
}
body.no-transitions * {
transition: none !important;
}
.dropdown-menu-demo {
display: inline-block;
width: 100%;
position: relative;
top: 0;
margin-bottom: 1rem !important;
}
.demo-icon-preview {
position: -webkit-sticky;
position: sticky;
top: 0;
}
.demo-icon-preview svg,
.demo-icon-preview i {
width: 15rem;
height: 15rem;
font-size: 15rem;
stroke-width: 1.5;
margin: 0 auto;
display: block;
}
@media (max-width: 575.98px) {
.demo-icon-preview svg,
.demo-icon-preview i {
width: 10rem;
height: 10rem;
font-size: 10rem;
}
}
.demo-icon-preview-icon pre {
margin: 0;
-webkit-user-select: all;
-moz-user-select: all;
user-select: all;
}
.demo-dividers > p {
opacity: 0.2;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.demo-icons-list {
display: flex;
flex-wrap: wrap;
padding: 0;
margin: 0 -2px -1px 0;
list-style: none;
}
.demo-icons-list > * {
flex: 1 0 4rem;
}
.demo-icons-list-wrap {
overflow: hidden;
}
.demo-icons-list-item {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
aspect-ratio: 1;
text-align: center;
padding: 0.5rem;
border-right: var(--tblr-border-width) var(--tblr-border-style) var(--tblr-border-color);
border-bottom: var(--tblr-border-width) var(--tblr-border-style) var(--tblr-border-color);
color: inherit;
cursor: pointer;
}
.demo-icons-list-item .icon {
width: 1.5rem;
height: 1.5rem;
font-size: 1.5rem;
}
.demo-icons-list-item:hover {
text-decoration: none;
}
.settings-btn {
position: fixed;
right: -1px;
top: 10rem;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
box-shadow: rgba(var(--tblr-body-color-rgb), 0.04) 0 2px 4px 0;
}
.settings-scheme {
display: inline-block;
border-radius: 50%;
height: 3rem;
width: 3rem;
position: relative;
border: var(--tblr-border-width) var(--tblr-border-style) var(--tblr-border-color);
box-shadow: rgba(var(--tblr-body-color-rgb), 0.04) 0 2px 4px 0;
}
.settings-scheme-light {
background: linear-gradient(135deg, #ffffff 50%, #f8fafc 50%);
}
.settings-scheme-mixed {
background-image: linear-gradient(135deg, #1d273b 50%, #fff 50%);
}
.settings-scheme-transparent {
background: #f8fafc;
}
.settings-scheme-dark {
background: #1d273b;
}
.settings-scheme-colored {
background-image: linear-gradient(135deg, var(--tblr-primary) 50%, #f8fafc 50%);
}

9
cp/public/assets/css/demo.min.css vendored Normal file
View file

@ -0,0 +1,9 @@
/*!
* Tabler v1.0.0-beta16 (https://tabler.io)
* @version 1.0.0-beta16
* @link https://tabler.io
* Copyright 2018-2022 The Tabler Authors
* Copyright 2018-2022 codecalm.net Paweł Kuna
* Licensed under MIT (https://github.com/tabler/tabler/blob/master/LICENSE)
*/
.highlight pre,pre.highlight{max-height:30rem;margin:1.5rem 0;overflow:auto;border-radius:var(--tblr-border-radius)}.highlight pre::-webkit-scrollbar,pre.highlight::-webkit-scrollbar{width:.5rem;height:.5rem;-webkit-transition:background .3s;transition:background .3s}@media (prefers-reduced-motion:reduce){.highlight pre::-webkit-scrollbar,pre.highlight::-webkit-scrollbar{-webkit-transition:none;transition:none}}.highlight pre::-webkit-scrollbar-thumb,pre.highlight::-webkit-scrollbar-thumb{border-radius:5px;background:rgba(var(--tblr-light-rgb),.16)}.highlight pre::-webkit-scrollbar-track,pre.highlight::-webkit-scrollbar-track{background:rgba(var(--tblr-light-rgb),.06)}.highlight pre:hover::-webkit-scrollbar-thumb,pre.highlight:hover::-webkit-scrollbar-thumb{background:rgba(var(--tblr-light-rgb),.32)}.highlight pre::-webkit-scrollbar-corner,pre.highlight::-webkit-scrollbar-corner{background:0 0}.highlight{margin:0}.highlight code>*{margin:0!important;padding:0!important}.highlight .c,.highlight .c1{color:#a0aec0}.highlight .nc,.highlight .nt,.highlight .nx{color:#ff8383}.highlight .na,.highlight .p{color:#ffe484}.highlight .dl,.highlight .s,.highlight .s2{color:#b5f4a5}.highlight .k{color:#93ddfd}.highlight .mi,.highlight .s1{color:#d9a9ff}.example{padding:2rem;margin:1rem 0 2rem;border:var(--tblr-border-width) var(--tblr-border-style) var(--tblr-border-color);border-radius:3px 3px 0 0;position:relative;min-height:12rem;display:flex;align-items:center;overflow-x:auto}.example-centered{justify-content:center}.example-centered .example-content{flex:0 auto}.example-content{font-size:.875rem;line-height:1.4285714286;color:#1d273b;flex:1;max-width:100%}.example-content .page-header{margin-bottom:0}.example-bg{background:#f1f5f9}.example-code{margin:2rem 0;border:var(--tblr-border-width) var(--tblr-border-style) var(--tblr-border-color);border-top:none}.example-code pre{margin:0;border:0;border-radius:0 0 3px 3px}.example+.example-code{margin-top:-2rem}.example-column{margin:0 auto}.example-column>.card:last-of-type{margin-bottom:0}.example-column-1{max-width:26rem}.example-column-2{max-width:52rem}.example-modal-backdrop{background:#1d273b;opacity:.24;position:absolute;width:100%;left:0;top:0;height:100%;border-radius:2px 2px 0 0}@media not print{.theme-dark .example{background-color:#1a2234;border-color:#243049}.theme-dark .example-content{color:#f8fafc}.theme-dark .example-code{border-color:#243049;border-top:none}}@media not print{@media (prefers-color-scheme:dark){.theme-dark-auto .example{background-color:#1a2234;border-color:#243049}.theme-dark-auto .example-content{color:#f8fafc}.theme-dark-auto .example-code{border-color:#243049;border-top:none}}}.card-sponsor{background:#dbe7f6 no-repeat center/100% 100%;border-color:#548ed2;min-height:316px}body.no-transitions *{transition:none!important}.dropdown-menu-demo{display:inline-block;width:100%;position:relative;top:0;margin-bottom:1rem!important}.demo-icon-preview{position:-webkit-sticky;position:sticky;top:0}.demo-icon-preview i,.demo-icon-preview svg{width:15rem;height:15rem;font-size:15rem;stroke-width:1.5;margin:0 auto;display:block}@media (max-width:575.98px){.demo-icon-preview i,.demo-icon-preview svg{width:10rem;height:10rem;font-size:10rem}}.demo-icon-preview-icon pre{margin:0;-webkit-user-select:all;-moz-user-select:all;user-select:all}.demo-dividers>p{opacity:.2;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.demo-icons-list{display:flex;flex-wrap:wrap;padding:0;margin:0 -2px -1px 0;list-style:none}.demo-icons-list>*{flex:1 0 4rem}.demo-icons-list-wrap{overflow:hidden}.demo-icons-list-item{display:flex;flex-direction:column;align-items:center;justify-content:center;aspect-ratio:1;text-align:center;padding:.5rem;border-right:var(--tblr-border-width) var(--tblr-border-style) var(--tblr-border-color);border-bottom:var(--tblr-border-width) var(--tblr-border-style) var(--tblr-border-color);color:inherit;cursor:pointer}.demo-icons-list-item .icon{width:1.5rem;height:1.5rem;font-size:1.5rem}.demo-icons-list-item:hover{text-decoration:none}.settings-btn{position:fixed;right:-1px;top:10rem;border-top-right-radius:0;border-bottom-right-radius:0;box-shadow:rgba(var(--tblr-body-color-rgb),.04) 0 2px 4px 0}.settings-scheme{display:inline-block;border-radius:50%;height:3rem;width:3rem;position:relative;border:var(--tblr-border-width) var(--tblr-border-style) var(--tblr-border-color);box-shadow:rgba(var(--tblr-body-color-rgb),.04) 0 2px 4px 0}.settings-scheme-light{background:linear-gradient(135deg,#fff 50%,#f8fafc 50%)}.settings-scheme-mixed{background-image:linear-gradient(135deg,#1d273b 50%,#fff 50%)}.settings-scheme-transparent{background:#f8fafc}.settings-scheme-dark{background:#1d273b}.settings-scheme-colored{background-image:linear-gradient(135deg,var(--tblr-primary) 50%,#f8fafc 50%)}

View file

@ -0,0 +1,301 @@
/*!
* Tabler v1.0.0-beta16 (https://tabler.io)
* @version 1.0.0-beta16
* @link https://tabler.io
* Copyright 2018-2022 The Tabler Authors
* Copyright 2018-2022 codecalm.net Paweł Kuna
* Licensed under MIT (https://github.com/tabler/tabler/blob/master/LICENSE)
*/
pre.highlight,
.highlight pre {
max-height: 30rem;
margin: 1.5rem 0;
overflow: auto;
border-radius: var(--tblr-border-radius);
}
pre.highlight::-webkit-scrollbar,
.highlight pre::-webkit-scrollbar {
width: 0.5rem;
height: 0.5rem;
-webkit-transition: background 0.3s;
transition: background 0.3s;
}
@media (prefers-reduced-motion: reduce) {
pre.highlight::-webkit-scrollbar,
.highlight pre::-webkit-scrollbar {
-webkit-transition: none;
transition: none;
}
}
pre.highlight::-webkit-scrollbar-thumb,
.highlight pre::-webkit-scrollbar-thumb {
border-radius: 5px;
background: rgba(var(--tblr-light-rgb), 0.16);
}
pre.highlight::-webkit-scrollbar-track,
.highlight pre::-webkit-scrollbar-track {
background: rgba(var(--tblr-light-rgb), 0.06);
}
pre.highlight:hover::-webkit-scrollbar-thumb,
.highlight pre:hover::-webkit-scrollbar-thumb {
background: rgba(var(--tblr-light-rgb), 0.32);
}
pre.highlight::-webkit-scrollbar-corner,
.highlight pre::-webkit-scrollbar-corner {
background: transparent;
}
.highlight {
margin: 0;
}
.highlight code > * {
margin: 0 !important;
padding: 0 !important;
}
.highlight .c, .highlight .c1 {
color: #a0aec0;
}
.highlight .nt, .highlight .nc, .highlight .nx {
color: #ff8383;
}
.highlight .na, .highlight .p {
color: #ffe484;
}
.highlight .s, .highlight .dl, .highlight .s2 {
color: #b5f4a5;
}
.highlight .k {
color: #93ddfd;
}
.highlight .s1, .highlight .mi {
color: #d9a9ff;
}
.example {
padding: 2rem;
margin: 1rem 0 2rem;
border: var(--tblr-border-width) var(--tblr-border-style) var(--tblr-border-color);
border-radius: 3px 3px 0 0;
position: relative;
min-height: 12rem;
display: flex;
align-items: center;
overflow-x: auto;
}
.example-centered {
justify-content: center;
}
.example-centered .example-content {
flex: 0 auto;
}
.example-content {
font-size: 0.875rem;
line-height: 1.4285714286;
color: #1d273b;
flex: 1;
max-width: 100%;
}
.example-content .page-header {
margin-bottom: 0;
}
.example-bg {
background: #f1f5f9;
}
.example-code {
margin: 2rem 0;
border: var(--tblr-border-width) var(--tblr-border-style) var(--tblr-border-color);
border-top: none;
}
.example-code pre {
margin: 0;
border: 0;
border-radius: 0 0 3px 3px;
}
.example + .example-code {
margin-top: -2rem;
}
.example-column {
margin: 0 auto;
}
.example-column > .card:last-of-type {
margin-bottom: 0;
}
.example-column-1 {
max-width: 26rem;
}
.example-column-2 {
max-width: 52rem;
}
.example-modal-backdrop {
background: #1d273b;
opacity: 0.24;
position: absolute;
width: 100%;
right: 0;
top: 0;
height: 100%;
border-radius: 2px 2px 0 0;
}
@media not print {
.theme-dark .example {
background-color: #1a2234;
border-color: #243049;
}
.theme-dark .example-content {
color: #f8fafc;
}
.theme-dark .example-code {
border-color: #243049;
border-top: none;
}
}
@media not print {
@media (prefers-color-scheme: dark) {
.theme-dark-auto .example {
background-color: #1a2234;
border-color: #243049;
}
.theme-dark-auto .example-content {
color: #f8fafc;
}
.theme-dark-auto .example-code {
border-color: #243049;
border-top: none;
}
}
}
.card-sponsor {
background: #dbe7f6 no-repeat center/100% 100%;
border-color: #548ed2;
min-height: 316px;
}
body.no-transitions * {
transition: none !important;
}
.dropdown-menu-demo {
display: inline-block;
width: 100%;
position: relative;
top: 0;
margin-bottom: 1rem !important;
}
.demo-icon-preview {
position: -webkit-sticky;
position: sticky;
top: 0;
}
.demo-icon-preview svg,
.demo-icon-preview i {
width: 15rem;
height: 15rem;
font-size: 15rem;
stroke-width: 1.5;
margin: 0 auto;
display: block;
}
@media (max-width: 575.98px) {
.demo-icon-preview svg,
.demo-icon-preview i {
width: 10rem;
height: 10rem;
font-size: 10rem;
}
}
.demo-icon-preview-icon pre {
margin: 0;
-webkit-user-select: all;
-moz-user-select: all;
user-select: all;
}
.demo-dividers > p {
opacity: 0.2;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.demo-icons-list {
display: flex;
flex-wrap: wrap;
padding: 0;
margin: 0 0 -1px -2px;
list-style: none;
}
.demo-icons-list > * {
flex: 1 0 4rem;
}
.demo-icons-list-wrap {
overflow: hidden;
}
.demo-icons-list-item {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
aspect-ratio: 1;
text-align: center;
padding: 0.5rem;
border-left: var(--tblr-border-width) var(--tblr-border-style) var(--tblr-border-color);
border-bottom: var(--tblr-border-width) var(--tblr-border-style) var(--tblr-border-color);
color: inherit;
cursor: pointer;
}
.demo-icons-list-item .icon {
width: 1.5rem;
height: 1.5rem;
font-size: 1.5rem;
}
.demo-icons-list-item:hover {
text-decoration: none;
}
.settings-btn {
position: fixed;
left: -1px;
top: 10rem;
border-top-left-radius: 0;
border-bottom-left-radius: 0;
box-shadow: rgba(var(--tblr-body-color-rgb), 0.04) 0 2px 4px 0;
}
.settings-scheme {
display: inline-block;
border-radius: 50%;
height: 3rem;
width: 3rem;
position: relative;
border: var(--tblr-border-width) var(--tblr-border-style) var(--tblr-border-color);
box-shadow: rgba(var(--tblr-body-color-rgb), 0.04) 0 2px 4px 0;
}
.settings-scheme-light {
background: linear-gradient(-135deg, #ffffff 50%, #f8fafc 50%);
}
.settings-scheme-mixed {
background-image: linear-gradient(-135deg, #1d273b 50%, #fff 50%);
}
.settings-scheme-transparent {
background: #f8fafc;
}
.settings-scheme-dark {
background: #1d273b;
}
.settings-scheme-colored {
background-image: linear-gradient(-135deg, var(--tblr-primary) 50%, #f8fafc 50%);
}

9
cp/public/assets/css/demo.rtl.min.css vendored Normal file
View file

@ -0,0 +1,9 @@
/*!
* Tabler v1.0.0-beta16 (https://tabler.io)
* @version 1.0.0-beta16
* @link https://tabler.io
* Copyright 2018-2022 The Tabler Authors
* Copyright 2018-2022 codecalm.net Paweł Kuna
* Licensed under MIT (https://github.com/tabler/tabler/blob/master/LICENSE)
*/
.highlight pre,pre.highlight{max-height:30rem;margin:1.5rem 0;overflow:auto;border-radius:var(--tblr-border-radius)}.highlight pre::-webkit-scrollbar,pre.highlight::-webkit-scrollbar{width:.5rem;height:.5rem;-webkit-transition:background .3s;transition:background .3s}@media (prefers-reduced-motion:reduce){.highlight pre::-webkit-scrollbar,pre.highlight::-webkit-scrollbar{-webkit-transition:none;transition:none}}.highlight pre::-webkit-scrollbar-thumb,pre.highlight::-webkit-scrollbar-thumb{border-radius:5px;background:rgba(var(--tblr-light-rgb),.16)}.highlight pre::-webkit-scrollbar-track,pre.highlight::-webkit-scrollbar-track{background:rgba(var(--tblr-light-rgb),.06)}.highlight pre:hover::-webkit-scrollbar-thumb,pre.highlight:hover::-webkit-scrollbar-thumb{background:rgba(var(--tblr-light-rgb),.32)}.highlight pre::-webkit-scrollbar-corner,pre.highlight::-webkit-scrollbar-corner{background:0 0}.highlight{margin:0}.highlight code>*{margin:0!important;padding:0!important}.highlight .c,.highlight .c1{color:#a0aec0}.highlight .nc,.highlight .nt,.highlight .nx{color:#ff8383}.highlight .na,.highlight .p{color:#ffe484}.highlight .dl,.highlight .s,.highlight .s2{color:#b5f4a5}.highlight .k{color:#93ddfd}.highlight .mi,.highlight .s1{color:#d9a9ff}.example{padding:2rem;margin:1rem 0 2rem;border:var(--tblr-border-width) var(--tblr-border-style) var(--tblr-border-color);border-radius:3px 3px 0 0;position:relative;min-height:12rem;display:flex;align-items:center;overflow-x:auto}.example-centered{justify-content:center}.example-centered .example-content{flex:0 auto}.example-content{font-size:.875rem;line-height:1.4285714286;color:#1d273b;flex:1;max-width:100%}.example-content .page-header{margin-bottom:0}.example-bg{background:#f1f5f9}.example-code{margin:2rem 0;border:var(--tblr-border-width) var(--tblr-border-style) var(--tblr-border-color);border-top:none}.example-code pre{margin:0;border:0;border-radius:0 0 3px 3px}.example+.example-code{margin-top:-2rem}.example-column{margin:0 auto}.example-column>.card:last-of-type{margin-bottom:0}.example-column-1{max-width:26rem}.example-column-2{max-width:52rem}.example-modal-backdrop{background:#1d273b;opacity:.24;position:absolute;width:100%;right:0;top:0;height:100%;border-radius:2px 2px 0 0}@media not print{.theme-dark .example{background-color:#1a2234;border-color:#243049}.theme-dark .example-content{color:#f8fafc}.theme-dark .example-code{border-color:#243049;border-top:none}}@media not print{@media (prefers-color-scheme:dark){.theme-dark-auto .example{background-color:#1a2234;border-color:#243049}.theme-dark-auto .example-content{color:#f8fafc}.theme-dark-auto .example-code{border-color:#243049;border-top:none}}}.card-sponsor{background:#dbe7f6 no-repeat center/100% 100%;border-color:#548ed2;min-height:316px}body.no-transitions *{transition:none!important}.dropdown-menu-demo{display:inline-block;width:100%;position:relative;top:0;margin-bottom:1rem!important}.demo-icon-preview{position:-webkit-sticky;position:sticky;top:0}.demo-icon-preview i,.demo-icon-preview svg{width:15rem;height:15rem;font-size:15rem;stroke-width:1.5;margin:0 auto;display:block}@media (max-width:575.98px){.demo-icon-preview i,.demo-icon-preview svg{width:10rem;height:10rem;font-size:10rem}}.demo-icon-preview-icon pre{margin:0;-webkit-user-select:all;-moz-user-select:all;user-select:all}.demo-dividers>p{opacity:.2;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.demo-icons-list{display:flex;flex-wrap:wrap;padding:0;margin:0 0 -1px -2px;list-style:none}.demo-icons-list>*{flex:1 0 4rem}.demo-icons-list-wrap{overflow:hidden}.demo-icons-list-item{display:flex;flex-direction:column;align-items:center;justify-content:center;aspect-ratio:1;text-align:center;padding:.5rem;border-left:var(--tblr-border-width) var(--tblr-border-style) var(--tblr-border-color);border-bottom:var(--tblr-border-width) var(--tblr-border-style) var(--tblr-border-color);color:inherit;cursor:pointer}.demo-icons-list-item .icon{width:1.5rem;height:1.5rem;font-size:1.5rem}.demo-icons-list-item:hover{text-decoration:none}.settings-btn{position:fixed;left:-1px;top:10rem;border-top-left-radius:0;border-bottom-left-radius:0;box-shadow:rgba(var(--tblr-body-color-rgb),.04) 0 2px 4px 0}.settings-scheme{display:inline-block;border-radius:50%;height:3rem;width:3rem;position:relative;border:var(--tblr-border-width) var(--tblr-border-style) var(--tblr-border-color);box-shadow:rgba(var(--tblr-body-color-rgb),.04) 0 2px 4px 0}.settings-scheme-light{background:linear-gradient(-135deg,#fff 50%,#f8fafc 50%)}.settings-scheme-mixed{background-image:linear-gradient(-135deg,#1d273b 50%,#fff 50%)}.settings-scheme-transparent{background:#f8fafc}.settings-scheme-dark{background:#1d273b}.settings-scheme-colored{background-image:linear-gradient(-135deg,var(--tblr-primary) 50%,#f8fafc 50%)}

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,520 @@
/*!
* Tabler v1.0.0-beta16 (https://tabler.io)
* @version 1.0.0-beta16
* @link https://tabler.io
* Copyright 2018-2022 The Tabler Authors
* Copyright 2018-2022 codecalm.net Paweł Kuna
* Licensed under MIT (https://github.com/tabler/tabler/blob/master/LICENSE)
*/
.payment {
width: 3.33332rem;
height: 2rem;
display: inline-block;
background: no-repeat center/100% 100%;
vertical-align: bottom;
font-style: normal;
box-shadow: 0 0 1px 1px rgba(0, 0, 0, 0.1);
border-radius: 2px;
}
.payment-provider-2checkout {
background-image: url("../img/payments/2checkout.svg");
}
.payment-provider-2checkout-dark {
background-image: url("../img/payments/2checkout-dark.svg");
}
.payment-provider-alipay {
background-image: url("../img/payments/alipay.svg");
}
.payment-provider-alipay-dark {
background-image: url("../img/payments/alipay-dark.svg");
}
.payment-provider-amazon {
background-image: url("../img/payments/amazon.svg");
}
.payment-provider-amazon-dark {
background-image: url("../img/payments/amazon-dark.svg");
}
.payment-provider-americanexpress {
background-image: url("../img/payments/americanexpress.svg");
}
.payment-provider-americanexpress-dark {
background-image: url("../img/payments/americanexpress-dark.svg");
}
.payment-provider-applepay {
background-image: url("../img/payments/applepay.svg");
}
.payment-provider-applepay-dark {
background-image: url("../img/payments/applepay-dark.svg");
}
.payment-provider-bancontact {
background-image: url("../img/payments/bancontact.svg");
}
.payment-provider-bancontact-dark {
background-image: url("../img/payments/bancontact-dark.svg");
}
.payment-provider-bitcoin {
background-image: url("../img/payments/bitcoin.svg");
}
.payment-provider-bitcoin-dark {
background-image: url("../img/payments/bitcoin-dark.svg");
}
.payment-provider-bitpay {
background-image: url("../img/payments/bitpay.svg");
}
.payment-provider-bitpay-dark {
background-image: url("../img/payments/bitpay-dark.svg");
}
.payment-provider-blik {
background-image: url("../img/payments/blik.svg");
}
.payment-provider-blik-dark {
background-image: url("../img/payments/blik-dark.svg");
}
.payment-provider-cirrus {
background-image: url("../img/payments/cirrus.svg");
}
.payment-provider-cirrus-dark {
background-image: url("../img/payments/cirrus-dark.svg");
}
.payment-provider-clickandbuy {
background-image: url("../img/payments/clickandbuy.svg");
}
.payment-provider-clickandbuy-dark {
background-image: url("../img/payments/clickandbuy-dark.svg");
}
.payment-provider-coinkite {
background-image: url("../img/payments/coinkite.svg");
}
.payment-provider-coinkite-dark {
background-image: url("../img/payments/coinkite-dark.svg");
}
.payment-provider-dinersclub {
background-image: url("../img/payments/dinersclub.svg");
}
.payment-provider-dinersclub-dark {
background-image: url("../img/payments/dinersclub-dark.svg");
}
.payment-provider-directdebit {
background-image: url("../img/payments/directdebit.svg");
}
.payment-provider-directdebit-dark {
background-image: url("../img/payments/directdebit-dark.svg");
}
.payment-provider-discover {
background-image: url("../img/payments/discover.svg");
}
.payment-provider-discover-dark {
background-image: url("../img/payments/discover-dark.svg");
}
.payment-provider-dotpay {
background-image: url("../img/payments/dotpay.svg");
}
.payment-provider-dotpay-dark {
background-image: url("../img/payments/dotpay-dark.svg");
}
.payment-provider-dwolla {
background-image: url("../img/payments/dwolla.svg");
}
.payment-provider-dwolla-dark {
background-image: url("../img/payments/dwolla-dark.svg");
}
.payment-provider-ebay {
background-image: url("../img/payments/ebay.svg");
}
.payment-provider-ebay-dark {
background-image: url("../img/payments/ebay-dark.svg");
}
.payment-provider-eway {
background-image: url("../img/payments/eway.svg");
}
.payment-provider-eway-dark {
background-image: url("../img/payments/eway-dark.svg");
}
.payment-provider-giropay {
background-image: url("../img/payments/giropay.svg");
}
.payment-provider-giropay-dark {
background-image: url("../img/payments/giropay-dark.svg");
}
.payment-provider-googlewallet {
background-image: url("../img/payments/googlewallet.svg");
}
.payment-provider-googlewallet-dark {
background-image: url("../img/payments/googlewallet-dark.svg");
}
.payment-provider-ingenico {
background-image: url("../img/payments/ingenico.svg");
}
.payment-provider-ingenico-dark {
background-image: url("../img/payments/ingenico-dark.svg");
}
.payment-provider-jcb {
background-image: url("../img/payments/jcb.svg");
}
.payment-provider-jcb-dark {
background-image: url("../img/payments/jcb-dark.svg");
}
.payment-provider-klarna {
background-image: url("../img/payments/klarna.svg");
}
.payment-provider-klarna-dark {
background-image: url("../img/payments/klarna-dark.svg");
}
.payment-provider-laser {
background-image: url("../img/payments/laser.svg");
}
.payment-provider-laser-dark {
background-image: url("../img/payments/laser-dark.svg");
}
.payment-provider-maestro {
background-image: url("../img/payments/maestro.svg");
}
.payment-provider-maestro-dark {
background-image: url("../img/payments/maestro-dark.svg");
}
.payment-provider-mastercard {
background-image: url("../img/payments/mastercard.svg");
}
.payment-provider-mastercard-dark {
background-image: url("../img/payments/mastercard-dark.svg");
}
.payment-provider-mir {
background-image: url("../img/payments/mir.svg");
}
.payment-provider-mir-dark {
background-image: url("../img/payments/mir-dark.svg");
}
.payment-provider-monero {
background-image: url("../img/payments/monero.svg");
}
.payment-provider-monero-dark {
background-image: url("../img/payments/monero-dark.svg");
}
.payment-provider-neteller {
background-image: url("../img/payments/neteller.svg");
}
.payment-provider-neteller-dark {
background-image: url("../img/payments/neteller-dark.svg");
}
.payment-provider-ogone {
background-image: url("../img/payments/ogone.svg");
}
.payment-provider-ogone-dark {
background-image: url("../img/payments/ogone-dark.svg");
}
.payment-provider-okpay {
background-image: url("../img/payments/okpay.svg");
}
.payment-provider-okpay-dark {
background-image: url("../img/payments/okpay-dark.svg");
}
.payment-provider-paybox {
background-image: url("../img/payments/paybox.svg");
}
.payment-provider-paybox-dark {
background-image: url("../img/payments/paybox-dark.svg");
}
.payment-provider-paymill {
background-image: url("../img/payments/paymill.svg");
}
.payment-provider-paymill-dark {
background-image: url("../img/payments/paymill-dark.svg");
}
.payment-provider-payone {
background-image: url("../img/payments/payone.svg");
}
.payment-provider-payone-dark {
background-image: url("../img/payments/payone-dark.svg");
}
.payment-provider-payoneer {
background-image: url("../img/payments/payoneer.svg");
}
.payment-provider-payoneer-dark {
background-image: url("../img/payments/payoneer-dark.svg");
}
.payment-provider-paypal {
background-image: url("../img/payments/paypal.svg");
}
.payment-provider-paypal-dark {
background-image: url("../img/payments/paypal-dark.svg");
}
.payment-provider-paysafecard {
background-image: url("../img/payments/paysafecard.svg");
}
.payment-provider-paysafecard-dark {
background-image: url("../img/payments/paysafecard-dark.svg");
}
.payment-provider-payu {
background-image: url("../img/payments/payu.svg");
}
.payment-provider-payu-dark {
background-image: url("../img/payments/payu-dark.svg");
}
.payment-provider-payza {
background-image: url("../img/payments/payza.svg");
}
.payment-provider-payza-dark {
background-image: url("../img/payments/payza-dark.svg");
}
.payment-provider-przelewy24 {
background-image: url("../img/payments/przelewy24.svg");
}
.payment-provider-przelewy24-dark {
background-image: url("../img/payments/przelewy24-dark.svg");
}
.payment-provider-ripple {
background-image: url("../img/payments/ripple.svg");
}
.payment-provider-ripple-dark {
background-image: url("../img/payments/ripple-dark.svg");
}
.payment-provider-sage {
background-image: url("../img/payments/sage.svg");
}
.payment-provider-sage-dark {
background-image: url("../img/payments/sage-dark.svg");
}
.payment-provider-sepa {
background-image: url("../img/payments/sepa.svg");
}
.payment-provider-sepa-dark {
background-image: url("../img/payments/sepa-dark.svg");
}
.payment-provider-shopify {
background-image: url("../img/payments/shopify.svg");
}
.payment-provider-shopify-dark {
background-image: url("../img/payments/shopify-dark.svg");
}
.payment-provider-skrill {
background-image: url("../img/payments/skrill.svg");
}
.payment-provider-skrill-dark {
background-image: url("../img/payments/skrill-dark.svg");
}
.payment-provider-solo {
background-image: url("../img/payments/solo.svg");
}
.payment-provider-solo-dark {
background-image: url("../img/payments/solo-dark.svg");
}
.payment-provider-square {
background-image: url("../img/payments/square.svg");
}
.payment-provider-square-dark {
background-image: url("../img/payments/square-dark.svg");
}
.payment-provider-stripe {
background-image: url("../img/payments/stripe.svg");
}
.payment-provider-stripe-dark {
background-image: url("../img/payments/stripe-dark.svg");
}
.payment-provider-switch {
background-image: url("../img/payments/switch.svg");
}
.payment-provider-switch-dark {
background-image: url("../img/payments/switch-dark.svg");
}
.payment-provider-tpay {
background-image: url("../img/payments/tpay.svg");
}
.payment-provider-tpay-dark {
background-image: url("../img/payments/tpay-dark.svg");
}
.payment-provider-ukash {
background-image: url("../img/payments/ukash.svg");
}
.payment-provider-ukash-dark {
background-image: url("../img/payments/ukash-dark.svg");
}
.payment-provider-unionpay {
background-image: url("../img/payments/unionpay.svg");
}
.payment-provider-unionpay-dark {
background-image: url("../img/payments/unionpay-dark.svg");
}
.payment-provider-verifone {
background-image: url("../img/payments/verifone.svg");
}
.payment-provider-verifone-dark {
background-image: url("../img/payments/verifone-dark.svg");
}
.payment-provider-verisign {
background-image: url("../img/payments/verisign.svg");
}
.payment-provider-verisign-dark {
background-image: url("../img/payments/verisign-dark.svg");
}
.payment-provider-visa {
background-image: url("../img/payments/visa.svg");
}
.payment-provider-visa-dark {
background-image: url("../img/payments/visa-dark.svg");
}
.payment-provider-webmoney {
background-image: url("../img/payments/webmoney.svg");
}
.payment-provider-webmoney-dark {
background-image: url("../img/payments/webmoney-dark.svg");
}
.payment-provider-westernunion {
background-image: url("../img/payments/westernunion.svg");
}
.payment-provider-westernunion-dark {
background-image: url("../img/payments/westernunion-dark.svg");
}
.payment-provider-worldpay {
background-image: url("../img/payments/worldpay.svg");
}
.payment-provider-worldpay-dark {
background-image: url("../img/payments/worldpay-dark.svg");
}
.payment-xs {
width: 2.49999rem;
height: 1.5rem;
}
.payment-sm {
width: 3.33332rem;
height: 2rem;
}
.payment-md {
width: 6.66664rem;
height: 4rem;
}
.payment-lg {
width: 8.3333rem;
height: 5rem;
}
.payment-xl {
width: 11.66662rem;
height: 7rem;
}
.payment-2xl {
width: 18.33326rem;
height: 11rem;
}

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,520 @@
/*!
* Tabler v1.0.0-beta16 (https://tabler.io)
* @version 1.0.0-beta16
* @link https://tabler.io
* Copyright 2018-2022 The Tabler Authors
* Copyright 2018-2022 codecalm.net Paweł Kuna
* Licensed under MIT (https://github.com/tabler/tabler/blob/master/LICENSE)
*/
.payment {
width: 3.33332rem;
height: 2rem;
display: inline-block;
background: no-repeat center/100% 100%;
vertical-align: bottom;
font-style: normal;
box-shadow: 0 0 1px 1px rgba(0, 0, 0, 0.1);
border-radius: 2px;
}
.payment-provider-2checkout {
background-image: url("../img/payments/2checkout.svg");
}
.payment-provider-2checkout-dark {
background-image: url("../img/payments/2checkout-dark.svg");
}
.payment-provider-alipay {
background-image: url("../img/payments/alipay.svg");
}
.payment-provider-alipay-dark {
background-image: url("../img/payments/alipay-dark.svg");
}
.payment-provider-amazon {
background-image: url("../img/payments/amazon.svg");
}
.payment-provider-amazon-dark {
background-image: url("../img/payments/amazon-dark.svg");
}
.payment-provider-americanexpress {
background-image: url("../img/payments/americanexpress.svg");
}
.payment-provider-americanexpress-dark {
background-image: url("../img/payments/americanexpress-dark.svg");
}
.payment-provider-applepay {
background-image: url("../img/payments/applepay.svg");
}
.payment-provider-applepay-dark {
background-image: url("../img/payments/applepay-dark.svg");
}
.payment-provider-bancontact {
background-image: url("../img/payments/bancontact.svg");
}
.payment-provider-bancontact-dark {
background-image: url("../img/payments/bancontact-dark.svg");
}
.payment-provider-bitcoin {
background-image: url("../img/payments/bitcoin.svg");
}
.payment-provider-bitcoin-dark {
background-image: url("../img/payments/bitcoin-dark.svg");
}
.payment-provider-bitpay {
background-image: url("../img/payments/bitpay.svg");
}
.payment-provider-bitpay-dark {
background-image: url("../img/payments/bitpay-dark.svg");
}
.payment-provider-blik {
background-image: url("../img/payments/blik.svg");
}
.payment-provider-blik-dark {
background-image: url("../img/payments/blik-dark.svg");
}
.payment-provider-cirrus {
background-image: url("../img/payments/cirrus.svg");
}
.payment-provider-cirrus-dark {
background-image: url("../img/payments/cirrus-dark.svg");
}
.payment-provider-clickandbuy {
background-image: url("../img/payments/clickandbuy.svg");
}
.payment-provider-clickandbuy-dark {
background-image: url("../img/payments/clickandbuy-dark.svg");
}
.payment-provider-coinkite {
background-image: url("../img/payments/coinkite.svg");
}
.payment-provider-coinkite-dark {
background-image: url("../img/payments/coinkite-dark.svg");
}
.payment-provider-dinersclub {
background-image: url("../img/payments/dinersclub.svg");
}
.payment-provider-dinersclub-dark {
background-image: url("../img/payments/dinersclub-dark.svg");
}
.payment-provider-directdebit {
background-image: url("../img/payments/directdebit.svg");
}
.payment-provider-directdebit-dark {
background-image: url("../img/payments/directdebit-dark.svg");
}
.payment-provider-discover {
background-image: url("../img/payments/discover.svg");
}
.payment-provider-discover-dark {
background-image: url("../img/payments/discover-dark.svg");
}
.payment-provider-dotpay {
background-image: url("../img/payments/dotpay.svg");
}
.payment-provider-dotpay-dark {
background-image: url("../img/payments/dotpay-dark.svg");
}
.payment-provider-dwolla {
background-image: url("../img/payments/dwolla.svg");
}
.payment-provider-dwolla-dark {
background-image: url("../img/payments/dwolla-dark.svg");
}
.payment-provider-ebay {
background-image: url("../img/payments/ebay.svg");
}
.payment-provider-ebay-dark {
background-image: url("../img/payments/ebay-dark.svg");
}
.payment-provider-eway {
background-image: url("../img/payments/eway.svg");
}
.payment-provider-eway-dark {
background-image: url("../img/payments/eway-dark.svg");
}
.payment-provider-giropay {
background-image: url("../img/payments/giropay.svg");
}
.payment-provider-giropay-dark {
background-image: url("../img/payments/giropay-dark.svg");
}
.payment-provider-googlewallet {
background-image: url("../img/payments/googlewallet.svg");
}
.payment-provider-googlewallet-dark {
background-image: url("../img/payments/googlewallet-dark.svg");
}
.payment-provider-ingenico {
background-image: url("../img/payments/ingenico.svg");
}
.payment-provider-ingenico-dark {
background-image: url("../img/payments/ingenico-dark.svg");
}
.payment-provider-jcb {
background-image: url("../img/payments/jcb.svg");
}
.payment-provider-jcb-dark {
background-image: url("../img/payments/jcb-dark.svg");
}
.payment-provider-klarna {
background-image: url("../img/payments/klarna.svg");
}
.payment-provider-klarna-dark {
background-image: url("../img/payments/klarna-dark.svg");
}
.payment-provider-laser {
background-image: url("../img/payments/laser.svg");
}
.payment-provider-laser-dark {
background-image: url("../img/payments/laser-dark.svg");
}
.payment-provider-maestro {
background-image: url("../img/payments/maestro.svg");
}
.payment-provider-maestro-dark {
background-image: url("../img/payments/maestro-dark.svg");
}
.payment-provider-mastercard {
background-image: url("../img/payments/mastercard.svg");
}
.payment-provider-mastercard-dark {
background-image: url("../img/payments/mastercard-dark.svg");
}
.payment-provider-mir {
background-image: url("../img/payments/mir.svg");
}
.payment-provider-mir-dark {
background-image: url("../img/payments/mir-dark.svg");
}
.payment-provider-monero {
background-image: url("../img/payments/monero.svg");
}
.payment-provider-monero-dark {
background-image: url("../img/payments/monero-dark.svg");
}
.payment-provider-neteller {
background-image: url("../img/payments/neteller.svg");
}
.payment-provider-neteller-dark {
background-image: url("../img/payments/neteller-dark.svg");
}
.payment-provider-ogone {
background-image: url("../img/payments/ogone.svg");
}
.payment-provider-ogone-dark {
background-image: url("../img/payments/ogone-dark.svg");
}
.payment-provider-okpay {
background-image: url("../img/payments/okpay.svg");
}
.payment-provider-okpay-dark {
background-image: url("../img/payments/okpay-dark.svg");
}
.payment-provider-paybox {
background-image: url("../img/payments/paybox.svg");
}
.payment-provider-paybox-dark {
background-image: url("../img/payments/paybox-dark.svg");
}
.payment-provider-paymill {
background-image: url("../img/payments/paymill.svg");
}
.payment-provider-paymill-dark {
background-image: url("../img/payments/paymill-dark.svg");
}
.payment-provider-payone {
background-image: url("../img/payments/payone.svg");
}
.payment-provider-payone-dark {
background-image: url("../img/payments/payone-dark.svg");
}
.payment-provider-payoneer {
background-image: url("../img/payments/payoneer.svg");
}
.payment-provider-payoneer-dark {
background-image: url("../img/payments/payoneer-dark.svg");
}
.payment-provider-paypal {
background-image: url("../img/payments/paypal.svg");
}
.payment-provider-paypal-dark {
background-image: url("../img/payments/paypal-dark.svg");
}
.payment-provider-paysafecard {
background-image: url("../img/payments/paysafecard.svg");
}
.payment-provider-paysafecard-dark {
background-image: url("../img/payments/paysafecard-dark.svg");
}
.payment-provider-payu {
background-image: url("../img/payments/payu.svg");
}
.payment-provider-payu-dark {
background-image: url("../img/payments/payu-dark.svg");
}
.payment-provider-payza {
background-image: url("../img/payments/payza.svg");
}
.payment-provider-payza-dark {
background-image: url("../img/payments/payza-dark.svg");
}
.payment-provider-przelewy24 {
background-image: url("../img/payments/przelewy24.svg");
}
.payment-provider-przelewy24-dark {
background-image: url("../img/payments/przelewy24-dark.svg");
}
.payment-provider-ripple {
background-image: url("../img/payments/ripple.svg");
}
.payment-provider-ripple-dark {
background-image: url("../img/payments/ripple-dark.svg");
}
.payment-provider-sage {
background-image: url("../img/payments/sage.svg");
}
.payment-provider-sage-dark {
background-image: url("../img/payments/sage-dark.svg");
}
.payment-provider-sepa {
background-image: url("../img/payments/sepa.svg");
}
.payment-provider-sepa-dark {
background-image: url("../img/payments/sepa-dark.svg");
}
.payment-provider-shopify {
background-image: url("../img/payments/shopify.svg");
}
.payment-provider-shopify-dark {
background-image: url("../img/payments/shopify-dark.svg");
}
.payment-provider-skrill {
background-image: url("../img/payments/skrill.svg");
}
.payment-provider-skrill-dark {
background-image: url("../img/payments/skrill-dark.svg");
}
.payment-provider-solo {
background-image: url("../img/payments/solo.svg");
}
.payment-provider-solo-dark {
background-image: url("../img/payments/solo-dark.svg");
}
.payment-provider-square {
background-image: url("../img/payments/square.svg");
}
.payment-provider-square-dark {
background-image: url("../img/payments/square-dark.svg");
}
.payment-provider-stripe {
background-image: url("../img/payments/stripe.svg");
}
.payment-provider-stripe-dark {
background-image: url("../img/payments/stripe-dark.svg");
}
.payment-provider-switch {
background-image: url("../img/payments/switch.svg");
}
.payment-provider-switch-dark {
background-image: url("../img/payments/switch-dark.svg");
}
.payment-provider-tpay {
background-image: url("../img/payments/tpay.svg");
}
.payment-provider-tpay-dark {
background-image: url("../img/payments/tpay-dark.svg");
}
.payment-provider-ukash {
background-image: url("../img/payments/ukash.svg");
}
.payment-provider-ukash-dark {
background-image: url("../img/payments/ukash-dark.svg");
}
.payment-provider-unionpay {
background-image: url("../img/payments/unionpay.svg");
}
.payment-provider-unionpay-dark {
background-image: url("../img/payments/unionpay-dark.svg");
}
.payment-provider-verifone {
background-image: url("../img/payments/verifone.svg");
}
.payment-provider-verifone-dark {
background-image: url("../img/payments/verifone-dark.svg");
}
.payment-provider-verisign {
background-image: url("../img/payments/verisign.svg");
}
.payment-provider-verisign-dark {
background-image: url("../img/payments/verisign-dark.svg");
}
.payment-provider-visa {
background-image: url("../img/payments/visa.svg");
}
.payment-provider-visa-dark {
background-image: url("../img/payments/visa-dark.svg");
}
.payment-provider-webmoney {
background-image: url("../img/payments/webmoney.svg");
}
.payment-provider-webmoney-dark {
background-image: url("../img/payments/webmoney-dark.svg");
}
.payment-provider-westernunion {
background-image: url("../img/payments/westernunion.svg");
}
.payment-provider-westernunion-dark {
background-image: url("../img/payments/westernunion-dark.svg");
}
.payment-provider-worldpay {
background-image: url("../img/payments/worldpay.svg");
}
.payment-provider-worldpay-dark {
background-image: url("../img/payments/worldpay-dark.svg");
}
.payment-xs {
width: 2.49999rem;
height: 1.5rem;
}
.payment-sm {
width: 3.33332rem;
height: 2rem;
}
.payment-md {
width: 6.66664rem;
height: 4rem;
}
.payment-lg {
width: 8.3333rem;
height: 5rem;
}
.payment-xl {
width: 11.66662rem;
height: 7rem;
}
.payment-2xl {
width: 18.33326rem;
height: 11rem;
}

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

14
cp/public/assets/css/tabler.min.css vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

14
cp/public/assets/css/tabler.rtl.min.css vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 32 KiB

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="640" height="480"><path fill="#00732f" d="M0 0h640v160H0z"/><path fill="#fff" d="M0 160h640v160H0z"/><path d="M0 320h640v160H0z"/><path fill="red" d="M0 0h220v480H0z"/></svg>

After

Width:  |  Height:  |  Size: 221 B

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 20 KiB

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="640" height="480"><defs><clipPath id="a"><path fill-opacity=".7" d="M-79.7 0H603v512H-79.7z"/></clipPath></defs><g fill-rule="evenodd" clip-path="url(#a)" transform="translate(74.7) scale(.9375)"><path fill="#fff" d="M-120 0h763.3v511.5H-120z"/><path d="M-118.3.6h760.9v216.1h-761z"/><path fill="#0061ff" d="M21.3 203.2h505V317h-505z"/><path fill="#e20000" d="M642.8 1.8V512H262L642.8 1.7zm-761.5 0V512H262L-118.7 1.7z"/><path fill="#ffd600" d="M440.4 203.3L364 184l64.9-49-79.7 11.4 41-69.5-70.7 41L332.3 37l-47.9 63.8-19.3-74-21.7 76.3-47.8-65 13.7 83.2L138.5 78l41 69.5-77.4-12.5 63.8 47.8L86 203.3h354.3z"/></g></svg>

After

Width:  |  Height:  |  Size: 668 B

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 38 KiB

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="640" height="480"><path fill="#e41e20" d="M0 0h640v480H0z"/><path id="a" d="M272 93.3c-4.6 0-12.3 1.5-12.2 5-13-2.1-14.3 3.2-13.5 8 1.2-1.9 2.7-3 3.9-3.1 1.7-.3 3.5.3 5.4 1.4a21.6 21.6 0 0 1 4.8 4.1c-4.6 1.1-8.2.4-11.8-.2a16.5 16.5 0 0 1-5.7-2.4c-1.5-1-2-2-4.3-4.3-2.7-2.8-5.6-2-4.7 2.3 2.1 4 5.6 5.8 10 6.6 2.1.3 5.3 1 8.9 1 3.6 0 7.6-.5 9.8 0-1.3.8-2.8 2.3-5.8 2.8-3 .6-7.5-1.8-10.3-2.4.3 2.3 3.3 4.5 9.1 5.7 9.6 2 17.5 3.6 22.8 6.5a37.3 37.3 0 0 1 10.9 9.2c4.7 5.5 5 9.8 5.2 10.8 1 8.8-2.1 13.8-7.9 15.4-2.8.7-8-.7-9.8-2.9-2-2.2-3.7-6-3.2-12 .5-2.2 3.1-8.3.9-9.5a273.7 273.7 0 0 0-32.3-15.1c-2.5-1-4.5 2.4-5.3 3.8a50.2 50.2 0 0 1-36-23.7c-4.2-7.6-11.3 0-10.1 7.3 1.9 8 8 13.8 15.4 18 7.5 4.1 17 8.2 26.5 8 5.2 1 5.1 7.6-1 8.9-12.1 0-21.8-.2-30.9-9-6.9-6.3-10.7 1.2-8.8 5.4 3.4 13.1 22.1 16.8 41 12.6 7.4-1.2 3 6.6 1 6.7-8 5.7-22.1 11.2-34.6 0-5.7-4.4-9.6-.8-7.4 5.5 5.5 16.5 26.7 13 41.2 5 3.7-2.1 7.1 2.7 2.6 6.4-18.1 12.6-27.1 12.8-35.3 8-10.2-4.1-11 7.2-5 11 6.7 4 23.8 1 36.4-7 5.4-4 5.6 2.3 2.2 4.8-14.9 12.9-20.8 16.3-36.3 14.2-7.7-.6-7.6 8.9-1.6 12.6 8.3 5.1 24.5-3.3 37-13.8 5.3-2.8 6.2 1.8 3.6 7.3a53.9 53.9 0 0 1-21.8 18c-7 2.7-13.6 2.3-18.3.7-5.8-2-6.5 4-3.3 9.4 1.9 3.3 9.8 4.3 18.4 1.3 8.6-3 17.8-10.2 24.1-18.5 5.5-4.9 4.9 1.6 2.3 6.2-12.6 20-24.2 27.4-39.5 26.2-6.7-1.2-8.3 4-4 9 7.6 6.2 17 6 25.4-.2 7.3-7 21.4-22.4 28.8-30.6 5.2-4.1 6.9 0 5.3 8.4-1.4 4.8-4.8 10-14.3 13.6-6.5 3.7-1.6 8.8 3.2 9 2.7 0 8.1-3.2 12.3-7.8 5.4-6.2 5.8-10.3 8.8-19.9 2.8-4.6 7.9-2.4 7.9 2.4-2.5 9.6-4.5 11.3-9.5 15.2-4.7 4.5 3.3 6 6 4.1 7.8-5.2 10.6-12 13.2-18.2 2-4.4 7.4-2.3 4.8 5-6 17.4-16 24.2-33.3 27.8-1.7.3-2.8 1.3-2.2 3.3l7 7c-10.7 3.2-19.4 5-30.2 8l-14.8-9.8c-1.3-3.2-2-8.2-9.8-4.7-5.2-2.4-7.7-1.5-10.6 1 4.2 0 6 1.2 7.7 3.1 2.2 5.7 7.2 6.3 12.3 4.7 3.3 2.7 5 4.9 8.4 7.7l-16.7-.5c-6-6.3-10.6-6-14.8-1-3.3.5-4.6.5-6.8 4.4 3.4-1.4 5.6-1.8 7.1-.3 6.3 3.7 10.4 2.9 13.5 0l17.5 1.1c-2.2 2-5.2 3-7.5 4.8-9-2.6-13.8 1-15.4 8.3a17 17 0 0 0-1.2 9.3c.8-3 2.3-5.5 4.9-7 8 2 11-1.3 11.5-6.1 4-3.2 9.8-3.9 13.7-7.1 4.6 1.4 6.8 2.3 11.4 3.8 1.6 5 5.3 6.9 11.3 5.6 7 .2 5.8 3.2 6.4 5.5 2-3.3 1.9-6.6-2.5-9.6-1.6-4.3-5.2-6.3-9.8-3.8-4.4-1.2-5.5-3-9.9-4.3 11-3.5 18.8-4.3 29.8-7.8l7.7 6.8c1.5.9 2.9 1.1 3.8 0 6.9-10 10-18.7 16.3-25.3 2.5-2.8 5.6-6.4 9-7.3 1.7-.5 3.8-.2 5.2 1.3 1.3 1.4 2.4 4.1 2 8.2-.7 5.7-2.1 7.6-3.7 11-1.7 3.5-3.6 5.6-5.7 8.3-4 5.3-9.4 8.4-12.6 10.5-6.4 4.1-9 2.3-14 2-6.4.7-8 3.8-2.8 8.1 4.8 2.6 9.2 2.9 12.8 2.2 3-.6 6.6-4.5 9.2-6.6 2.8-3.3 7.6.6 4.3 4.5-5.9 7-11.7 11.6-19 11.5-7.7 1-6.2 5.3-1.2 7.4 9.2 3.7 17.4-3.3 21.6-8 3.2-3.5 5.5-3.6 5 1.9-3.3 9.9-7.6 13.7-14.8 14.2-5.8-.6-5.9 4-1.6 7 9.6 6.6 16.6-4.8 19.9-11.6 2.3-6.2 5.9-3.3 6.3 1.8 0 6.9-3 12.4-11.3 19.4 6.3 10.1 13.7 20.4 20 30.5l19.2-214L320 139c-2-1.8-8.8-9.8-10.5-11-.7-.6-1-1-.1-1.4.9-.4 3-.8 4.5-1-4-4.1-7.6-5.4-15.3-7.6 1.9-.8 3.7-.4 9.3-.6a30.2 30.2 0 0 0-13.5-10.2c4.2-3 5-3.2 9.2-6.7a86.3 86.3 0 0 1-19.5-3.8 37.4 37.4 0 0 0-12-3.4zm.8 8.4c3.8 0 6.1 1.3 6.1 2.9 0 1.6-2.3 2.9-6.1 2.9s-6.2-1.5-6.2-3c0-1.6 2.4-2.8 6.2-2.8z"/><use width="100%" height="100%" transform="matrix(-1 0 0 1 640 0)" xlink:href="#a"/></svg>

After

Width:  |  Height:  |  Size: 3.1 KiB

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="640" height="480"><path fill="red" d="M0 0h640v160H0z"/><path fill="#00f" d="M0 160h640v160H0z"/><path fill="orange" d="M0 320h640v160H0z"/></svg>

After

Width:  |  Height:  |  Size: 193 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="640" height="480"><g fill-rule="evenodd" stroke-width="1pt"><path fill="red" d="M0 0h640v243.6H0z"/><path d="M0 236.4h640V480H0z"/></g><path fill="#ffec00" fill-rule="evenodd" d="M228.7 148.2c165.2 43.3 59 255.6-71.3 167.2l-8.8 13.6c76.7 54.6 152.6 10.6 174-46.4 22.2-58.8-7.6-141.5-92.6-150l-1.3 15.6z"/><path fill="#ffec00" fill-rule="evenodd" d="M170 330.8l21.7 10.1-10.2 21.8-21.7-10.2zm149-99.5h24v24h-24zm-11.7-38.9l22.3-8.6 8.7 22.3-22.3 8.7zm-26-29.1l17.1-16.9 16.9 17-17 16.9zm-26.2-39.8l22.4 8.4-8.5 22.4-22.4-8.4zM316 270l22.3 8.9-9 22.2-22.2-8.9zm-69.9 70l22-9.3 9.5 22-22 9.4zm-39.5 2.8h24v24h-24zm41.3-116l-20.3-15-20.3 14.6 8-23-20.3-15h24.5l8.5-22.6 7.8 22.7 24.7-.3-19.6 15.3 7 23.4z"/><path fill="#fe0" fill-rule="evenodd" d="M336 346.4c-1.2.4-6.2 12.4-9.7 18.2l3.7 1c13.6 4.8 20.4 9.2 26.2 17.5a7.9 7.9 0 0 0 10.2.7s2.8-1 6.4-5c3-4.5 2.2-8-1.4-11.1-11-8-22.9-14-35.4-21.3z"/><path fill-rule="evenodd" d="M365.3 372.8a4.3 4.3 0 1 1-8.7 0 4.3 4.3 0 0 1 8.6 0zm-21.4-13.6a4.3 4.3 0 1 1-8.7 0 4.3 4.3 0 0 1 8.7 0zm10.9 7a4.3 4.3 0 1 1-8.7 0 4.3 4.3 0 0 1 8.7 0z"/><path fill="#fe0" fill-rule="evenodd" d="M324.5 363.7c-42.6-24.3-87.3-50.5-130-74.8-18.7-11.7-19.6-33.4-7-49.9 1.2-2.3 2.8-1.8 3.4-.5 1.5 8 6 16.3 11.4 21.5C247 288.4 290 315.8 334 345.6c-3.4 5.8-6 12.3-9.5 18z"/><path fill="#ffec00" fill-rule="evenodd" d="M297.2 305.5l17.8 16-16 17.8-17.8-16z"/><path fill="none" stroke="#000" stroke-width="3" d="M331.5 348.8l-125-75.5m109.6 58.1L274 304.1m18.2 42.7L249.3 322"/></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="640" height="480"><path fill="#3a7dce" fill-rule="evenodd" d="M0 0h640v480H0z"/><path fill="#fff" d="M184.8 225.3c-2.9-5.9-2.9-5.9-2.9-11.8-1.4 0-1.7.3-2.5 0-.8-.2-1.2 5.5-3.9 4.4-.4-.6 2-4.7-.6-6.4-.8-.5.2-3.9-.2-5.4 0 0-3.3 1.8-5.7-4.4-1.3-1.6-3 1.5-3 1.5s.8 1.9-.5 2.3c-1.9-1.4-3.2-.6-5.6-2.5-2.3-2 .5-4.1-4-5.7 3-7.4 3-6 10.2-8.9-4.4-3-4.4-3-7.3-7.4-4.3-1.4-5.7-3-10-5.9-5.8-7.3-8.7-22.1-8.7-32.4 3.6-3.5 8.6 11.8 15.9 16.2l10 4.4c5.8 3 7.3 6 11.6 8.9l13 4.4c5.8 4.4 8.7 10.3 13 11.8 4.7 0 5.6-2.7 7.1-3 8.5-.4 12.8-1.5 14.5-4 1.7-2.2 5.8 1.1 17.4-3.3l-1.5-6s3.1-2.5 7.3-1.4c-.2-2.7-.4-9.9 3.7-13.1-2.5-2.7-.9-4.6-.9-4.6s2.3-2.3 2.6-3.5c-1.2-6.5 1-6.6 1.6-8.5s-2-1.2-1.3-3.9c.7-2.6 4.9-3.2 5.5-5.4.5-2.2-1.2-3.3-1.1-3.8.9-2 .1-7 0-8.9 7.7-2 10.3-8.5 13-5.9 1.4-8.8 2.8-11.8 11.5-11.8 1.2-2.7-3.1-5-1.4-5.9 2.9-.3 5-.2 8.5 4.3 1 1.4 1.2-2 2.3-2.4 1-.4 3.7-.4 4-2.2.5-1.8 1-4.1 2.5-7 1.2-2.5 2.2.9 3.2 5.6 6.1.2 19.9 1.6 25.7 3.2 4.3 1.1 7.2-1.2 11.3-1.6 3.1 3.1 6 .8 7.6 7.5 2.3 3.6 6 .3 6.9 1.3 4.8 13.6 21.4 4.5 22.7 4.7 2 0 4.7 6 6.3 6 2.8-.5 2-2.4 4.4-1.7-.7 5.2 4.6 11 4.6 14.9 0 0 1.3.6 2.5-.5s2.3-4 3.3-4l6.5 1.2c7.8 2.8 11.8 3.4 14.8 4.8 1.5 2.6 2.8 4 5.7 3.5 2.4 1.6.6 3.8 2 3.9 3-1.5 3.9-3.1 6.8-1.6a17.6 17.6 0 0 1 7.2 7.4c0 1.4-1.5 7.3 0 16.2.7 3 1 5.3 4.1 10.3-.8 5.3 4 14 4 16.2 0 3-2.4 4.5-3.8 7.5 5.8 4.4 0 11.8-2.9 16.2 21.7 4.4 11.6 13.3 28.9 8.8-4.3 10.4-2.8 9.5 1.5 19.9-8.6 5.9-.2 7.7-6 15-.3.5 3.5 6.5 8.8 6.5-1.4 11.8-5.8 7.4-4.3 25-11.4-.2-6.8 13.3-14.4 11.9.4 8.4 4.3 9.2 2.8 17.7-5.7 1.5-5.7 1.5-8.6 5.9l-4.4-1.5c-1.4 7.4-4.3 8.9 0 16.3H439c-.1 2.5 2.5 3.2 3 5.9-.3 1-8.3 5.7-14.5 5.9-1.6 3.6 4.3 7.5 4 9.3-6.8 1.4-9.8 9.9-9.8 9.9s3.5 1.4 2.9 3c-1.9-1.5-2.9-1.6-5.8-1.6-1.4.4-5 0-8.3 5.8-3.7 1.2-5.5.8-8.3 4.6-1.2-3.7-3 0-5.2 1.4s-5.1 4.9-5.5 4.7c0-1 1.3-4.7 1.3-4.7l-7.2 1.5-.9.1c-.5 0-.4-4.3-1.8-4.1-1.3.1-5.2 5.5-6.6 5.6-1.3.2-1.7-1.7-2.9-1.5-1.1.2-3.4 5.6-4.2 5.8-.8.1-4-3.4-6.8-2.9-14.2 5.1-16.4-10-18.7-1.5-3-1.6-2.4-.7-5.4.1-2 .5-2.1-2.6-3.9-2.5-3.4 0-3.2 3.4-5.1 2.4-1.5-7-10.8-5.7-11.7-8.6-.7-3.1 4-3 5.6-5.2 1.1-3-1.3-4.1 3.5-7 6.2-4.3 2.6-6 3.7-9.2 2-4.6 2-5.8.4-9.9 0 0-4.9-13.2-5.8-13.2-3-.9-3 4.9-7.2 6.4-8.6 3-24-7.5-26.6-7.5-2.4 0-13.7 2.8-13.3-3-1.6 5.6-7.8 1.3-8.2 1.3-5.8 0-3.6 4.6-7.5 4.4-1.7-.6-19.5-1.6-19.5-1.6v3l-11.6-6-10-3c-8.7-2.9-4.4-10.3-18.8-5.8v-9H195c3-17.6 0-8.8-1.4-25l-5.8 1.5c-5.7-8 8-6.5-4.3-11.8 0 0 .2-8.8-2.9-6-.6.4 1.5 4.5 1.5 4.5-11.6-1.5-14.5-4.4-14.5-16.2 0 0 9.5 1.3 8.7 0a73 73 0 0 1-2.8-17.6c-.2-2 8.8-6.8 7-11.5 1.2-.4 4.4-.5 4.4-.5"/><path fill="none" stroke="#fff" stroke-linecap="round" stroke-linejoin="round" stroke-width="2.1" d="M574.6 284.3a3 3 0 0 0 0 2.8c1-1.3.2-1.9 0-2.8z"/><path fill="none" stroke="#fff" stroke-linejoin="round" stroke-width="2" d="M203.3 167.8s-2.4-.3-1.9 1.8c.8-1.7 1.8-1.7 1.9-1.8zm.5-5c-1.3 0-3-.2-2.4 2 .8-1.7 2.4-1.9 2.4-2zm9.1 28.3s2.1-.1 1.6 2c-.8-1.6-1.5-1.9-1.6-2z"/></svg>

After

Width:  |  Height:  |  Size: 2.9 KiB

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="640" height="480"><path fill="#74acdf" d="M0 0h640v480H0z"/><path fill="#fff" d="M0 160h640v160H0z"/><g id="c" transform="translate(-64) scale(.96)"><path id="a" fill="#f6b40e" stroke="#85340a" stroke-width="1.1" d="M396.8 251.3l28.5 62s.5 1.2 1.3.9c.8-.4.3-1.5.3-1.5l-23.7-64m-.7 24.1c-.4 9.4 5.4 14.6 4.7 23-.8 8.5 3.8 13.2 5 16.5 1 3.3-1.3 5.2-.3 5.7s3-2.1 2.4-6.8c-.7-4.6-4.2-6-3.4-16.3.8-10.3-4.2-12.7-3-22"/><use width="100%" height="100%" transform="rotate(22.5 400 250)" xlink:href="#a"/><use width="100%" height="100%" transform="rotate(45 400 250)" xlink:href="#a"/><use width="100%" height="100%" transform="rotate(67.5 400 250)" xlink:href="#a"/><path id="b" fill="#85340a" d="M404.3 274.4c.5 9 5.6 13 4.6 21.3 2.2-6.5-3.1-11.6-2.8-21.2m-7.7-23.8l19.5 42.6-16.3-43.9"/><use width="100%" height="100%" transform="rotate(22.5 400 250)" xlink:href="#b"/><use width="100%" height="100%" transform="rotate(45 400 250)" xlink:href="#b"/><use width="100%" height="100%" transform="rotate(67.5 400 250)" xlink:href="#b"/></g><use width="100%" height="100%" transform="rotate(90 320 240)" xlink:href="#c"/><use width="100%" height="100%" transform="rotate(180 320 240)" xlink:href="#c"/><use width="100%" height="100%" transform="rotate(-90 320 240)" xlink:href="#c"/><circle cx="320" cy="240" r="26.7" fill="#f6b40e" stroke="#85340a" stroke-width="1.4"/><path id="h" fill="#843511" d="M329.1 234.3c-1.8 0-3.6.8-4.6 2.4 2 1.9 6.6 2 9.7-.2a7 7 0 0 0-5.1-2.2zm0 .4c1.7 0 3.4.8 3.6 1.6-2 2.3-5.3 2-7.4.4a4.3 4.3 0 0 1 3.8-2z"/><use width="100%" height="100%" transform="matrix(-1 0 0 1 640.2 0)" xlink:href="#d"/><use width="100%" height="100%" transform="matrix(-1 0 0 1 640.2 0)" xlink:href="#e"/><use width="100%" height="100%" transform="translate(18.1)" xlink:href="#f"/><use width="100%" height="100%" transform="matrix(-1 0 0 1 640.2 0)" xlink:href="#g"/><path fill="#85340a" d="M316 243.7a1.9 1.9 0 1 0 1.8 2.9 4 4 0 0 0 2.2.6h.2a3.9 3.9 0 0 0 2.3-.6 1.9 1.9 0 1 0 1.8-3c.5.3.8.7.8 1.3 0 .6-.5 1.2-1.2 1.2a1.2 1.2 0 0 1-1.2-1.2 3 3 0 0 1-2.6 1.7 3 3 0 0 1-2.5-1.7 1.2 1.2 0 0 1-1.3 1.2c-.6 0-1.2-.6-1.2-1.2s.3-1 .8-1.2zm2 5.5c-2.1 0-3 1.8-4.8 3 1-.4 1.9-1.2 3.3-2s2.7.2 3.5.2c.8 0 2-1 3.5-.2 1.4.8 2.3 1.6 3.3 2-1.9-1.2-2.7-3-4.8-3a5.5 5.5 0 0 0-2 .6 5.5 5.5 0 0 0-2-.7z"/><path fill="#85340a" d="M317.2 251.6c-.8 0-1.8.2-3.4.6 3.7-.8 4.5.5 6.2.5 1.6 0 2.4-1.3 6.1-.5-4-1.2-4.9-.4-6.1-.4-.8 0-1.4-.3-2.8-.2z"/><path fill="#85340a" d="M314 252.2h-.8c4.3.5 2.3 3 6.8 3s2.5-2.5 6.8-3c-4.5-.4-3.1 2.3-6.8 2.3-3.5 0-2.4-2.3-6-2.3zm9.7 6.7a3.7 3.7 0 0 0-7.4 0 3.8 3.8 0 0 1 7.4 0z"/><path id="e" fill="#85340a" d="M303.4 234.3c4.7-4.1 10.7-4.8 14-1.7a8 8 0 0 1 1.5 3.5c.4 2.3-.3 4.8-2.1 7.4l.8.4a14.6 14.6 0 0 0 1.6-9.4 13.3 13.3 0 0 0-.6-2.3c-4.5-3.7-10.7-4-15.2 2z"/><path id="d" fill="#85340a" d="M310.8 233c2.7 0 3.3.7 4.5 1.7 1.2 1 1.9.8 2 1 .3.2 0 .8-.3.6-.5-.2-1.3-.6-2.5-1.6s-2.5-1-3.7-1c-3.7 0-5.7 3-6.2 2.8-.3-.2 2.1-3.5 6.2-3.5z"/><use width="100%" height="100%" transform="translate(-18.4)" xlink:href="#h"/><circle id="f" cx="310.9" cy="236.3" r="1.9" fill="#85340a"/><path id="g" fill="#85340a" d="M305.9 237.5c3.5 2.7 7 2.5 9 1.3 2-1.3 2-1.7 1.6-1.7-.4 0-.8.4-2.4 1.3-1.7.8-4.1.8-8.2-.9z"/></svg>

After

Width:  |  Height:  |  Size: 3.2 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 7.7 KiB

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="640" height="480"><g fill-rule="evenodd"><path fill="#fff" d="M640 480H0V0h640z"/><path fill="#df0000" d="M640 480H0V320h640zm0-319.9H0V.1h640z"/></g></svg>

After

Width:  |  Height:  |  Size: 203 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="640" height="480"><g stroke-width="1pt"><path fill="#006" d="M0 0h640v480H0z"/><path fill="#fff" d="M0 0v28l307 222h38.7v-28L38.7 0H0zm345.7 0v28l-307 222H0v-28L307 0h38.7z"/><path fill="#fff" d="M144 0v250h57.6V0H144zM0 83.3v83.4h345.7V83.3H0z"/><path fill="#c00" d="M0 100v50h345.7v-50H0zM155.6 0v250H190V0h-34.5zM0 250l115.2-83.3H141L25.8 250H0zM0 0l115.2 83.3H89.5L0 18.6V0zm204.7 83.3L319.9 0h25.8L230.5 83.3h-25.8zm141 166.7l-115.2-83.3h25.7l89.5 64.7V250z"/><path fill="#fff" fill-rule="evenodd" d="M299.8 392.5l-43.7 3.8 6 43.4L232 408l-30.1 31.7 6-43.4-43.7-3.8 37.7-22.3-24.3-36.5 41 15.5 13.4-41.7 13.5 41.7 41-15.5-24.3 36.5m224.4 62.3L476 416.7l17.8 6.7 5.8-18.1 5.8 18.1 17.8-6.7-10.5 15.8 16.4 9.7-19 1.7 2.6 18.9-13-13.9-13.2 13.9 2.6-18.9-19-1.6m16.4-291.9L476 134.6l17.8 6.7 5.8-18.1 5.8 18.1 17.8-6.7-10.5 15.8 16.4 9.8-19 1.6 2.6 18.9-13-13.8-13.2 13.7 2.6-18.8-19-1.6M380.8 265l-10.5-15.8 17.8 6.7 5.8-18.1 5.9 18.1 17.8-6.7L407 265l16.4 9.7-19 1.7 2.7 18.9-13.2-13.9-13 13.9 2.5-18.9-19-1.6m216.3-38L570 221l17.8 6.7 5.8-18.1 5.9 18.1 17.8-6.7-10.5 15.8 16.3 9.7-19 1.7 2.6 18.8-13-13.8-13.2 13.8 2.6-18.8-19-1.7M542 320l-10.3 6.5 2.9-11.9-9.3-7.8 12.1-1 4.6-11.2 4.7 11.3 12.1.9-9.3 7.8 2.9 11.9"/></g></svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 9.1 KiB

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="640" height="480"><defs><clipPath id="a"><path fill-opacity=".7" d="M106.3 0h1133.3v850H106.3z"/></clipPath></defs><g clip-path="url(#a)" transform="matrix(.56472 0 0 .56482 -60 -.1)"><path fill="#0053a5" d="M0 0h1300v850H0z"/><g fill="#ffce00"><path d="M400 0h250v850H400z"/><path d="M0 300h1300v250H0z"/></g><g fill="#d21034"><path d="M475 0h100v850H475z"/><path d="M0 375h1300v100H0z"/></g></g></svg>

After

Width:  |  Height:  |  Size: 450 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="640" height="480"><path fill="#3f9c35" d="M.1 0h640v480H.1z"/><path fill="#ed2939" d="M.1 0h640v320H.1z"/><path fill="#00b9e4" d="M.1 0h640v160H.1z"/><circle cx="304" cy="240" r="72" fill="#fff"/><circle cx="320" cy="240" r="60" fill="#ed2939"/><path fill="#fff" d="M384 200l7.7 21.5 20.6-9.8-9.8 20.7L424 240l-21.5 7.7 9.8 20.6-20.6-9.8L384 280l-7.7-21.5-20.6 9.8 9.8-20.6L344 240l21.5-7.7-9.8-20.6 20.6 9.8L384 200z"/></svg>

After

Width:  |  Height:  |  Size: 473 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="640" height="480"><defs><clipPath id="a"><path fill-opacity=".7" d="M-85.3 0h682.6v512H-85.3z"/></clipPath></defs><g fill-rule="evenodd" clip-path="url(#a)" transform="translate(80) scale(.9375)"><path fill="#009" d="M-85.3 0h682.6v512H-85.3V0z"/><path fill="#FC0" d="M56.5 0l511 512.3V.3L56.5 0z"/><path fill="#FFF" d="M439.9 481.5L412 461.2l-28.6 20.2 10.8-33.2-28.2-20.5h35l10.8-33.2 10.7 33.3h35l-28 20.7 10.4 33zm81.3 10.4l-35-.1-10.7-33.3-10.8 33.2h-35l28.2 20.5-10.8 33.2 28.6-20.2 28 20.3-10.5-33 28-20.6zM365.6 384.7l28-20.7-35-.1-10.7-33.2-10.8 33.2-35-.1 28.2 20.5-10.8 33.3 28.6-20.3 28 20.4-10.5-33zm-64.3-64.5l28-20.6-35-.1-10.7-33.3-10.9 33.2h-34.9l28.2 20.5-10.8 33.2 28.6-20.2 27.9 20.3-10.4-33zm-63.7-63.6l28-20.7h-35L220 202.5l-10.8 33.2h-35l28.2 20.4-10.8 33.3 28.6-20.3 28 20.4-10.5-33zm-64.4-64.3l28-20.6-35-.1-10.7-33.3-10.9 33.2h-34.9L138 192l-10.8 33.2 28.6-20.2 27.9 20.3-10.4-33zm-63.6-63.9l27.9-20.7h-35L91.9 74.3 81 107.6H46L74.4 128l-10.9 33.2L92.1 141l27.8 20.4-10.3-33zm-64-64l27.9-20.7h-35L27.9 10.3 17 43.6h-35L10.4 64l-11 33.3L28.1 77l27.8 20.4-10.3-33zm-64-64L9.4-20.3h-35l-10.7-33.3L-47-20.4h-35L-53.7 0l-10.8 33.2L-35.9 13l27.8 20.4-10.3-33z"/></g></svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="640" height="480"><path fill="#00267f" d="M0 0h640v480H0z"/><path fill="#ffc726" d="M213.3 0h213.4v480H213.3z"/><path id="a" d="M319.8 135.5c-7 19-14 38.6-29.2 53.7 4.7-1.6 13-3 18.2-2.8v79.5l-22.4 3.3c-.8 0-1-1.3-1-3-2.2-24.7-8-45.5-14.8-67-.5-2.9-9-14-2.4-12 .8 0 9.5 3.6 8.2 1.9a85 85 0 0 0-46.4-24c-1.5-.3-2.4.5-1 2.2 22.4 34.6 41.3 75.5 41.1 124 8.8 0 30-5.2 38.7-5.2v56.1H320l2.5-156.7z"/><use width="100%" height="100%" transform="matrix(-1 0 0 1 639.5 0)" xlink:href="#a"/></svg>

After

Width:  |  Height:  |  Size: 577 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="640" height="480"><path fill="#006a4e" d="M0 0h640v480H0z"/><circle cx="280" cy="240" r="160" fill="#f42a41"/></svg>

After

Width:  |  Height:  |  Size: 163 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="640" height="480"><g fill-rule="evenodd" stroke-width="1pt"><path d="M0 0h213.3v480H0z"/><path fill="#ffd90c" d="M213.3 0h213.4v480H213.3z"/><path fill="#f31830" d="M426.7 0H640v480H426.7z"/></g></svg>

After

Width:  |  Height:  |  Size: 248 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="640" height="480"><g fill-rule="evenodd"><path fill="#de0000" d="M640 479.6H.4V0H640z"/><path fill="#35a100" d="M639.6 480H0V240.2h639.6z"/><path fill="#fff300" d="M254.6 276.2l-106-72.4h131L320 86.6 360.4 204l131-.1-106 72.4 40.5 117.3-106-72.6L214 393.4"/></g></svg>

After

Width:  |  Height:  |  Size: 315 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="640" height="480"><g fill-rule="evenodd" stroke-width="1pt"><path fill="#d62612" d="M0 320h640v160H0z"/><path fill="#fff" d="M0 0h640v160H0z"/><path fill="#00966e" d="M0 160h640v160H0z"/></g></svg>

After

Width:  |  Height:  |  Size: 244 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="640" height="480"><defs><clipPath id="a"><path fill-opacity=".7" d="M0 0h640v480H0z"/></clipPath></defs><g fill-rule="evenodd" stroke-width="1pt" clip-path="url(#a)"><path fill="#e10011" d="M-32.5 0h720v480h-720z"/><path fill="#fff" d="M114.3 479.8l-146.8.2V0h146l94.3 30.4-93.5 29.5 93.5 30.5-93.5 29.5 93.5 30.5-93.5 29.5 93.5 30.5-93.5 29.5 93.5 30.5-93.5 29.5 93.5 30.5-93.5 29.5 93.5 30.5-93.5 29.5 93.5 30.5-93.5 29.5"/></g></svg>

After

Width:  |  Height:  |  Size: 483 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="640" height="480"><defs><clipPath id="a"><path fill-opacity=".7" d="M-90.5 0H592v512H-90.5z"/></clipPath></defs><g fill-rule="evenodd" clip-path="url(#a)" transform="translate(84.9) scale(.9375)"><path fill="#00cf00" d="M-178 0l428.8 256L-178 512zm857.6 0L250.8 256l428.8 256z"/><path fill="red" d="M-178 0l428.8 256L679.6 0zm0 512l428.8-256 428.8 256z"/><path fill="#fff" d="M679.6 0h-79.9L-178 464.3V512h79.9L679.6 47.7z"/><path fill="#fff" d="M398.9 256a148 148 0 1 1-296.1 0 148 148 0 0 1 296 0z"/><path fill="#fff" d="M-178 0v47.7L599.7 512h79.9v-47.7L-98.1 0z"/><path fill="red" stroke="#00de00" stroke-width="3.9" d="M280 200.2l-19.3.3-10 16.4-9.9-16.4-19.2-.4 9.3-16.9-9.2-16.8 19.2-.4 10-16.4 9.9 16.5 19.2.4-9.3 16.8zm-64.6 111.6l-19.2.3-10 16.4-9.9-16.4-19.2-.4 9.3-16.9-9.2-16.8 19.2-.4 10-16.4 9.9 16.5 19.2.4-9.3 16.8zm130.6 0l-19.2.3-10 16.4-10-16.4-19.1-.4 9.3-16.9-9.3-16.8 19.2-.4 10-16.4 10 16.5 19.2.4-9.4 16.8z"/></g></svg>

After

Width:  |  Height:  |  Size: 991 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="640" height="480"><defs><clipPath id="a"><path fill="gray" d="M67.6-154h666v666h-666z"/></clipPath></defs><g clip-path="url(#a)" transform="matrix(.961 0 0 .7207 -65 111)"><g fill-rule="evenodd" stroke-width="1pt"><path fill="#319400" d="M0-154h333v666H0z"/><path fill="#ffd600" d="M333-154h666v333H333z"/><path fill="#de2110" d="M333 179h666v333H333z"/></g></g></svg>

After

Width:  |  Height:  |  Size: 415 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="640" height="480"><g fill-rule="evenodd" stroke-width="1pt"><path fill="#fff" d="M0 0h640v480H0z"/><path fill="#00267f" d="M0 0h213.3v480H0z"/><path fill="#f31830" d="M426.7 0H640v480H426.7z"/></g></svg>

After

Width:  |  Height:  |  Size: 250 B

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 22 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 14 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 109 KiB

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="640" height="480"><path fill="#21468b" d="M0 0h640v480H0z"/><path fill="#fff" d="M0 0h640v320H0z"/><path fill="#ae1c28" d="M0 0h640v160H0z"/></svg>

After

Width:  |  Height:  |  Size: 194 B

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 7.8 KiB

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="640" height="480"><defs><clipPath id="a"><path fill-opacity=".7" d="M-12 0h640v480H-12z"/></clipPath></defs><g fill-rule="evenodd" clip-path="url(#a)" transform="translate(12)"><path fill="#fff" d="M968.5 480h-979V1.8h979z"/><path fill="#ffe900" d="M968.5 344.5h-979V143.3h979z"/><path fill="#08ced6" d="M968.5 480h-979V320.6h979zm0-318.7h-979V2h979z"/><path d="M-11 0c2.3 0 391.8 236.8 391.8 236.8L-12 479.2-10.9 0z"/></g></svg>

After

Width:  |  Height:  |  Size: 476 B

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 24 KiB

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="640" height="480"><defs><clipPath id="a"><path fill-opacity=".7" d="M0 0h640v480H0z"/></clipPath></defs><g fill-rule="evenodd" stroke-width="1pt" clip-path="url(#a)"><path fill="#fff" d="M-28 0h699.7v512H-28z"/><path fill="#d72828" d="M-53-77.8h218.7v276.2H-53zM289.4-.6h381v199h-381zM-27.6 320h190.4v190.3H-27.6zm319.6 2.1h378.3v188.2H292z"/><path fill="#003897" d="M196.7-25.4H261v535.7h-64.5z"/><path fill="#003897" d="M-27.6 224.8h698v63.5h-698z"/></g></svg>

After

Width:  |  Height:  |  Size: 509 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="640" height="480"><g fill-rule="evenodd"><path fill="#00cbff" d="M0 0h640v480H0z"/><path fill="#fff" d="M0 160h640v160H0z"/><path d="M0 186h640v108H0z"/></g></svg>

After

Width:  |  Height:  |  Size: 210 B

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 5.7 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 45 KiB

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="640" height="480"><path fill="#fff" d="M150.131 0h339.656v480H150.132z"/><path fill="#bf0a30" d="M-19.65 0h169.781v480H-19.65zm509.438 0h169.78v480H489.882zm-288.75 231.938l-13.313 4.5 61.406 53.906c4.688 13.781-1.593 17.812-5.625 25.125l66.563-8.438-1.594 67.031 13.875-.375-3.094-66.562 66.75 7.969c-4.125-8.719-7.781-13.313-4.031-27.188l61.313-51.094-10.688-3.937c-8.813-6.75 3.75-32.531 5.625-48.844 0 0-35.719 12.281-38.063 5.813l-9.187-17.532-32.531 35.813c-3.563.844-5.063-.563-5.906-3.563l15-74.812-23.813 13.406c-1.969.938-3.938.188-5.25-2.156l-22.969-45.938-23.625 47.72c-1.781 1.687-3.562 1.874-5.062.75l-22.688-12.75 13.688 74.155c-1.125 3-3.75 3.75-6.75 2.157L239.85 171.75c-4.031 6.562-6.75 17.156-12.187 19.594-5.344 2.25-23.438-4.5-35.532-7.125 4.125 14.906 17.063 39.656 8.907 47.812z"/></svg>

After

Width:  |  Height:  |  Size: 857 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="640" height="480"><defs><path id="a" d="M0-360l69.4 215.8 212-80.3L156-35.6 351 80.1 125 99.8l31.1 224.6L0 160l-156.2 164.3 31.1-224.5L-351 80l195-115.7-125.5-188.9 212 80.3z"/><path id="b" d="M0-210L54.9-75.5l144.8 10.6-111 93.8 34.7 141L0 93.3-123.4 170l34.6-141-111-93.8 145-10.6z"/></defs><path fill="green" d="M0 0h640v480H0z"/><circle cx="320" cy="240" r="66.7" fill="#ffe000"/><circle cx="340.8" cy="240" r="54.9" fill="green"/><circle cx="109.8" cy="173.3" r="69.8" fill="#ffe000"/><path fill="#802000" stroke="#7b3100" stroke-width="1.5" d="M105 226h17.5s.7-1.6-.2-2.4c-1-.8-4.7-1-3.7-3.8 2-5.8 2.4-4 3.7-17.8 1.3-13.8 2-35.5 2-35.5h-2.6s.5 6.7-1 15.5c-1.4 8.8-1.9 9.5-3.5 16.3-1.6 6.7-1.8 7.3-3.3 11.2-1.4 4-1.6 4.1-3.8 7.8-2.3 3.6-1.5 2.2-2.7 4.4-.7 1.1-1.4.8-1.9 1.6-.4.8-.5 2.7-.5 2.7z"/><path fill="green" d="M118.3 122.5c.2 2.7-.1 6.3-1.2 9.2-1.2 3.2-2.4 6.5-2.3 9.8-1.8.6-3.7-3.9-5.5-1.2 1.3 3.7 4.4 6.6 6.4 9.9.4 1 3.4 3.7 1.6 4.3-4.3-1.5-5.4-7-8-10.3a19 19 0 0 0-15.5-10c-2.5.1-10.4-.5-8.4 3.7 3 2 6.8 3.4 9.8 5.7 2.3.2 6.3 4 6.1 5.4-4-1.6-5.8-3.5-10-5.2-5.8-2.2-13.7-.9-17 4.8-.5 1.5-1.4 5.8.5 6.3 2.2-3.4 5.3-7.3 9.9-6.2 3.6.3-4 6.7-1.1 5.4 1-.4 3-1.8 4.6-2 1.5 0 2.3 1 3.4 1.2 2.3.3 3 1.2 2.7 1.8-.2.6-1 0-3.3.8-1.1.4-1.7 1.4-3 1.9-1.4.4-4.2.5-5.2 0-3.7-1.5-9.7-1.3-10.8 3.3 0 2-1.8-.2-2.6.7-.7 2.2-.8 4.4-4 4.2-2 2-4 4.2-6.6 5.7 1.5 3.4 7.3-3.4 7-.5-2.5 3.5 1.4 4.2 3 1.5 2.9-3 6.5-6.7 10.7-3.6 2 1.9 3.2-1 4.7-1 1 2.5 2.1.2 3.2-.5 1.7-.2 1.2 2.2 3.2.7 4.1-2.7 9.1-.4 13.1-3 4.3-2 .6 1.5-.5 2.9-1.9 3.6-.3 8.4-4.3 10.6-1.7 4.3 1.9 10-1.7 13.2-.5 2 4.6 1.8 6 2.6 2.6 0 0-5.8 2.5-6.6 3.4 2 3.2-3.8 2.5-5.6.4-4 .6-8.6 2.6-12.3 2.2-4.5 4.2 1.9 1.8 3.7-1.4 4.1-3.4 9.4-.3 13.3 1 .2 1.7 2.4 2.8 3 1.2.7 2.8-.1 3-2.1 1.6-6 .8-12.4 3-18.3 1.5-1.8 3.6-.3 4.5 1.4 3 3.5 5.1 7.8 8.7 10.7 3.3 1.5 6.3 3.9 7.8 7.3 0 2.6 7.4 3 5.2 0-2.1-2.7-.7-5.6 1.4-7.5 1.2.3.9-1.8 0-1-1.5-.3-1.6-3 .4-1.7 3.5 1.1-.2-2.5-1.5-2.6-2.9-1.8-6.2-3.8-7.6-7 3.8 0 7.7 2.1 11.5.9 3.1-1.6 6.2 0 7.3 2.8 2.4-.4 1.4-2.8 0-3.6 1.7-.7 3-2.2.8-3.5-1-1.4 1.5-4-1.7-3.8.1-2.5-.8-4.7-3.5-5.6-2.7-2.2-10.6 3.4-10.3-1.7-.8-2.8 3.2-.4 4.3-1.8 1.1-3-5.5-2.6-3.3-5 1.4-.8 8.1-2.1 2.9-3.1a8.3 8.3 0 0 1-7-1.1c-1.9 3.1-7.2-1.8-6.3 3.8-.7 2.1-5.5 7.6-6.8 3.4 1-3.3 6.8-4.3 5-8.8-.3-2.7-2.6.5-3.6.3-.6-1.7 1.6-3.8 3.2-4.2 3 2.4 3-3 6-2.5 2.1-.5-.7-1.4-1.3-1.8.6-1.5 3.9-2.3.7-3.7-2.9-2-5 2.1-7.3 2.3-2.2-2.5 2-3.7 3.2-5 .1-1-2.4-.3-1.7-1.2.7-1.1 5.2-1.2 3-3a14.7 14.7 0 0 0-10.2.6c-2 .6-2.5 5-4.2 4.8-.7-2 .3-5.8-2.4-6.3zm15 42.3c2.4-.4 0 3.7-1 3.6 0-1.4-3.6-1.3-1.3-2.6a7.3 7.3 0 0 1 2.3-1z"/><g fill="#ffe000" transform="translate(0 80) scale(.0635)"><use width="100%" height="100%" x="7560" y="4200" xlink:href="#a"/><use width="100%" height="100%" x="6300" y="2205" xlink:href="#a"/><use width="100%" height="100%" x="7560" y="840" xlink:href="#a"/><use width="100%" height="100%" x="8680" y="1869" xlink:href="#a"/><use width="100%" height="100%" x="8064" y="2730" xlink:href="#b"/></g></svg>

After

Width:  |  Height:  |  Size: 3 KiB

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="640" height="480"><path fill="#007fff" d="M0 0h640v480H0z"/><path fill="#f7d618" d="M28.8 96H96l20.8-67.2L137.6 96h67.2l-54.4 41.6 20.8 67.2-54.4-41.6-54.4 41.6 20.8-67.2L28.8 96zM600 0L0 360v120h40l600-360V0h-40"/><path fill="#ce1021" d="M640 0L0 384v96L640 96V0"/></svg>

After

Width:  |  Height:  |  Size: 319 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="640" height="480"><defs><clipPath id="a"><path fill-opacity=".7" d="M-12.4 32h640v480h-640z"/></clipPath></defs><g fill-rule="evenodd" clip-path="url(#a)" transform="translate(12.4 -32)"><path fill="#00f" d="M-52 32h719.3v119H-52z"/><path fill="#ff0" d="M-52 391.6h719.3V512H-52z"/><path fill="#009a00" d="M-52 271.3h719.3v120.3H-52z"/><path fill="#fff" d="M-52 151h719.3v120.3H-52z"/><path fill="red" d="M247.7 32.5h119.9V512H247.7z"/><path fill="#ff0" d="M99.3 137.7l-31.5-21.8-31.3 22L47.4 101 16.9 78l38.2-1 12.5-36.3L80.3 77l38.1.7L88.2 101"/></g></svg>

After

Width:  |  Height:  |  Size: 605 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="640" height="480"><defs><clipPath id="a"><path fill-opacity=".7" d="M-79.5 32h640v480h-640z"/></clipPath></defs><g fill-rule="evenodd" stroke-width="1pt" clip-path="url(#a)" transform="translate(79.5 -32)"><path fill="#ff0" d="M-119.5 32h720v480h-720z"/><path fill="#00ca00" d="M-119.5 32v480l480-480h-480z"/><path fill="red" d="M120.5 512h480V32l-480 480z"/></g></svg>

After

Width:  |  Height:  |  Size: 416 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="640" height="480"><g fill-rule="evenodd" stroke-width="1pt"><path fill="#d52b1e" d="M0 0h640v480H0z"/><g fill="#fff"><path d="M170 195h300v90H170z"/><path d="M275 90h90v300h-90z"/></g></g></svg>

After

Width:  |  Height:  |  Size: 241 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="640" height="480"><g fill-rule="evenodd"><path fill="#00cd00" d="M426.8 0H640v480H426.8z"/><path fill="#ff9a00" d="M0 0h212.9v480H0z"/><path fill="#fff" d="M212.9 0h214v480h-214z"/></g></svg>

After

Width:  |  Height:  |  Size: 238 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="640" height="480"><path fill="#006" d="M0 0h640v480H0z"/><g stroke-width="1pt"><path fill="#fff" d="M0 0v24.8L319.8 222H360v-24.8L40.2 0H0zm360 0v24.8L40.2 222H0v-24.8L319.8 0H360z"/><path fill="#fff" d="M150 0v222h60V0h-60zM0 74v74h360V74H0z"/><path fill="#c00" d="M0 88.8v44.4h360V88.8H0zM162 0v222h36V0h-36zM0 222l120-74h26.8l-120 74H0zM0 0l120 74H93.2L0 16.5V0zm213.2 74l120-74H360L240 74h-26.8zM360 222l-120-74h26.8l93.2 57.4v16.5z"/></g><path fill="#fff" fill-rule="evenodd" d="M471.6 213l5.2-16.7-14-10.6 17.6-.2 6-16.5 5.6 16.5 17.7.5-14.1 10.5 5 16.7-14.5-10m27.1 13l10.4-13.9-9.7-14.8 16.7 5.8 11-13.5v17.6l16.4 6.4-16.8 5-.8 17.5-10.2-14.4m-98.4 15l-.7-17.5-16.8-5.2L431 198v-17.4l10.9 13.5 16.8-5.6-9.8 14.7 10.3 14-17-4.5m-39.6 40.9l-7.4-15.8-17.4 1.8 12.8-12.3L384 211l15.2 8.2 13.3-11.8-3.4 17.4 14.9 8.9-17.3 2.5M389 291.8l-13.3-11.1-15 9.2 6.4-16.7-12.9-11.6 17.3.7 7-16.4 4.3 17.2 17.2 1.5-14.6 9.8m3.2 60.4l-16.5-4.8-10.1 14.5-.7-17.9-16.4-5.5 16.1-6.2v-18l10.7 14.1 16.4-5.6-9.6 15m29.5 50.8l-17 2.4-3.5 17.4-7.8-16-17.1 1.6 12.2-12.3-7.1-16.4 15.3 8.5 12.8-11.8L393 362m45 38l-15.1 8.2 2.6 17.6-12.7-12.4-15.6 7.6 7.3-15.9-12.3-12.9 17.3 2.6 8-15.5 3.4 17.4m53.8 9l-8.3 15.3 11.7 13.2-17.4-3.3-8.9 15-2.4-17.3-17.2-4 15.8-7.4-1.7-17.5 12.2 12.8m57.4-13.1l-.5 17.4 16.3 6.4-17 5-1.2 17.5-10-14.3-17 4.4 10.8-13.9-9.4-14.7 16.6 5.7M559 209.8l12 12.6 15.9-7.4-8.3 15.8 11.5 13.1-17-2.8-9 15.5L562 239l-17-3.5 15.7-8m34.2 21l5.5 16.6 17.5.3-14.2 10.7 4.7 16.8-14.1-10-14.6 10.1 5.4-16.8-13.8-10.6 17.6-.4m19.5 33.2l-2 17.4 15.7 7.7-17.3 3.6-2.7 17.3-8.7-15.1-17.4 2.9 12-13-8.1-15.5 16 7.2m3 39.8l-7.8 15.6L603 379l-17.4-2.7-8.4 15.3-3-17.3-17.4-3.3 15.6-8-2.3-17.4 12.6 12.3m-9.8 39.1l-14.7 9.2 3.8 17.3-13.5-11.5-15 8.6 6.3-16.3-13.1-12.1 17.4 1.5 7-16 4.4 17.2"/></svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="640" height="480"><defs><clipPath id="a"><path fill-opacity=".7" d="M0 0h682.7v512H0z"/></clipPath></defs><g fill-rule="evenodd" clip-path="url(#a)" transform="scale(.9375)"><path fill="#fff" d="M256 0h512v256H256z"/><path fill="#0039a6" d="M0 0h256v256H0z"/><path fill="#fff" d="M167.8 191.7L128.2 162l-39.5 30 14.7-48.8L64 113.1l48.7-.5L127.8 64l15.5 48.5 48.7.1-39.2 30.4 15 48.7z"/><path fill="#d52b1e" d="M0 256h768v256H0z"/></g></svg>

After

Width:  |  Height:  |  Size: 487 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="640" height="480"><path fill="#007a5e" d="M0 0h213.3v480H0z"/><path fill="#ce1126" d="M213.3 0h213.4v480H213.3z"/><path fill="#fcd116" d="M426.7 0H640v480H426.7z"/><g fill="#fcd116" transform="translate(320 240) scale(7.1111)"><g id="b"><path id="a" d="M0-8L-2.5-.4 1.3.9z"/><use width="100%" height="100%" transform="scale(-1 1)" xlink:href="#a"/></g><use width="100%" height="100%" transform="rotate(72)" xlink:href="#b"/><use width="100%" height="100%" transform="rotate(144)" xlink:href="#b"/><use width="100%" height="100%" transform="rotate(-144)" xlink:href="#b"/><use width="100%" height="100%" transform="rotate(-72)" xlink:href="#b"/></g></svg>

After

Width:  |  Height:  |  Size: 744 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="640" height="480"><defs><path id="a" fill="#ffde00" d="M-.6.8L0-1 .6.8-1-.3h2z"/></defs><path fill="#de2910" d="M0 0h640v480H0z"/><use width="30" height="20" transform="matrix(71.9991 0 0 72 120 120)" xlink:href="#a"/><use width="30" height="20" transform="matrix(-12.33562 -20.5871 20.58684 -12.33577 240.3 48)" xlink:href="#a"/><use width="30" height="20" transform="matrix(-3.38573 -23.75998 23.75968 -3.38578 288 95.8)" xlink:href="#a"/><use width="30" height="20" transform="matrix(6.5991 -23.0749 23.0746 6.59919 288 168)" xlink:href="#a"/><use width="30" height="20" transform="matrix(14.9991 -18.73557 18.73533 14.99929 240 216)" xlink:href="#a"/></svg>

After

Width:  |  Height:  |  Size: 751 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="640" height="480"><g fill-rule="evenodd" stroke-width="1pt"><path fill="#ffe800" d="M0 0h640v480H0z"/><path fill="#00148e" d="M0 240h640v240H0z"/><path fill="#da0010" d="M0 360h640v120H0z"/></g></svg>

After

Width:  |  Height:  |  Size: 247 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="640" height="480"><g fill-rule="evenodd" stroke-width="1pt"><path fill="#0000b4" d="M0 0h640v480H0z"/><path fill="#fff" d="M0 75.4h640v322.3H0z"/><path fill="#d90000" d="M0 157.7h640v157.7H0z"/></g></svg>

After

Width:  |  Height:  |  Size: 251 B

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