33 Commits
Author SHA1 Message Date
Dave Mc Nicoll 81e124b144 - Added getenvonce 2026-06-01 15:23:49 +00:00
Dave Mc Nicoll 9cd6f10d7e - Merged with master done 2026-06-01 15:23:48 +00:00
Dave Mc Nicoll a36dbeeef2 - Fixed conflicts 2026-06-01 15:23:42 +00:00
mcndave 7ed88ec89f - Added createStream methods and fixed multiple errors views 2026-06-01 15:23:11 +00:00
mcndave c6e9bb6a38 - Added MethodNotAllowed interface 2026-06-01 15:23:04 +00:00
Dave Mc Nicoll e934c1a92c -Rebasing 2026-06-01 15:23:04 +00:00
mcndave baf6fdf952 - Added createStream methods and fixed multiple errors views 2026-06-01 15:23:03 +00:00
Dave Mc Nicoll e0da7ae734 - Merged with master done 2026-06-01 15:22:54 +00:00
Dave Mc Nicoll 64f273e65c - Rebased 2026-06-01 15:22:54 +00:00
Dave Mc Nicoll 9031236930 - WIP on ulmus-user mechanics updates 2026-06-01 15:22:54 +00:00
mcndave 7ee4b2d8bb - Added createStream methods and fixed multiple errors views 2026-06-01 15:22:38 +00:00
mcndave 06c4f46486 - Added MethodNotAllowed interface 2026-06-01 15:21:56 +00:00
Dave Mc Nicoll 01d48463b3 - Merged with master done 2026-05-21 15:18:50 +00:00
Dave Mc Nicoll abe94e498f - Fixed conflicts 2026-05-21 15:18:49 +00:00
Dev adfd619c5f - Fixed default view order to 1000 2026-05-21 15:18:04 +00:00
mcndave 16ee06593c - Added createStream methods and fixed multiple errors views 2026-05-21 15:18:03 +00:00
mcndave 5bb5e8ce61 - Added MethodNotAllowed interface 2026-05-21 15:16:58 +00:00
Dave Mc Nicoll fda052d2f3 - Redefined view order 2026-03-03 16:34:41 +00:00
Dave Mc Nicoll dac7acde87 - Fixed email route argument pattern and added getenvonce() method 2026-02-25 19:43:36 +00:00
Dave Mc Nicoll b16b4803c5 -Rebasing 2026-02-25 19:43:32 +00:00
Dev d54d78ccc5 - Default URL in back button 2026-02-25 19:41:00 +00:00
mcndave 9ff4d6c44d - Restored PHP 8.3 compatibility. 2026-02-25 19:41:00 +00:00
mcndave a4b02607f3 - WIP on skeleton 2026-02-25 19:41:00 +00:00
mcndave d74c916558 - Added createStream methods and fixed multiple errors views 2026-02-25 19:40:58 +00:00
Dave Mc Nicoll ca388e8a52 - Merged with master done 2026-02-25 19:40:07 +00:00
mcndave b12fc65ea9 Fixed missing namespace of Factory 2026-02-25 19:39:12 +00:00
mcndave 4b76a387fe - Various fixes bugs and missing code in project's skeleton 2026-02-25 19:39:12 +00:00
Dave Mc Nicoll 1c2ce07179 - Fixed merges of latest master 2025-06-13 19:25:08 +00:00
Dave Mc Nicoll af8b686e3b - WIP on ulmus-user mechanics updates 2025-06-13 19:14:30 +00:00
Dave Mc Nicoll 7a48d707e0 - Reworked ApplicationStrategy to allows better overridding of it's classes 2025-05-26 18:19:43 +00:00
Dave Mc Nicoll 156defddc9 - WIP on Lean's event definition 2025-05-19 17:29:52 +00:00
Dave Mc Nicoll 42f33d9f13 - Added AdapterProxy autoload in ORM 2025-05-12 15:06:47 +00:00
Dave Mc Nicoll 69382f912b - Added Authorize into definition, matching ulmus-user modifications 2025-03-28 13:41:32 +00:00
42 changed files with 508 additions and 139 deletions

No files matched your search

+25 -13
View File
@@ -1,9 +1,13 @@
<?php
use Lean\Factory\HttpFactory;
use Lean\Factory\HttpFactoryInterface;
use Ulmus\User\{Authorize\HeaderAuthentication,
Entity,
use Ulmus\User\{Entity,
Lib\Authenticate,
Lib\Authorize,
Middleware\AuthenticationMiddleware,
Middleware\HeaderAuthenticationMiddleware,
Middleware\PostRequestAuthenticationMiddleware,
Authorize\PostRequestAuthentication};
@@ -12,31 +16,39 @@ use Picea\Picea;
use Storage\{ Cookie, Session };
use Psr\Container\ContainerInterface;
use function DI\{get, autowire, create};
return [
Authorize::class => create(Authorize::class)->constructor(get(Entity\UserInterface::class), get(Session::class), get(Cookie::class), get('authentication.method')),
Authenticate::class => create(Authenticate::class)->constructor(get(Entity\UserInterface::class), get(Session::class), get(Cookie::class), get('authentication.method')),
HeaderAuthenticationMiddleware::class => create(HeaderAuthenticationMiddleware::class)->constructor(get(Entity\UserInterface::class), get('authorize.error')),
AuthenticationMiddleware::class => create(AuthenticationMiddleware::class)->constructor(get(Authorize::class), get('authorize.error')),
PostRequestAuthentication::class => create(PostRequestAuthentication::class)->constructor(get(\Ulmus\User\Lib\Authenticate::class), "email", "email", "password"),
HeaderAuthentication::class => autowire(HeaderAuthentication::class),
PostRequestAuthenticationMiddleware::class => create(PostRequestAuthenticationMiddleware::class)->constructor(get(Entity\UserInterface::class), get('authentication.error'), get(PostRequestAuthentication::class)),
HeaderAuthenticationMiddleware::class => create(HeaderAuthenticationMiddleware::class)->constructor(get(HeaderAuthentication::class)),
PostRequestAuthentication::class => create(PostRequestAuthentication::class)->constructor("email", "email", "password"),
PostRequestAuthenticationMiddleware::class => create(PostRequestAuthenticationMiddleware::class)->constructor(get(PostRequestAuthentication::class)),
'authentication.method' => null,
'authorize.error' => function($c) {
return function(array $errorData) {
return HttpFactory::createJsonResponse($errorData + [
'api.error' => "Authorization failed",
'api.datetime' => (new \DateTime)->format(\DateTime::ISO8601),
], 403);
'authorize.error' => function(ContainerInterface $c) {
return function(array $errorData) use ($c) {
return $c->get(HttpFactoryInterface::class)::createJsonResponse($errorData + [
'api.error' => "Authorization failed",
'api.datetime' => (new \DateTime)->format(\DateTime::ATOM),
], 403);
};
},
'authentication.error' => function($c, Picea $picea) {
return function($message) use ($picea) {
return HttpFactory::createHtmlResponse($picea->renderHtml('lean/error/500', [
return function($message) use ($c, $picea) {
return $c->get(HttpFactoryInterface::class)::createHtmlResponse($picea->renderHtml('lean/error/500', [
'title' => "Authentication failed",
'subtitle' => "",
'message' => $message,
+13 -6
View File
@@ -1,8 +1,6 @@
<?php
use Picea\Picea;
use function DI\autowire, DI\create, DI\get;
use Lean\{ Lean, Routing, Event\RoutingCompileRoutes, Event\RoutingMapRoutes };
use Mcnd\Event;
use Taxus\Taxus;
@@ -11,6 +9,9 @@ use Notes\Route\Attribute\Method\Route;
use Notes\Security\SecurityHandler;
use Psr\Container\ContainerInterface;
use Psr\Http\Message\{ ResponseInterface, ServerRequestInterface };
use Ulmus\User\Entity\UserInterface;
use function DI\autowire, DI\create, DI\get;
return [
Event\EventManager::class => autowire(Event\EventManager::class),
@@ -25,6 +26,7 @@ return [
Event\EventDefinition::class => function($c) {
$extension = $c->has(\Picea\Extension\UrlExtension::class) ? $c->get(\Picea\Extension\UrlExtension::class) : null;
$user = $c->get(UserInterface::class);
return new Event\EventDefinition([
new class($extension) implements RoutingCompileRoutes {
@@ -40,7 +42,12 @@ return [
}
},
new class() implements RoutingMapRoutes {
new class($user) implements RoutingMapRoutes {
public function __construct(
protected UserInterface $user
) {}
public function execute(Routing $routing, ContainerInterface $container, ServerRequestInterface & $request, Route $attribute) : void
{
$class = $attribute->class;
@@ -54,7 +61,7 @@ return [
$securityHandler = $container->get(SecurityHandler::class);
if ( $redirect = $securityHandler->verify($class, $method) ) {
if ( empty($object->user) || ! $object->user->logged ) {
if (! $this->user->loggedIn() ) {
if ($container->has(Session::class)) {
$container->get(Session::class)->set('redirectedFrom', (string)$request->getUri());
}
@@ -64,8 +71,8 @@ return [
}
}
if ( $securityHandler->isLocked($class, $method) && $container->has(Taxus::class) && $container->has(SecurityHandler::class) ) {
if ( $forbidden = $container->get(SecurityHandler::class)->taxus($class, $method, $object->user ?? null) ) {
if ( $securityHandler->isLocked($class, $method) && $container->has(Taxus::class)) {
if ( $forbidden = $securityHandler->taxus($class, $method, $this->user) ) {
$routing->response = $forbidden;
return;
+24 -3
View File
@@ -1,10 +1,13 @@
<?php
use function DI\autowire, DI\create, DI\get;
use Lean\ApplicationStrategy\{ ThrowableHandler, ThrowableHandlerInterface, NotFoundDecoratorInterface, NotFoundDecorator, MethodNotAllowedInterface, };
use Psr\Container\ContainerInterface;
use Psr\Http\Message\ServerRequestInterface;
use Laminas\{ Diactoros\ServerRequestFactory, HttpHandlerRunner\Emitter\EmitterInterface, HttpHandlerRunner\Emitter\SapiEmitter };
use Lean\Factory\{ HttpFactory, HttpFactoryInterface };
use Picea\Picea;
use function DI\{ autowire, create, get };
return [
ServerRequestInterface::class => function ($c) {
@@ -14,4 +17,22 @@ return [
},
EmitterInterface::class => create(SapiEmitter::class),
ThrowableHandlerInterface::class => autowire(ThrowableHandler::class),
NotFoundDecoratorInterface::class => autowire(NotFoundDecorator::class),
# MethodNotAllowedInterface::class => autowire(MethodNotAllowedDecorator::class),
HttpFactoryInterface::class => create(HttpFactory::class),
'error.401' => function(ContainerInterface $c, Picea $picea) {
return $c->get(HttpFactoryInterface::class)::createHtmlResponse($picea->renderHtml("lean/error/401", []), 401);
},
'error.404' => function(ContainerInterface $c, Picea $picea) {
return $c->get(HttpFactoryInterface::class)::createHtmlResponse($picea->renderHtml("lean/error/404", []), 404);
},
'error.500' => function(ContainerInterface $c, Picea $picea) {
return $c->get(HttpFactoryInterface::class)::createHtmlResponse($picea->renderHtml("lean/error/500", []), 500);
}
];
+7 -3
View File
@@ -11,8 +11,12 @@ return [
]),
AdapterProxy::class => function (Psr\Container\ContainerInterface $c) {
return new AdapterProxy(
$c->get(ConnectionAdapter::class),
);
$proxy = new AdapterProxy();
$autoload = $c->get(\Lean\Lean::class)->getConnectionAdapters();
$proxy->push($autoload);
return $proxy;
},
];
+3 -2
View File
@@ -59,7 +59,7 @@ return [
$router = $container->get(Router::class);
foreach([ 'routes.middlewares', 'app.middlewares' ] as $key) {
if ( $container->has($key) ) {
if ($container->has($key)) {
foreach ($container->get($key) as $i => $middleware) {
if ($container->has($middleware)) {
$router->middleware($container->get($middleware));
@@ -68,7 +68,8 @@ return [
}
}
$router->addPatternMatcher('email', '[^@ \t\r\n]+@[^@ \t\r\n]+\.[^@ \t\r\n]+');
$router->addPatternMatcher('email', '[^@ \t\r\n]+@[^@ \t\r\n]+\.[^@ \t\r\n/]+');
$router->addPatternMatcher('ids', '\b\d[\d,]*\b');
$routing = $container->get(Lean\Routing::class);
$routing->registerRoute($container, getenv('URL_BASE'));
+3 -9
View File
@@ -26,7 +26,7 @@ return [
],
[
'path' => implode(DIRECTORY_SEPARATOR, [ $dir, "view", '' ]),
'order' => 99,
'order' => 1000,
],
],
@@ -66,20 +66,14 @@ return [
'routes' => [],
'cronard' => [],
'taxus' => [
'is_dev' => [ ' dev' => "Is a developper of this application or has the same rights" ],
'is_admin' => [ 'admin' => "Can manage almost everything in this application."],
'is_moderator' => [ 'moderator' => "Can moderate this application."],
'is_user' => [ 'user' => "Is an authenticated user."],
'is_anonymous' => [ 'anonymous' => "Is an anonymous user."],
],
],
'lean.autoload' => add([
Lean::class,
]),
\Lean\Factory\HttpFactoryInterface::class => autowire(\Lean\Factory\HttpFactory::class),
Lean::class => autowire(Lean::class),
JavascriptMiddleware::class => create(JavascriptMiddleware::class),
+9
View File
@@ -5,6 +5,15 @@
"week": "week"
},
"interval": {
"years": "{$years} year(s)",
"months": "{$months} month(s)",
"days": "{$days} day(s)",
"hours": "{$hours} hour(s)",
"minutes": "{$minutes} minutes(s)",
"seconds": "{$seconds} second(s)"
},
"month": {
"list": [
"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "Décember"
+9
View File
@@ -4,6 +4,15 @@
"week": "semaine"
},
"interval": {
"years": "{$years} années(s)",
"months": "{$months} mois",
"days": "{$days} jour(s)",
"hours": "{$hours} heure(s)",
"minutes": "{$minutes} minutes(s)",
"seconds": "{$seconds} seconde(s)"
},
"month": {
"list": [
"Janvier", "Février", "Mars", "Avril", "Mai", "Juin", "Juillet", "Août", "Septembre", "Octobre", "Novembre", "Décembre"
Executable → Regular
View File
File renamed without changes.
+26 -2
View File
@@ -8,17 +8,27 @@
],
"minimum-stability": "dev",
"require": {
"php": "^8.2",
"php": "^8.4",
"ext-apcu": "*",
"ext-sodium": "*",
"ext-bcmath": "*",
"ext-json": "*",
"ext-readline": "*",
"league/route": "^5.0.0-dev",
"laminas/laminas-diactoros": "2.24.x-dev",
"laminas/laminas-httphandlerrunner": "2.5.x-dev",
"vlucas/phpdotenv": "^3.4@dev",
"middlewares/whoops": "dev-master",
"ralouphie/getallheaders": "dev-master",
"ralouphie/getallheaders": "3.x",
"guzzlehttp/guzzle": "7.9.x-dev",
"symfony/mailer": "6.3.x-dev",
"league/oauth2-client": "dev-master",
"php-di/php-di": "dev-master",
"league/commonmark": "^2.7@dev",
"assets-package/ace": "dev-master",
"mcnd/dump": "dev-master",
"mcnd/storage": "dev-master",
"mcnd/cli": "dev-master",
"mcnd/event": "dev-master",
"mcnd/ulmus": "dev-master",
"mcnd/ulmus-api": "dev-master",
@@ -27,6 +37,7 @@
"mcnd/picea-ui": "dev-master",
"mcnd/picea-asset": "dev-master",
"mcnd/cronard": "dev-master",
"mcnd/lean-api": "dev-master",
"mcnd/lean-console": "dev-master",
"mcnd/kash": "dev-master",
"mcnd/taxus": "dev-master",
@@ -39,6 +50,10 @@
"type": "vcs",
"url": "https://git.mcnd.ca/mcndave/cronard.git"
},
{
"type": "vcs",
"url": "https://git.mcnd.ca/mcndave/cli.git"
},
{
"type": "vcs",
"url": "https://git.mcnd.ca/mcndave/dump.git"
@@ -51,6 +66,10 @@
"type": "vcs",
"url": "https://git.mcnd.ca/mcndave/lean.git"
},
{
"type": "vcs",
"url": "https://git.mcnd.ca/mcndave/lean-api.git"
},
{
"type": "vcs",
"url": "https://git.mcnd.ca/mcndave/lean-console.git"
@@ -118,6 +137,10 @@
{
"type": "vcs",
"url": "https://git.mcnd.ca/mcndave/negundo-client.git"
},
{
"type": "vcs",
"url": "https://git.mcnd.ca/assets-package/ace.git"
}
],
"autoload": {
@@ -136,6 +159,7 @@
"extra" : {
"lean" : {
"autoload": {
"order": 1000,
"definitions" : [
"meta/definitions/definitions.php",
"meta/definitions/storage.php",
+1 -1
View File
@@ -10,7 +10,7 @@ return [
],
'keys' => (function() {
return explode(',', getenv('KEYS') ?? "") ;
return explode(',', getenvonce('KEYS') ?? "") ;
})(),
'meta' => [
+8 -5
View File
@@ -4,6 +4,7 @@ use function DI\autowire, DI\create, DI\get;
use %NAMESPACE%\Entity;
use Psr\Container\ContainerInterface;
use Psr\Http\Message\ServerRequestInterface;
use Ulmus\Entity\Field\Datetime,
@@ -21,16 +22,18 @@ use TheBugs\Email\{ EmailConfiguration, MailerInterface, SwiftMailer };
use Taxus\{ Taxus, PermissionGrantInterface };
use Lean\Factory\HttpFactoryInterface;
return [
\Ulmus\User\Entity\UserInterface::class => autowire(Entity\User::class),
SecurityHandler::class => create(SecurityHandler::class)->constructor(function() {
return Lean\Factory\HttpFactory::createRedirectResponse(getenv("URL_BASE")."/login");
SecurityHandler::class => create(SecurityHandler::class)->constructor(function(ContainerInterface $c) {
return $c->get(HttpFactoryInterface::class)::createRedirectResponse(getenv("URL_BASE")."/login");
}, get('authentication.unauthorize'), get(Taxus::class)),
'authentication.unauthorize' => function($c, Picea $picea) {
return function($message) use ($picea) {
return Lean\Factory\HttpFactory::createHtmlResponse($picea->renderHtml('lean/error/401', [
'authentication.unauthorize' => function(ContainerInterface $c, Picea $picea) {
return function($message) use ($c, $picea) {
return $c->get(HttpFactoryInterface::class)::createHtmlResponse($picea->renderHtml('lean/error/401', [
'title' => "",
'subtitle' => "",
'message' => $message,
@@ -7,6 +7,10 @@ use function DI\{ autowire, add, create, get };
$dir = dirname(__DIR__, 2);
return [
\%NAMESPACE%\Factory\FormFactoryInterface::class => autowire(\%NAMESPACE%\Factory\FormFactory::class),
\Lean\Api\Factory\MessageFactoryInterface::class => autowire(\%NAMESPACE%\Lib\Message::class),
'%APPKEY%' => [
'picea' => [
'context' => "%ESCAPED_NAMESPACE%\\View",
+10
View File
@@ -1,3 +1,13 @@
<?php
if (! function_exists('getenvonce')) {
function getenvonce(string $name) : array|string|false
{
$value = getenv($name);
unset($_ENV[$name], $_SERVER[$name]);
putenv($name . "=");
return $value;
}
}
return require("env/" . ( getenv('APP_ENV') ?? 'prod' ) . ".php");
+4 -4
View File
@@ -4,7 +4,7 @@ use Picea\Picea;
use Negundo\Client\{ NegundoMiddleware, SoftwareConfig };
use Lean\Factory\HttpFactory;
use Lean\Factory\HttpFactoryInterface;
use Psr\Http\Server\MiddlewareInterface,
Psr\Http\Message\ServerRequestInterface,
@@ -31,11 +31,11 @@ return [
"errorHandler" => create(NegundoMiddleware::class)->constructor(get(SoftwareConfig::class), null, get('app.errorhandler.html')),
'app.errorhandler.html' => function($c, Picea $picea) {
return function(\Throwable $exception) use ($picea) {
'app.errorhandler.html' => function(\Psr\Container\ContainerInterface $c, Picea $picea) {
return function(\Throwable $exception) use ($c, $picea) {
error_log($exception->getMessage());
return HttpFactory::createHtmlResponse($picea->renderHtml('lean/error/500', [
return $c->get(HttpFactoryInterface::class)::createHtmlResponse($picea->renderHtml('lean/error/500', [
'title' => "Une erreur s'est produite lors de l'exécution du script.",
'subtitle' => "Êtes-vous connecté avec le bon compte ?",
'message' => $exception->getMessage(),
+46
View File
@@ -0,0 +1,46 @@
<?php
namespace %NAMESPACE%\Factory;
use Lean\Api\Factory\MessageFactoryInterface;
use Lean\LanguageHandler;
use Picea\Ui\Method\FormContextInterface;
use Picea\Ui\Method\FormInterface;
use Psr\Http\Message\ServerRequestInterface;
use Storage\Session;
use Ulmus\Entity\EntityInterface;
use Ulmus\User\Entity\UserInterface;
use Ulmus\User\Lib\Authenticate;
class FormFactory implements FormFactoryInterface
{
/*
public function __construct(
protected ServerRequestInterface $request,
protected Authenticate $authenticate,
protected Session $session,
protected LanguageHandler $languageHandler,
protected MessageFactoryInterface $messageFactory,
) {}
public function save(EntityInterface $entity): FormInterface
{
return new Form\Save($this->languageHandler, $this->messageFactory, $entity);
}
public function saveContext(? ServerRequestInterface $request = null, ? string $formName = null): FormContextInterface
{
return new Form\SaveContext($request ?: $this->request, $formName);
}
public function delete(EntityInterface $entity): FormInterface
{
return new Form\Delete($this->languageHandler, $this->messageFactory, $entity);
}
public function deleteContext(?ServerRequestInterface $request = null, ?string $formName = null): FormContextInterface
{
return new Lib\FormContext($request, $formName);
}
*/
}
@@ -0,0 +1,25 @@
<?php
namespace %NAMESPACE%\Factory;
use Lean\Api\Factory\MessageFactoryInterface;
use Psr\Http\Message\ServerRequestInterface;
use Picea\Ui\Method\{ FormInterface, FormContextInterface };
use Storage\Session;
use Lean\LanguageHandler;
use Ulmus\Entity\EntityInterface;
use Ulmus\User\Entity\UserInterface;
use Ulmus\User\Lib\Authenticate;
interface FormFactoryInterface
{
/* public function __construct(ServerRequestInterface $request, Authenticate $authenticate, Session $session, LanguageHandler $languageHandler, MessageFactoryInterface $messageFactory,);
public function save(EntityInterface $entity): FormInterface;
public function saveContext(?ServerRequestInterface $request = null, ?string $formName = null): FormContextInterface;
public function delete(EntityInterface $entity): FormInterface;
public function deleteContext(?ServerRequestInterface $request = null, ?string $formName = null): FormContextInterface;*/
}
+28
View File
@@ -0,0 +1,28 @@
<?php
namespace %NAMESPACE%\Lib;
use Picea\Picea;
use Storage\Session;
use Mcnd\Event\EventManager;
use Notes\{ Attribute\Ignore, Route\Attribute\Object\Route, Security\Attribute\Security };
use Ulmus\User\Entity\{ User, UserInterface };
use %NAMESPACE%\{ Entity, Lib, Form, Factory };
#[Security(locked: false)]
#[Route(base: "/api", method: [ "GET", "POST", "PUT", "PATCH", "DELETE", ])]
trait ApiTrait {
use \Lean\ControllerTrait, \Lean\Api\LeanApiTrait {
\Lean\Api\LeanApiTrait::renderMarkdown insteadof \Lean\ControllerTrait;
}
#[Ignore]
public UserInterface $user;
#[Ignore]
protected EventManager $eventManager;
#[Ignore]
protected Factory\FormFactoryInterface $formFactory;
}
-15
View File
@@ -23,19 +23,4 @@ trait ControllerTrait {
#[Ignore]
protected EventManager $eventManager;
#[Ignore]
public function __construct(Picea $picea, Session $session, UserInterface $user, \Notes\Breadcrumb\Breadcrumb $breadcrumb, EventManager $eventManager) {
$this->initializeController($picea, $session, $user, $breadcrumb, $eventManager);
}
#[Ignore]
public function initializeController(Picea $picea, Session $session, UserInterface $user, \Notes\Breadcrumb\Breadcrumb $breadcrumb, EventManager $eventManager) {
$this->picea = $picea;
$this->session = $session;
$this->eventManager = $eventManager;
$this->breadcrumb = $breadcrumb;
$this->user = $user;
}
}
+21 -5
View File
@@ -2,9 +2,10 @@
namespace %NAMESPACE%\Lib;
use Lean\Api\Factory\MessageFactoryInterface;
use Picea\Ui\Method\FormMessage;
class Message implements FormMessage {
class Message implements FormMessage, MessageFactoryInterface {
const MESSAGE_TYPE = [
'success' => [
@@ -34,7 +35,7 @@ class Message implements FormMessage {
public ? string $header = null;
public function __construct(string $message, string $type = "error", ? string $header = null, ? string $class = null)
public function __construct(string $message = "", string $type = "error", ? string $header = null, ? string $class = null)
{
$this->message = $message;
@@ -86,18 +87,33 @@ class Message implements FormMessage {
return $this->type === "error";
}
public static function generateSuccess(string $message, ? string $header = null, ? string $class = null) : self
public static function generateSuccess(string $message, ? string $header = null, ? string $class = null) : MessageFactoryInterface
{
return new static($message, 'success', $header, $class);
}
public static function generateError(string $message, ? string $header = null, ? string $class = null) : self
public static function generateError(string $message, ? string $header = null, ? string $class = null) : MessageFactoryInterface
{
return new static($message, 'error', $header, $class);
}
public static function generateWarning(string $message, ? string $header = null, ? string $class = null) : self
public static function generateWarning(string $message, ? string $header = null, ? string $class = null) : MessageFactoryInterface
{
return new static($message, 'warning', $header, $class);
}
public static function generateInformation(string $message, ?string $header = null, ?string $class = null): MessageFactoryInterface
{
return new static($message, 'information', $header, $class);
}
public static function generateDebug(string $message, ?string $header = null, ?string $class = null): MessageFactoryInterface
{
return new static($message, 'debug', $header, $class);
}
public static function generateTrace(string $message, ?string $header = null, ?string $class = null): MessageFactoryInterface
{
return new static($message, 'trace', $header, $class);
}
}
+3
View File
@@ -22,6 +22,8 @@ class Application
public array $entities;
public array $connectionAdapters;
public array $events;
public array $tellJson;
@@ -68,6 +70,7 @@ class Application
if (is_array($ulmus = $this->data['ulmus'] ?? false)) {
if ($ulmus['entities'] ?? false) {
$this->entities = $ulmus['entities'];
$this->connectionAdapters = $ulmus['adapters'] ?? [];
}
}
+28 -19
View File
@@ -2,40 +2,48 @@
namespace Lean;
use League\Route\Http\Exception\MethodNotAllowedException;
use League\Route\Strategy;
use League\Route\Http\Exception\NotFoundException;
use Picea\Asset\Asset;
use Lean\ApplicationStrategy\MethodNotAllowedInterface;
use Lean\ApplicationStrategy\NotFoundDecoratorInterface;
use Lean\ApplicationStrategy\ThrowableHandlerInterface;
use Lean\Factory\HttpFactoryInterface;
use Psr\Container\ContainerInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Picea\Picea;
use Psr\Http\Server\RequestHandlerInterface;
use function DI\get;
class ApplicationStrategy extends Strategy\ApplicationStrategy {
public const ASSET_TRIGGER_UPDATE = [
"js", "mjs", "manifest", "webmanifest", "css", "png", "ico",
"jpg", "jpeg", "gif", "webp", "woff", "woff2", "eot", "svg",
"ttf"
];
public function __construct(
protected Picea $picea,
protected ContainerInterface $di,
) {}
ContainerInterface $di,
) {
$this->setContainer($di);
}
public function getNotFoundDecorator(NotFoundException $exception): MiddlewareInterface
{
return new class($this->picea, $this->di) implements MiddlewareInterface {
return $this->getContainer()->get(NotFoundDecoratorInterface::class);
}
public function __construct(
protected Picea $picea,
protected ContainerInterface $di,
) { }
public function getThrowableHandler(): MiddlewareInterface
{
return $this->getContainer()->get(ThrowableHandlerInterface::class);
}
public function getMethodNotAllowedDecorator(MethodNotAllowedException $exception): MiddlewareInterface
{
return $this->getContainer()->has(MethodNotAllowedInterface::class) ? $this->getContainer()->get(MethodNotAllowedInterface::class) : parent::getMethodNotAllowedDecorator($exception);
}
/*
<<<<<<< HEAD
public function getMethodNotAllowedDecorator(MethodNotAllowedException $exception): MiddlewareInterface
{
return $this->getContainer()->has(MethodNotAllowedInterface::class) ? $this->getContainer()->get(MethodNotAllowedInterface::class) : parent::getMethodNotAllowedDecorator($exception);
=======
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
if (php_sapi_name() !== 'cli' and ! defined('STDIN')) {
@@ -58,8 +66,9 @@ class ApplicationStrategy extends Strategy\ApplicationStrategy {
}
}
return new \Laminas\Diactoros\Response\HtmlResponse($this->picea->renderHtml("lean/error/404", [], $this), 404);
return $this->di->get('error.404');
}
};
}
>>>>>>> af8b686 (- WIP on ulmus-user mechanics updates)
}*/
}
@@ -0,0 +1,10 @@
<?php
namespace Lean\ApplicationStrategy;
use Psr\Http\Server\MiddlewareInterface;
interface MethodNotAllowedInterface extends MiddlewareInterface
{
}
@@ -0,0 +1,62 @@
<?php
namespace Lean\ApplicationStrategy;
use DI\Attribute\Inject;
use Lean\ApplicationStrategy;
use Lean\Factory\HttpFactoryInterface;
use Picea\Picea;
use Psr\Container\ContainerInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
class NotFoundDecorator implements NotFoundDecoratorInterface
{
#[Inject]
protected Picea $picea;
#[Inject]
protected ContainerInterface $container;
#[Inject]
protected HttpFactoryInterface $httpFactory;
public const ASSET_TRIGGER_UPDATE = [
"js", "mjs", "manifest", "webmanifest", "css", "png", "ico",
"jpg", "jpeg", "gif", "webp", "woff", "woff2", "eot", "svg",
"ttf"
];
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
if (php_sapi_name() !== 'cli' and ! defined('STDIN')) {
return $this->throw404($request);
}
return $handler->handle($request);
}
public function throw404(ServerRequestInterface $request) : ResponseInterface
{
return $this->checkAssetTrigger($request) ?: $this->container->get('error.404');
}
protected function checkAssetTrigger(ServerRequestInterface $request) : false|ResponseInterface
{
if (getenv('DEBUG') && $this->container->has(\Picea\Asset\Asset::class)) {
$params = $request->getServerParams();
$scpName = basename(explode('?', $params['REQUEST_URI'] ?? "", 2)[0]);
list(, $ext) = array_pad(explode('.', $scpName), 2, null);
if ($ext && in_array($ext, static::ASSET_TRIGGER_UPDATE)) {
$this->container->get(\Picea\Asset\Asset::class)->launchInstall();
return $this->httpFactory->createTextResponse("Asset updated");
}
}
return false;
}
}
@@ -0,0 +1,10 @@
<?php
namespace Lean\ApplicationStrategy;
use Psr\Http\Server\MiddlewareInterface;
interface NotFoundDecoratorInterface extends MiddlewareInterface
{
}
@@ -0,0 +1,22 @@
<?php
namespace Lean\ApplicationStrategy;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
class ThrowableHandler implements ThrowableHandlerInterface
{
public function process(
ServerRequestInterface $request,
RequestHandlerInterface $handler
): ResponseInterface {
try {
return $handler->handle($request);
} catch (Throwable $e) {
throw $e;
}
}
}
@@ -0,0 +1,10 @@
<?php
namespace Lean\ApplicationStrategy;
use Psr\Http\Server\MiddlewareInterface;
interface ThrowableHandlerInterface extends MiddlewareInterface
{
}
+2 -2
View File
@@ -102,7 +102,7 @@ class Composer
throw new \UnexpectedValueException("Composer file 'composer.json' could not be found within your project's root folder.");
}
return $content ??= file_exists($path) ? json_decode(file_get_contents($path), true) : false;
return $content ??= file_exists($path) ? json_decode(file_get_contents($path), true, 512, \JSON_THROW_ON_ERROR) : false;
}
protected static function getNamespaceFromAutoload(Event $event) : ? string
@@ -125,7 +125,7 @@ class Composer
$event->getIO()->writeError("Your composer file do not seem to contains a valid psr-4 project pointing to the src folder.");
return null;
return false;
}
protected static function createPath(... $path) : string
+12 -12
View File
@@ -8,6 +8,7 @@ use Notes\Attribute\Ignore;
use Notes\Route\Attribute\Object\Route;
use Notes\Security\Attribute\Security;
use Picea, Picea\Ui\Method\FormContext;
use Picea\Ui\Method\FormContextInterface;
use TheBugs\Email\MailerInterface;
use Storage\{ Cookie, Session };
use League\CommonMark\CommonMarkConverter;
@@ -20,9 +21,6 @@ use function file_get_contents;
#[Route(method: [ "GET", "POST" ])]
trait ControllerTrait {
#[Inject]
public \Notes\Breadcrumb\Breadcrumb $breadcrumb;
#[Inject]
public Session $session;
@@ -147,13 +145,15 @@ trait ControllerTrait {
#[Ignore]
public function renderCLI(ServerRequestInterface $request, mixed $data) : ResponseInterface
{
if ($data instanceof \JsonSerializable ) {
return $this->renderJson(
$data
);
}
elseif ( is_array($data) ) {
var_export($data);
if (! $data instanceof \Stringable) {
if ($data instanceof \JsonSerializable) {
return $this->renderJson(
$data
);
}
elseif (is_iterable($data) || is_object($data)) {
return $this->renderText(var_export($data, true));
}
}
return $this->renderText(
@@ -210,7 +210,7 @@ trait ControllerTrait {
}
#[Ignore]
public function pushContext(FormContext $context) : FormContext
public function pushContext(FormContextInterface $context) : FormContextInterface
{
$this->contextList[$context->formName ?? uniqid("context_")] = $context;
@@ -218,7 +218,7 @@ trait ControllerTrait {
}
#[Ignore]
public function context(? string $name = null) : ? FormContext
public function context(? string $name = null) : ? FormContextInterface
{
return $name ? $this->contextList[$name] : array_values($this->contextList)[0] ?? null;
}
+1
View File
@@ -6,6 +6,7 @@ use Lean\Routing;
use Notes\Route\Attribute\Method\Route;
use Psr\Container\ContainerInterface;
use Psr\Http\Message\{ ResponseInterface, ServerRequestInterface };
use Ulmus\User\Entity\UserInterface;
interface RoutingMapRoutes {
public function execute(Routing $routing, ContainerInterface $container, ServerRequestInterface & $request, Route $attribute) : void;
+8 -1
View File
@@ -5,9 +5,11 @@ namespace Lean\Factory;
use Laminas\Diactoros\Response\{EmptyResponse, HtmlResponse, JsonResponse, RedirectResponse, TextResponse};
use Lean\Response\{ DownloadResponse, ImageResponse, FileDownloadResponse, PdfResponse };
use Laminas\Diactoros\Response;
use Laminas\Diactoros\StreamFactory;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\StreamInterface;
class HttpFactory
class HttpFactory implements HttpFactoryInterface
{
public static function createResponse(string $url, int $code = 302, array $headers = []) : ResponseInterface
{
@@ -58,4 +60,9 @@ class HttpFactory
{
return new FileDownloadResponse($path, $code, $headers);
}
public static function createStream(string $content): StreamInterface
{
return new StreamFactory()->createStream($content);
}
}
+21
View File
@@ -0,0 +1,21 @@
<?php
namespace Lean\Factory;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\StreamInterface;
interface HttpFactoryInterface
{
public static function createResponse(string $url, int $code = 302, array $headers = []) : ResponseInterface;
public static function createRedirectResponse(string $url, int $code = 302, array $headers = []) : ResponseInterface;
public static function createHtmlResponse(string $html, int $code = 200, array $headers = []) : ResponseInterface;
public static function createTextResponse(string $text, int $code = 200, array $headers = []) : ResponseInterface;
public static function createJsonResponse(mixed $data, int $code = 200, array $headers = []) : ResponseInterface;
public static function createEmptyResponse(int $code = 204, array $headers = []) : ResponseInterface;
public static function createPdfResponse(\Stringable|string $binary, int $code = 200, array $headers = []) : ResponseInterface;
public static function createDownloadableResponse(string $data, string $filename, int $code = 200, array $headers = []) : ResponseInterface;
public static function createImageResponse(string $data, int $code = 200, array $headers = []) : ResponseInterface;
public static function createFileDownloadResponse(string $path, int $code = 200, array $headers = []) : ResponseInterface;
public static function createStream(string $content) : StreamInterface;
}
+8 -8
View File
@@ -27,18 +27,15 @@ class Kernel {
public array $paths = [];
public int $errorReporting = E_ALL & ~E_USER_DEPRECATED & ~E_DEPRECATED & ~E_STRICT & ~E_NOTICE;
public int $errorReporting = E_ALL & ~E_USER_DEPRECATED & ~E_DEPRECATED & ~E_NOTICE;
public array $definitionFilePaths;
public string $errorLogPath;
public string $projectPath;
public function __construct(string $projectPath)
{
$this->projectPath = $projectPath;
public function __construct(
public string $projectPath
) {
$this->setEnvironment();
$this->initializeEngine();
$this->setupContainer();
@@ -73,7 +70,9 @@ class Kernel {
$path = getenv("PROJECT_PATH") . DIRECTORY_SEPARATOR . getenv($envkey);
if (getenv('DEBUG') && ! file_exists($path)) {
mkdir($path, 0755, true);
if (false === mkdir($path, 0755, true)) {
throw new \Exception(sprintf("Folder '%s' could not be created", $path));
}
}
static::putenv($name, realpath($path));
@@ -155,6 +154,7 @@ class Kernel {
# Must be removed from KERNEL !
$this->container->has('ulmus.caching') and ( Ulmus::$cache = $this->container->get('ulmus.caching') );
# $this->container->has(AdapterProxy::class) and ( $ )
return $this;
}
+15 -10
View File
@@ -77,37 +77,42 @@ class Lean
public function getRoutable() : array
{
return array_merge(...array_map(fn($app) => $app->routes ?? [], $this->applications));
return array_merge(...array_map(fn(Application $app) => $app->routes ?? [], $this->applications));
}
public function getCronard() : array
{
return array_merge(...array_map(fn($app) => $app->cronard ?? [], $this->applications));
return array_merge(...array_map(fn(Application $app) => $app->cronard ?? [], $this->applications));
}
public function getCLI() : array
{
return array_merge(...array_map(fn($app) => $app->cli ?? [], $this->applications));
return array_merge(...array_map(fn(Application $app) => $app->cli ?? [], $this->applications));
}
public function getEvents() : array
{
return array_merge(...array_map(fn($app) => $app->events ?? [], $this->applications));
return array_merge(...array_map(fn(Application $app) => $app->events ?? [], $this->applications));
}
public function getTaxusPrivileges() : array
{
return array_merge(...array_map(fn($app) => $app->taxus ?? [], $this->applications));
return array_merge(...array_map(fn(Application $app) => $app->taxus ?? [], $this->applications));
}
public function getEntities() : array
{
return array_merge(...array_map(fn($app) => $app->entities ?? [], $this->applications));
return array_merge(...array_map(fn(Application $app) => $app->entities ?? [], $this->applications));
}
public function getConnectionAdapters() : array
{
return array_merge(...array_map(fn(Application $app) => $app->connectionAdapters ?? [], $this->applications));
}
public function getViewPaths() : array
{
$list = array_merge(...array_map(fn($app) => $app->views ?? [], $this->applications));
$list = array_merge(...array_map(fn(Application $app) => $app->views ?? [], $this->applications));
$this->verifyPathList($list);
@@ -118,7 +123,7 @@ class Lean
public function getAssetPaths() : array
{
$list = array_merge(...array_map(fn($app) => $app->piceaAssets ?? [], $this->applications));
$list = array_merge(...array_map(fn(Application $app) => $app->piceaAssets ?? [], $this->applications));
$this->verifyPathList($list);
@@ -140,11 +145,11 @@ class Lean
{
switch($reader) {
case "php":
$list = array_merge(...array_map(fn($app) => $app->tellPhp ?? [], $this->applications));
$list = array_merge(...array_map(fn(Application $app) => $app->tellPhp ?? [], $this->applications));
break;
case "json":
$list = array_merge(...array_map(fn($app) => $app->tellJson ?? [], $this->applications));
$list = array_merge(...array_map(fn(Application $app) => $app->tellJson ?? [], $this->applications));
break;
}
+23
View File
@@ -0,0 +1,23 @@
{% arguments \DateInterval $interval %}
{% if $interval->y %}
{% lang "lean.date.interval.years", [ 'years' => $interval->y ] %},
{% endif %}
{% if $interval->m %}
{% lang "lean.date.interval.months", [ 'months' => $interval->m ] %},
{% endif %}
{% if $interval->d %}
{% lang "lean.date.interval.days", [ 'days' => $interval->d ] %},
{% endif %}
{% if $interval->h %}
{% lang "lean.date.interval.hours", [ 'hours' => $interval->h ] %},
{% endif %}
{% if $interval->i %}
{% lang "lean.date.interval.minutes", [ 'minutes' => $interval->i ] %}
{% else %}
{% lang "lean.date.interval.seconds", [ 'seconds' => $interval->s ] %}
{% endif %}
+2 -2
View File
@@ -9,7 +9,7 @@
<div class="title">{% _ "title" %}</div>
<div class="subtitle">{% _ "subtitle" %}</div>
<div class="content">{% _ "message" %}</div>
<u><a href="#" onclick="history.back()">{% _ "back" %}</a></u>
<u><a href="{% url %}">{% _ "back" %}</a></u>
</div>
{% endsection %}
@@ -22,5 +22,5 @@
{% section "head.css" %}
.title {font-size:2rem}
.subtitle {font-size:1.25rem; padding-top: 1rem;}
.content {padding-top:1rem}
.content {background: #f7f7f7;padding: 7px;color: #8c3c3c;max-height:300px;overflow-y:auto}
{% endsection %}
-6
View File
@@ -18,9 +18,3 @@
{% view "lean/picto/undraw_lost" %}
</div>
{% endsection %}
{% section "head.css" %}
.title {font-size:2rem}
.subtitle {font-size:1.25rem; padding-top: 1rem;}
.content {padding-top:1rem}
{% endsection %}
-6
View File
@@ -18,9 +18,3 @@
{% view "lean/picto/undraw_error" %}
</div>
{% endsection %}
{% section "head.css" %}
.title {font-size:2rem}
.subtitle {font-size:1.25rem; padding-top: 1rem;}
.content {background: #f7f7f7;padding: 7px;color: #8c3c3c;max-height:300px;overflow-y:auto}
{% endsection %}
+2 -2
View File
@@ -10,14 +10,14 @@
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.1/css/bulma.min.css">
<style>
body {background:#272822}
body {background:#272822;min-height:100vh;}
#main-content {min-height: 100vh;width: 100vw;align-items:center;justify-content: center;}
#wrapper-content {max-width:960px; max-height:65vh;flex-direction:row-reverse; margin:0 10vw}
#wrapper-content .content-right {background:#efefef;padding:5vh 2vw;align-items:center;display:flex;justify-content:center; width:100%;border-radius:6px 0 0 6px}
#wrapper-content .content-left {background:#ffffff;padding:5vh 2vw;border-radius:0 6px 6px 0;display:flex;align-items:center;justify-content: center}
.form-user-login {width:80%;}
.picto-login svg {max-width:100%;}
.picto-login svg {max-width:100%;width:100%;max-height:33vh}
{% section "head.css" %}{% endsection %}
</style>
+1 -1
View File
@@ -1 +1 @@
<svg id="e7dedc5b-fca6-4313-b5a0-e6297481e8ae" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1022.7" height="785.81" viewBox="0 0 1022.7 785.81"><defs><linearGradient id="af83dc26-9572-4816-b7a1-1af4f72ff554" x1="678.2" y1="821.79" x2="678.2" y2="493.4" gradientTransform="translate(-20.24 29.65) rotate(-2.31)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="gray" stop-opacity="0.25"/><stop offset="0.54" stop-color="gray" stop-opacity="0.12"/><stop offset="1" stop-color="gray" stop-opacity="0.1"/></linearGradient></defs><title>bug fixing</title><ellipse cx="468.63" cy="660.88" rx="425" ry="33" fill="#6c63ff" opacity="0.1"/><g opacity="0.1"><path d="M933.7,529.93c-2.54-7.71-12.84-11.26-23-7.92a24.76,24.76,0,0,0-4.23,1.83c-.65-.18-1.32-.34-2-.46a22.42,22.42,0,0,0,.63-6.79A24.6,24.6,0,0,0,916,495.12a24.63,24.63,0,0,0,10.86-21.47,23.76,23.76,0,0,0,8.23-9.32c4.9-9.7,2.87-20.6-4.54-24.35s-17.4,1.08-22.3,10.78a23.69,23.69,0,0,0-2.63,12.15,24.63,24.63,0,0,0-10.86,21.47,24.63,24.63,0,0,0-10.86,21.47A24.64,24.64,0,0,0,873,527.33a23.76,23.76,0,0,0-8.23,9.32,25.46,25.46,0,0,0-2.08,5.74,21.18,21.18,0,0,0-4.44-4.73,25.38,25.38,0,0,0-1-4.5c-3.34-10.17-12.3-16.37-20-13.83s-11.26,12.83-7.92,23a23.07,23.07,0,0,0,7.56,11.08,25.38,25.38,0,0,0,1,4.5c1.94,5.9,5.77,10.46,10.15,12.75a23.23,23.23,0,0,0-.83,3.9,25.29,25.29,0,0,0-7.54,14.91,25.27,25.27,0,0,0-7.54,14.92,24.63,24.63,0,0,0-5,6.81c-4.91,9.7-2.88,20.61,4.53,24.35s17.4-1.07,22.31-10.78a24.62,24.62,0,0,0,2.5-8.09,25.29,25.29,0,0,0,7.54-14.91,25.27,25.27,0,0,0,7.54-14.92A25.21,25.21,0,0,0,879,571.94,25.21,25.21,0,0,0,886.56,557a24.11,24.11,0,0,0,3.39-4,23.46,23.46,0,0,0,12.27-.77,24.76,24.76,0,0,0,4.23-1.83,23.2,23.2,0,0,0,13.42-.48C930,546.61,936.23,537.65,933.7,529.93Z" transform="translate(-88.65 -57.09)" fill="#3f3d56"/><g opacity="0.1"><path d="M915.77,499.53a21.5,21.5,0,0,1-3.44,2.75,23,23,0,0,1-1.11,8.43,26.18,26.18,0,0,0,2.1-3.43A24.64,24.64,0,0,0,915.77,499.53Z" transform="translate(-88.65 -57.09)"/><path d="M926.63,478.06a21.5,21.5,0,0,1-3.44,2.75,23,23,0,0,1-1.11,8.43,25.65,25.65,0,0,0,2.1-3.44A24.85,24.85,0,0,0,926.63,478.06Z" transform="translate(-88.65 -57.09)"/><path d="M902,470.07a21.91,21.91,0,0,1,.17-4.41,24.93,24.93,0,0,0-4.78,6.57,25.63,25.63,0,0,0-1.52,3.73A22.75,22.75,0,0,1,902,470.07Z" transform="translate(-88.65 -57.09)"/><path d="M833.07,600a23.59,23.59,0,0,1,2.95-3.38,22.92,22.92,0,0,1,.87-4,25.09,25.09,0,0,0-2.29,3.71A25.59,25.59,0,0,0,833.07,600Z" transform="translate(-88.65 -57.09)"/><path d="M840.61,585.1a23.59,23.59,0,0,1,2.95-3.38,23,23,0,0,1,.83-3.9l0,0a25.68,25.68,0,0,0-2.2,3.59A26.76,26.76,0,0,0,840.61,585.1Z" transform="translate(-88.65 -57.09)"/><path d="M904.9,521a20.82,20.82,0,0,1-3.43,2.74,22.45,22.45,0,0,1-.63,6.79,18.75,18.75,0,0,1,2,.46,24.76,24.76,0,0,1,4.23-1.83c10.18-3.34,20.47.21,23,7.92a11.68,11.68,0,0,1,.32,6c3.35-3.94,4.74-8.74,3.3-13.14-2.54-7.71-12.84-11.26-23-7.92a24.76,24.76,0,0,0-4.23,1.83c-.65-.18-1.32-.34-2-.46C904.65,522.59,904.79,521.8,904.9,521Z" transform="translate(-88.65 -57.09)"/><path d="M829.35,607.49a25.09,25.09,0,0,0-2.29,3.71,26.56,26.56,0,0,0-1.54,3.74,24.48,24.48,0,0,1,3-3.4A22.92,22.92,0,0,1,829.35,607.49Z" transform="translate(-88.65 -57.09)"/><path d="M891.09,491.54a22,22,0,0,1,.17-4.41,24.93,24.93,0,0,0-4.78,6.57,25.63,25.63,0,0,0-1.52,3.73A22.75,22.75,0,0,1,891.09,491.54Z" transform="translate(-88.65 -57.09)"/><path d="M875.4,579.1a24.29,24.29,0,0,1-1,4.38,26.67,26.67,0,0,0,2.09-3.44,25.49,25.49,0,0,0,1.63-4A24.23,24.23,0,0,1,875.4,579.1Z" transform="translate(-88.65 -57.09)"/><path d="M860.32,608.92a24.15,24.15,0,0,1-1,4.38,25.65,25.65,0,0,0,2.1-3.44,26.47,26.47,0,0,0,1.63-4A23.57,23.57,0,0,1,860.32,608.92Z" transform="translate(-88.65 -57.09)"/><path d="M867.86,594a24.11,24.11,0,0,1-1,4.38A26.67,26.67,0,0,0,869,595a25.49,25.49,0,0,0,1.63-4A24.23,24.23,0,0,1,867.86,594Z" transform="translate(-88.65 -57.09)"/><path d="M882.94,564.19a24,24,0,0,1-1,4.37,25.89,25.89,0,0,0,2.09-3.43,25.48,25.48,0,0,0,1.64-4.07A23.22,23.22,0,0,1,882.94,564.19Z" transform="translate(-88.65 -57.09)"/><path d="M833.57,526.48c7.72-2.53,16.68,3.66,20,13.83a25.68,25.68,0,0,1,1,4.51,21.18,21.18,0,0,1,4.44,4.73,25.53,25.53,0,0,1,2.08-5.75c.35-.68.73-1.33,1.12-2a21.07,21.07,0,0,0-4-4.18,25.38,25.38,0,0,0-1-4.5c-3.34-10.17-12.3-16.37-20-13.83-4.4,1.44-7.44,5.41-8.62,10.43A11.69,11.69,0,0,1,833.57,526.48Z" transform="translate(-88.65 -57.09)"/><path d="M869.37,534.48a21.85,21.85,0,0,1,.18-4.4,24.73,24.73,0,0,0-4.79,6.57,25.07,25.07,0,0,0-1.52,3.72A23,23,0,0,1,869.37,534.48Z" transform="translate(-88.65 -57.09)"/><path d="M880.23,513a21.85,21.85,0,0,1,.18-4.4,24.52,24.52,0,0,0-4.79,6.56,25.63,25.63,0,0,0-1.52,3.73A22.75,22.75,0,0,1,880.23,513Z" transform="translate(-88.65 -57.09)"/><path d="M852.78,623.83a24.25,24.25,0,0,1-1,4.39,25.73,25.73,0,0,0,3.73-7.49A23.57,23.57,0,0,1,852.78,623.83Z" transform="translate(-88.65 -57.09)"/></g><path d="M948.52,430.71a23.68,23Line truncated
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1022.7" height="785.81" viewBox="0 0 1022.7 785.81" role="img" artist="Katerina Limpitsouni" source="https://undraw.co/"><defs><linearGradient id="af83dc26-9572-4816-b7a1-1af4f72ff554-63" x1="678.2" y1="821.79" x2="678.2" y2="493.4" gradientTransform="translate(-20.24 29.65) rotate(-2.31)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="gray" stop-opacity="0.25"/><stop offset="0.54" stop-color="gray" stop-opacity="0.12"/><stop offset="1" stop-color="gray" stop-opacity="0.1"/></linearGradient></defs><title>bug fixing</title><ellipse cx="468.63" cy="660.88" rx="425" ry="33" fill="#6c63ff" opacity="0.1"/><g opacity="0.1"><path d="M933.7,529.93c-2.54-7.71-12.84-11.26-23-7.92a24.76,24.76,0,0,0-4.23,1.83c-.65-.18-1.32-.34-2-.46a22.42,22.42,0,0,0,.63-6.79A24.6,24.6,0,0,0,916,495.12a24.63,24.63,0,0,0,10.86-21.47,23.76,23.76,0,0,0,8.23-9.32c4.9-9.7,2.87-20.6-4.54-24.35s-17.4,1.08-22.3,10.78a23.69,23.69,0,0,0-2.63,12.15,24.63,24.63,0,0,0-10.86,21.47,24.63,24.63,0,0,0-10.86,21.47A24.64,24.64,0,0,0,873,527.33a23.76,23.76,0,0,0-8.23,9.32,25.46,25.46,0,0,0-2.08,5.74,21.18,21.18,0,0,0-4.44-4.73,25.38,25.38,0,0,0-1-4.5c-3.34-10.17-12.3-16.37-20-13.83s-11.26,12.83-7.92,23a23.07,23.07,0,0,0,7.56,11.08,25.38,25.38,0,0,0,1,4.5c1.94,5.9,5.77,10.46,10.15,12.75a23.23,23.23,0,0,0-.83,3.9,25.29,25.29,0,0,0-7.54,14.91,25.27,25.27,0,0,0-7.54,14.92,24.63,24.63,0,0,0-5,6.81c-4.91,9.7-2.88,20.61,4.53,24.35s17.4-1.07,22.31-10.78a24.62,24.62,0,0,0,2.5-8.09,25.29,25.29,0,0,0,7.54-14.91,25.27,25.27,0,0,0,7.54-14.92A25.21,25.21,0,0,0,879,571.94,25.21,25.21,0,0,0,886.56,557a24.11,24.11,0,0,0,3.39-4,23.46,23.46,0,0,0,12.27-.77,24.76,24.76,0,0,0,4.23-1.83,23.2,23.2,0,0,0,13.42-.48C930,546.61,936.23,537.65,933.7,529.93Z" transform="translate(-88.65 -57.09)" fill="#3f3d56"/><g opacity="0.1"><path d="M915.77,499.53a21.5,21.5,0,0,1-3.44,2.75,23,23,0,0,1-1.11,8.43,26.18,26.18,0,0,0,2.1-3.43A24.64,24.64,0,0,0,915.77,499.53Z" transform="translate(-88.65 -57.09)"/><path d="M926.63,478.06a21.5,21.5,0,0,1-3.44,2.75,23,23,0,0,1-1.11,8.43,25.65,25.65,0,0,0,2.1-3.44A24.85,24.85,0,0,0,926.63,478.06Z" transform="translate(-88.65 -57.09)"/><path d="M902,470.07a21.91,21.91,0,0,1,.17-4.41,24.93,24.93,0,0,0-4.78,6.57,25.63,25.63,0,0,0-1.52,3.73A22.75,22.75,0,0,1,902,470.07Z" transform="translate(-88.65 -57.09)"/><path d="M833.07,600a23.59,23.59,0,0,1,2.95-3.38,22.92,22.92,0,0,1,.87-4,25.09,25.09,0,0,0-2.29,3.71A25.59,25.59,0,0,0,833.07,600Z" transform="translate(-88.65 -57.09)"/><path d="M840.61,585.1a23.59,23.59,0,0,1,2.95-3.38,23,23,0,0,1,.83-3.9l0,0a25.68,25.68,0,0,0-2.2,3.59A26.76,26.76,0,0,0,840.61,585.1Z" transform="translate(-88.65 -57.09)"/><path d="M904.9,521a20.82,20.82,0,0,1-3.43,2.74,22.45,22.45,0,0,1-.63,6.79,18.75,18.75,0,0,1,2,.46,24.76,24.76,0,0,1,4.23-1.83c10.18-3.34,20.47.21,23,7.92a11.68,11.68,0,0,1,.32,6c3.35-3.94,4.74-8.74,3.3-13.14-2.54-7.71-12.84-11.26-23-7.92a24.76,24.76,0,0,0-4.23,1.83c-.65-.18-1.32-.34-2-.46C904.65,522.59,904.79,521.8,904.9,521Z" transform="translate(-88.65 -57.09)"/><path d="M829.35,607.49a25.09,25.09,0,0,0-2.29,3.71,26.56,26.56,0,0,0-1.54,3.74,24.48,24.48,0,0,1,3-3.4A22.92,22.92,0,0,1,829.35,607.49Z" transform="translate(-88.65 -57.09)"/><path d="M891.09,491.54a22,22,0,0,1,.17-4.41,24.93,24.93,0,0,0-4.78,6.57,25.63,25.63,0,0,0-1.52,3.73A22.75,22.75,0,0,1,891.09,491.54Z" transform="translate(-88.65 -57.09)"/><path d="M875.4,579.1a24.29,24.29,0,0,1-1,4.38,26.67,26.67,0,0,0,2.09-3.44,25.49,25.49,0,0,0,1.63-4A24.23,24.23,0,0,1,875.4,579.1Z" transform="translate(-88.65 -57.09)"/><path d="M860.32,608.92a24.15,24.15,0,0,1-1,4.38,25.65,25.65,0,0,0,2.1-3.44,26.47,26.47,0,0,0,1.63-4A23.57,23.57,0,0,1,860.32,608.92Z" transform="translate(-88.65 -57.09)"/><path d="M867.86,594a24.11,24.11,0,0,1-1,4.38A26.67,26.67,0,0,0,869,595a25.49,25.49,0,0,0,1.63-4A24.23,24.23,0,0,1,867.86,594Z" transform="translate(-88.65 -57.09)"/><path d="M882.94,564.19a24,24,0,0,1-1,4.37,25.89,25.89,0,0,0,2.09-3.43,25.48,25.48,0,0,0,1.64-4.07A23.22,23.22,0,0,1,882.94,564.19Z" transform="translate(-88.65 -57.09)"/><path d="M833.57,526.48c7.72-2.53,16.68,3.66,20,13.83a25.68,25.68,0,0,1,1,4.51,21.18,21.18,0,0,1,4.44,4.73,25.53,25.53,0,0,1,2.08-5.75c.35-.68.73-1.33,1.12-2a21.07,21.07,0,0,0-4-4.18,25.38,25.38,0,0,0-1-4.5c-3.34-10.17-12.3-16.37-20-13.83-4.4,1.44-7.44,5.41-8.62,10.43A11.69,11.69,0,0,1,833.57,526.48Z" transform="translate(-88.65 -57.09)"/><path d="M869.37,534.48a21.85,21.85,0,0,1,.18-4.4,24.73,24.73,0,0,0-4.79,6.57,25.07,25.07,0,0,0-1.52,3.72A23,23,0,0,1,869.37,534.48Z" transform="translate(-88.65 -57.09)"/><path d="M880.23,513a21.85,21.85,0,0,1,.18-4.4,24.52,24.52,0,0,0-4.79,6.56,25.63,25.63,0,0,0-1.52,3.73A22.75,22.75,0,0,1,880.23,513Z" transform="translate(-88.65 -57.09)"/><path d="M852.78,623.83a24.25,24.25,0,0,1-1,4.39,25.73,25.73,0,0,0,3.73-7.49A23.57,23.57,0,0,1,852.78,623.83Z" transform="translate(-88.65 -57.09)"/></g><path d="M948.52,430.7Line truncated

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 40 KiB

+1 -1
View File
@@ -1 +1 @@
<svg id="a63b68c9-40cd-4f97-89ed-e7d494eb42f9" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" width="742.41705" height="712.57302" viewBox="0 0 742.41705 712.57302"><path id="aa38b2e7-2ea9-4025-adcf-83f87c0cfc4a" data-name="Path 968" d="M853.60644,262.60547h-3.9v-106.977a61.915,61.915,0,0,0-61.915-61.915h-226.65a61.915,61.915,0,0,0-61.916,61.914v586.884a61.915,61.915,0,0,0,61.915,61.915h226.648a61.915,61.915,0,0,0,61.915-61.915v-403.758h3.9Z" transform="translate(-228.79147 -93.71349)" fill="#3f3d56"/><path id="f27259c2-0089-4137-bfd8-cb22dff914f1" data-name="Path 969" d="M837.00647,151.48149v595.175a46.959,46.959,0,0,1-46.942,46.952h-231.3a46.966,46.966,0,0,1-46.973-46.952v-595.175a46.965,46.965,0,0,1,46.971-46.951h28.058a22.329,22.329,0,0,0,20.656,30.74h131.868a22.329,22.329,0,0,0,20.656-30.74h30.055a46.959,46.959,0,0,1,46.951,46.942Z" transform="translate(-228.79147 -93.71349)" fill="#fff"/><circle id="fc31cc31-f989-45cc-bd1e-521a0ee1871b" data-name="Ellipse 18" cx="445.56497" cy="200.129" r="96.565" fill="#6c63ff"/><path id="a573942c-3bf3-4c43-b474-689725a927f7" data-name="Path 39" d="M779.67245,494.30947h-205.537a3.81,3.81,0,0,1-3.806-3.806V439.51949a3.811,3.811,0,0,1,3.806-3.806h205.537a3.811,3.811,0,0,1,3.806,3.806v50.985a3.811,3.811,0,0,1-3.806,3.806Zm-205.537-57.074a2.286,2.286,0,0,0-2.284,2.284v50.985a2.286,2.286,0,0,0,2.284,2.284h205.537a2.286,2.286,0,0,0,2.284-2.284v-50.985a2.286,2.286,0,0,0-2.284-2.284Z" transform="translate(-228.79147 -93.71349)" fill="#e6e6e6"/><path id="fb5feb1e-1fe2-48fa-806d-0a2b51d12b49" data-name="Path 40" d="M637.69945,454.07448a2.66449,2.66449,0,0,0,0,5.329h125.605a2.665,2.665,0,0,0,.2041-5.32611q-.0585-.00221-.11713-.0019h-125.692Z" transform="translate(-228.79147 -93.71349)" fill="#e6e6e6"/><path id="bcb9932f-0864-4b7e-b0ed-f7254bb9b8bf" data-name="Path 41" d="M637.69945,470.05846a2.66449,2.66449,0,0,0,0,5.329h125.605a2.665,2.665,0,0,0,.2041-5.32611q-.0585-.00219-.11713-.00189h-125.692Z" transform="translate(-228.79147 -93.71349)" fill="#e6e6e6"/><path id="f88e2a8b-becc-4da9-bd36-af011daaaaf2" data-name="Path 42" d="M779.67245,579.28947h-205.537a3.81,3.81,0,0,1-3.806-3.806V524.49949a3.811,3.811,0,0,1,3.806-3.806h205.537a3.811,3.811,0,0,1,3.806,3.806v50.985A3.811,3.811,0,0,1,779.67245,579.28947Zm-205.537-57.074a2.286,2.286,0,0,0-2.284,2.284v50.985a2.286,2.286,0,0,0,2.284,2.284h205.537a2.286,2.286,0,0,0,2.284-2.284v-50.985a2.286,2.286,0,0,0-2.284-2.284Z" transform="translate(-228.79147 -93.71349)" fill="#e6e6e6"/><path id="e192d34f-2ccc-4f79-b47a-46430e4d87f6" data-name="Path 43" d="M637.69945,539.33047a2.66449,2.66449,0,0,0,0,5.329h125.605a2.665,2.665,0,0,0,.087-5.328h-125.692Z" transform="translate(-228.79147 -93.71349)" fill="#e6e6e6"/><path id="b230677c-48cc-4ee6-87d6-a753204ffe47" data-name="Path 44" d="M637.69945,555.3185a2.66449,2.66449,0,0,0,0,5.329h125.605a2.665,2.665,0,0,0,.087-5.328h-125.692Z" transform="translate(-228.79147 -93.71349)" fill="#e6e6e6"/><path id="b88a2a79-0ae3-4fd9-9894-02e0db9a2271" data-name="Path 39-2" d="M779.67245,664.54748h-205.537a3.81,3.81,0,0,1-3.806-3.806V609.7575a3.811,3.811,0,0,1,3.806-3.806h205.537a3.811,3.811,0,0,1,3.806,3.806v50.985a3.811,3.811,0,0,1-3.806,3.806Zm-205.537-57.074a2.286,2.286,0,0,0-2.284,2.284v50.985a2.286,2.286,0,0,0,2.284,2.284h205.537a2.286,2.286,0,0,0,2.284-2.284v-50.985a2.286,2.286,0,0,0-2.284-2.284Z" transform="translate(-228.79147 -93.71349)" fill="#e6e6e6"/><path id="aa2394a9-8b56-4a12-a2cd-a583e6ea12eb" data-name="Path 40-2" d="M637.69945,624.59148a2.66449,2.66449,0,1,0,0,5.329h125.605a2.665,2.665,0,0,0,.2041-5.32611q-.0585-.00219-.11713-.00189h-125.692Z" transform="translate(-228.79147 -93.71349)" fill="#e6e6e6"/><path id="bc352cb2-8959-4b51-bd18-df6817a9a47e" data-name="Path 41-2" d="M637.69945,640.57846a2.66449,2.66449,0,0,0,0,5.329h125.605a2.665,2.665,0,0,0,.2041-5.32611q-.0585-.0022-.11713-.00189h-125.692Z" transform="translate(-228.79147 -93.71349)" fill="#e6e6e6"/><path id="b30ee82f-5b3a-4aa4-9db7-ead828191937" data-name="Path 970" d="M969.27042,806.28651h-738.541c-1.071,0-1.938-.468-1.938-1.045s.868-1.045,1.938-1.045H969.27054c1.06994,0,1.938.468,1.938,1.045S970.34146,806.28651,969.27042,806.28651Z" transform="translate(-228.79147 -93.71349)" fill="#e6e6e6"/><g id="f24cf2fd-107c-4150-a0f1-6f6b12d88bf3" data-name="Group 58"><path id="a2b576eb-bb95-4480-aa60-cd8aa023fe61" data-name="Path 438" d="M937.99248,765.52151a19.4741,19.4741,0,0,1-18.806-3.313c-6.587-5.528-8.652-14.636-10.332-23.07l-4.97-24.945,10.405,7.165c7.483,5.152,15.134,10.47,20.316,17.933s7.443,17.651,3.28,25.726" transform="translate(-228.79147 -93.71349)" fill="#e6e6e6"/><path id="fe1c5433-44e0-47a6-8430-329cbd7c4dea" data-name="Path 439" d="M936.38547,797.45852c1.31-9.542,2.657-19.206,1.738-28.849-.816-8.565-3.429-16.93-8.749-23.789a39.57365,39.57365,0,0,0-10.153-9.2c-1.015-.641-1.95.968-.939,1.606a37.62192,37.62192,0,0,1,14.881,17.956c3.24,8.241,3.76,17.224,3.2,25.977-.338,5.294-1.053,10.553-1.774,15.805a.964.964,0,0,0,.6Line truncated
<svg width="742" height="712" id="a63b68c9-40cd-4f97-89ed-e7d494eb42f9" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 742.41705 712.57302"><path id="aa38b2e7-2ea9-4025-adcf-83f87c0cfc4a" data-name="Path 968" d="M853.60644,262.60547h-3.9v-106.977a61.915,61.915,0,0,0-61.915-61.915h-226.65a61.915,61.915,0,0,0-61.916,61.914v586.884a61.915,61.915,0,0,0,61.915,61.915h226.648a61.915,61.915,0,0,0,61.915-61.915v-403.758h3.9Z" transform="translate(-228.79147 -93.71349)" fill="#3f3d56"/><path id="f27259c2-0089-4137-bfd8-cb22dff914f1" data-name="Path 969" d="M837.00647,151.48149v595.175a46.959,46.959,0,0,1-46.942,46.952h-231.3a46.966,46.966,0,0,1-46.973-46.952v-595.175a46.965,46.965,0,0,1,46.971-46.951h28.058a22.329,22.329,0,0,0,20.656,30.74h131.868a22.329,22.329,0,0,0,20.656-30.74h30.055a46.959,46.959,0,0,1,46.951,46.942Z" transform="translate(-228.79147 -93.71349)" fill="#fff"/><circle id="fc31cc31-f989-45cc-bd1e-521a0ee1871b" data-name="Ellipse 18" cx="445.56497" cy="200.129" r="96.565" fill="#6c63ff"/><path id="a573942c-3bf3-4c43-b474-689725a927f7" data-name="Path 39" d="M779.67245,494.30947h-205.537a3.81,3.81,0,0,1-3.806-3.806V439.51949a3.811,3.811,0,0,1,3.806-3.806h205.537a3.811,3.811,0,0,1,3.806,3.806v50.985a3.811,3.811,0,0,1-3.806,3.806Zm-205.537-57.074a2.286,2.286,0,0,0-2.284,2.284v50.985a2.286,2.286,0,0,0,2.284,2.284h205.537a2.286,2.286,0,0,0,2.284-2.284v-50.985a2.286,2.286,0,0,0-2.284-2.284Z" transform="translate(-228.79147 -93.71349)" fill="#e6e6e6"/><path id="fb5feb1e-1fe2-48fa-806d-0a2b51d12b49" data-name="Path 40" d="M637.69945,454.07448a2.66449,2.66449,0,0,0,0,5.329h125.605a2.665,2.665,0,0,0,.2041-5.32611q-.0585-.00221-.11713-.0019h-125.692Z" transform="translate(-228.79147 -93.71349)" fill="#e6e6e6"/><path id="bcb9932f-0864-4b7e-b0ed-f7254bb9b8bf" data-name="Path 41" d="M637.69945,470.05846a2.66449,2.66449,0,0,0,0,5.329h125.605a2.665,2.665,0,0,0,.2041-5.32611q-.0585-.00219-.11713-.00189h-125.692Z" transform="translate(-228.79147 -93.71349)" fill="#e6e6e6"/><path id="f88e2a8b-becc-4da9-bd36-af011daaaaf2" data-name="Path 42" d="M779.67245,579.28947h-205.537a3.81,3.81,0,0,1-3.806-3.806V524.49949a3.811,3.811,0,0,1,3.806-3.806h205.537a3.811,3.811,0,0,1,3.806,3.806v50.985A3.811,3.811,0,0,1,779.67245,579.28947Zm-205.537-57.074a2.286,2.286,0,0,0-2.284,2.284v50.985a2.286,2.286,0,0,0,2.284,2.284h205.537a2.286,2.286,0,0,0,2.284-2.284v-50.985a2.286,2.286,0,0,0-2.284-2.284Z" transform="translate(-228.79147 -93.71349)" fill="#e6e6e6"/><path id="e192d34f-2ccc-4f79-b47a-46430e4d87f6" data-name="Path 43" d="M637.69945,539.33047a2.66449,2.66449,0,0,0,0,5.329h125.605a2.665,2.665,0,0,0,.087-5.328h-125.692Z" transform="translate(-228.79147 -93.71349)" fill="#e6e6e6"/><path id="b230677c-48cc-4ee6-87d6-a753204ffe47" data-name="Path 44" d="M637.69945,555.3185a2.66449,2.66449,0,0,0,0,5.329h125.605a2.665,2.665,0,0,0,.087-5.328h-125.692Z" transform="translate(-228.79147 -93.71349)" fill="#e6e6e6"/><path id="b88a2a79-0ae3-4fd9-9894-02e0db9a2271" data-name="Path 39-2" d="M779.67245,664.54748h-205.537a3.81,3.81,0,0,1-3.806-3.806V609.7575a3.811,3.811,0,0,1,3.806-3.806h205.537a3.811,3.811,0,0,1,3.806,3.806v50.985a3.811,3.811,0,0,1-3.806,3.806Zm-205.537-57.074a2.286,2.286,0,0,0-2.284,2.284v50.985a2.286,2.286,0,0,0,2.284,2.284h205.537a2.286,2.286,0,0,0,2.284-2.284v-50.985a2.286,2.286,0,0,0-2.284-2.284Z" transform="translate(-228.79147 -93.71349)" fill="#e6e6e6"/><path id="aa2394a9-8b56-4a12-a2cd-a583e6ea12eb" data-name="Path 40-2" d="M637.69945,624.59148a2.66449,2.66449,0,1,0,0,5.329h125.605a2.665,2.665,0,0,0,.2041-5.32611q-.0585-.00219-.11713-.00189h-125.692Z" transform="translate(-228.79147 -93.71349)" fill="#e6e6e6"/><path id="bc352cb2-8959-4b51-bd18-df6817a9a47e" data-name="Path 41-2" d="M637.69945,640.57846a2.66449,2.66449,0,0,0,0,5.329h125.605a2.665,2.665,0,0,0,.2041-5.32611q-.0585-.0022-.11713-.00189h-125.692Z" transform="translate(-228.79147 -93.71349)" fill="#e6e6e6"/><path id="b30ee82f-5b3a-4aa4-9db7-ead828191937" data-name="Path 970" d="M969.27042,806.28651h-738.541c-1.071,0-1.938-.468-1.938-1.045s.868-1.045,1.938-1.045H969.27054c1.06994,0,1.938.468,1.938,1.045S970.34146,806.28651,969.27042,806.28651Z" transform="translate(-228.79147 -93.71349)" fill="#e6e6e6"/><g id="f24cf2fd-107c-4150-a0f1-6f6b12d88bf3" data-name="Group 58"><path id="a2b576eb-bb95-4480-aa60-cd8aa023fe61" data-name="Path 438" d="M937.99248,765.52151a19.4741,19.4741,0,0,1-18.806-3.313c-6.587-5.528-8.652-14.636-10.332-23.07l-4.97-24.945,10.405,7.165c7.483,5.152,15.134,10.47,20.316,17.933s7.443,17.651,3.28,25.726" transform="translate(-228.79147 -93.71349)" fill="#e6e6e6"/><path id="fe1c5433-44e0-47a6-8430-329cbd7c4dea" data-name="Path 439" d="M936.38547,797.45852c1.31-9.542,2.657-19.206,1.738-28.849-.816-8.565-3.429-16.93-8.749-23.789a39.57365,39.57365,0,0,0-10.153-9.2c-1.015-.641-1.95.968-.939,1.606a37.62192,37.62192,0,0,1,14.881,17.956c3.24,8.241,3.76,17.224,3.2,25.977-.338,5.294-1.053,10.553-1.774,15.805a.964.964,0,0,0,.65,1.144.936.Line truncated

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

+1 -1
View File
@@ -10,7 +10,7 @@
{% if $messageList %}
<div class="message-wrapper">{% php
foreach($messageList as $name => $context) {
foreach($context->messages ?? [] as $message) {
foreach($context->formContextMessages ?? [] as $message) {
echo $message->render();
}
}