finish basic

This commit is contained in:
guaosi 2019-03-01 14:08:34 +08:00
commit 31c665249f
130 changed files with 11683 additions and 0 deletions

15
.editorconfig Normal file
View File

@ -0,0 +1,15 @@
root = true
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
indent_style = space
indent_size = 4
trim_trailing_whitespace = true
[*.md]
trim_trailing_whitespace = false
[*.yml]
indent_size = 2

41
.env.example Normal file
View File

@ -0,0 +1,41 @@
APP_NAME=Laravel
APP_ENV=local
APP_KEY=
APP_DEBUG=true
APP_URL=http://localhost
LOG_CHANNEL=stack
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=homestead
DB_USERNAME=homestead
DB_PASSWORD=secret
BROADCAST_DRIVER=log
CACHE_DRIVER=file
QUEUE_CONNECTION=redis
SESSION_DRIVER=file
SESSION_LIFETIME=120
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
MAIL_DRIVER=smtp
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
PUSHER_APP_ID=
PUSHER_APP_KEY=
PUSHER_APP_SECRET=
PUSHER_APP_CLUSTER=mt1
MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
HORIZON_IP=127.0.0.1

5
.gitattributes vendored Normal file
View File

@ -0,0 +1,5 @@
* text=auto
*.css linguist-vendored
*.scss linguist-vendored
*.js linguist-vendored
CHANGELOG.md export-ignore

11
.gitignore vendored Normal file
View File

@ -0,0 +1,11 @@
/node_modules
/public/hot
/public/storage
/storage/*.key
/vendor
.env
.phpunit.result.cache
Homestead.json
Homestead.yaml
npm-debug.log
yarn-error.log

View File

@ -0,0 +1,5 @@
<component name="InspectionProjectProfileManager">
<settings>
<option name="PROJECT_PROFILE" />
</settings>
</component>

6
.idea/misc.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="JavaScriptSettings">
<option name="languageLevel" value="ES6" />
</component>
</project>

8
.idea/modules.xml Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/test.iml" filepath="$PROJECT_DIR$/.idea/test.iml" />
</modules>
</component>
</project>

8
.idea/test.iml Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

10
.idea/workspace.xml Normal file
View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="NodePackageJsonFileManager">
<packageJsonPaths />
</component>
<component name="PropertiesComponent">
<property name="nodejs_interpreter_path.stuck_in_default_project" value="undefined stuck path" />
<property name="nodejs_npm_path_reset_for_default_project" value="true" />
</component>
</project>

View File

@ -0,0 +1,133 @@
<?php
namespace App\Api\Helpers;
use Symfony\Component\HttpFoundation\Response as FoundationResponse;
use Response;
trait ApiResponse
{
/**
* @var int
*/
protected $statusCode = FoundationResponse::HTTP_OK;
/**
* @return mixed
*/
public function getStatusCode()
{
return $this->statusCode;
}
/**
* @param $statusCode
* @return $this
*/
public function setStatusCode($statusCode,$httpCode=null)
{
$httpCode = $httpCode ?? $statusCode;
$this->statusCode = $statusCode;
return $this;
}
/**
* @param $data
* @param array $header
* @return mixed
*/
public function respond($data, $header = [])
{
return Response::json($data,$this->getStatusCode(),$header);
}
/**
* @param $status
* @param array $data
* @param null $code
* @return mixed
*/
public function status($status, array $data, $code = null){
if ($code){
$this->setStatusCode($code);
}
$status = [
'status' => $status,
'code' => $this->statusCode
];
$data = array_merge($status,$data);
return $this->respond($data);
}
/**
* @param $message
* @param int $code
* @param string $status
* @return mixed
*/
/*
* 格式
* data:
* code:422
* message:xxx
* status:'error'
*/
public function failed($message, $code = FoundationResponse::HTTP_BAD_REQUEST,$status = 'error'){
return $this->setStatusCode($code)->message($message,$status);
}
/**
* @param $message
* @param string $status
* @return mixed
*/
public function message($message, $status = "success"){
return $this->status($status,[
'message' => $message
]);
}
/**
* @param string $message
* @return mixed
*/
public function internalError($message = "Internal Error!"){
return $this->failed($message,FoundationResponse::HTTP_INTERNAL_SERVER_ERROR);
}
/**
* @param string $message
* @return mixed
*/
public function created($message = "created")
{
return $this->setStatusCode(FoundationResponse::HTTP_CREATED)
->message($message);
}
/**
* @param $data
* @param string $status
* @return mixed
*/
public function success($data, $status = "success"){
return $this->status($status,compact('data'));
}
/**
* @param string $message
* @return mixed
*/
public function notFond($message = 'Not Fond!')
{
return $this->failed($message,Foundationresponse::HTTP_NOT_FOUND);
}
}

View File

@ -0,0 +1,109 @@
<?php
namespace App\Api\Helpers;
use Exception;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Auth\AuthenticationException;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Http\Request;
use Illuminate\Validation\ValidationException;
use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;
use Tymon\JWTAuth\Exceptions\TokenInvalidException;
class ExceptionReport
{
use ApiResponse;
/**
* @var Exception
*/
public $exception;
/**
* @var Request
*/
public $request;
/**
* @var
*/
protected $report;
/**
* ExceptionReport constructor.
* @param Request $request
* @param Exception $exception
*/
function __construct(Request $request, Exception $exception)
{
$this->request = $request;
$this->exception = $exception;
}
/**
* @var array
*/
//当抛出这些异常时可以使用我们定义的错误信息与HTTP状态码
//可以把常见异常放在这里
public $doReport = [
AuthenticationException::class => ['未授权',401],
ModelNotFoundException::class => ['该模型未找到',404],
AuthorizationException::class => ['没有此权限',403],
ValidationException::class => [],
UnauthorizedHttpException::class=>['未登录或登录状态失效',422],
TokenInvalidException::class=>['token不正确',400],
NotFoundHttpException::class=>['没有找到该页面',404],
MethodNotAllowedHttpException::class=>['访问方式不正确',405],
];
public function register($className,callable $callback){
$this->doReport[$className] = $callback;
}
/**
* @return bool
*/
public function shouldReturn(){
//只有请求包含是json或者ajax请求时才有效
// if (! ($this->request->wantsJson() || $this->request->ajax())){
//
// return false;
// }
foreach (array_keys($this->doReport) as $report){
if ($this->exception instanceof $report){
$this->report = $report;
return true;
}
}
return false;
}
/**
* @param Exception $e
* @return static
*/
public static function make(Exception $e){
return new static(\request(),$e);
}
/**
* @return mixed
*/
public function report(){
if ($this->exception instanceof ValidationException){
$error = array_first($this->exception->errors());
return $this->failed(array_first($error),$this->exception->status);
}
$message = $this->doReport[$this->report];
return $this->failed($message[0],$message[1]);
}
public function prodReport(){
return $this->failed('服务器错误','500');
}
}

42
app/Console/Kernel.php Normal file
View File

@ -0,0 +1,42 @@
<?php
namespace App\Console;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
class Kernel extends ConsoleKernel
{
/**
* The Artisan commands provided by your application.
*
* @var array
*/
protected $commands = [
//
];
/**
* Define the application's command schedule.
*
* @param \Illuminate\Console\Scheduling\Schedule $schedule
* @return void
*/
protected function schedule(Schedule $schedule)
{
// $schedule->command('inspire')
// ->hourly();
}
/**
* Register the commands for the application.
*
* @return void
*/
protected function commands()
{
$this->load(__DIR__.'/Commands');
require base_path('routes/console.php');
}
}

View File

@ -0,0 +1,53 @@
<?php
namespace App\Exceptions;
use App\Api\Helpers\ExceptionReport;
use Exception;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
class Handler extends ExceptionHandler
{
protected $dontReport = [
//
];
/**
* A list of the inputs that are never flashed for validation exceptions.
*
* @var array
*/
protected $dontFlash = [
'password',
'password_confirmation',
];
/**
* Report or log an exception.
*
* @param \Exception $exception
* @return void
*/
public function report(Exception $exception)
{
parent::report($exception);
}
public function render($request, Exception $exception)
{
//ajax请求我们才捕捉异常
if ($request->ajax()){
// 将方法拦截到自己的ExceptionReport
$reporter = ExceptionReport::make($exception);
if ($reporter->shouldReturn()){
return $reporter->report();
}
if(env('APP_DEBUG')){
//开发环境,则显示详细错误信息
return parent::render($request, $exception);
}else{
//线上环境,未知错误则显示500
return $reporter->prodReport();
}
}
return parent::render($request, $exception);
}
}

View File

@ -0,0 +1,76 @@
<?php
namespace App\Http\Controllers\Api;
use App\Http\Requests\Api\UserRequest;
use App\Http\Resources\Api\AdminResource;
use App\Jobs\Api\SaveLastTokenJob;
use App\Models\Admin;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Tymon\JWTAuth\Exceptions\TokenExpiredException;
class AdminController extends Controller
{
//返回用户列表
public function index()
{
//3个用户为一页
$admins = Admin::paginate(3);
return AdminResource::collection($admins);
}
//返回单一用户信息
public function show(Admin $admin)
{
return $this->success(new AdminResource($admin));
}
//返回当前登录用户信息
public function info()
{
$admins = Auth::user();
return $this->success(new AdminResource($admins));
}
//用户注册
public function store(UserRequest $request)
{
$admin = Admin::create($request->all());
if ($admin) {
return $this->setStatusCode(201)->success('用户注册成功');
}
return $this->failed('用户注册失败');
}
//用户登录
public function login(Request $request)
{
//获取当前守护的名称
$present_guard = Auth::getDefaultDriver();
$token = Auth::claims(['guard'=>$present_guard])->attempt(['name' => $request->name, 'password' => $request->password]);
if ($token) {
//如果登陆先检查原先是否有存token有的话先失效然后再存入最新的token
$user = Auth::user();
if ($user->last_token) {
try{
Auth::setToken($user->last_token)->invalidate();
}catch (TokenExpiredException $e){
//因为让一个过期的token再失效会抛出异常所以我们捕捉异常不需要做任何处理
}
}
SaveLastTokenJob::dispatch($user,$token);
return $this->setStatusCode(201)->success(['token' => 'bearer ' . $token]);
}
return $this->failed('账号或密码错误', 400);
}
//用户退出
public function logout()
{
Auth::logout();
return $this->success('退出成功...');
}
}

View File

@ -0,0 +1,14 @@
<?php
namespace App\Http\Controllers\Api;
use App\Api\Helpers\ApiResponse;
use App\Http\Controllers\Controller as BaseController;
class Controller extends BaseController
{
use ApiResponse;
// 其他通用的Api帮助函数
}

View File

@ -0,0 +1,73 @@
<?php
namespace App\Http\Controllers\Api;
use App\Http\Requests\Api\UserRequest;
use App\Http\Resources\Api\UserResource;
use App\Jobs\Api\SaveLastTokenJob;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Tymon\JWTAuth\Exceptions\TokenExpiredException;
class UserController extends Controller
{
//返回用户列表
public function index(){
//3个用户为一页
$users = User::paginate(3);
return UserResource::collection($users);
}
//返回单一用户信息
public function show(User $user){
return $this->success(new UserResource($user));
}
//返回当前登录用户信息
public function info(){
$user = Auth::user();
return $this->success(new UserResource($user));
}
//用户注册
public function store(UserRequest $request){
$user = User::create($request->all());
if($user){
return $this->setStatusCode(201)->success('用户注册成功');
}
return $this->failed('用户注册失败');
}
//用户登录
public function login(Request $request){
$token=Auth::claims(['type'=>'api'])->attempt(['name'=>$request->name,'password'=>$request->password]);
if($token) {
//如果登陆先检查原先是否有存token有的话先失效然后再存入最新的token
$user = Auth::user();
if($user->last_token){
try{
Auth::setToken($user->last_token)->invalidate();
}catch (TokenExpiredException $e){
//因为让一个过期的token再失效会抛出异常所以我们捕捉异常不需要做任何处理
}
}
SaveLastTokenJob::dispatch($user,$token);
return $this->setStatusCode(201)->success(['token' => 'bearer ' . $token]);
}
return $this->failed('账号或密码错误',400);
}
//用户退出
public function logout(){
Auth::logout();
return $this->success('退出成功...');
}
public function test(Request $request){
$token = Auth::guard('api')->getToken();
$token = Auth::guard('admin')->setToken($token)->refresh();
dd(Auth::guard('admin')->setToken($token)->check());
return $token;
$token = Auth::guard('api')->getToken();
Auth::guard('api')->setToken($token)->invalidate();
}
}

View File

@ -0,0 +1,32 @@
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\SendsPasswordResetEmails;
class ForgotPasswordController extends Controller
{
/*
|--------------------------------------------------------------------------
| Password Reset Controller
|--------------------------------------------------------------------------
|
| This controller is responsible for handling password reset emails and
| includes a trait which assists in sending these notifications from
| your application to your users. Feel free to explore this trait.
|
*/
use SendsPasswordResetEmails;
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('guest');
}
}

View File

@ -0,0 +1,43 @@
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
class LoginController extends Controller
{
/*
|--------------------------------------------------------------------------
| Login Controller
|--------------------------------------------------------------------------
|
| This controller handles authenticating users for the application and
| redirecting them to your home screen. The controller uses a trait
| to conveniently provide its functionality to your applications.
|
*/
use AuthenticatesUsers;
/**
* Where to redirect users after login.
*
* @var string
*/
protected $redirectTo = '/home';
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('guest')->except('logout');
}
public function username()
{
return 'name';
}
}

View File

@ -0,0 +1,72 @@
<?php
namespace App\Http\Controllers\Auth;
use FApp\Models\User;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
use Illuminate\Foundation\Auth\RegistersUsers;
class RegisterController extends Controller
{
/*
|--------------------------------------------------------------------------
| Register Controller
|--------------------------------------------------------------------------
|
| This controller handles the registration of new users as well as their
| validation and creation. By default this controller uses a trait to
| provide this functionality without requiring any additional code.
|
*/
use RegistersUsers;
/**
* Where to redirect users after registration.
*
* @var string
*/
protected $redirectTo = '/home';
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('guest');
}
/**
* Get a validator for an incoming registration request.
*
* @param array $data
* @return \Illuminate\Contracts\Validation\Validator
*/
protected function validator(array $data)
{
return Validator::make($data, [
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
'password' => ['required', 'string', 'min:6', 'confirmed'],
]);
}
/**
* Create a new user instance after a valid registration.
*
* @param array $data
* @return \App\Models\User
*/
protected function create(array $data)
{
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
]);
}
}

View File

@ -0,0 +1,39 @@
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\ResetsPasswords;
class ResetPasswordController extends Controller
{
/*
|--------------------------------------------------------------------------
| Password Reset Controller
|--------------------------------------------------------------------------
|
| This controller is responsible for handling password reset requests
| and uses a simple trait to include this behavior. You're free to
| explore this trait and override any methods you wish to tweak.
|
*/
use ResetsPasswords;
/**
* Where to redirect users after resetting their password.
*
* @var string
*/
protected $redirectTo = '/home';
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('guest');
}
}

View File

@ -0,0 +1,41 @@
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\VerifiesEmails;
class VerificationController extends Controller
{
/*
|--------------------------------------------------------------------------
| Email Verification Controller
|--------------------------------------------------------------------------
|
| This controller is responsible for handling email verification for any
| user that recently registered with the application. Emails may also
| be re-sent if the user didn't receive the original email message.
|
*/
use VerifiesEmails;
/**
* Where to redirect users after verification.
*
* @var string
*/
protected $redirectTo = '/home';
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('auth');
$this->middleware('signed')->only('verify');
$this->middleware('throttle:6,1')->only('verify', 'resend');
}
}

View File

@ -0,0 +1,13 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
class Controller extends BaseController
{
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
}

85
app/Http/Kernel.php Normal file
View File

@ -0,0 +1,85 @@
<?php
namespace App\Http;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
class Kernel extends HttpKernel
{
/**
* The application's global HTTP middleware stack.
*
* These middleware are run during every request to your application.
*
* @var array
*/
protected $middleware = [
\App\Http\Middleware\CheckForMaintenanceMode::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
\App\Http\Middleware\TrimStrings::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
\App\Http\Middleware\TrustProxies::class,
];
/**
* The application's route middleware groups.
*
* @var array
*/
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
// \Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
'api' => [
'throttle:60,1',
'bindings',
],
];
/**
* The application's route middleware.
*
* These middleware may be assigned to groups or used individually.
*
* @var array
*/
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
'cors'=> \Medz\Cors\Laravel\Middleware\ShouldGroup::class,
'api.refresh'=>\App\Http\Middleware\Api\RefreshTokenMiddleware::class,
'admin.refresh'=>\App\Http\Middleware\Api\RefreshAdminTokenMiddleware::class,
'admin.guard'=>\App\Http\Middleware\Api\AdminGuardMiddleware::class,
'api.guard'=>\App\Http\Middleware\Api\UserGuardMiddleware::class,
];
/**
* The priority-sorted list of middleware.
*
* This forces non-global middleware to always be in the given order.
*
* @var array
*/
protected $middlewarePriority = [
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\Authenticate::class,
\Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
\Illuminate\Auth\Middleware\Authorize::class,
];
}

View File

@ -0,0 +1,22 @@
<?php
namespace App\Http\Middleware\Api;
use Closure;
class AdminGuardMiddleware
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
*
* @throws \Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException
*
* @return mixed
*/
public function handle($request, Closure $next)
{
config(['auth.defaults.guard'=>'admin']);
return $next($request);
}
}

View File

@ -0,0 +1,76 @@
<?php
namespace App\Http\Middleware\Api;
use App\Jobs\Api\SaveLastTokenJob;
use Auth;
use Closure;
use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;
use Tymon\JWTAuth\Exceptions\JWTException;
use Tymon\JWTAuth\Exceptions\TokenExpiredException;
use Tymon\JWTAuth\Exceptions\TokenInvalidException;
use Tymon\JWTAuth\Http\Middleware\BaseMiddleware;
// 注意,我们要继承的是 jwt 的 BaseMiddleware
class RefreshAdminTokenMiddleware extends BaseMiddleware
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
*
* @throws \Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException
*
* @return mixed
* @throws TokenInvalidException
*/
public function handle($request, Closure $next)
{
// 检查此次请求中是否带有 token如果没有则抛出异常。
$this->checkForToken($request);
//1. 格式通过验证是否是专属于这个的token
//获取当前守护的名称
$present_guard = Auth::getDefaultDriver();
//获取当前token
$token=Auth::getToken();
//即使过期了也能获取到token里的 载荷 信息。
$payload = Auth::manager()->getJWTProvider()->decode($token->get());
//如果不包含guard字段或者guard所对应的值与当前的guard守护值不相同
//证明是不属于当前guard守护的token
if(empty($payload['guard'])||$payload['guard']!=$present_guard){
throw new TokenInvalidException();
}
//使用 try 包裹,以捕捉 token 过期所抛出的 TokenExpiredException 异常
//2. 此时进入的都是属于当前guard守护的token
try {
// 检测用户的登录状态,如果正常则通过
if ($this->auth->parseToken()->authenticate()) {
return $next($request);
}
throw new UnauthorizedHttpException('jwt-auth', '未登录');
} catch (TokenExpiredException $exception) {
// 3. 此处捕获到了 token 过期所抛出的 TokenExpiredException 异常,我们在这里需要做的是刷新该用户的 token 并将它添加到响应头中
try {
// 刷新用户的 token
$token = $this->auth->refresh();
// 使用一次性登录以保证此次请求的成功
Auth::onceUsingId($this->auth->manager()->getPayloadFactory()->buildClaimsCollection()->toPlainArray()['sub']);
//刷新了token将token存入数据库
$user = Auth::user();
SaveLastTokenJob::dispatch($user,$token);
} catch (JWTException $exception) {
// 如果捕获到此异常,即代表 refresh 也过期了,用户无法刷新令牌,需要重新登录。
throw new UnauthorizedHttpException('jwt-auth', $exception->getMessage());
}
}
// 在响应头中返回新的 token
return $this->setAuthenticationHeader($next($request), $token);
}
}

View File

@ -0,0 +1,77 @@
<?php
namespace App\Http\Middleware\Api;
use App\Jobs\Api\SaveLastTokenJob;
use Auth;
use Closure;
use Tymon\JWTAuth\Exceptions\JWTException;
use Tymon\JWTAuth\Exceptions\TokenInvalidException;
use Tymon\JWTAuth\Facades\JWTAuth;
use Tymon\JWTAuth\Http\Middleware\BaseMiddleware;
use Tymon\JWTAuth\Exceptions\TokenExpiredException;
use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;
// 注意,我们要继承的是 jwt 的 BaseMiddleware
class RefreshTokenMiddleware extends BaseMiddleware
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
*
* @throws \Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException
*
* @return mixed
*/
public function handle($request, Closure $next)
{
// 检查此次请求中是否带有 token如果没有则抛出异常。
$this->checkForToken($request);
//1. 格式通过验证是否是专属于这个的token
//获取当前守护的名称
$present_guard = Auth::getDefaultDriver();
//获取当前token
$token=Auth::getToken();
//即使过期了也能获取到token里的 载荷 信息。
$payload = Auth::manager()->getJWTProvider()->decode($token->get());
//如果不包含guard字段或者guard所对应的值与当前的guard守护值不相同
//证明是不属于当前guard守护的token
if(empty($payload['guard'])||$payload['guard']!=$present_guard){
throw new TokenInvalidException();
}
//使用 try 包裹,以捕捉 token 过期所抛出的 TokenExpiredException 异常
//2. 此时进入的都是属于当前guard守护的token
try {
// 检测用户的登录状态,如果正常则通过
if ($this->auth->parseToken()->authenticate()) {
return $next($request);
}
throw new UnauthorizedHttpException('jwt-auth', '未登录');
} catch (TokenExpiredException $exception) {
// 此处捕获到了 token 过期所抛出的 TokenExpiredException 异常,我们在这里需要做的是刷新该用户的 token 并将它添加到响应头中
try {
// 刷新用户的 token
$token = $this->auth->refresh();
// 使用一次性登录以保证此次请求的成功
Auth::onceUsingId($this->auth->manager()->getPayloadFactory()->buildClaimsCollection()->toPlainArray()['sub']);
//刷新了token将token存入数据库
$user = Auth::user();
SaveLastTokenJob::dispatch($user,$token);
} catch (JWTException $exception) {
// 如果捕获到此异常,即代表 refresh 也过期了,用户无法刷新令牌,需要重新登录。
throw new UnauthorizedHttpException('jwt-auth', $exception->getMessage());
}
}
// 在响应头中返回新的 token
return $this->setAuthenticationHeader($next($request), $token);
}
}

View File

@ -0,0 +1,22 @@
<?php
namespace App\Http\Middleware\Api;
use Closure;
class UserGuardMiddleware
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
*
* @throws \Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException
*
* @return mixed
*/
public function handle($request, Closure $next)
{
config(['auth.defaults.guard'=>'api']);
return $next($request);
}
}

View File

@ -0,0 +1,21 @@
<?php
namespace App\Http\Middleware;
use Illuminate\Auth\Middleware\Authenticate as Middleware;
class Authenticate extends Middleware
{
/**
* Get the path the user should be redirected to when they are not authenticated.
*
* @param \Illuminate\Http\Request $request
* @return string
*/
protected function redirectTo($request)
{
if (! $request->expectsJson()) {
return route('login');
}
}
}

View File

@ -0,0 +1,17 @@
<?php
namespace App\Http\Middleware;
use Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode as Middleware;
class CheckForMaintenanceMode extends Middleware
{
/**
* The URIs that should be reachable while maintenance mode is enabled.
*
* @var array
*/
protected $except = [
//
];
}

View File

@ -0,0 +1,17 @@
<?php
namespace App\Http\Middleware;
use Illuminate\Cookie\Middleware\EncryptCookies as Middleware;
class EncryptCookies extends Middleware
{
/**
* The names of the cookies that should not be encrypted.
*
* @var array
*/
protected $except = [
//
];
}

View File

@ -0,0 +1,26 @@
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Auth;
class RedirectIfAuthenticated
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @param string|null $guard
* @return mixed
*/
public function handle($request, Closure $next, $guard = null)
{
if (Auth::guard($guard)->check()) {
return redirect('/home');
}
return $next($request);
}
}

View File

@ -0,0 +1,18 @@
<?php
namespace App\Http\Middleware;
use Illuminate\Foundation\Http\Middleware\TrimStrings as Middleware;
class TrimStrings extends Middleware
{
/**
* The names of the attributes that should not be trimmed.
*
* @var array
*/
protected $except = [
'password',
'password_confirmation',
];
}

View File

@ -0,0 +1,23 @@
<?php
namespace App\Http\Middleware;
use Illuminate\Http\Request;
use Fideloper\Proxy\TrustProxies as Middleware;
class TrustProxies extends Middleware
{
/**
* The trusted proxies for this application.
*
* @var array
*/
protected $proxies;
/**
* The headers that should be used to detect proxies.
*
* @var int
*/
protected $headers = Request::HEADER_X_FORWARDED_ALL;
}

View File

@ -0,0 +1,24 @@
<?php
namespace App\Http\Middleware;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;
class VerifyCsrfToken extends Middleware
{
/**
* Indicates whether the XSRF-TOKEN cookie should be set on the response.
*
* @var bool
*/
protected $addHttpCookie = true;
/**
* The URIs that should be excluded from CSRF verification.
*
* @var array
*/
protected $except = [
//
];
}

View File

@ -0,0 +1,50 @@
<?php
namespace App\Http\Requests\Api;
class AdminRequest extends FormRequest
{
public function rules()
{
switch ($this->method()) {
case 'GET':
{
return [
'id' => ['required,exists:users,id']
];
}
case 'POST':
{
return [
'name' => ['required', 'max:12', 'unique:users,name'],
'password' => ['required', 'max:16', 'min:6']
];
}
case 'PUT':
case 'PATCH':
case 'DELETE':
default:
{
return [
];
}
}
}
public function messages()
{
return [
'id.required'=>'用户ID必须填写',
'id.exists'=>'用户不存在',
'name.unique' => '用户名已经存在',
'name.required' => '用户名不能为空',
'name.max' => '用户名最大长度为12个字符',
'password.required' => '密码不能为空',
'password.max' => '密码长度不能超过16个字符',
'password.min' => '密码长度不能小于6个字符'
];
}
}

View File

@ -0,0 +1,13 @@
<?php
namespace App\Http\Requests\Api;
use Illuminate\Foundation\Http\FormRequest as BaseFormRequest;
class FormRequest extends BaseFormRequest
{
public function authorize()
{
return true;
}
}

View File

@ -0,0 +1,50 @@
<?php
namespace App\Http\Requests\Api;
class UserRequest extends FormRequest
{
public function rules()
{
switch ($this->method()) {
case 'GET':
{
return [
'id' => ['required,exists:users,id']
];
}
case 'POST':
{
return [
'name' => ['required', 'max:12', 'unique:users,name'],
'password' => ['required', 'max:16', 'min:6']
];
}
case 'PUT':
case 'PATCH':
case 'DELETE':
default:
{
return [
];
}
}
}
public function messages()
{
return [
'id.required'=>'用户ID必须填写',
'id.exists'=>'用户不存在',
'name.unique' => '用户名已经存在',
'name.required' => '用户名不能为空',
'name.max' => '用户名最大长度为12个字符',
'password.required' => '密码不能为空',
'password.max' => '密码长度不能超过16个字符',
'password.min' => '密码长度不能小于6个字符'
];
}
}

View File

@ -0,0 +1,26 @@
<?php
namespace App\Http\Resources\Api;
use App\Models\Enum\AdminEnum;
use Illuminate\Http\Resources\Json\JsonResource;
class AdminResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function toArray($request)
{
return [
'id'=>$this->id,
'name' => $this->name,
'status' => AdminEnum::getStatusName($this->status),
'created_at'=>(string)$this->created_at,
'updated_at'=>(string)$this->updated_at
];
}
}

View File

@ -0,0 +1,26 @@
<?php
namespace App\Http\Resources\Api;
use App\Models\Enum\UserEnum;
use Illuminate\Http\Resources\Json\JsonResource;
class UserResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function toArray($request)
{
return [
'id'=>$this->id,
'name' => $this->name,
'status' => UserEnum::getStatusName($this->status),
'created_at'=>(string)$this->created_at,
'updated_at'=>(string)$this->updated_at
];
}
}

View File

@ -0,0 +1,40 @@
<?php
namespace App\Jobs\Api;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
class SaveLastTokenJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
protected $model;
protected $token;
/**
* Create a new job instance.
*
* @return void
*/
public function __construct($model,$token)
{
//
$this->model=$model;
$this->token=$token;
}
/**
* Execute the job.
*
* @return void
*/
public function handle()
{
//
$this->model->last_token = $this->token;
$this->model->save();
}
}

55
app/Models/Admin.php Normal file
View File

@ -0,0 +1,55 @@
<?php
namespace App\Models;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Tymon\JWTAuth\Contracts\JWTSubject;
class Admin extends Authenticatable implements JWTSubject
{
use Notifiable;
/**
* Get the identifier that will be stored in the subject claim of the JWT.
*
* @return mixed
*/
public function getJWTIdentifier()
{
return $this->getKey();
}
/**
* Return a key value array, containing any custom claims to be added to the JWT.
*
* @return array
*/
public function getJWTCustomClaims()
{
return [];
}
protected $table = 'admins';
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'name', 'password'
];
/**
* The attributes that should be hidden for arrays.
*
* @var array
*/
protected $hidden = [
'password'
];
//将密码进行加密
public function setPasswordAttribute($value)
{
$this->attributes['password'] = bcrypt($value);
}
}

23
app/Models/Enum/AdminEnum.php Executable file
View File

@ -0,0 +1,23 @@
<?php
namespace App\Models\Enum;
class AdminEnum
{
// 状态类别
const INVALID = -1; //已删除
const NORMAL = 0; //正常
const FREEZE = 1; //冻结
public static function getStatusName($status){
switch ($status){
case self::INVALID:
return '已删除';
case self::NORMAL:
return '正常';
case self::FREEZE:
return '冻结';
default:
return '正常';
}
}
}

23
app/Models/Enum/UserEnum.php Executable file
View File

@ -0,0 +1,23 @@
<?php
namespace App\Models\Enum;
class UserEnum
{
// 状态类别
const INVALID = -1; //已删除
const NORMAL = 0; //正常
const FREEZE = 1; //冻结
public static function getStatusName($status){
switch ($status){
case self::INVALID:
return '已删除';
case self::NORMAL:
return '正常';
case self::FREEZE:
return '冻结';
default:
return '正常';
}
}
}

54
app/Models/User.php Normal file
View File

@ -0,0 +1,54 @@
<?php
namespace App\Models;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Tymon\JWTAuth\Contracts\JWTSubject;
class User extends Authenticatable implements JWTSubject
{
use Notifiable;
/**
* Get the identifier that will be stored in the subject claim of the JWT.
*
* @return mixed
*/
public function getJWTIdentifier()
{
return $this->getKey();
}
/**
* Return a key value array, containing any custom claims to be added to the JWT.
*
* @return array
*/
public function getJWTCustomClaims()
{
return [];
}
protected $table = 'users';
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'name', 'password'
];
/**
* The attributes that should be hidden for arrays.
*
* @var array
*/
protected $hidden = [
'password'
];
//将密码进行加密
public function setPasswordAttribute($value)
{
$this->attributes['password'] = bcrypt($value);
}
}

View File

@ -0,0 +1,28 @@
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
//
}
/**
* Register any application services.
*
* @return void
*/
public function register()
{
//
}
}

View File

@ -0,0 +1,39 @@
<?php
namespace App\Providers;
use Illuminate\Support\Facades\Gate;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use Laravel\Horizon\Horizon;
class AuthServiceProvider extends ServiceProvider
{
/**
* The policy mappings for the application.
*
* @var array
*/
protected $policies = [
'App\Model' => 'App\Policies\ModelPolicy',
];
/**
* Register any authentication / authorization services.
*
* @return void
*/
public function boot()
{
$this->registerPolicies();
Horizon::auth(function($request){
if(env('APP_ENV','local') == 'local'){
return true;
}else{
$get_ip = $request->getClientIp();
$can_ip=env('HORIZON_IP','127.0.0.1');
return $get_ip == $can_ip;
}
});
//
}
}

View File

@ -0,0 +1,21 @@
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Broadcast;
class BroadcastServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
Broadcast::routes();
require base_path('routes/channels.php');
}
}

View File

@ -0,0 +1,34 @@
<?php
namespace App\Providers;
use Illuminate\Support\Facades\Event;
use Illuminate\Auth\Events\Registered;
use Illuminate\Auth\Listeners\SendEmailVerificationNotification;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
class EventServiceProvider extends ServiceProvider
{
/**
* The event listener mappings for the application.
*
* @var array
*/
protected $listen = [
Registered::class => [
SendEmailVerificationNotification::class,
],
];
/**
* Register any events for your application.
*
* @return void
*/
public function boot()
{
parent::boot();
//
}
}

View File

@ -0,0 +1,50 @@
<?php
namespace App\Providers;
use Laravel\Horizon\Horizon;
use Illuminate\Support\Facades\Gate;
use Laravel\Horizon\HorizonApplicationServiceProvider;
class HorizonServiceProvider extends HorizonApplicationServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
parent::boot();
// Horizon::routeSmsNotificationsTo('15556667777');
// Horizon::routeMailNotificationsTo('example@example.com');
// Horizon::routeSlackNotificationsTo('slack-webhook-url', '#channel');
}
/**
* Register the Horizon gate.
*
* This gate determines who can access Horizon in non-local environments.
*
* @return void
*/
protected function gate()
{
Gate::define('viewHorizon', function ($user) {
return in_array($user->email, [
//
]);
});
}
/**
* Register any application services.
*
* @return void
*/
public function register()
{
// Horizon::night();
}
}

View File

@ -0,0 +1,73 @@
<?php
namespace App\Providers;
use Illuminate\Support\Facades\Route;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
class RouteServiceProvider extends ServiceProvider
{
/**
* This namespace is applied to your controller routes.
*
* In addition, it is set as the URL generator's root namespace.
*
* @var string
*/
protected $namespace = 'App\Http\Controllers';
/**
* Define your route model bindings, pattern filters, etc.
*
* @return void
*/
public function boot()
{
//
parent::boot();
}
/**
* Define the routes for the application.
*
* @return void
*/
public function map()
{
$this->mapApiRoutes();
$this->mapWebRoutes();
//
}
/**
* Define the "web" routes for the application.
*
* These routes all receive session state, CSRF protection, etc.
*
* @return void
*/
protected function mapWebRoutes()
{
Route::middleware('web')
->namespace($this->namespace)
->group(base_path('routes/web.php'));
}
/**
* Define the "api" routes for the application.
*
* These routes are typically stateless.
*
* @return void
*/
protected function mapApiRoutes()
{
Route::prefix('api')
->middleware('api')
->namespace($this->namespace)
->group(base_path('routes/api.php'));
}
}

53
artisan Executable file
View File

@ -0,0 +1,53 @@
#!/usr/bin/env php
<?php
define('LARAVEL_START', microtime(true));
/*
|--------------------------------------------------------------------------
| Register The Auto Loader
|--------------------------------------------------------------------------
|
| Composer provides a convenient, automatically generated class loader
| for our application. We just need to utilize it! We'll require it
| into the script here so that we do not have to worry about the
| loading of any our classes "manually". Feels great to relax.
|
*/
require __DIR__.'/vendor/autoload.php';
$app = require_once __DIR__.'/bootstrap/app.php';
/*
|--------------------------------------------------------------------------
| Run The Artisan Application
|--------------------------------------------------------------------------
|
| When we run the console application, the current CLI command will be
| executed in this console and the response sent back to a terminal
| or another output device for the developers. Here goes nothing!
|
*/
$kernel = $app->make(Illuminate\Contracts\Console\Kernel::class);
$status = $kernel->handle(
$input = new Symfony\Component\Console\Input\ArgvInput,
new Symfony\Component\Console\Output\ConsoleOutput
);
/*
|--------------------------------------------------------------------------
| Shutdown The Application
|--------------------------------------------------------------------------
|
| Once Artisan has finished running, we will fire off the shutdown events
| so that any final work may be done by the application before we shut
| down the process. This is the last thing to happen to the request.
|
*/
$kernel->terminate($input, $status);
exit($status);

55
bootstrap/app.php Normal file
View File

@ -0,0 +1,55 @@
<?php
/*
|--------------------------------------------------------------------------
| Create The Application
|--------------------------------------------------------------------------
|
| The first thing we will do is create a new Laravel application instance
| which serves as the "glue" for all the components of Laravel, and is
| the IoC container for the system binding all of the various parts.
|
*/
$app = new Illuminate\Foundation\Application(
$_ENV['APP_BASE_PATH'] ?? dirname(__DIR__)
);
/*
|--------------------------------------------------------------------------
| Bind Important Interfaces
|--------------------------------------------------------------------------
|
| Next, we need to bind some important interfaces into the container so
| we will be able to resolve them when needed. The kernels serve the
| incoming requests to this application from both the web and CLI.
|
*/
$app->singleton(
Illuminate\Contracts\Http\Kernel::class,
App\Http\Kernel::class
);
$app->singleton(
Illuminate\Contracts\Console\Kernel::class,
App\Console\Kernel::class
);
$app->singleton(
Illuminate\Contracts\Debug\ExceptionHandler::class,
App\Exceptions\Handler::class
);
/*
|--------------------------------------------------------------------------
| Return The Application
|--------------------------------------------------------------------------
|
| This script returns the application instance. The instance is given to
| the calling script so we can separate the building of the instances
| from the actual running of the application and sending responses.
|
*/
return $app;

2
bootstrap/cache/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
*
!.gitignore

65
composer.json Normal file
View File

@ -0,0 +1,65 @@
{
"name": "laravel/laravel",
"type": "project",
"description": "The Laravel Framework.",
"keywords": [
"framework",
"laravel"
],
"license": "MIT",
"require": {
"php": "^7.1.3",
"fideloper/proxy": "^4.0",
"laravel/framework": "5.7.*",
"laravel/horizon": "^3.0",
"laravel/tinker": "^1.0",
"medz/cors": "^1.4",
"tymon/jwt-auth": "1.0.0-rc.3"
},
"require-dev": {
"beyondcode/laravel-dump-server": "^1.0",
"filp/whoops": "^2.0",
"fzaninotto/faker": "^1.4",
"mockery/mockery": "^1.0",
"nunomaduro/collision": "^2.0",
"phpunit/phpunit": "^7.0"
},
"config": {
"optimize-autoloader": true,
"preferred-install": "dist",
"sort-packages": true
},
"extra": {
"laravel": {
"dont-discover": []
}
},
"autoload": {
"psr-4": {
"App\\": "app/"
},
"classmap": [
"database/seeds",
"database/factories"
]
},
"autoload-dev": {
"psr-4": {
"Tests\\": "tests/"
}
},
"minimum-stability": "dev",
"prefer-stable": true,
"scripts": {
"post-autoload-dump": [
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
"@php artisan package:discover --ansi"
],
"post-root-package-install": [
"@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
],
"post-create-project-cmd": [
"@php artisan key:generate --ansi"
]
}
}

6005
composer.lock generated Normal file

File diff suppressed because it is too large Load Diff

229
config/app.php Normal file
View File

@ -0,0 +1,229 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Application Name
|--------------------------------------------------------------------------
|
| This value is the name of your application. This value is used when the
| framework needs to place the application's name in a notification or
| any other location as required by the application or its packages.
|
*/
'name' => env('APP_NAME', 'Laravel'),
/*
|--------------------------------------------------------------------------
| Application Environment
|--------------------------------------------------------------------------
|
| This value determines the "environment" your application is currently
| running in. This may determine how you prefer to configure various
| services the application utilizes. Set this in your ".env" file.
|
*/
'env' => env('APP_ENV', 'production'),
/*
|--------------------------------------------------------------------------
| Application Debug Mode
|--------------------------------------------------------------------------
|
| When your application is in debug mode, detailed error messages with
| stack traces will be shown on every error that occurs within your
| application. If disabled, a simple generic error page is shown.
|
*/
'debug' => env('APP_DEBUG', false),
/*
|--------------------------------------------------------------------------
| Application URL
|--------------------------------------------------------------------------
|
| This URL is used by the console to properly generate URLs when using
| the Artisan command line tool. You should set this to the root of
| your application so that it is used when running Artisan tasks.
|
*/
'url' => env('APP_URL', 'http://localhost'),
'asset_url' => env('ASSET_URL', null),
/*
|--------------------------------------------------------------------------
| Application Timezone
|--------------------------------------------------------------------------
|
| Here you may specify the default timezone for your application, which
| will be used by the PHP date and date-time functions. We have gone
| ahead and set this to a sensible default for you out of the box.
|
*/
'timezone' => 'UTC',
/*
|--------------------------------------------------------------------------
| Application Locale Configuration
|--------------------------------------------------------------------------
|
| The application locale determines the default locale that will be used
| by the translation service provider. You are free to set this value
| to any of the locales which will be supported by the application.
|
*/
'locale' => 'en',
/*
|--------------------------------------------------------------------------
| Application Fallback Locale
|--------------------------------------------------------------------------
|
| The fallback locale determines the locale to use when the current one
| is not available. You may change the value to correspond to any of
| the language folders that are provided through your application.
|
*/
'fallback_locale' => 'en',
/*
|--------------------------------------------------------------------------
| Faker Locale
|--------------------------------------------------------------------------
|
| This locale will be used by the Faker PHP library when generating fake
| data for your database seeds. For example, this will be used to get
| localized telephone numbers, street address information and more.
|
*/
'faker_locale' => 'en_US',
/*
|--------------------------------------------------------------------------
| Encryption Key
|--------------------------------------------------------------------------
|
| This key is used by the Illuminate encrypter service and should be set
| to a random, 32 character string, otherwise these encrypted strings
| will not be safe. Please do this before deploying an application!
|
*/
'key' => env('APP_KEY'),
'cipher' => 'AES-256-CBC',
/*
|--------------------------------------------------------------------------
| Autoloaded Service Providers
|--------------------------------------------------------------------------
|
| The service providers listed here will be automatically loaded on the
| request to your application. Feel free to add your own services to
| this array to grant expanded functionality to your applications.
|
*/
'providers' => [
/*
* Laravel Framework Service Providers...
*/
Illuminate\Auth\AuthServiceProvider::class,
Illuminate\Broadcasting\BroadcastServiceProvider::class,
Illuminate\Bus\BusServiceProvider::class,
Illuminate\Cache\CacheServiceProvider::class,
Illuminate\Foundation\Providers\ConsoleSupportServiceProvider::class,
Illuminate\Cookie\CookieServiceProvider::class,
Illuminate\Database\DatabaseServiceProvider::class,
Illuminate\Encryption\EncryptionServiceProvider::class,
Illuminate\Filesystem\FilesystemServiceProvider::class,
Illuminate\Foundation\Providers\FoundationServiceProvider::class,
Illuminate\Hashing\HashServiceProvider::class,
Illuminate\Mail\MailServiceProvider::class,
Illuminate\Notifications\NotificationServiceProvider::class,
Illuminate\Pagination\PaginationServiceProvider::class,
Illuminate\Pipeline\PipelineServiceProvider::class,
Illuminate\Queue\QueueServiceProvider::class,
Illuminate\Redis\RedisServiceProvider::class,
Illuminate\Auth\Passwords\PasswordResetServiceProvider::class,
Illuminate\Session\SessionServiceProvider::class,
Illuminate\Translation\TranslationServiceProvider::class,
Illuminate\Validation\ValidationServiceProvider::class,
Illuminate\View\ViewServiceProvider::class,
/*
* Package Service Providers...
*/
/*
* Application Service Providers...
*/
App\Providers\AppServiceProvider::class,
App\Providers\AuthServiceProvider::class,
// App\Providers\BroadcastServiceProvider::class,
App\Providers\EventServiceProvider::class,
App\Providers\RouteServiceProvider::class,
Tymon\JWTAuth\Providers\LaravelServiceProvider::class,
],
/*
|--------------------------------------------------------------------------
| Class Aliases
|--------------------------------------------------------------------------
|
| This array of class aliases will be registered when this application
| is started. However, feel free to register as many as you wish as
| the aliases are "lazy" loaded so they don't hinder performance.
|
*/
'aliases' => [
'App' => Illuminate\Support\Facades\App::class,
'Artisan' => Illuminate\Support\Facades\Artisan::class,
'Auth' => Illuminate\Support\Facades\Auth::class,
'Blade' => Illuminate\Support\Facades\Blade::class,
'Broadcast' => Illuminate\Support\Facades\Broadcast::class,
'Bus' => Illuminate\Support\Facades\Bus::class,
'Cache' => Illuminate\Support\Facades\Cache::class,
'Config' => Illuminate\Support\Facades\Config::class,
'Cookie' => Illuminate\Support\Facades\Cookie::class,
'Crypt' => Illuminate\Support\Facades\Crypt::class,
'DB' => Illuminate\Support\Facades\DB::class,
'Eloquent' => Illuminate\Database\Eloquent\Model::class,
'Event' => Illuminate\Support\Facades\Event::class,
'File' => Illuminate\Support\Facades\File::class,
'Gate' => Illuminate\Support\Facades\Gate::class,
'Hash' => Illuminate\Support\Facades\Hash::class,
'Lang' => Illuminate\Support\Facades\Lang::class,
'Log' => Illuminate\Support\Facades\Log::class,
'Mail' => Illuminate\Support\Facades\Mail::class,
'Notification' => Illuminate\Support\Facades\Notification::class,
'Password' => Illuminate\Support\Facades\Password::class,
'Queue' => Illuminate\Support\Facades\Queue::class,
'Redirect' => Illuminate\Support\Facades\Redirect::class,
'Redis' => Illuminate\Support\Facades\Redis::class,
'Request' => Illuminate\Support\Facades\Request::class,
'Response' => Illuminate\Support\Facades\Response::class,
'Route' => Illuminate\Support\Facades\Route::class,
'Schema' => Illuminate\Support\Facades\Schema::class,
'Session' => Illuminate\Support\Facades\Session::class,
'Storage' => Illuminate\Support\Facades\Storage::class,
'URL' => Illuminate\Support\Facades\URL::class,
'Validator' => Illuminate\Support\Facades\Validator::class,
'View' => Illuminate\Support\Facades\View::class,
],
];

110
config/auth.php Normal file
View File

@ -0,0 +1,110 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Authentication Defaults
|--------------------------------------------------------------------------
|
| This option controls the default authentication "guard" and password
| reset options for your application. You may change these defaults
| as required, but they're a perfect start for most applications.
|
*/
'defaults' => [
'guard' => 'web',
'passwords' => 'users',
],
/*
|--------------------------------------------------------------------------
| Authentication Guards
|--------------------------------------------------------------------------
|
| Next, you may define every authentication guard for your application.
| Of course, a great default configuration has been defined for you
| here which uses session storage and the Eloquent user provider.
|
| All authentication drivers have a user provider. This defines how the
| users are actually retrieved out of your database or other storage
| mechanisms used by this application to persist your user's data.
|
| Supported: "session", "token"
|
*/
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'jwt',
'provider' => 'users',
],
'admin' => [
'driver' => 'jwt',
'provider' => 'admins',
],
],
/*
|--------------------------------------------------------------------------
| User Providers
|--------------------------------------------------------------------------
|
| All authentication drivers have a user provider. This defines how the
| users are actually retrieved out of your database or other storage
| mechanisms used by this application to persist your user's data.
|
| If you have multiple user tables or models you may configure multiple
| sources which represent each model / table. These sources may then
| be assigned to any extra authentication guards you have defined.
|
| Supported: "database", "eloquent"
|
*/
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\Models\User::class,
],
'admins' => [
'driver' => 'eloquent',
'model' => App\Models\Admin::class,
],
// 'users' => [
// 'driver' => 'database',
// 'table' => 'users',
// ],
],
/*
|--------------------------------------------------------------------------
| Resetting Passwords
|--------------------------------------------------------------------------
|
| You may specify multiple password reset configurations if you have more
| than one user table or model in the application and you want to have
| separate password reset settings based on the specific user types.
|
| The expire time is the number of minutes that the reset token should be
| considered valid. This security feature keeps tokens short-lived so
| they have less time to be guessed. You may change this as needed.
|
*/
'passwords' => [
'users' => [
'provider' => 'users',
'table' => 'password_resets',
'expire' => 60,
],
],
];

59
config/broadcasting.php Normal file
View File

@ -0,0 +1,59 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Default Broadcaster
|--------------------------------------------------------------------------
|
| This option controls the default broadcaster that will be used by the
| framework when an event needs to be broadcast. You may set this to
| any of the connections defined in the "connections" array below.
|
| Supported: "pusher", "redis", "log", "null"
|
*/
'default' => env('BROADCAST_DRIVER', 'null'),
/*
|--------------------------------------------------------------------------
| Broadcast Connections
|--------------------------------------------------------------------------
|
| Here you may define all of the broadcast connections that will be used
| to broadcast events to other systems or over websockets. Samples of
| each available type of connection are provided inside this array.
|
*/
'connections' => [
'pusher' => [
'driver' => 'pusher',
'key' => env('PUSHER_APP_KEY'),
'secret' => env('PUSHER_APP_SECRET'),
'app_id' => env('PUSHER_APP_ID'),
'options' => [
'cluster' => env('PUSHER_APP_CLUSTER'),
'encrypted' => true,
],
],
'redis' => [
'driver' => 'redis',
'connection' => 'default',
],
'log' => [
'driver' => 'log',
],
'null' => [
'driver' => 'null',
],
],
];

93
config/cache.php Normal file
View File

@ -0,0 +1,93 @@
<?php
use Illuminate\Support\Str;
return [
/*
|--------------------------------------------------------------------------
| Default Cache Store
|--------------------------------------------------------------------------
|
| This option controls the default cache connection that gets used while
| using this caching library. This connection is used when another is
| not explicitly specified when executing a given caching function.
|
| Supported: "apc", "array", "database", "file", "memcached", "redis"
|
*/
'default' => env('CACHE_DRIVER', 'file'),
/*
|--------------------------------------------------------------------------
| Cache Stores
|--------------------------------------------------------------------------
|
| Here you may define all of the cache "stores" for your application as
| well as their drivers. You may even define multiple stores for the
| same cache driver to group types of items stored in your caches.
|
*/
'stores' => [
'apc' => [
'driver' => 'apc',
],
'array' => [
'driver' => 'array',
],
'database' => [
'driver' => 'database',
'table' => 'cache',
'connection' => null,
],
'file' => [
'driver' => 'file',
'path' => storage_path('framework/cache/data'),
],
'memcached' => [
'driver' => 'memcached',
'persistent_id' => env('MEMCACHED_PERSISTENT_ID'),
'sasl' => [
env('MEMCACHED_USERNAME'),
env('MEMCACHED_PASSWORD'),
],
'options' => [
// Memcached::OPT_CONNECT_TIMEOUT => 2000,
],
'servers' => [
[
'host' => env('MEMCACHED_HOST', '127.0.0.1'),
'port' => env('MEMCACHED_PORT', 11211),
'weight' => 100,
],
],
],
'redis' => [
'driver' => 'redis',
'connection' => 'cache',
],
],
/*
|--------------------------------------------------------------------------
| Cache Key Prefix
|--------------------------------------------------------------------------
|
| When utilizing a RAM based store such as APC or Memcached, there might
| be other applications utilizing the same cache. So, we'll specify a
| value to get prefixed to all our keys so we can avoid collisions.
|
*/
'prefix' => env('CACHE_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_cache'),
];

14
config/cors.php Normal file
View File

@ -0,0 +1,14 @@
<?php
return [
'allow-credentials' => env('CORS_ALLOW_CREDENTIAILS', false), // set "Access-Control-Allow-Credentials" 👉 string "false" or "true".
'allow-headers' => ['*'], // ex: Content-Type, Accept, X-Requested-With
'expose-headers' => ['Authorization'],
'origins' => ['*'], // ex: http://localhost
'methods' => ['*'], // ex: GET, POST, PUT, PATCH, DELETE
'max-age' => env('CORS_ACCESS_CONTROL_MAX_AGE', 0),
'laravel' => [
'allow-route-perfix' => env('CORS_LARAVEL_ALLOW_ROUTE_PERFIX', '*'), // The perfix is using \Illumante\Http\Request::is method. 👉
'route-group-mode' => env('CORS_LARAVEL_ROUTE_GROUP_MODE', false),
],
];

131
config/database.php Normal file
View File

@ -0,0 +1,131 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Default Database Connection Name
|--------------------------------------------------------------------------
|
| Here you may specify which of the database connections below you wish
| to use as your default connection for all database work. Of course
| you may use many connections at once using the Database library.
|
*/
'default' => env('DB_CONNECTION', 'mysql'),
/*
|--------------------------------------------------------------------------
| Database Connections
|--------------------------------------------------------------------------
|
| Here are each of the database connections setup for your application.
| Of course, examples of configuring each database platform that is
| supported by Laravel is shown below to make development simple.
|
|
| All database work in Laravel is done through the PHP PDO facilities
| so make sure you have the driver for your particular database of
| choice installed on your machine before you begin development.
|
*/
'connections' => [
'sqlite' => [
'driver' => 'sqlite',
'database' => env('DB_DATABASE', database_path('database.sqlite')),
'prefix' => '',
'foreign_key_constraints' => env('DB_FOREIGN_KEYS', true),
],
'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' => '',
'prefix_indexes' => true,
'strict' => true,
'engine' => null,
],
'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' => '',
'prefix_indexes' => true,
'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' => '',
'prefix_indexes' => true,
],
],
/*
|--------------------------------------------------------------------------
| Migration Repository Table
|--------------------------------------------------------------------------
|
| This table keeps track of all the migrations that have already run for
| your application. Using this information, we can determine which of
| the migrations on disk haven't actually been run in the database.
|
*/
'migrations' => 'migrations',
/*
|--------------------------------------------------------------------------
| Redis Databases
|--------------------------------------------------------------------------
|
| Redis is an open source, fast, and advanced key-value store that also
| provides a richer body of commands than a typical key-value system
| such as APC or Memcached. Laravel makes it easy to dig right in.
|
*/
'redis' => [
'client' => 'predis',
'default' => [
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => env('REDIS_DB', 0),
],
'cache' => [
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => env('REDIS_CACHE_DB', 1),
],
],
];

69
config/filesystems.php Normal file
View File

@ -0,0 +1,69 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Default Filesystem Disk
|--------------------------------------------------------------------------
|
| Here you may specify the default filesystem disk that should be used
| by the framework. The "local" disk, as well as a variety of cloud
| based disks are available to your application. Just store away!
|
*/
'default' => env('FILESYSTEM_DRIVER', 'local'),
/*
|--------------------------------------------------------------------------
| Default Cloud Filesystem Disk
|--------------------------------------------------------------------------
|
| Many applications store files both locally and in the cloud. For this
| reason, you may specify a default "cloud" driver here. This driver
| will be bound as the Cloud disk implementation in the container.
|
*/
'cloud' => env('FILESYSTEM_CLOUD', 's3'),
/*
|--------------------------------------------------------------------------
| Filesystem Disks
|--------------------------------------------------------------------------
|
| Here you may configure as many filesystem "disks" as you wish, and you
| may even configure multiple disks of the same driver. Defaults have
| been setup for each driver as an example of the required options.
|
| Supported Drivers: "local", "ftp", "sftp", "s3", "rackspace"
|
*/
'disks' => [
'local' => [
'driver' => 'local',
'root' => storage_path('app'),
],
'public' => [
'driver' => 'local',
'root' => storage_path('app/public'),
'url' => env('APP_URL').'/storage',
'visibility' => 'public',
],
's3' => [
'driver' => 's3',
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'region' => env('AWS_DEFAULT_REGION'),
'bucket' => env('AWS_BUCKET'),
'url' => env('AWS_URL'),
],
],
];

52
config/hashing.php Normal file
View File

@ -0,0 +1,52 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Default Hash Driver
|--------------------------------------------------------------------------
|
| This option controls the default hash driver that will be used to hash
| passwords for your application. By default, the bcrypt algorithm is
| used; however, you remain free to modify this option if you wish.
|
| Supported: "bcrypt", "argon", "argon2id"
|
*/
'driver' => 'bcrypt',
/*
|--------------------------------------------------------------------------
| Bcrypt Options
|--------------------------------------------------------------------------
|
| Here you may specify the configuration options that should be used when
| passwords are hashed using the Bcrypt algorithm. This will allow you
| to control the amount of time it takes to hash the given password.
|
*/
'bcrypt' => [
'rounds' => env('BCRYPT_ROUNDS', 10),
],
/*
|--------------------------------------------------------------------------
| Argon Options
|--------------------------------------------------------------------------
|
| Here you may specify the configuration options that should be used when
| passwords are hashed using the Argon algorithm. These will allow you
| to control the amount of time it takes to hash the given password.
|
*/
'argon' => [
'memory' => 1024,
'threads' => 2,
'time' => 2,
],
];

149
config/horizon.php Normal file
View File

@ -0,0 +1,149 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Horizon Path
|--------------------------------------------------------------------------
|
| This is the URI path where Horizon will be accessible from. Feel free
| to change this path to anything you like. Note that the URI will not
| affect the paths of its internal API that aren't exposed to users.
|
*/
'path' => 'horizon',
/*
|--------------------------------------------------------------------------
| Horizon Redis Connection
|--------------------------------------------------------------------------
|
| This is the name of the Redis connection where Horizon will store the
| meta information required for it to function. It includes the list
| of supervisors, failed jobs, job metrics, and other information.
|
*/
'use' => 'default',
/*
|--------------------------------------------------------------------------
| Horizon Redis Prefix
|--------------------------------------------------------------------------
|
| This prefix will be used when storing all Horizon data in Redis. You
| may modify the prefix when you are running multiple installations
| of Horizon on the same server so that they don't have problems.
|
*/
'prefix' => env('HORIZON_PREFIX', 'horizon:'),
/*
|--------------------------------------------------------------------------
| Horizon Route Middleware
|--------------------------------------------------------------------------
|
| These middleware will get attached onto each Horizon route, giving you
| the chance to add your own middleware to this list or change any of
| the existing middleware. Or, you can simply stick with this list.
|
*/
'middleware' => ['web'],
/*
|--------------------------------------------------------------------------
| Queue Wait Time Thresholds
|--------------------------------------------------------------------------
|
| This option allows you to configure when the LongWaitDetected event
| will be fired. Every connection / queue combination may have its
| own, unique threshold (in seconds) before this event is fired.
|
*/
'waits' => [
'redis:default' => 60,
],
/*
|--------------------------------------------------------------------------
| Job Trimming Times
|--------------------------------------------------------------------------
|
| Here you can configure for how long (in minutes) you desire Horizon to
| persist the recent and failed jobs. Typically, recent jobs are kept
| for one hour while all failed jobs are stored for an entire week.
|
*/
'trim' => [
'recent' => 60,
'failed' => 10080,
'monitored' => 10080,
],
/*
|--------------------------------------------------------------------------
| Fast Termination
|--------------------------------------------------------------------------
|
| When this option is enabled, Horizon's "terminate" command will not
| wait on all of the workers to terminate unless the --wait option
| is provided. Fast termination can shorten deployment delay by
| allowing a new instance of Horizon to start while the last
| instance will continue to terminate each of its workers.
|
*/
'fast_termination' => false,
/*
|--------------------------------------------------------------------------
| Memory Limit (MB)
|--------------------------------------------------------------------------
|
| This value describes the maximum amount of memory the Horizon worker
| may consume before it is terminated and restarted. You should set
| this value according to the resources available to your server.
|
*/
'memory_limit' => 64,
/*
|--------------------------------------------------------------------------
| Queue Worker Configuration
|--------------------------------------------------------------------------
|
| Here you may define the queue worker settings used by your application
| in all environments. These supervisors and settings handle all your
| queued jobs and will be provisioned by Horizon during deployment.
|
*/
'environments' => [
'production' => [
'supervisor-1' => [
'connection' => 'redis',
'queue' => ['default'],
'balance' => 'simple',
'processes' => 10,
'tries' => 3,
],
],
'local' => [
'supervisor-1' => [
'connection' => 'redis',
'queue' => ['default'],
'balance' => 'simple',
'processes' => 3,
'tries' => 3,
],
],
],
];

304
config/jwt.php Normal file
View File

@ -0,0 +1,304 @@
<?php
/*
* This file is part of jwt-auth.
*
* (c) Sean Tymon <tymon148@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
return [
/*
|--------------------------------------------------------------------------
| JWT Authentication Secret
|--------------------------------------------------------------------------
|
| Don't forget to set this in your .env file, as it will be used to sign
| your tokens. A helper command is provided for this:
| `php artisan jwt:secret`
|
| Note: This will be used for Symmetric algorithms only (HMAC),
| since RSA and ECDSA use a private/public key combo (See below).
|
*/
'secret' => env('JWT_SECRET'),
/*
|--------------------------------------------------------------------------
| JWT Authentication Keys
|--------------------------------------------------------------------------
|
| The algorithm you are using, will determine whether your tokens are
| signed with a random string (defined in `JWT_SECRET`) or using the
| following public & private keys.
|
| Symmetric Algorithms:
| HS256, HS384 & HS512 will use `JWT_SECRET`.
|
| Asymmetric Algorithms:
| RS256, RS384 & RS512 / ES256, ES384 & ES512 will use the keys below.
|
*/
'keys' => [
/*
|--------------------------------------------------------------------------
| Public Key
|--------------------------------------------------------------------------
|
| A path or resource to your public key.
|
| E.g. 'file://path/to/public/key'
|
*/
'public' => env('JWT_PUBLIC_KEY'),
/*
|--------------------------------------------------------------------------
| Private Key
|--------------------------------------------------------------------------
|
| A path or resource to your private key.
|
| E.g. 'file://path/to/private/key'
|
*/
'private' => env('JWT_PRIVATE_KEY'),
/*
|--------------------------------------------------------------------------
| Passphrase
|--------------------------------------------------------------------------
|
| The passphrase for your private key. Can be null if none set.
|
*/
'passphrase' => env('JWT_PASSPHRASE'),
],
/*
|--------------------------------------------------------------------------
| JWT time to live
|--------------------------------------------------------------------------
|
| Specify the length of time (in minutes) that the token will be valid for.
| Defaults to 1 hour.
|
| You can also set this to null, to yield a never expiring token.
| Some people may want this behaviour for e.g. a mobile app.
| This is not particularly recommended, so make sure you have appropriate
| systems in place to revoke the token if necessary.
| Notice: If you set this to null you should remove 'exp' element from 'required_claims' list.
|
*/
'ttl' => env('JWT_TTL', 1),
/*
|--------------------------------------------------------------------------
| Refresh time to live
|--------------------------------------------------------------------------
|
| Specify the length of time (in minutes) that the token can be refreshed
| within. I.E. The user can refresh their token within a 2 week window of
| the original token being created until they must re-authenticate.
| Defaults to 2 weeks.
|
| You can also set this to null, to yield an infinite refresh time.
| Some may want this instead of never expiring tokens for e.g. a mobile app.
| This is not particularly recommended, so make sure you have appropriate
| systems in place to revoke the token if necessary.
|
*/
'refresh_ttl' => env('JWT_REFRESH_TTL', 20160),
/*
|--------------------------------------------------------------------------
| JWT hashing algorithm
|--------------------------------------------------------------------------
|
| Specify the hashing algorithm that will be used to sign the token.
|
| See here: https://github.com/namshi/jose/tree/master/src/Namshi/JOSE/Signer/OpenSSL
| for possible values.
|
*/
'algo' => env('JWT_ALGO', 'HS256'),
/*
|--------------------------------------------------------------------------
| Required Claims
|--------------------------------------------------------------------------
|
| Specify the required claims that must exist in any token.
| A TokenInvalidException will be thrown if any of these claims are not
| present in the payload.
|
*/
'required_claims' => [
'iss',
'iat',
'exp',
'nbf',
'sub',
'jti',
],
/*
|--------------------------------------------------------------------------
| Persistent Claims
|--------------------------------------------------------------------------
|
| Specify the claim keys to be persisted when refreshing a token.
| `sub` and `iat` will automatically be persisted, in
| addition to the these claims.
|
| Note: If a claim does not exist then it will be ignored.
|
*/
'persistent_claims' => [
// 'foo',
// 'bar',
],
/*
|--------------------------------------------------------------------------
| Lock Subject
|--------------------------------------------------------------------------
|
| This will determine whether a `prv` claim is automatically added to
| the token. The purpose of this is to ensure that if you have multiple
| authentication models e.g. `App\User` & `App\OtherPerson`, then we
| should prevent one authentication request from impersonating another,
| if 2 tokens happen to have the same id across the 2 different models.
|
| Under specific circumstances, you may want to disable this behaviour
| e.g. if you only have one authentication model, then you would save
| a little on token size.
|
*/
'lock_subject' => true,
/*
|--------------------------------------------------------------------------
| Leeway
|--------------------------------------------------------------------------
|
| This property gives the jwt timestamp claims some "leeway".
| Meaning that if you have any unavoidable slight clock skew on
| any of your servers then this will afford you some level of cushioning.
|
| This applies to the claims `iat`, `nbf` and `exp`.
|
| Specify in seconds - only if you know you need it.
|
*/
'leeway' => env('JWT_LEEWAY', 0),
/*
|--------------------------------------------------------------------------
| Blacklist Enabled
|--------------------------------------------------------------------------
|
| In order to invalidate tokens, you must have the blacklist enabled.
| If you do not want or need this functionality, then set this to false.
|
*/
'blacklist_enabled' => env('JWT_BLACKLIST_ENABLED', true),
/*
| -------------------------------------------------------------------------
| Blacklist Grace Period
| -------------------------------------------------------------------------
|
| When multiple concurrent requests are made with the same JWT,
| it is possible that some of them fail, due to token regeneration
| on every request.
|
| Set grace period in seconds to prevent parallel request failure.
|
*/
'blacklist_grace_period' => env('JWT_BLACKLIST_GRACE_PERIOD', 0),
/*
|--------------------------------------------------------------------------
| Cookies encryption
|--------------------------------------------------------------------------
|
| By default Laravel encrypt cookies for security reason.
| If you decide to not decrypt cookies, you will have to configure Laravel
| to not encrypt your cookie token by adding its name into the $except
| array available in the middleware "EncryptCookies" provided by Laravel.
| see https://laravel.com/docs/master/responses#cookies-and-encryption
| for details.
|
| Set it to true if you want to decrypt cookies.
|
*/
'decrypt_cookies' => false,
/*
|--------------------------------------------------------------------------
| Providers
|--------------------------------------------------------------------------
|
| Specify the various providers used throughout the package.
|
*/
'providers' => [
/*
|--------------------------------------------------------------------------
| JWT Provider
|--------------------------------------------------------------------------
|
| Specify the provider that is used to create and decode the tokens.
|
*/
'jwt' => Tymon\JWTAuth\Providers\JWT\Lcobucci::class,
/*
|--------------------------------------------------------------------------
| Authentication Provider
|--------------------------------------------------------------------------
|
| Specify the provider that is used to authenticate users.
|
*/
'auth' => Tymon\JWTAuth\Providers\Auth\Illuminate::class,
/*
|--------------------------------------------------------------------------
| Storage Provider
|--------------------------------------------------------------------------
|
| Specify the provider that is used to store tokens in the blacklist.
|
*/
'storage' => Tymon\JWTAuth\Providers\Storage\Illuminate::class,
],
];

93
config/logging.php Normal file
View File

@ -0,0 +1,93 @@
<?php
use Monolog\Handler\StreamHandler;
use Monolog\Handler\SyslogUdpHandler;
return [
/*
|--------------------------------------------------------------------------
| Default Log Channel
|--------------------------------------------------------------------------
|
| This option defines the default log channel that gets used when writing
| messages to the logs. The name specified in this option should match
| one of the channels defined in the "channels" configuration array.
|
*/
'default' => env('LOG_CHANNEL', 'stack'),
/*
|--------------------------------------------------------------------------
| Log Channels
|--------------------------------------------------------------------------
|
| Here you may configure the log channels for your application. Out of
| the box, Laravel uses the Monolog PHP logging library. This gives
| you a variety of powerful log handlers / formatters to utilize.
|
| Available Drivers: "single", "daily", "slack", "syslog",
| "errorlog", "monolog",
| "custom", "stack"
|
*/
'channels' => [
'stack' => [
'driver' => 'stack',
'channels' => ['daily'],
],
'single' => [
'driver' => 'single',
'path' => storage_path('logs/laravel.log'),
'level' => 'debug',
],
'daily' => [
'driver' => 'daily',
'path' => storage_path('logs/laravel.log'),
'level' => 'debug',
'days' => 14,
],
'slack' => [
'driver' => 'slack',
'url' => env('LOG_SLACK_WEBHOOK_URL'),
'username' => 'Laravel Log',
'emoji' => ':boom:',
'level' => 'critical',
],
'papertrail' => [
'driver' => 'monolog',
'level' => 'debug',
'handler' => SyslogUdpHandler::class,
'handler_with' => [
'host' => env('PAPERTRAIL_URL'),
'port' => env('PAPERTRAIL_PORT'),
],
],
'stderr' => [
'driver' => 'monolog',
'handler' => StreamHandler::class,
'formatter' => env('LOG_STDERR_FORMATTER'),
'with' => [
'stream' => 'php://stderr',
],
],
'syslog' => [
'driver' => 'syslog',
'level' => 'debug',
],
'errorlog' => [
'driver' => 'errorlog',
'level' => 'debug',
],
],
];

136
config/mail.php Normal file
View File

@ -0,0 +1,136 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Mail Driver
|--------------------------------------------------------------------------
|
| Laravel supports both SMTP and PHP's "mail" function as drivers for the
| sending of e-mail. You may specify which one you're using throughout
| your application here. By default, Laravel is setup for SMTP mail.
|
| Supported: "smtp", "sendmail", "mailgun", "mandrill", "ses",
| "sparkpost", "log", "array"
|
*/
'driver' => env('MAIL_DRIVER', 'smtp'),
/*
|--------------------------------------------------------------------------
| SMTP Host Address
|--------------------------------------------------------------------------
|
| Here you may provide the host address of the SMTP server used by your
| applications. A default option is provided that is compatible with
| the Mailgun mail service which will provide reliable deliveries.
|
*/
'host' => env('MAIL_HOST', 'smtp.mailgun.org'),
/*
|--------------------------------------------------------------------------
| SMTP Host Port
|--------------------------------------------------------------------------
|
| This is the SMTP port used by your application to deliver e-mails to
| users of the application. Like the host we have set this value to
| stay compatible with the Mailgun e-mail application by default.
|
*/
'port' => env('MAIL_PORT', 587),
/*
|--------------------------------------------------------------------------
| Global "From" Address
|--------------------------------------------------------------------------
|
| You may wish for all e-mails sent by your application to be sent from
| the same address. Here, you may specify a name and address that is
| used globally for all e-mails that are sent by your application.
|
*/
'from' => [
'address' => env('MAIL_FROM_ADDRESS', 'hello@example.com'),
'name' => env('MAIL_FROM_NAME', 'Example'),
],
/*
|--------------------------------------------------------------------------
| E-Mail Encryption Protocol
|--------------------------------------------------------------------------
|
| Here you may specify the encryption protocol that should be used when
| the application send e-mail messages. A sensible default using the
| transport layer security protocol should provide great security.
|
*/
'encryption' => env('MAIL_ENCRYPTION', 'tls'),
/*
|--------------------------------------------------------------------------
| SMTP Server Username
|--------------------------------------------------------------------------
|
| If your SMTP server requires a username for authentication, you should
| set it here. This will get used to authenticate with your server on
| connection. You may also set the "password" value below this one.
|
*/
'username' => env('MAIL_USERNAME'),
'password' => env('MAIL_PASSWORD'),
/*
|--------------------------------------------------------------------------
| Sendmail System Path
|--------------------------------------------------------------------------
|
| When using the "sendmail" driver to send e-mails, we will need to know
| the path to where Sendmail lives on this server. A default path has
| been provided here, which will work well on most of your systems.
|
*/
'sendmail' => '/usr/sbin/sendmail -bs',
/*
|--------------------------------------------------------------------------
| Markdown Mail Settings
|--------------------------------------------------------------------------
|
| If you are using Markdown based email rendering, you may configure your
| theme and component paths here, allowing you to customize the design
| of the emails. Or, you may simply stick with the Laravel defaults!
|
*/
'markdown' => [
'theme' => 'default',
'paths' => [
resource_path('views/vendor/mail'),
],
],
/*
|--------------------------------------------------------------------------
| Log Channel
|--------------------------------------------------------------------------
|
| If you are using the "log" driver, you may specify the logging channel
| if you prefer to keep mail messages separate from other log entries
| for simpler reading. Otherwise, the default channel will be used.
|
*/
'log_channel' => env('MAIL_LOG_CHANNEL'),
];

86
config/queue.php Normal file
View File

@ -0,0 +1,86 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Default Queue Connection Name
|--------------------------------------------------------------------------
|
| Laravel's queue API supports an assortment of back-ends via a single
| API, giving you convenient access to each back-end using the same
| syntax for every one. Here you may define a default connection.
|
*/
'default' => env('QUEUE_CONNECTION', 'sync'),
/*
|--------------------------------------------------------------------------
| Queue Connections
|--------------------------------------------------------------------------
|
| Here you may configure the connection information for each server that
| is used by your application. A default configuration has been added
| for each back-end shipped with Laravel. You are free to add more.
|
| Drivers: "sync", "database", "beanstalkd", "sqs", "redis", "null"
|
*/
'connections' => [
'sync' => [
'driver' => 'sync',
],
'database' => [
'driver' => 'database',
'table' => 'jobs',
'queue' => 'default',
'retry_after' => 90,
],
'beanstalkd' => [
'driver' => 'beanstalkd',
'host' => 'localhost',
'queue' => 'default',
'retry_after' => 90,
],
'sqs' => [
'driver' => 'sqs',
'key' => env('SQS_KEY', 'your-public-key'),
'secret' => env('SQS_SECRET', 'your-secret-key'),
'prefix' => env('SQS_PREFIX', 'https://sqs.us-east-1.amazonaws.com/your-account-id'),
'queue' => env('SQS_QUEUE', 'your-queue-name'),
'region' => env('SQS_REGION', 'us-east-1'),
],
'redis' => [
'driver' => 'redis',
'connection' => 'default',
'queue' => env('REDIS_QUEUE', 'default'),
'retry_after' => 90,
'block_for' => null,
],
],
/*
|--------------------------------------------------------------------------
| Failed Queue Jobs
|--------------------------------------------------------------------------
|
| These options configure the behavior of failed queue job logging so you
| can control which database and table are used to store the jobs that
| have failed. You may change them to any database / table you wish.
|
*/
'failed' => [
'database' => env('DB_CONNECTION', 'mysql'),
'table' => 'failed_jobs',
],
];

43
config/services.php Normal file
View File

@ -0,0 +1,43 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Third Party Services
|--------------------------------------------------------------------------
|
| This file is for storing the credentials for third party services such
| as Stripe, Mailgun, SparkPost and others. This file provides a sane
| default location for this type of information, allowing packages
| to have a conventional place to find your various credentials.
|
*/
'mailgun' => [
'domain' => env('MAILGUN_DOMAIN'),
'secret' => env('MAILGUN_SECRET'),
'endpoint' => env('MAILGUN_ENDPOINT', 'api.mailgun.net'),
],
'ses' => [
'key' => env('SES_KEY'),
'secret' => env('SES_SECRET'),
'region' => env('SES_REGION', 'us-east-1'),
],
'sparkpost' => [
'secret' => env('SPARKPOST_SECRET'),
],
'stripe' => [
'model' => App\Models\User::class,
'key' => env('STRIPE_KEY'),
'secret' => env('STRIPE_SECRET'),
'webhook' => [
'secret' => env('STRIPE_WEBHOOK_SECRET'),
'tolerance' => env('STRIPE_WEBHOOK_TOLERANCE', 300),
],
],
];

199
config/session.php Normal file
View File

@ -0,0 +1,199 @@
<?php
use Illuminate\Support\Str;
return [
/*
|--------------------------------------------------------------------------
| Default Session Driver
|--------------------------------------------------------------------------
|
| This option controls the default session "driver" that will be used on
| requests. By default, we will use the lightweight native driver but
| you may specify any of the other wonderful drivers provided here.
|
| Supported: "file", "cookie", "database", "apc",
| "memcached", "redis", "array"
|
*/
'driver' => env('SESSION_DRIVER', 'file'),
/*
|--------------------------------------------------------------------------
| Session Lifetime
|--------------------------------------------------------------------------
|
| Here you may specify the number of minutes that you wish the session
| to be allowed to remain idle before it expires. If you want them
| to immediately expire on the browser closing, set that option.
|
*/
'lifetime' => env('SESSION_LIFETIME', 120),
'expire_on_close' => false,
/*
|--------------------------------------------------------------------------
| Session Encryption
|--------------------------------------------------------------------------
|
| This option allows you to easily specify that all of your session data
| should be encrypted before it is stored. All encryption will be run
| automatically by Laravel and you can use the Session like normal.
|
*/
'encrypt' => false,
/*
|--------------------------------------------------------------------------
| Session File Location
|--------------------------------------------------------------------------
|
| When using the native session driver, we need a location where session
| files may be stored. A default has been set for you but a different
| location may be specified. This is only needed for file sessions.
|
*/
'files' => storage_path('framework/sessions'),
/*
|--------------------------------------------------------------------------
| Session Database Connection
|--------------------------------------------------------------------------
|
| When using the "database" or "redis" session drivers, you may specify a
| connection that should be used to manage these sessions. This should
| correspond to a connection in your database configuration options.
|
*/
'connection' => env('SESSION_CONNECTION', null),
/*
|--------------------------------------------------------------------------
| Session Database Table
|--------------------------------------------------------------------------
|
| When using the "database" session driver, you may specify the table we
| should use to manage the sessions. Of course, a sensible default is
| provided for you; however, you are free to change this as needed.
|
*/
'table' => 'sessions',
/*
|--------------------------------------------------------------------------
| Session Cache Store
|--------------------------------------------------------------------------
|
| When using the "apc" or "memcached" session drivers, you may specify a
| cache store that should be used for these sessions. This value must
| correspond with one of the application's configured cache stores.
|
*/
'store' => env('SESSION_STORE', null),
/*
|--------------------------------------------------------------------------
| Session Sweeping Lottery
|--------------------------------------------------------------------------
|
| Some session drivers must manually sweep their storage location to get
| rid of old sessions from storage. Here are the chances that it will
| happen on a given request. By default, the odds are 2 out of 100.
|
*/
'lottery' => [2, 100],
/*
|--------------------------------------------------------------------------
| Session Cookie Name
|--------------------------------------------------------------------------
|
| Here you may change the name of the cookie used to identify a session
| instance by ID. The name specified here will get used every time a
| new session cookie is created by the framework for every driver.
|
*/
'cookie' => env(
'SESSION_COOKIE',
Str::slug(env('APP_NAME', 'laravel'), '_').'_session'
),
/*
|--------------------------------------------------------------------------
| Session Cookie Path
|--------------------------------------------------------------------------
|
| The session cookie path determines the path for which the cookie will
| be regarded as available. Typically, this will be the root path of
| your application but you are free to change this when necessary.
|
*/
'path' => '/',
/*
|--------------------------------------------------------------------------
| Session Cookie Domain
|--------------------------------------------------------------------------
|
| Here you may change the domain of the cookie used to identify a session
| in your application. This will determine which domains the cookie is
| available to in your application. A sensible default has been set.
|
*/
'domain' => env('SESSION_DOMAIN', null),
/*
|--------------------------------------------------------------------------
| HTTPS Only Cookies
|--------------------------------------------------------------------------
|
| By setting this option to true, session cookies will only be sent back
| to the server if the browser has a HTTPS connection. This will keep
| the cookie from being sent to you if it can not be done securely.
|
*/
'secure' => env('SESSION_SECURE_COOKIE', false),
/*
|--------------------------------------------------------------------------
| HTTP Access Only
|--------------------------------------------------------------------------
|
| Setting this value to true will prevent JavaScript from accessing the
| value of the cookie and the cookie will only be accessible through
| the HTTP protocol. You are free to modify this option if needed.
|
*/
'http_only' => true,
/*
|--------------------------------------------------------------------------
| Same-Site Cookies
|--------------------------------------------------------------------------
|
| This option determines how your cookies behave when cross-site requests
| take place, and can be used to mitigate CSRF attacks. By default, we
| do not enable this as other CSRF protection services are in place.
|
| Supported: "lax", "strict"
|
*/
'same_site' => null,
];

36
config/view.php Normal file
View File

@ -0,0 +1,36 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| View Storage Paths
|--------------------------------------------------------------------------
|
| Most templating systems load templates from disk. Here you may specify
| an array of paths that should be checked for your views. Of course
| the usual Laravel view path has already been registered for you.
|
*/
'paths' => [
resource_path('views'),
],
/*
|--------------------------------------------------------------------------
| Compiled View Path
|--------------------------------------------------------------------------
|
| This option determines where all the compiled Blade templates will be
| stored for your application. Typically, this is within the storage
| directory. However, as usual, you are free to change this value.
|
*/
'compiled' => env(
'VIEW_COMPILED_PATH',
realpath(storage_path('framework/views'))
),
];

1
database/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
*.sqlite

View File

@ -0,0 +1,24 @@
<?php
use Faker\Generator as Faker;
/*
|--------------------------------------------------------------------------
| Model Factories
|--------------------------------------------------------------------------
|
| This directory should contain each of the model factory definitions for
| your application. Factories provide a convenient way to generate new
| model instances for testing / seeding your application's database.
|
*/
$factory->define(App\Models\User::class, function (Faker $faker) {
return [
'name' => $faker->name,
'email' => $faker->unique()->safeEmail,
'email_verified_at' => now(),
'password' => '$2y$10$TKh8H1.PfQx37YgCzwiKb.KjNyWgaHb9cbcoQgdIVFlYg7B77UdFm', // secret
'remember_token' => str_random(10),
];
});

View File

@ -0,0 +1,36 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateUsersTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('users');
}
}

View File

@ -0,0 +1,32 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreatePasswordResetsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('password_resets', function (Blueprint $table) {
$table->string('email')->index();
$table->string('token');
$table->timestamp('created_at')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('password_resets');
}
}

View File

@ -0,0 +1,16 @@
<?php
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
/**
* Seed the application's database.
*
* @return void
*/
public function run()
{
// $this->call(UsersTableSeeder::class);
}
}

25
package.json Normal file
View File

@ -0,0 +1,25 @@
{
"private": true,
"scripts": {
"dev": "npm run development",
"development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
"watch": "npm run development -- --watch",
"watch-poll": "npm run watch -- --watch-poll",
"hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js",
"prod": "npm run production",
"production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
},
"devDependencies": {
"axios": "^0.18",
"bootstrap": "^4.0.0",
"cross-env": "^5.1",
"jquery": "^3.2",
"laravel-mix": "^4.0.7",
"lodash": "^4.17.5",
"popper.js": "^1.12",
"resolve-url-loader": "^2.3.1",
"sass": "^1.15.2",
"sass-loader": "^7.1.0",
"vue": "^2.5.17"
}
}

33
phpunit.xml Normal file
View File

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
backupStaticAttributes="false"
bootstrap="vendor/autoload.php"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false">
<testsuites>
<testsuite name="Unit">
<directory suffix="Test.php">./tests/Unit</directory>
</testsuite>
<testsuite name="Feature">
<directory suffix="Test.php">./tests/Feature</directory>
</testsuite>
</testsuites>
<filter>
<whitelist processUncoveredFilesFromWhitelist="true">
<directory suffix=".php">./app</directory>
</whitelist>
</filter>
<php>
<env name="APP_ENV" value="testing"/>
<env name="BCRYPT_ROUNDS" value="4"/>
<env name="CACHE_DRIVER" value="array"/>
<env name="MAIL_DRIVER" value="array"/>
<env name="QUEUE_CONNECTION" value="sync"/>
<env name="SESSION_DRIVER" value="array"/>
</php>
</phpunit>

21
public/.htaccess Normal file
View File

@ -0,0 +1,21 @@
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews -Indexes
</IfModule>
RewriteEngine On
# Handle Authorization Header
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
# Redirect Trailing Slashes If Not A Folder...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} (.+)/$
RewriteRule ^ %1 [L,R=301]
# Handle Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
</IfModule>

8
public/css/app.css vendored Normal file

File diff suppressed because one or more lines are too long

0
public/favicon.ico Normal file
View File

60
public/index.php Normal file
View File

@ -0,0 +1,60 @@
<?php
/**
* Laravel - A PHP Framework For Web Artisans
*
* @package Laravel
* @author Taylor Otwell <taylor@laravel.com>
*/
define('LARAVEL_START', microtime(true));
/*
|--------------------------------------------------------------------------
| Register The Auto Loader
|--------------------------------------------------------------------------
|
| Composer provides a convenient, automatically generated class loader for
| our application. We just need to utilize it! We'll simply require it
| into the script here so that we don't have to worry about manual
| loading any of our classes later on. It feels great to relax.
|
*/
require __DIR__.'/../vendor/autoload.php';
/*
|--------------------------------------------------------------------------
| Turn On The Lights
|--------------------------------------------------------------------------
|
| We need to illuminate PHP development, so let us turn on the lights.
| This bootstraps the framework and gets it ready for use, then it
| will load up this application so that we can run it and send
| the responses back to the browser and delight our users.
|
*/
$app = require_once __DIR__.'/../bootstrap/app.php';
/*
|--------------------------------------------------------------------------
| Run The Application
|--------------------------------------------------------------------------
|
| Once we have the application, we can handle the incoming request
| through the kernel, and send the associated response back to
| the client's browser allowing them to enjoy the creative
| and wonderful application we have prepared for them.
|
*/
$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);
$response = $kernel->handle(
$request = Illuminate\Http\Request::capture()
);
$response->send();
$kernel->terminate($request, $response);

1
public/js/app.js vendored Normal file

File diff suppressed because one or more lines are too long

2
public/robots.txt Normal file
View File

@ -0,0 +1,2 @@
User-agent: *
Disallow:

1
public/svg/403.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 6.5 KiB

1
public/svg/404.svg Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 1024 1024"><defs><linearGradient id="a" x1="50.31%" x2="50%" y1="74.74%" y2="0%"><stop offset="0%" stop-color="#FFE98A"/><stop offset="67.7%" stop-color="#B63E59"/><stop offset="100%" stop-color="#68126F"/></linearGradient><circle id="c" cx="603" cy="682" r="93"/><filter id="b" width="203.2%" height="203.2%" x="-51.6%" y="-51.6%" filterUnits="objectBoundingBox"><feOffset in="SourceAlpha" result="shadowOffsetOuter1"/><feGaussianBlur in="shadowOffsetOuter1" result="shadowBlurOuter1" stdDeviation="32"/><feColorMatrix in="shadowBlurOuter1" values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0"/></filter><linearGradient id="d" x1="49.48%" x2="49.87%" y1="11.66%" y2="77.75%"><stop offset="0%" stop-color="#F7EAB9"/><stop offset="100%" stop-color="#E5765E"/></linearGradient><linearGradient id="e" x1="91.59%" x2="66.97%" y1="5.89%" y2="100%"><stop offset="0%" stop-color="#A22A50"/><stop offset="100%" stop-color="#EE7566"/></linearGradient><linearGradient id="f" x1="49.48%" x2="49.61%" y1="11.66%" y2="98.34%"><stop offset="0%" stop-color="#F7EAB9"/><stop offset="100%" stop-color="#E5765E"/></linearGradient><linearGradient id="g" x1="78.5%" x2="36.4%" y1="106.76%" y2="26.41%"><stop offset="0%" stop-color="#A22A50"/><stop offset="100%" stop-color="#EE7566"/></linearGradient></defs><g fill="none" fill-rule="evenodd"><rect width="1024" height="1024" fill="url(#a)"/><use fill="black" filter="url(#b)" xlink:href="#c"/><use fill="#FFF6CB" xlink:href="#c"/><g fill="#FFFFFF" opacity=".3" transform="translate(14 23)"><circle cx="203" cy="255" r="3" fill-opacity=".4"/><circle cx="82" cy="234" r="2"/><circle cx="22" cy="264" r="2" opacity=".4"/><circle cx="113" cy="65" r="3"/><circle cx="202" cy="2" r="2"/><circle cx="2" cy="114" r="2"/><circle cx="152" cy="144" r="2"/><circle cx="362" cy="224" r="2"/><circle cx="453" cy="65" r="3" opacity=".4"/><circle cx="513" cy="255" r="3"/><circle cx="593" cy="115" r="3"/><circle cx="803" cy="5" r="3" opacity=".4"/><circle cx="502" cy="134" r="2"/><circle cx="832" cy="204" r="2"/><circle cx="752" cy="114" r="2"/><circle cx="933" cy="255" r="3" opacity=".4"/><circle cx="703" cy="225" r="3"/><circle cx="903" cy="55" r="3"/><circle cx="982" cy="144" r="2"/><circle cx="632" cy="14" r="2"/></g><g transform="translate(0 550)"><path fill="#8E2C15" d="M259 5.47c0 5.33 3.33 9.5 10 12.5s9.67 9.16 9 18.5h1c.67-6.31 1-11.8 1-16.47 8.67 0 13.33-1.33 14-4 .67 4.98 1.67 8.3 3 9.97 1.33 1.66 2 5.16 2 10.5h1c0-5.65.33-9.64 1-11.97 1-3.5 4-10.03-1-14.53S295 7 290 3c-5-4-10-3-13 2s-5 7-9 7-5-3.53-5-5.53c0-2 2-5-1.5-5s-7.5 0-7.5 2c0 1.33 1.67 2 5 2z"/><path fill="url(#d)" d="M1024 390H0V105.08C77.3 71.4 155.26 35 297.4 35c250 0 250.76 125.25 500 125 84.03-.08 160.02-18.2 226.6-40.93V390z"/><path fill="url(#d)" d="M1024 442H0V271.82c137.51-15.4 203.1-50.49 356.67-60.1C555.24 199.3 606.71 86.59 856.74 86.59c72.78 0 124.44 10.62 167.26 25.68V442z"/><path fill="url(#e)" d="M1024 112.21V412H856.91c99.31-86.5 112.63-140.75 39.97-162.78C710.24 192.64 795.12 86.58 856.9 86.58c72.7 0 124.3 10.6 167.09 25.63z"/><path fill="url(#e)" d="M1024 285.32V412H857c99.31-86.6 112.63-140.94 39.97-163L1024 285.32z"/><path fill="url(#f)" d="M0 474V223.93C67.12 190.69 129.55 155 263 155c250 0 331.46 162.6 530 175 107.42 6.71 163-26.77 231-58.92V474H0z"/><path fill="url(#e)" d="M353.02 474H0V223.93C67.12 190.69 129.55 155 263 155c71.14 0 151.5 12.76 151.5 70.5 0 54.5-45.5 79.72-112.5 109-82.26 35.95-54.57 111.68 51.02 139.5z"/><path fill="url(#g)" d="M353.02 474H0v-14.8l302-124.7c-82.26 35.95-54.57 111.68 51.02 139.5z"/></g><g fill="#FFFFFF" opacity=".2" transform="translate(288 523)"><circle cx="250" cy="110" r="110"/><circle cx="420" cy="78" r="60"/><circle cx="70" cy="220" r="70"/></g><g fill="#FFFFFF" fill-rule="nonzero" opacity=".08" transform="translate(135 316)"><path d="M10 80.22a14.2 14.2 0 0 1 20 0 14.2 14.2 0 0 0 20 0l20-19.86a42.58 42.58 0 0 1 60 0l15 14.9a21.3 21.3 0 0 0 30 0 21.3 21.3 0 0 1 30 0l.9.9A47.69 47.69 0 0 1 220 110H0v-5.76c0-9.02 3.6-17.67 10-24.02zm559.1-66.11l5.9-5.86c11.07-11 28.93-11 40 0l10 9.94a14.19 14.19 0 0 0 20 0 14.19 14.19 0 0 1 20 0 16.36 16.36 0 0 0 21.3 1.5l8.7-6.47a33.47 33.47 0 0 1 40 0l4.06 3.03A39.6 39.6 0 0 1 755 48H555a47.77 47.77 0 0 1 14.1-33.89z"/></g></g></svg>

After

Width:  |  Height:  |  Size: 4.2 KiB

1
public/svg/500.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 15 KiB

1
public/svg/503.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 5.4 KiB

8
public/vendor/horizon/app-dark.css vendored Normal file

File diff suppressed because one or more lines are too long

8
public/vendor/horizon/app.css vendored Normal file

File diff suppressed because one or more lines are too long

1
public/vendor/horizon/app.js vendored Normal file

File diff suppressed because one or more lines are too long

6
public/vendor/horizon/css/app.css vendored Normal file

File diff suppressed because one or more lines are too long

1
public/vendor/horizon/css/app.css.map vendored Normal file
View File

@ -0,0 +1 @@
{"version":3,"file":"/css/app.css","sources":[],"mappings":";;;;;A","sourceRoot":""}

BIN
public/vendor/horizon/img/favicon.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 648 B

4
public/vendor/horizon/img/horizon.svg vendored Normal file
View File

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="226" height="30" viewBox="0 0 226 30">
<path fill="#405263" d="M54.132 25l-.644-4.144h-5.936V5.68h-4.788V25h11.368zm13.3 0H63.68l-.28-1.708c-1.12 1.176-2.436 1.988-4.312 1.988-2.184 0-3.724-1.316-3.724-3.808 0-3.22 2.464-4.732 7.84-5.208v-.252c0-1.204-.672-1.736-2.072-1.736-1.54 0-2.968.392-4.424 1.036l-.504-3.192c1.568-.644 3.332-1.064 5.572-1.064 3.78 0 5.656 1.26 5.656 4.76V25zm-4.228-3.78v-2.912c-2.884.448-3.668 1.4-3.668 2.604 0 .868.532 1.344 1.316 1.344.812 0 1.596-.364 2.352-1.036zm15.876-5.908L78.38 11c-2.016.14-3.164 1.428-4.004 2.996l-.448-2.716h-3.696V25h4.228v-7.616c1.036-1.12 2.576-1.932 4.62-2.072zM92.184 25h-3.752l-.28-1.708c-1.12 1.176-2.436 1.988-4.312 1.988-2.184 0-3.724-1.316-3.724-3.808 0-3.22 2.464-4.732 7.84-5.208v-.252c0-1.204-.672-1.736-2.072-1.736-1.54 0-2.968.392-4.424 1.036l-.504-3.192c1.568-.644 3.332-1.064 5.572-1.064 3.78 0 5.656 1.26 5.656 4.76V25zm-4.228-3.78v-2.912c-2.884.448-3.668 1.4-3.668 2.604 0 .868.532 1.344 1.316 1.344.812 0 1.596-.364 2.352-1.036zm19.544-9.94h-4.116l-2.492 8.484-2.548-8.68-4.536.532 4.676 13.44h4.228L107.5 11.28zm13.552 6.832c0 .42-.028.868-.084 1.092h-8.232c.224 2.156 1.512 2.996 3.36 2.996 1.512 0 2.996-.56 4.508-1.428l.42 2.968c-1.484.952-3.304 1.54-5.46 1.54-4.116 0-7.056-2.184-7.056-7.084 0-4.48 2.744-7.196 6.468-7.196 4.2 0 6.076 3.136 6.076 7.112zm-4.032-1.232c-.14-2.072-.868-3.136-2.156-3.136-1.176 0-2.016 1.036-2.156 3.136h4.312zM127.66 25V4.784l-4.256.672V25h4.256zm25.032 0V5.68h-1.932v8.344h-10.724V5.68h-1.932V25h1.932v-9.24h10.724V25h1.932zm15.876-6.608c0 4.368-2.632 6.888-6.02 6.888-3.388 0-5.936-2.52-5.936-6.888 0-4.396 2.604-6.916 5.936-6.916 3.444 0 6.02 2.52 6.02 6.916zm-1.904 0c0-3.052-1.456-5.348-4.116-5.348-2.632 0-4.06 2.212-4.06 5.348 0 3.052 1.456 5.32 4.06 5.32 2.688 0 4.116-2.184 4.116-5.32zm12.208-5.18l-.308-1.736c-2.184.056-3.724 1.512-4.704 2.996l-.42-2.716h-1.372V25h1.848v-8.316c.896-1.764 2.772-3.332 4.956-3.472zm5.264-5.964c0-.728-.588-1.344-1.316-1.344-.728 0-1.344.616-1.344 1.344 0 .728.616 1.344 1.344 1.344.728 0 1.316-.616 1.316-1.344zM183.716 25V11.756h-1.82V25h1.82zm13.748 0l-.252-1.54h-7.868l7.896-10.276v-1.428h-9.604l.252 1.54h7.224l-7.896 10.276V25h10.248zm14.476-6.608c0 4.368-2.632 6.888-6.02 6.888-3.388 0-5.936-2.52-5.936-6.888 0-4.396 2.604-6.916 5.936-6.916 3.444 0 6.02 2.52 6.02 6.916zm-1.904 0c0-3.052-1.456-5.348-4.116-5.348-2.632 0-4.06 2.212-4.06 5.348 0 3.052 1.456 5.32 4.06 5.32 2.688 0 4.116-2.184 4.116-5.32zM225.884 25v-9.464c0-2.548-1.316-4.06-3.948-4.06-1.792 0-3.304.952-4.76 2.24l-.308-1.96h-1.428V25h1.848v-9.576c1.456-1.428 2.884-2.296 4.284-2.296 1.68 0 2.464 1.036 2.464 2.744V25h1.848z"/>
<path fill="#405263" d="M5.26176342 26.4094389C2.04147988 23.6582233 0 19.5675182 0 15c0-4.1421356 1.67893219-7.89213562 4.39339828-10.60660172C7.10786438 1.67893219 10.8578644 0 15 0c8.2842712 0 15 6.71572875 15 15 0 8.2842712-6.7157288 15-15 15-3.716753 0-7.11777662-1.3517984-9.73823658-3.5905611zM4.03811305 15.9222506C5.70084247 14.4569342 6.87195416 12.5 10 12.5c5 0 5 5 10 5 3.1280454 0 4.2991572-1.9569336 5.961887-3.4222502C25.4934253 8.43417206 20.7645408 4 15 4 8.92486775 4 4 8.92486775 4 15c0 .3105915.01287248.6181765.03811305.9222506z"/>
</svg>

After

Width:  |  Height:  |  Size: 3.2 KiB

806
public/vendor/horizon/img/sprite.svg vendored Normal file
View File

@ -0,0 +1,806 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<symbol viewBox="0 0 20 20" id="zondicon-add-outline">
<path d="M11 9h4v2h-4v4H9v-4H5V9h4V5h2v4zm-1 11a10 10 0 1 1 0-20 10 10 0 0 1 0 20zm0-2a8 8 0 1 0 0-16 8 8 0 0 0 0 16z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-add-solid">
<path d="M11 9V5H9v4H5v2h4v4h2v-4h4V9h-4zm-1 11a10 10 0 1 1 0-20 10 10 0 0 1 0 20z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-adjust">
<path d="M10 2v16a8 8 0 1 0 0-16zm0 18a10 10 0 1 1 0-20 10 10 0 0 1 0 20z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-airplane">
<path d="M8.4 12H2.8L1 15H0V5h1l1.8 3h5.6L6 0h2l4.8 8H18a2 2 0 1 1 0 4h-5.2L8 20H6l2.4-8z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-align-center">
<path d="M1 1h18v2H1V1zm0 8h18v2H1V9zm0 8h18v2H1v-2zM4 5h12v2H4V5zm0 8h12v2H4v-2z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-align-justified">
<path d="M1 1h18v2H1V1zm0 8h18v2H1V9zm0 8h18v2H1v-2zM1 5h18v2H1V5zm0 8h18v2H1v-2z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-align-left">
<path d="M1 1h18v2H1V1zm0 8h18v2H1V9zm0 8h18v2H1v-2zM1 5h12v2H1V5zm0 8h12v2H1v-2z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-align-right">
<path d="M1 1h18v2H1V1zm0 8h18v2H1V9zm0 8h18v2H1v-2zM7 5h12v2H7V5zm0 8h12v2H7v-2z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-anchor">
<path d="M4.34 15.66A7.97 7.97 0 0 0 9 17.94V10H5V8h4V5.83a3 3 0 1 1 2 0V8h4v2h-4v7.94a7.97 7.97 0 0 0 4.66-2.28l-1.42-1.42h5.66l-2.83 2.83a10 10 0 0 1-14.14 0L.1 14.24h5.66l-1.42 1.42zM10 4a1 1 0 1 0 0-2 1 1 0 0 0 0 2z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-announcement">
<path d="M3 6c0-1.1.9-2 2-2h8l4-4h2v16h-2l-4-4H5a2 2 0 0 1-2-2H1V6h2zm8 9v5H8l-1.67-5H5v-2h8v2h-2z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-apparel">
<path d="M7 0H6L0 3v6l4-1v12h12V8l4 1V3l-6-3h-1a3 3 0 0 1-6 0z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-arrow-outline-down">
<path d="M10 20a10 10 0 1 1 0-20 10 10 0 0 1 0 20zm0-2a8 8 0 1 0 0-16 8 8 0 0 0 0 16zm-2-8V5h4v5h3l-5 5-5-5h3z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-arrow-outline-left">
<path d="M0 10a10 10 0 1 1 20 0 10 10 0 0 1-20 0zm2 0a8 8 0 1 0 16 0 8 8 0 0 0-16 0zm8-2h5v4h-5v3l-5-5 5-5v3z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-arrow-outline-right">
<path d="M20 10a10 10 0 1 1-20 0 10 10 0 0 1 20 0zm-2 0a8 8 0 1 0-16 0 8 8 0 0 0 16 0zm-8 2H5V8h5V5l5 5-5 5v-3z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-arrow-outline-up">
<path d="M10 0a10 10 0 1 1 0 20 10 10 0 0 1 0-20zm0 2a8 8 0 1 0 0 16 8 8 0 0 0 0-16zm2 8v5H8v-5H5l5-5 5 5h-3z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-arrow-thick-down">
<path d="M7 10V2h6v8h5l-8 8-8-8h5z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-arrow-thick-left">
<path d="M10 13h8V7h-8V2l-8 8 8 8v-5z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-arrow-thick-right">
<path d="M10 7H2v6h8v5l8-8-8-8v5z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-arrow-thick-up">
<path d="M7 10v8h6v-8h5l-8-8-8 8h5z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-arrow-thin-down">
<path d="M9 16.172l-6.071-6.071-1.414 1.414L10 20l.707-.707 7.778-7.778-1.414-1.414L11 16.172V0H9z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-arrow-thin-left">
<path d="M3.828 9l6.071-6.071-1.414-1.414L0 10l.707.707 7.778 7.778 1.414-1.414L3.828 11H20V9H3.828z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-arrow-thin-right">
<path d="M16.172 9l-6.071-6.071 1.414-1.414L20 10l-.707.707-7.778 7.778-1.414-1.414L16.172 11H0V9z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-arrow-thin-up">
<path d="M9 3.828L2.929 9.899 1.515 8.485 10 0l.707.707 7.778 7.778-1.414 1.414L11 3.828V20H9V3.828z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-at-symbol">
<path d="M13.6 13.47A4.99 4.99 0 0 1 5 10a5 5 0 0 1 8-4V5h2v6.5a1.5 1.5 0 0 0 3 0V10a8 8 0 1 0-4.42 7.16l.9 1.79A10 10 0 1 1 20 10h-.18.17v1.5a3.5 3.5 0 0 1-6.4 1.97zM10 13a3 3 0 1 0 0-6 3 3 0 0 0 0 6z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-attachment">
<path d="M15 3H7a7 7 0 1 0 0 14h8v-2H7A5 5 0 0 1 7 5h8a3 3 0 0 1 0 6H7a1 1 0 0 1 0-2h8V7H7a3 3 0 1 0 0 6h8a5 5 0 0 0 0-10z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-backspace">
<path d="M0 10l7-7h13v14H7l-7-7zm14.41 0l2.13-2.12-1.42-1.42L13 8.6l-2.12-2.13-1.42 1.42L11.6 10l-2.13 2.12 1.42 1.42L13 11.4l2.12 2.13 1.42-1.42L14.4 10z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-badge">
<path d="M10 12a6 6 0 1 1 0-12 6 6 0 0 1 0 12zm0-3a3 3 0 1 0 0-6 3 3 0 0 0 0 6zm4 2.75V20l-4-4-4 4v-8.25a6.97 6.97 0 0 0 8 0z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-battery-full">
<path d="M0 6c0-1.1.9-2 2-2h16a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V6zm2 0v8h16V6H2zm1 1h4v6H3V7zm5 0h4v6H8V7zm5 0h4v6h-4V7z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-battery-half">
<path d="M0 6c0-1.1.9-2 2-2h16a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V6zm2 0v8h16V6H2zm1 1h4v6H3V7zm5 0h4v6H8V7z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-battery-low">
<path d="M0 6c0-1.1.9-2 2-2h16a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V6zm2 0v8h16V6H2zm1 1h4v6H3V7z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-beverage">
<path d="M9 18v-7L0 2V0h20v2l-9 9v7l5 1v1H4v-1l5-1zm2-10a2 2 0 1 0 0-4 2 2 0 0 0 0 4z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-block">
<path d="M0 10a10 10 0 1 1 20 0 10 10 0 0 1-20 0zm16.32-4.9L5.09 16.31A8 8 0 0 0 16.32 5.09zm-1.41-1.42A8 8 0 0 0 3.68 14.91L14.91 3.68z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-bluetooth">
<path d="M9.41 0l6 6-4 4 4 4-6 6H9v-7.59l-3.3 3.3-1.4-1.42L8.58 10l-4.3-4.3L5.7 4.3 9 7.58V0h.41zM11 4.41V7.6L12.59 6 11 4.41zM12.59 14L11 12.41v3.18L12.59 14z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-bolt">
<path d="M13 8V0L8.11 5.87 3 12h4v8L17 8h-4z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-book-reference">
<path d="M6 4H5a1 1 0 1 1 0-2h11V1a1 1 0 0 0-1-1H4a2 2 0 0 0-2 2v16c0 1.1.9 2 2 2h12a2 2 0 0 0 2-2V5a1 1 0 0 0-1-1h-7v8l-2-2-2 2V4z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-bookmark">
<path d="M2 2c0-1.1.9-2 2-2h12a2 2 0 0 1 2 2v18l-8-4-8 4V2z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-bookmark-outline">
<path d="M2 2c0-1.1.9-2 2-2h12a2 2 0 0 1 2 2v18l-8-4-8 4V2zm2 0v15l6-3 6 3V2H4z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-bookmark-outline-add">
<path d="M2 2c0-1.1.9-2 2-2h12a2 2 0 0 1 2 2v18l-8-4-8 4V2zm2 0v15l6-3 6 3V2H4zm5 5V5h2v2h2v2h-2v2H9V9H7V7h2z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-border-all">
<path d="M11 11v6h6v-6h-6zm0-2h6V3h-6v6zm-2 2H3v6h6v-6zm0-2V3H3v6h6zm-8 9V1h18v18H1v-1z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-border-bottom">
<path d="M1 1h2v2H1V1zm0 4h2v2H1V5zm0 4h2v2H1V9zm0 4h2v2H1v-2zm0 4h18v2H1v-2zM5 1h2v2H5V1zm0 8h2v2H5V9zm4-8h2v2H9V1zm0 4h2v2H9V5zm0 4h2v2H9V9zm0 4h2v2H9v-2zm4-12h2v2h-2V1zm0 8h2v2h-2V9zm4-8h2v2h-2V1zm0 4h2v2h-2V5zm0 4h2v2h-2V9zm0 4h2v2h-2v-2z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-border-horizontal">
<path d="M1 1h2v2H1V1zm0 4h2v2H1V5zm0 4h18v2H1V9zm0 4h2v2H1v-2zm0 4h2v2H1v-2zM5 1h2v2H5V1zm0 16h2v2H5v-2zM9 1h2v2H9V1zm0 4h2v2H9V5zm0 8h2v2H9v-2zm0 4h2v2H9v-2zm4-16h2v2h-2V1zm0 16h2v2h-2v-2zm4-16h2v2h-2V1zm0 4h2v2h-2V5zm0 8h2v2h-2v-2zm0 4h2v2h-2v-2z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-border-inner">
<path d="M9 9V1h2v8h8v2h-8v8H9v-8H1V9h8zM1 1h2v2H1V1zm0 4h2v2H1V5zm0 8h2v2H1v-2zm0 4h2v2H1v-2zM5 1h2v2H5V1zm0 16h2v2H5v-2zm8-16h2v2h-2V1zm0 16h2v2h-2v-2zm4-16h2v2h-2V1zm0 4h2v2h-2V5zm0 8h2v2h-2v-2zm0 4h2v2h-2v-2z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-border-left">
<path d="M1 1h2v18H1V1zm4 0h2v2H5V1zm0 8h2v2H5V9zm0 8h2v2H5v-2zM9 1h2v2H9V1zm0 4h2v2H9V5zm0 4h2v2H9V9zm0 4h2v2H9v-2zm0 4h2v2H9v-2zm4-16h2v2h-2V1zm0 8h2v2h-2V9zm0 8h2v2h-2v-2zm4-16h2v2h-2V1zm0 4h2v2h-2V5zm0 4h2v2h-2V9zm0 4h2v2h-2v-2zm0 4h2v2h-2v-2z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-border-none">
<path d="M1 1h2v2H1V1zm0 4h2v2H1V5zm0 4h2v2H1V9zm0 4h2v2H1v-2zm0 4h2v2H1v-2zM5 1h2v2H5V1zm0 8h2v2H5V9zm0 8h2v2H5v-2zM9 1h2v2H9V1zm0 4h2v2H9V5zm0 4h2v2H9V9zm0 4h2v2H9v-2zm0 4h2v2H9v-2zm4-16h2v2h-2V1zm0 8h2v2h-2V9zm0 8h2v2h-2v-2zm4-16h2v2h-2V1zm0 4h2v2h-2V5zm0 4h2v2h-2V9zm0 4h2v2h-2v-2zm0 4h2v2h-2v-2z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-border-outer">
<path d="M2 19H1V1h18v18H2zm1-2h14V3H3v14zm10-8h2v2h-2V9zM9 9h2v2H9V9zM5 9h2v2H5V9zm4-4h2v2H9V5zm0 8h2v2H9v-2z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-border-right">
<path d="M5 1h2v2H5V1zm0 8h2v2H5V9zm0 8h2v2H5v-2zM9 1h2v2H9V1zm0 4h2v2H9V5zm0 4h2v2H9V9zm0 4h2v2H9v-2zm0 4h2v2H9v-2zm4-16h2v2h-2V1zm0 8h2v2h-2V9zm0 8h2v2h-2v-2zM1 1h2v2H1V1zm0 4h2v2H1V5zm0 4h2v2H1V9zm0 4h2v2H1v-2zm0 4h2v2H1v-2zM17 1h2v18h-2V1z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-border-top">
<path d="M1 1h18v2H1V1zm0 4h2v2H1V5zm0 4h2v2H1V9zm0 4h2v2H1v-2zm0 4h2v2H1v-2zm4-8h2v2H5V9zm0 8h2v2H5v-2zM9 5h2v2H9V5zm0 4h2v2H9V9zm0 4h2v2H9v-2zm0 4h2v2H9v-2zm4-8h2v2h-2V9zm0 8h2v2h-2v-2zm4-12h2v2h-2V5zm0 4h2v2h-2V9zm0 4h2v2h-2v-2zm0 4h2v2h-2v-2z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-border-vertical">
<path d="M1 1h2v2H1V1zm0 4h2v2H1V5zm0 4h2v2H1V9zm0 4h2v2H1v-2zm0 4h2v2H1v-2zM5 1h2v2H5V1zm0 8h2v2H5V9zm0 8h2v2H5v-2zM9 1h2v18H9V1zm4 0h2v2h-2V1zm0 8h2v2h-2V9zm0 8h2v2h-2v-2zm4-16h2v2h-2V1zm0 4h2v2h-2V5zm0 4h2v2h-2V9zm0 4h2v2h-2v-2zm0 4h2v2h-2v-2z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-box">
<path d="M0 2C0 .9.9 0 2 0h16a2 2 0 0 1 2 2v2H0V2zm1 3h18v13a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V5zm6 2v2h6V7H7z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-brightness-down">
<path d="M10 13a3 3 0 1 1 0-6 3 3 0 0 1 0 6zM9 4a1 1 0 1 1 2 0 1 1 0 1 1-2 0zm4.54 1.05a1 1 0 1 1 1.41 1.41 1 1 0 1 1-1.41-1.41zM16 9a1 1 0 1 1 0 2 1 1 0 1 1 0-2zm-1.05 4.54a1 1 0 1 1-1.41 1.41 1 1 0 1 1 1.41-1.41zM11 16a1 1 0 1 1-2 0 1 1 0 1 1 2 0zm-4.54-1.05a1 1 0 1 1-1.41-1.41 1 1 0 1 1 1.41 1.41zM4 11a1 1 0 1 1 0-2 1 1 0 1 1 0 2zm1.05-4.54a1 1 0 1 1 1.41-1.41 1 1 0 1 1-1.41 1.41z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-brightness-up">
<path d="M10 14a4 4 0 1 1 0-8 4 4 0 0 1 0 8zM9 1a1 1 0 1 1 2 0v2a1 1 0 1 1-2 0V1zm6.65 1.94a1 1 0 1 1 1.41 1.41l-1.4 1.4a1 1 0 1 1-1.41-1.41l1.4-1.4zM18.99 9a1 1 0 1 1 0 2h-1.98a1 1 0 1 1 0-2h1.98zm-1.93 6.65a1 1 0 1 1-1.41 1.41l-1.4-1.4a1 1 0 1 1 1.41-1.41l1.4 1.4zM11 18.99a1 1 0 1 1-2 0v-1.98a1 1 0 1 1 2 0v1.98zm-6.65-1.93a1 1 0 1 1-1.41-1.41l1.4-1.4a1 1 0 1 1 1.41 1.41l-1.4 1.4zM1.01 11a1 1 0 1 1 0-2h1.98a1 1 0 1 1 0 2H1.01zm1.93-6.65a1 1 0 1 1 1.41-1.41l1.4 1.4a1 1 0 1 1-1.41 1.41l-1.4-1.4z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-browser-window">
<path d="M0 3c0-1.1.9-2 2-2h16a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V3zm2 2v12h16V5H2z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-browser-window-new">
<path d="M9 10V8h2v2h2v2h-2v2H9v-2H7v-2h2zM0 3c0-1.1.9-2 2-2h16a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V3zm2 2v12h16V5H2z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-browser-window-open">
<path d="M0 3c0-1.1.9-2 2-2h16a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V3zm2 2v12h16V5H2zm8 3l4 5H6l4-5z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-bug">
<path d="M15.3 14.89l2.77 2.77a1 1 0 0 1 0 1.41 1 1 0 0 1-1.41 0l-2.59-2.58A5.99 5.99 0 0 1 11 18V9.04a1 1 0 0 0-2 0V18a5.98 5.98 0 0 1-3.07-1.51l-2.59 2.58a1 1 0 0 1-1.41 0 1 1 0 0 1 0-1.41l2.77-2.77A5.95 5.95 0 0 1 4.07 13H1a1 1 0 1 1 0-2h3V8.41L.93 5.34a1 1 0 0 1 0-1.41 1 1 0 0 1 1.41 0l2.1 2.1h11.12l2.1-2.1a1 1 0 0 1 1.41 0 1 1 0 0 1 0 1.41L16 8.41V11h3a1 1 0 1 1 0 2h-3.07c-.1.67-.32 1.31-.63 1.89zM15 5H5a5 5 0 1 1 10 0z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-buoy">
<path d="M17.16 6.42a8.03 8.03 0 0 0-3.58-3.58l-1.34 2.69a5.02 5.02 0 0 1 2.23 2.23l2.69-1.34zm0 7.16l-2.69-1.34a5.02 5.02 0 0 1-2.23 2.23l1.34 2.69a8.03 8.03 0 0 0 3.58-3.58zM6.42 2.84a8.03 8.03 0 0 0-3.58 3.58l2.69 1.34a5.02 5.02 0 0 1 2.23-2.23L6.42 2.84zM2.84 13.58a8.03 8.03 0 0 0 3.58 3.58l1.34-2.69a5.02 5.02 0 0 1-2.23-2.23l-2.69 1.34zM10 20a10 10 0 1 1 0-20 10 10 0 0 1 0 20zm0-7a3 3 0 1 0 0-6 3 3 0 0 0 0 6z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-calculator">
<path d="M2 2c0-1.1.9-2 2-2h12a2 2 0 0 1 2 2v16a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V2zm3 1v2h10V3H5zm0 4v2h2V7H5zm4 0v2h2V7H9zm4 0v2h2V7h-2zm-8 4v2h2v-2H5zm4 0v2h2v-2H9zm4 0v6h2v-6h-2zm-8 4v2h2v-2H5zm4 0v2h2v-2H9z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-calendar">
<path d="M1 4c0-1.1.9-2 2-2h14a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V4zm2 2v12h14V6H3zm2-6h2v2H5V0zm8 0h2v2h-2V0zM5 9h2v2H5V9zm0 4h2v2H5v-2zm4-4h2v2H9V9zm0 4h2v2H9v-2zm4-4h2v2h-2V9zm0 4h2v2h-2v-2z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-camera">
<path d="M0 6c0-1.1.9-2 2-2h3l2-2h6l2 2h3a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V6zm10 10a5 5 0 1 0 0-10 5 5 0 0 0 0 10zm0-2a3 3 0 1 1 0-6 3 3 0 0 1 0 6z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-chart">
<path d="M4.13 12H4a2 2 0 1 0 1.8 1.11L7.86 10a2.03 2.03 0 0 0 .65-.07l1.55 1.55a2 2 0 1 0 3.72-.37L15.87 8H16a2 2 0 1 0-1.8-1.11L12.14 10a2.03 2.03 0 0 0-.65.07L9.93 8.52a2 2 0 1 0-3.72.37L4.13 12zM0 4c0-1.1.9-2 2-2h16a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V4z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-chart-bar">
<path d="M1 10h3v10H1V10zM6 0h3v20H6V0zm5 8h3v12h-3V8zm5-4h3v16h-3V4z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-chart-pie">
<path d="M19.95 11A10 10 0 1 1 9 .05V11h10.95zm-.08-2.6H11.6V.13a10 10 0 0 1 8.27 8.27z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-chat-bubble-dots">
<path d="M10 15l-4 4v-4H2a2 2 0 0 1-2-2V3c0-1.1.9-2 2-2h16a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2h-8zM5 7v2h2V7H5zm4 0v2h2V7H9zm4 0v2h2V7h-2z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-checkmark">
<path d="M0 11l2-2 5 5L18 3l2 2L7 18z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-checkmark-outline">
<path d="M2.93 17.07A10 10 0 1 1 17.07 2.93 10 10 0 0 1 2.93 17.07zm12.73-1.41A8 8 0 1 0 4.34 4.34a8 8 0 0 0 11.32 11.32zM6.7 9.29L9 11.6l4.3-4.3 1.4 1.42L9 14.4l-3.7-3.7 1.4-1.42z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-cheveron-down">
<path d="M9.293 12.95l.707.707L15.657 8l-1.414-1.414L10 10.828 5.757 6.586 4.343 8z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-cheveron-left">
<path d="M7.05 9.293L6.343 10 12 15.657l1.414-1.414L9.172 10l4.242-4.243L12 4.343z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-cheveron-outline-down">
<path d="M20 10a10 10 0 1 1-20 0 10 10 0 0 1 20 0zM10 2a8 8 0 1 0 0 16 8 8 0 0 0 0-16zm-.7 10.54L5.75 9l1.41-1.41L10 10.4l2.83-2.82L14.24 9 10 13.24l-.7-.7z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-cheveron-outline-left">
<path d="M10 20a10 10 0 1 1 0-20 10 10 0 0 1 0 20zm8-10a8 8 0 1 0-16 0 8 8 0 0 0 16 0zM7.46 9.3L11 5.75l1.41 1.41L9.6 10l2.82 2.83L11 14.24 6.76 10l.7-.7z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-cheveron-outline-right">
<path d="M10 0a10 10 0 1 1 0 20 10 10 0 0 1 0-20zM2 10a8 8 0 1 0 16 0 8 8 0 0 0-16 0zm10.54.7L9 14.25l-1.41-1.41L10.4 10 7.6 7.17 9 5.76 13.24 10l-.7.7z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-cheveron-outline-up">
<path d="M0 10a10 10 0 1 1 20 0 10 10 0 0 1-20 0zm10 8a8 8 0 1 0 0-16 8 8 0 0 0 0 16zm.7-10.54L14.25 11l-1.41 1.41L10 9.6l-2.83 2.8L5.76 11 10 6.76l.7.7z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-cheveron-right">
<path d="M12.95 10.707l.707-.707L8 4.343 6.586 5.757 10.828 10l-4.242 4.243L8 15.657l4.95-4.95z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-cheveron-up">
<path d="M10.707 7.05L10 6.343 4.343 12l1.414 1.414L10 9.172l4.243 4.242L15.657 12z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-clipboard">
<path d="M7.03 2.6a3 3 0 0 1 5.94 0L15 3v1h1a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V6c0-1.1.9-2 2-2h1V3l2.03-.4zM5 6H4v12h12V6h-1v1H5V6zm5-2a1 1 0 1 0 0-2 1 1 0 0 0 0 2z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-close">
<path d="M10 8.586L2.929 1.515 1.515 2.929 8.586 10l-7.071 7.071 1.414 1.414L10 11.414l7.071 7.071 1.414-1.414L11.414 10l7.071-7.071-1.414-1.414L10 8.586z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-close-outline">
<path d="M2.93 17.07A10 10 0 1 1 17.07 2.93 10 10 0 0 1 2.93 17.07zm1.41-1.41A8 8 0 1 0 15.66 4.34 8 8 0 0 0 4.34 15.66zm9.9-8.49L11.41 10l2.83 2.83-1.41 1.41L10 11.41l-2.83 2.83-1.41-1.41L8.59 10 5.76 7.17l1.41-1.41L10 8.59l2.83-2.83 1.41 1.41z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-close-solid">
<path d="M2.93 17.07A10 10 0 1 1 17.07 2.93 10 10 0 0 1 2.93 17.07zM11.4 10l2.83-2.83-1.41-1.41L10 8.59 7.17 5.76 5.76 7.17 8.59 10l-2.83 2.83 1.41 1.41L10 11.41l2.83 2.83 1.41-1.41L11.41 10z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-cloud">
<path d="M16.88 9.1A4 4 0 0 1 16 17H5a5 5 0 0 1-1-9.9V7a3 3 0 0 1 4.52-2.59A4.98 4.98 0 0 1 17 8c0 .38-.04.74-.12 1.1z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-cloud-upload">
<path d="M16.88 9.1A4 4 0 0 1 16 17H5a5 5 0 0 1-1-9.9V7a3 3 0 0 1 4.52-2.59A4.98 4.98 0 0 1 17 8c0 .38-.04.74-.12 1.1zM11 11h3l-4-4-4 4h3v3h2v-3z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-code">
<path d="M.7 9.3l4.8-4.8 1.4 1.42L2.84 10l4.07 4.07-1.41 1.42L0 10l.7-.7zm18.6 1.4l.7-.7-5.49-5.49-1.4 1.42L17.16 10l-4.07 4.07 1.41 1.42 4.78-4.78z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-coffee">
<path d="M4 11H2a2 2 0 0 1-2-2V5c0-1.1.9-2 2-2h2V1h14v10a4 4 0 0 1-4 4H8a4 4 0 0 1-4-4zm0-2V5H2v4h2zm-2 8v-1h18v1l-4 2H6l-4-2z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-cog">
<path d="M3.94 6.5L2.22 3.64l1.42-1.42L6.5 3.94c.52-.3 1.1-.54 1.7-.7L9 0h2l.8 3.24c.6.16 1.18.4 1.7.7l2.86-1.72 1.42 1.42-1.72 2.86c.3.52.54 1.1.7 1.7L20 9v2l-3.24.8c-.16.6-.4 1.18-.7 1.7l1.72 2.86-1.42 1.42-2.86-1.72c-.52.3-1.1.54-1.7.7L11 20H9l-.8-3.24c-.6-.16-1.18-.4-1.7-.7l-2.86 1.72-1.42-1.42 1.72-2.86c-.3-.52-.54-1.1-.7-1.7L0 11V9l3.24-.8c.16-.6.4-1.18.7-1.7zM10 13a3 3 0 1 0 0-6 3 3 0 0 0 0 6z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-color-palette">
<path d="M9 20v-1.7l.01-.24L15.07 12h2.94c1.1 0 1.99.89 1.99 2v4a2 2 0 0 1-2 2H9zm0-3.34V5.34l2.08-2.07a1.99 1.99 0 0 1 2.82 0l2.83 2.83a2 2 0 0 1 0 2.82L9 16.66zM0 1.99C0 .9.89 0 2 0h4a2 2 0 0 1 2 2v16a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V2zM4 17a1 1 0 1 0 0-2 1 1 0 0 0 0 2z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-compose">
<path d="M2 4v14h14v-6l2-2v10H0V2h10L8 4H2zm10.3-.3l4 4L8 16H4v-4l8.3-8.3zm1.4-1.4L16 0l4 4-2.3 2.3-4-4z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-computer-desktop">
<path d="M7 17H2a2 2 0 0 1-2-2V2C0 .9.9 0 2 0h16a2 2 0 0 1 2 2v13a2 2 0 0 1-2 2h-5l4 2v1H3v-1l4-2zM2 2v11h16V2H2z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-computer-laptop">
<path d="M18 16h2v1a1 1 0 0 1-1 1H1a1 1 0 0 1-1-1v-1h2V4c0-1.1.9-2 2-2h12a2 2 0 0 1 2 2v12zM4 4v9h12V4H4zm4 11v1h4v-1H8z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-conversation">
<path d="M17 11v3l-3-3H8a2 2 0 0 1-2-2V2c0-1.1.9-2 2-2h10a2 2 0 0 1 2 2v7a2 2 0 0 1-2 2h-1zm-3 2v2a2 2 0 0 1-2 2H6l-3 3v-3H2a2 2 0 0 1-2-2V8c0-1.1.9-2 2-2h2v3a4 4 0 0 0 4 4h6z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-credit-card">
<path d="M18 6V4H2v2h16zm0 4H2v6h16v-6zM0 4c0-1.1.9-2 2-2h16a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V4zm4 8h4v2H4v-2z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-currency-dollar">
<path d="M10 20a10 10 0 1 1 0-20 10 10 0 0 1 0 20zm1-5h1a3 3 0 0 0 0-6H7.99a1 1 0 0 1 0-2H14V5h-3V3H9v2H8a3 3 0 1 0 0 6h4a1 1 0 1 1 0 2H6v2h3v2h2v-2z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-dashboard">
<path d="M10 20a10 10 0 1 1 0-20 10 10 0 0 1 0 20zm-5.6-4.29a9.95 9.95 0 0 1 11.2 0 8 8 0 1 0-11.2 0zm6.12-7.64l3.02-3.02 1.41 1.41-3.02 3.02a2 2 0 1 1-1.41-1.41z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-date-add">
<path d="M15 2h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V4c0-1.1.9-2 2-2h2V0h2v2h6V0h2v2zM3 6v12h14V6H3zm6 5V9h2v2h2v2h-2v2H9v-2H7v-2h2z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-dial-pad">
<path d="M5 4a2 2 0 1 1 0-4 2 2 0 0 1 0 4zm5 0a2 2 0 1 1 0-4 2 2 0 0 1 0 4zm5 0a2 2 0 1 1 0-4 2 2 0 0 1 0 4zM5 9a2 2 0 1 1 0-4 2 2 0 0 1 0 4zm5 0a2 2 0 1 1 0-4 2 2 0 0 1 0 4zm5 0a2 2 0 1 1 0-4 2 2 0 0 1 0 4zM5 14a2 2 0 1 1 0-4 2 2 0 0 1 0 4zm5 0a2 2 0 1 1 0-4 2 2 0 0 1 0 4zm0 6a2 2 0 1 1 0-4 2 2 0 0 1 0 4zm5-6a2 2 0 1 1 0-4 2 2 0 0 1 0 4z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-directions">
<path d="M10 0l10 10-10 10L0 10 10 0zM6 10v3h2v-3h3v3l4-4-4-4v3H8a2 2 0 0 0-2 2z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-document">
<path d="M4 18h12V6h-4V2H4v16zm-2 1V0h12l4 4v16H2v-1z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-document-add">
<path d="M9 10V8h2v2h2v2h-2v2H9v-2H7v-2h2zm-5 8h12V6h-4V2H4v16zm-2 1V0h12l4 4v16H2v-1z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-dots-horizontal-double">
<path d="M10 9a2 2 0 1 1 0-4 2 2 0 0 1 0 4zm0 6a2 2 0 1 1 0-4 2 2 0 0 1 0 4z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-dots-horizontal-triple">
<path d="M10 12a2 2 0 1 1 0-4 2 2 0 0 1 0 4zm0-6a2 2 0 1 1 0-4 2 2 0 0 1 0 4zm0 12a2 2 0 1 1 0-4 2 2 0 0 1 0 4z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-download">
<path d="M13 8V2H7v6H2l8 8 8-8h-5zM0 18h20v2H0v-2z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-duplicate">
<path d="M6 6V2c0-1.1.9-2 2-2h10a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2h-4v4a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V8c0-1.1.9-2 2-2h4zm2 0h4a2 2 0 0 1 2 2v4h4V2H8v4zM2 8v10h10V8H2zm4 4v-2h2v2h2v2H8v2H6v-2H4v-2h2z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-edit-copy">
<path d="M6 6V2c0-1.1.9-2 2-2h10a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2h-4v4a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V8c0-1.1.9-2 2-2h4zm2 0h4a2 2 0 0 1 2 2v4h4V2H8v4zM2 8v10h10V8H2z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-edit-crop">
<path d="M14 16H6a2 2 0 0 1-2-2V6H0V4h4V0h2v14h14v2h-4v4h-2v-4zm0-3V6H7V4h7a2 2 0 0 1 2 2v7h-2z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-edit-cut">
<path d="M9.77 11.5l5.34 3.91c.44.33 1.24.59 1.79.59H20L6.89 6.38A3.5 3.5 0 1 0 5.5 8.37L7.73 10 5.5 11.63a3.5 3.5 0 1 0 1.38 1.99l2.9-2.12zM3.5 7a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3zm0 9a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3zM15.1 4.59A3.53 3.53 0 0 1 16.9 4H20l-7.5 5.5L10.45 8l4.65-3.41z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-edit-pencil">
<path d="M12.3 3.7l4 4L4 20H0v-4L12.3 3.7zm1.4-1.4L16 0l4 4-2.3 2.3-4-4z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-education">
<path d="M3.33 8L10 12l10-6-10-6L0 6h10v2H3.33zM0 8v8l2-2.22V9.2L0 8zm10 12l-5-3-2-1.2v-6l7 4.2 7-4.2v6L10 20z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-envelope">
<path d="M18 2a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V4c0-1.1.9-2 2-2h16zm-4.37 9.1L20 16v-2l-5.12-3.9L20 6V4l-10 8L0 4v2l5.12 4.1L0 14v2l6.37-4.9L10 14l3.63-2.9z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-exclamation-outline">
<path d="M2.93 17.07A10 10 0 1 1 17.07 2.93 10 10 0 0 1 2.93 17.07zm12.73-1.41A8 8 0 1 0 4.34 4.34a8 8 0 0 0 11.32 11.32zM9 5h2v6H9V5zm0 8h2v2H9v-2z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-exclamation-solid">
<path d="M2.93 17.07A10 10 0 1 1 17.07 2.93 10 10 0 0 1 2.93 17.07zM9 5v6h2V5H9zm0 8v2h2v-2H9z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-explore">
<path d="M10 20a10 10 0 1 1 0-20 10 10 0 0 1 0 20zM7.88 7.88l-3.54 7.78 7.78-3.54 3.54-7.78-7.78 3.54zM10 11a1 1 0 1 1 0-2 1 1 0 0 1 0 2z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-factory">
<path d="M10.5 20H0V7l5 3.33V7l5 3.33V7l5 3.33V0h5v20h-9.5z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-fast-forward">
<path d="M1 5l9 5-9 5V5zm9 0l9 5-9 5V5z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-fast-rewind">
<path d="M19 5v10l-9-5 9-5zm-9 0v10l-9-5 9-5z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-film">
<path d="M0 4c0-1.1.9-2 2-2h16a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V4zm6 0v12h8V4H6zM2 5v2h2V5H2zm0 4v2h2V9H2zm0 4v2h2v-2H2zm14-8v2h2V5h-2zm0 4v2h2V9h-2zm0 4v2h2v-2h-2zM8 7l5 3-5 3V7z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-filter">
<path d="M12 12l8-8V0H0v4l8 8v8l4-4v-4z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-flag">
<path d="M7.667 12H2v8H0V0h12l.333 2H20l-3 6 3 6H8l-.333-2z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-flashlight">
<path d="M13 7v11a2 2 0 0 1-2 2H9a2 2 0 0 1-2-2V7L5 5V3h10v2l-2 2zM9 8v1a1 1 0 1 0 2 0V8a1 1 0 0 0-2 0zM5 0h10v2H5V0z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-folder">
<path d="M0 4c0-1.1.9-2 2-2h7l2 2h7a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V4z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-folder-outline">
<path d="M0 4c0-1.1.9-2 2-2h7l2 2h7a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V4zm2 2v10h16V6H2z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-folder-outline-add">
<path d="M0 4c0-1.1.9-2 2-2h7l2 2h7a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V4zm2 2v10h16V6H2zm7 4V8h2v2h2v2h-2v2H9v-2H7v-2h2z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-format-bold">
<path d="M3 19V1h8a5 5 0 0 1 3.88 8.16A5.5 5.5 0 0 1 11.5 19H3zm7.5-8H7v5h3.5a2.5 2.5 0 1 0 0-5zM7 4v4h3a2 2 0 1 0 0-4H7z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-format-italic">
<path d="M8 1h9v2H8V1zm3 2h3L8 17H5l6-14zM2 17h9v2H2v-2z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-format-text-size">
<path d="M16 9v8h-2V9h-4V7h10v2h-4zM8 5v12H6V5H0V3h15v2H8z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-format-underline">
<path d="M16 9A6 6 0 1 1 4 9V1h3v8a3 3 0 0 0 6 0V1h3v8zM2 17h16v2H2v-2z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-gift">
<path d="M14.83 4H20v6h-1v10H1V10H0V4h5.17A3 3 0 0 1 10 .76 3 3 0 0 1 14.83 4zM8 10H3v8h5v-8zm4 0v8h5v-8h-5zM8 6H2v2h6V6zm4 0v2h6V6h-6zM8 4a1 1 0 1 0 0-2 1 1 0 0 0 0 2zm4 0a1 1 0 1 0 0-2 1 1 0 0 0 0 2z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-globe">
<path d="M10 20a10 10 0 1 1 0-20 10 10 0 0 1 0 20zm2-2.25a8 8 0 0 0 4-2.46V9a2 2 0 0 1-2-2V3.07a7.95 7.95 0 0 0-3-1V3a2 2 0 0 1-2 2v1a2 2 0 0 1-2 2v2h3a2 2 0 0 1 2 2v5.75zm-4 0V15a2 2 0 0 1-2-2v-1h-.5A1.5 1.5 0 0 1 4 10.5V8H2.25A8.01 8.01 0 0 0 8 17.75z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-hand-stop">
<path d="M17 16a4 4 0 0 1-4 4H7a4 4 0 0 1-4-4.01V4a1 1 0 0 1 1-1 1 1 0 0 1 1 1v6h1V2a1 1 0 0 1 1-1 1 1 0 0 1 1 1v8h1V1a1 1 0 1 1 2 0v9h1V2a1 1 0 0 1 1-1 1 1 0 0 1 1 1v13h1V9a1 1 0 0 1 1-1h1v8z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-hard-drive">
<path d="M2 2c0-1.1.9-2 2-2h12a2 2 0 0 1 2 2v16a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V2zm10.4 5.6A5 5 0 1 0 15 12V5l-2.6 2.6zM10 14a2 2 0 1 1 0-4 2 2 0 0 1 0 4zM6 3v2h4V3H6zM4 3a1 1 0 1 0 0-2 1 1 0 0 0 0 2zm0 16a1 1 0 1 0 0-2 1 1 0 0 0 0 2zm12 0a1 1 0 1 0 0-2 1 1 0 0 0 0 2zm0-16a1 1 0 1 0 0-2 1 1 0 0 0 0 2z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-headphones">
<path d="M16 8A6 6 0 1 0 4 8v11H2a2 2 0 0 1-2-2v-4a2 2 0 0 1 2-2V8a8 8 0 1 1 16 0v3a2 2 0 0 1 2 2v4a2 2 0 0 1-2 2h-2V8zm-4 2h3v10h-3V10zm-7 0h3v10H5V10z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-heart">
<path d="M10 3.22l-.61-.6a5.5 5.5 0 0 0-7.78 7.77L10 18.78l8.39-8.4a5.5 5.5 0 0 0-7.78-7.77l-.61.61z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-home">
<path d="M8 20H3V10H0L10 0l10 10h-3v10h-5v-6H8v6z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-hot">
<path d="M10 0s8 7.58 8 12a8 8 0 1 1-16 0c0-1.5.91-3.35 2.12-5.15A3 3 0 0 0 10 6V0zM8 0a3 3 0 1 0 0 6V0z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-hour-glass">
<path d="M3 18a7 7 0 0 1 4-6.33V8.33A7 7 0 0 1 3 2H1V0h18v2h-2a7 7 0 0 1-4 6.33v3.34A7 7 0 0 1 17 18h2v2H1v-2h2zM5 2a5 5 0 0 0 4 4.9V10h2V6.9A5 5 0 0 0 15 2H5z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-inbox">
<path d="M0 2C0 .9.9 0 2 0h16a2 2 0 0 1 2 2v16a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V2zm14 12h4V2H2v12h4c0 1.1.9 2 2 2h4a2 2 0 0 0 2-2z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-inbox-check">
<path d="M0 2C0 .9.9 0 2 0h16a2 2 0 0 1 2 2v16a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V2zm14 12h4V2H2v12h4c0 1.1.9 2 2 2h4a2 2 0 0 0 2-2zM5 9l2-2 2 2 4-4 2 2-6 6-4-4z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-inbox-download">
<path d="M0 2C0 .9.9 0 2 0h16a2 2 0 0 1 2 2v16a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V2zm14 12h4V2H2v12h4c0 1.1.9 2 2 2h4a2 2 0 0 0 2-2zM9 8V5h2v3h3l-4 4-4-4h3z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-inbox-full">
<path d="M14 14h4V2H2v12h4c0 1.1.9 2 2 2h4a2 2 0 0 0 2-2zM0 2C0 .9.9 0 2 0h16a2 2 0 0 1 2 2v16a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V2zm4 2h12v2H4V4zm0 3h12v2H4V7zm0 3h12v2H4v-2z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-indent-decrease">
<path d="M1 1h18v2H1V1zm6 8h12v2H7V9zm-6 8h18v2H1v-2zM7 5h12v2H7V5zm0 8h12v2H7v-2zM5 6v8l-4-4 4-4z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-indent-increase">
<path d="M1 1h18v2H1V1zm6 8h12v2H7V9zm-6 8h18v2H1v-2zM7 5h12v2H7V5zm0 8h12v2H7v-2zM1 6l4 4-4 4V6z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-information-outline">
<path d="M2.93 17.07A10 10 0 1 1 17.07 2.93 10 10 0 0 1 2.93 17.07zm12.73-1.41A8 8 0 1 0 4.34 4.34a8 8 0 0 0 11.32 11.32zM9 11V9h2v6H9v-4zm0-6h2v2H9V5z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-information-solid">
<path d="M2.93 17.07A10 10 0 1 1 17.07 2.93 10 10 0 0 1 2.93 17.07zM9 11v4h2V9H9v2zm0-6v2h2V5H9z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-key">
<path d="M12.26 11.74L10 14H8v2H6v2l-2 2H0v-4l8.26-8.26a6 6 0 1 1 4 4zm4.86-4.62A3 3 0 0 0 15 2a3 3 0 0 0-2.12.88l4.24 4.24z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-keyboard">
<path d="M0 6c0-1.1.9-2 2-2h16a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V6zm2 0v2h2V6H2zm1 3v2h2V9H3zm-1 3v2h2v-2H2zm3 0v2h10v-2H5zm11 0v2h2v-2h-2zM6 9v2h2V9H6zm3 0v2h2V9H9zm3 0v2h2V9h-2zm3 0v2h2V9h-2zM5 6v2h2V6H5zm3 0v2h2V6H8zm3 0v2h2V6h-2zm3 0v2h4V6h-4z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-layers">
<path d="M10 1l10 6-10 6L0 7l10-6zm6.67 10L20 13l-10 6-10-6 3.33-2L10 15l6.67-4z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-library">
<path d="M0 6l10-6 10 6v2H0V6zm0 12h20v2H0v-2zm2-2h16v2H2v-2zm0-8h4v8H2V8zm6 0h4v8H8V8zm6 0h4v8h-4V8z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-light-bulb">
<path d="M7 13.33a7 7 0 1 1 6 0V16H7v-2.67zM7 17h6v1.5c0 .83-.67 1.5-1.5 1.5h-3A1.5 1.5 0 0 1 7 18.5V17zm2-5.1V14h2v-2.1a5 5 0 1 0-2 0z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-link">
<path d="M9.26 13a2 2 0 0 1 .01-2.01A3 3 0 0 0 9 5H5a3 3 0 0 0 0 6h.08a6.06 6.06 0 0 0 0 2H5A5 5 0 0 1 5 3h4a5 5 0 0 1 .26 10zm1.48-6a2 2 0 0 1-.01 2.01A3 3 0 0 0 11 15h4a3 3 0 0 0 0-6h-.08a6.06 6.06 0 0 0 0-2H15a5 5 0 0 1 0 10h-4a5 5 0 0 1-.26-10z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-list-add">
<path d="M15 9h-3v2h3v3h2v-3h3V9h-3V6h-2v3zM0 3h10v2H0V3zm0 8h10v2H0v-2zm0-4h10v2H0V7zm0 8h10v2H0v-2z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-list-bullet">
<path d="M1 4h2v2H1V4zm4 0h14v2H5V4zM1 9h2v2H1V9zm4 0h14v2H5V9zm-4 5h2v2H1v-2zm4 0h14v2H5v-2z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-load-balancer">
<path d="M17 12h-6v4h1v4H8v-4h1v-4H3v4h1v4H0v-4h1v-4a2 2 0 0 1 2-2h6V6H7V0h6v6h-2v4h6a2 2 0 0 1 2 2v4h1v4h-4v-4h1v-4z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-location">
<path d="M10 20S3 10.87 3 7a7 7 0 1 1 14 0c0 3.87-7 13-7 13zm0-11a2 2 0 1 0 0-4 2 2 0 0 0 0 4z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-location-current">
<path d="M0 0l20 8-8 4-2 8z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-location-food">
<path d="M18 11v7a2 2 0 0 1-4 0v-5h-2V3a3 3 0 0 1 3-3h3v11zM4 10a2 2 0 0 1-2-2V1a1 1 0 0 1 2 0v4h1V1a1 1 0 0 1 2 0v4h1V1a1 1 0 0 1 2 0v7a2 2 0 0 1-2 2v8a2 2 0 0 1-4 0v-8z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-location-gas-station">
<path d="M13 18h1v2H0v-2h1V2c0-1.1.9-2 2-2h8a2 2 0 0 1 2 2v16zM3 2v6h8V2H3zm10 8h1a2 2 0 0 1 2 2v3a1 1 0 0 0 2 0v-5l-2-2V6l-2-2 1-1 5 5v7a3 3 0 0 1-6 0v-3h-1v-2z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-location-hotel">
<path d="M2 12h18v6h-2v-2H2v2H0V2h2v10zm8-6h8a2 2 0 0 1 2 2v3H10V6zm-4 5a3 3 0 1 1 0-6 3 3 0 0 1 0 6z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-location-marina">
<path d="M8 1.88V0h2v16h10l-4 4H2l-2-4h8v-2H0v-.26A24.03 24.03 0 0 0 8 1.88zM19.97 14H10v-.36A11.94 11.94 0 0 0 10 .36v-.2A16.01 16.01 0 0 1 19.97 14z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-location-park">
<path d="M5.33 12.77A4 4 0 1 1 3 5.13V5a4 4 0 0 1 5.71-3.62 3.5 3.5 0 0 1 6.26 1.66 2.5 2.5 0 0 1 2 2.08 4 4 0 1 1-2.7 7.49A5.02 5.02 0 0 1 12 14.58V18l2 1v1H6v-1l2-1v-3l-2.67-2.23zM5 10l3 3v-3H5z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-location-restroom">
<path d="M12 16H9l2-4.5V9c0-1.1.9-2 2-2h2a2 2 0 0 1 2 2v2.5l2 4.5h-3v4h-4v-4zm-5-3h2V9a2 2 0 0 0-2-2H3a2 2 0 0 0-2 2v4h2v7h4v-7zM5 6a3 3 0 1 1 0-6 3 3 0 0 1 0 6zm9 0a3 3 0 1 1 0-6 3 3 0 0 1 0 6z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-location-shopping">
<path d="M16 6v2h2l2 12H0L2 8h2V6a6 6 0 1 1 12 0zm-2 0a4 4 0 1 0-8 0v2h8V6zM4 10v2h2v-2H4zm10 0v2h2v-2h-2z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-lock-closed">
<path d="M4 8V6a6 6 0 1 1 12 0v2h1a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2v-8c0-1.1.9-2 2-2h1zm5 6.73V17h2v-2.27a2 2 0 1 0-2 0zM7 6v2h6V6a3 3 0 0 0-6 0z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-lock-open">
<path d="M4 8V6a6 6 0 1 1 12 0h-3v2h4a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2v-8c0-1.1.9-2 2-2h1zm5 6.73V17h2v-2.27a2 2 0 1 0-2 0zM7 6v2h6V6a3 3 0 0 0-6 0z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-map">
<path d="M0 0l6 4 8-4 6 4v16l-6-4-8 4-6-4V0zm7 6v11l6-3V3L7 6z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-menu">
<path d="M0 3h20v2H0V3zm0 6h20v2H0V9zm0 6h20v2H0v-2z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-mic">
<path d="M9 18v-1.06A8 8 0 0 1 2 9h2a6 6 0 1 0 12 0h2a8 8 0 0 1-7 7.94V18h3v2H6v-2h3zM6 4a4 4 0 1 1 8 0v5a4 4 0 1 1-8 0V4z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-minus-outline">
<path d="M10 20a10 10 0 1 1 0-20 10 10 0 0 1 0 20zm0-2a8 8 0 1 0 0-16 8 8 0 0 0 0 16zm5-9v2H5V9h10z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-minus-solid">
<path d="M10 20a10 10 0 1 1 0-20 10 10 0 0 1 0 20zm5-11H5v2h10V9z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-mobile-devices">
<path d="M17 6V5h-2V2H3v14h5v4h3.25H11a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6zm-5.75 14H3a2 2 0 0 1-2-2V2c0-1.1.9-2 2-2h12a2 2 0 0 1 2 2v4a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2h-5.75zM11 8v8h6V8h-6zm3 11a1 1 0 1 0 0-2 1 1 0 0 0 0 2z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-mood-happy">
<path d="M10 20a10 10 0 1 1 0-20 10 10 0 0 1 0 20zm0-2a8 8 0 1 0 0-16 8 8 0 0 0 0 16zM6.5 9a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3zm7 0a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3zm2.16 3a6 6 0 0 1-11.32 0h11.32z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-mood-sad">
<path d="M10 20a10 10 0 1 1 0-20 10 10 0 0 1 0 20zm0-2a8 8 0 1 0 0-16 8 8 0 0 0 0 16zM6.5 9a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3zm7 0a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3zm2.16 6H4.34a6 6 0 0 1 11.32 0z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-mouse">
<path d="M4 9V6A6 6 0 0 1 9 .08V9H4zm0 2v3a6 6 0 1 0 12 0v-3H4zm12-2V6a6 6 0 0 0-5-5.92V9h5z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-music-album">
<path d="M0 0h20v20H0V0zm10 18a8 8 0 1 0 0-16 8 8 0 0 0 0 16zm0-5a3 3 0 1 1 0-6 3 3 0 0 1 0 6z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-music-artist">
<path d="M15.75 8l-3.74-3.75a3.99 3.99 0 0 1 6.82-3.08A4 4 0 0 1 15.75 8zm-13.9 7.3l9.2-9.19 2.83 2.83-9.2 9.2-2.82-2.84zm-1.4 2.83l2.11-2.12 1.42 1.42-2.12 2.12-1.42-1.42zM10 15l2-2v7h-2v-5z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-music-notes">
<path d="M20 2.5V0L6 2v12.17A3 3 0 0 0 5 14H3a3 3 0 0 0 0 6h2a3 3 0 0 0 3-3V5.71L18 4.3v7.88a3 3 0 0 0-1-.17h-2a3 3 0 0 0 0 6h2a3 3 0 0 0 3-3V2.5z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-music-playlist">
<path d="M16 17a3 3 0 0 1-3 3h-2a3 3 0 0 1 0-6h2a3 3 0 0 1 1 .17V1l6-1v4l-4 .67V17zM0 3h12v2H0V3zm0 4h12v2H0V7zm0 4h12v2H0v-2zm0 4h6v2H0v-2z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-navigation-more">
<path d="M4 12a2 2 0 1 1 0-4 2 2 0 0 1 0 4zm6 0a2 2 0 1 1 0-4 2 2 0 0 1 0 4zm6 0a2 2 0 1 1 0-4 2 2 0 0 1 0 4z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-network">
<path d="M10 20a10 10 0 1 1 0-20 10 10 0 0 1 0 20zm7.75-8a8.01 8.01 0 0 0 0-4h-3.82a28.81 28.81 0 0 1 0 4h3.82zm-.82 2h-3.22a14.44 14.44 0 0 1-.95 3.51A8.03 8.03 0 0 0 16.93 14zm-8.85-2h3.84a24.61 24.61 0 0 0 0-4H8.08a24.61 24.61 0 0 0 0 4zm.25 2c.41 2.4 1.13 4 1.67 4s1.26-1.6 1.67-4H8.33zm-6.08-2h3.82a28.81 28.81 0 0 1 0-4H2.25a8.01 8.01 0 0 0 0 4zm.82 2a8.03 8.03 0 0 0 4.17 3.51c-.42-.96-.74-2.16-.95-3.51H3.07zm13.86-8a8.03 8.03 0 0 0-4.17-3.51c.42.96.74 2.16.95 3.51h3.22zm-8.6 0h3.34c-.41-2.4-1.13-4-1.67-4S8.74 3.6 8.33 6zM3.07 6h3.22c.2-1.35.53-2.55.95-3.51A8.03 8.03 0 0 0 3.07 6z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-news-paper">
<path d="M16 2h4v15a3 3 0 0 1-3 3H3a3 3 0 0 1-3-3V0h16v2zm0 2v13a1 1 0 0 0 1 1 1 1 0 0 0 1-1V4h-2zM2 2v15a1 1 0 0 0 1 1h11.17a2.98 2.98 0 0 1-.17-1V2H2zm2 8h8v2H4v-2zm0 4h8v2H4v-2zM4 4h8v4H4V4z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-notifications">
<path d="M4 8a6 6 0 0 1 4.03-5.67 2 2 0 1 1 3.95 0A6 6 0 0 1 16 8v6l3 2v1H1v-1l3-2V8zm8 10a2 2 0 1 1-4 0h4z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-notifications-outline">
<path d="M6 8v7h8V8a4 4 0 1 0-8 0zm2.03-5.67a2 2 0 1 1 3.95 0A6 6 0 0 1 16 8v6l3 2v1H1v-1l3-2V8a6 6 0 0 1 4.03-5.67zM12 18a2 2 0 1 1-4 0h4z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-paste">
<path d="M10.5 20H2a2 2 0 0 1-2-2V6c0-1.1.9-2 2-2h1V3l2.03-.4a3 3 0 0 1 5.94 0L13 3v1h1a2 2 0 0 1 2 2v1h-2V6h-1v1H3V6H2v12h5v2h3.5zM8 4a1 1 0 1 0 0-2 1 1 0 0 0 0 2zm2 4h8a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2h-8a2 2 0 0 1-2-2v-8c0-1.1.9-2 2-2zm0 2v8h8v-8h-8z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-pause">
<path d="M5 4h3v12H5V4zm7 0h3v12h-3V4z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-pause-outline">
<path d="M2.93 17.07A10 10 0 1 1 17.07 2.93 10 10 0 0 1 2.93 17.07zm12.73-1.41A8 8 0 1 0 4.34 4.34a8 8 0 0 0 11.32 11.32zM7 6h2v8H7V6zm4 0h2v8h-2V6z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-pause-solid">
<path d="M2.93 17.07A10 10 0 1 1 17.07 2.93 10 10 0 0 1 2.93 17.07zM7 6v8h2V6H7zm4 0v8h2V6h-2z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-pen-tool">
<path d="M11 9.27V0l6 11-4 6H7l-4-6L9 0v9.27a2 2 0 1 0 2 0zM6 18h8v2H6v-2z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-phone">
<path d="M20 18.35V19a1 1 0 0 1-1 1h-2A17 17 0 0 1 0 3V1a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v4c0 .56-.31 1.31-.7 1.7L3.16 8.84c1.52 3.6 4.4 6.48 8 8l2.12-2.12c.4-.4 1.15-.71 1.7-.71H19a1 1 0 0 1 .99 1v3.35z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-photo">
<path d="M0 4c0-1.1.9-2 2-2h16a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V4zm11 9l-3-3-6 6h16l-5-5-2 2zm4-4a2 2 0 1 0 0-4 2 2 0 0 0 0 4z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-php-elephant">
<path fill-rule="evenodd"
d="M10 12v8A10 10 0 0 1 8.17.17L10 2h5a5 5 0 0 1 5 4.99v9.02A4 4 0 0 1 16 20v-2a2 2 0 1 0 0-4h-4l-2-2zm5.5-3a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-pin">
<path d="M11 12h6v-1l-3-1V2l3-1V0H3v1l3 1v8l-3 1v1h6v7l1 1 1-1v-7z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-play">
<path d="M4 4l12 6-12 6z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-play-outline">
<path d="M2.93 17.07A10 10 0 1 1 17.07 2.93 10 10 0 0 1 2.93 17.07zm12.73-1.41A8 8 0 1 0 4.34 4.34a8 8 0 0 0 11.32 11.32zM7 6l8 4-8 4V6z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-plugin">
<path d="M20 14v4a2 2 0 0 1-2 2h-4v-2a2 2 0 0 0-2-2 2 2 0 0 0-2 2v2H6a2 2 0 0 1-2-2v-4H2a2 2 0 0 1-2-2 2 2 0 0 1 2-2h2V6c0-1.1.9-2 2-2h4V2a2 2 0 0 1 2-2 2 2 0 0 1 2 2v2h4a2 2 0 0 1 2 2v4h-2a2 2 0 0 0-2 2 2 2 0 0 0 2 2h2z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-portfolio">
<path d="M9 12H1v6a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-6h-8v2H9v-2zm0-1H0V5c0-1.1.9-2 2-2h4V2a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v1h4a2 2 0 0 1 2 2v6h-9V9H9v2zm3-8V2H8v1h4z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-printer">
<path d="M4 16H0V6h20v10h-4v4H4v-4zm2-4v6h8v-6H6zM4 0h12v5H4V0zM2 8v2h2V8H2zm4 0v2h2V8H6z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-pylon">
<path d="M17.4 18H20v2H0v-2h2.6L8 0h4l5.4 18zm-3.2-4H5.8l-1.2 4h10.8l-1.2-4zm-2.4-8H8.2L7 10h6l-1.2-4z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-question">
<path d="M10 20a10 10 0 1 1 0-20 10 10 0 0 1 0 20zm2-13c0 .28-.21.8-.42 1L10 9.58c-.57.58-1 1.6-1 2.42v1h2v-1c0-.29.21-.8.42-1L13 9.42c.57-.58 1-1.6 1-2.42a4 4 0 1 0-8 0h2a2 2 0 1 1 4 0zm-3 8v2h2v-2H9z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-queue">
<path d="M0 2h20v4H0V2zm0 8h20v2H0v-2zm0 6h20v2H0v-2z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-radar">
<path d="M12 10a2 2 0 0 1-3.41 1.41A2 2 0 0 1 10 8V0a9.97 9.97 0 0 1 10 10h-8zm7.9 1.41A10 10 0 1 1 8.59.1v2.03a8 8 0 1 0 9.29 9.29h2.02zm-4.07 0a6 6 0 1 1-7.25-7.25v2.1a3.99 3.99 0 0 0-1.4 6.57 4 4 0 0 0 6.56-1.42h2.1z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-radio">
<path d="M20 9v9a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V8c0-1.1.9-2 2-2h13.8L.74 1.97 1.26.03 20 5.06V9zm-5 9a3 3 0 1 0 0-6 3 3 0 0 0 0 6zM2 8v2h16V8H2zm1.5 10a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3zm5 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3zm6.5-1a2 2 0 1 1 0-4 2 2 0 0 1 0 4z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-refresh">
<path d="M10 3v2a5 5 0 0 0-3.54 8.54l-1.41 1.41A7 7 0 0 1 10 3zm4.95 2.05A7 7 0 0 1 10 17v-2a5 5 0 0 0 3.54-8.54l1.41-1.41zM10 20l-4-4 4-4v8zm0-12V0l4 4-4 4z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-reload">
<path d="M14.66 15.66A8 8 0 1 1 17 10h-2a6 6 0 1 0-1.76 4.24l1.42 1.42zM12 10h8l-4 4-4-4z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-reply">
<path d="M15 17v-2.99A4 4 0 0 0 11 10H8v5L2 9l6-6v5h3a6 6 0 0 1 6 6v3h-2z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-reply-all">
<path d="M18 17v-2.99A4 4 0 0 0 14 10h-3v5L5 9l6-6v5h3a6 6 0 0 1 6 6v3h-2zM6 6V3L0 9l6 6v-3L3 9l3-3z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-repost">
<path d="M5 4a2 2 0 0 0-2 2v6H0l4 4 4-4H5V6h7l2-2H5zm10 4h-3l4-4 4 4h-3v6a2 2 0 0 1-2 2H6l2-2h7V8z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-save-disk">
<path d="M0 2C0 .9.9 0 2 0h14l4 4v14a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V2zm5 0v6h10V2H5zm6 1h3v4h-3V3z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-screen-full">
<path d="M2.8 15.8L0 13v7h7l-2.8-2.8 4.34-4.32-1.42-1.42L2.8 15.8zM17.2 4.2L20 7V0h-7l2.8 2.8-4.34 4.32 1.42 1.42L17.2 4.2zm-1.4 13L13 20h7v-7l-2.8 2.8-4.32-4.34-1.42 1.42 4.33 4.33zM4.2 2.8L7 0H0v7l2.8-2.8 4.32 4.34 1.42-1.42L4.2 2.8z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-search">
<path d="M12.9 14.32a8 8 0 1 1 1.41-1.41l5.35 5.33-1.42 1.42-5.33-5.34zM8 14A6 6 0 1 0 8 2a6 6 0 0 0 0 12z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-send">
<path d="M0 0l20 10L0 20V0zm0 8v4l10-2L0 8z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-servers">
<path d="M0 2C0 .9.9 0 2 0h16a2 2 0 0 1 2 2v2a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V2zm0 7c0-1.1.9-2 2-2h16a2 2 0 0 1 2 2v2a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V9zm0 7c0-1.1.9-2 2-2h16a2 2 0 0 1 2 2v2a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2v-2zM12 2v2h2V2h-2zm4 0v2h2V2h-2zm-4 7v2h2V9h-2zm4 0v2h2V9h-2zm-4 7v2h2v-2h-2zm4 0v2h2v-2h-2z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-share">
<path d="M4 10c0-1.1.9-2 2-2h8c1.1 0 2 .9 2 2v8c0 1.1-.9 2-2 2H6c-1.1 0-2-.9-2-2v-8zm2 0v8h8v-8h-2V8H8v2H6zm3-6.17V16h2V3.83l3.07 3.07 1.42-1.41L10 0l-.7.7-4.8 4.8 1.42 1.4L9 3.84z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-share-alt">
<path d="M5.08 12.16A2.99 2.99 0 0 1 0 10a3 3 0 0 1 5.08-2.16l8.94-4.47a3 3 0 1 1 .9 1.79L5.98 9.63a3.03 3.03 0 0 1 0 .74l8.94 4.47A2.99 2.99 0 0 1 20 17a3 3 0 1 1-5.98-.37l-8.94-4.47z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-shield">
<path d="M19 11a7.5 7.5 0 0 1-3.5 5.94L10 20l-5.5-3.06A7.5 7.5 0 0 1 1 11V3c3.38 0 6.5-1.12 9-3 2.5 1.89 5.62 3 9 3v8zm-9 1.08l2.92 2.04-1.03-3.41 2.84-2.15-3.56-.08L10 5.12 8.83 8.48l-3.56.08L8.1 10.7l-1.03 3.4L10 12.09z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-shopping-cart">
<path d="M4 2h16l-3 9H4a1 1 0 1 0 0 2h13v2H4a3 3 0 0 1 0-6h.33L3 5 2 2H0V0h3a1 1 0 0 1 1 1v1zm1 18a2 2 0 1 1 0-4 2 2 0 0 1 0 4zm10 0a2 2 0 1 1 0-4 2 2 0 0 1 0 4z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-show-sidebar">
<path d="M7 3H2v14h5V3zm2 0v14h9V3H9zM0 3c0-1.1.9-2 2-2h16a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V3zm3 1h3v2H3V4zm0 3h3v2H3V7zm0 3h3v2H3v-2z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-shuffle">
<path d="M6.59 12.83L4.4 15c-.58.58-1.59 1-2.4 1H0v-2h2c.29 0 .8-.2 1-.41l2.17-2.18 1.42 1.42zM16 4V1l4 4-4 4V6h-2c-.29 0-.8.2-1 .41l-2.17 2.18L9.4 7.17 11.6 5c.58-.58 1.59-1 2.41-1h2zm0 10v-3l4 4-4 4v-3h-2c-.82 0-1.83-.42-2.41-1l-8.6-8.59C2.8 6.21 2.3 6 2 6H0V4h2c.82 0 1.83.42 2.41 1l8.6 8.59c.2.2.7.41.99.41h2z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-star-full">
<path d="M10 15l-5.878 3.09 1.123-6.545L.489 6.91l6.572-.955L10 0l2.939 5.955 6.572.955-4.756 4.635 1.123 6.545z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-station">
<path d="M9 11.73a2 2 0 1 1 2 0V20H9v-8.27zm5.24 2.51l-1.41-1.41A3.99 3.99 0 0 0 10 6a4 4 0 0 0-2.83 6.83l-1.41 1.41a6 6 0 1 1 8.49 0zm2.83 2.83l-1.41-1.41a8 8 0 1 0-11.31 0l-1.42 1.41a10 10 0 1 1 14.14 0z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-step-backward">
<path d="M4 5h3v10H4V5zm12 0v10l-9-5 9-5z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-step-forward">
<path d="M13 5h3v10h-3V5zM4 5l9 5-9 5V5z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-stethoscope">
<path d="M17 10.27V4.99a1 1 0 0 0-2 0V15a5 5 0 0 1-10 0v-1.08A6 6 0 0 1 0 8V2C0 .9.9 0 2 0h1a1 1 0 0 1 1 1 1 1 0 0 1-1 1H2v6a4 4 0 1 0 8 0V2H9a1 1 0 0 1-1-1 1 1 0 0 1 1-1h1a2 2 0 0 1 2 2v6a6 6 0 0 1-5 5.92V15a3 3 0 0 0 6 0V5a3 3 0 0 1 6 0v5.27a2 2 0 1 1-2 0z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-store-front">
<path d="M18 9.87V20H2V9.87a4.25 4.25 0 0 0 3-.38V14h10V9.5a4.26 4.26 0 0 0 3 .37zM3 0h4l-.67 6.03A3.43 3.43 0 0 1 3 9C1.34 9 .42 7.73.95 6.15L3 0zm5 0h4l.7 6.3c.17 1.5-.91 2.7-2.42 2.7h-.56A2.38 2.38 0 0 1 7.3 6.3L8 0zm5 0h4l2.05 6.15C19.58 7.73 18.65 9 17 9a3.42 3.42 0 0 1-3.33-2.97L13 0z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-stroke-width">
<path d="M0 0h20v5H0V0zm0 7h20v4H0V7zm0 6h20v3H0v-3zm0 5h20v2H0v-2z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-subdirectory-left">
<path d="M18 12v1H8v5l-6-6 6-6v5h8V2h2z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-subdirectory-right">
<path d="M3.5 13H12v5l6-6-6-6v5H4V2H2v11z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-swap">
<path d="M9 6a4 4 0 1 1 8 0v8h3l-4 4-4-4h3V6a2 2 0 0 0-2-2 2 2 0 0 0-2 2v8a4 4 0 1 1-8 0V6H0l4-4 4 4H5v8a2 2 0 0 0 2 2 2 2 0 0 0 2-2V6z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-tablet">
<path d="M2 2c0-1.1.9-2 2-2h12a2 2 0 0 1 2 2v16a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V2zm2 0v14h12V2H4zm6 17a1 1 0 1 0 0-2 1 1 0 0 0 0 2z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-tag">
<path d="M0 10V2l2-2h8l10 10-10 10L0 10zm4.5-4a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-target">
<path d="M17.94 11H13V9h4.94A8 8 0 0 0 11 2.06V7H9V2.06A8 8 0 0 0 2.06 9H7v2H2.06A8 8 0 0 0 9 17.94V13h2v4.94A8 8 0 0 0 17.94 11zM10 20a10 10 0 1 1 0-20 10 10 0 0 1 0 20z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-text-box">
<path d="M0 0h6v6H0V0zm2 2v2h2V2H2zm12-2h6v6h-6V0zm2 2v2h2V2h-2zm-2 12h6v6h-6v-6zm2 2v2h2v-2h-2zM0 14h6v6H0v-6zm2 2v2h2v-2H2zM6 2h8v2H6V2zm0 14h8v2H6v-2zM16 6h2v8h-2V6zM2 6h2v8H2V6zm5 1h6v2H7V7zm2 2h2v4H9V9z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-text-decoration">
<path d="M12 5h-2v12H8V3h8v2h-2v12h-2V5zM8 3a4 4 0 1 0 0 8V3z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-thermometer">
<path d="M9 11.17V7h2v4.17a3 3 0 1 1-2 0zm-1-.63a4 4 0 1 0 4 0V4a2 2 0 1 0-4 0v6.53zM6 9.53V4a4 4 0 0 1 8 0v5.53A5.99 5.99 0 0 1 10 20 6 6 0 0 1 6 9.53z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-thumbs-down">
<path d="M11 20a2 2 0 0 1-2-2v-6H2a2 2 0 0 1-2-2V8l2.3-6.12A3.11 3.11 0 0 1 5 0h8a2 2 0 0 1 2 2v8l-3 7v3h-1zm6-10V0h3v10h-3z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-thumbs-up">
<path d="M11 0h1v3l3 7v8a2 2 0 0 1-2 2H5c-1.1 0-2.31-.84-2.7-1.88L0 12v-2a2 2 0 0 1 2-2h7V2a2 2 0 0 1 2-2zm6 10h3v10h-3V10z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-ticket">
<path d="M20 12v5H0v-5a2 2 0 1 0 0-4V3h20v5a2 2 0 1 0 0 4zM3 5v10h14V5H3zm7 7.08l-2.92 2.04L8.1 10.7 5.27 8.56l3.56-.08L10 5.12l1.17 3.36 3.56.08-2.84 2.15 1.03 3.4L10 12.09z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-time">
<path d="M10 20a10 10 0 1 1 0-20 10 10 0 0 1 0 20zm0-2a8 8 0 1 0 0-16 8 8 0 0 0 0 16zm-1-7.59V4h2v5.59l3.95 3.95-1.41 1.41L9 10.41z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-timer">
<path d="M16.32 7.1A8 8 0 1 1 9 4.06V2h2v2.06c1.46.18 2.8.76 3.9 1.62l1.46-1.46 1.42 1.42-1.46 1.45zM10 18a6 6 0 1 0 0-12 6 6 0 0 0 0 12zM7 0h6v2H7V0zm5.12 8.46l1.42 1.42L10 13.4 8.59 12l3.53-3.54z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-translate">
<path d="M7.41 9l2.24 2.24-.83 2L6 10.4l-3.3 3.3-1.4-1.42L4.58 9l-.88-.88c-.53-.53-1-1.3-1.3-2.12h2.2c.15.28.33.53.51.7l.89.9.88-.88C7.48 6.1 8 4.84 8 4H0V2h5V0h2v2h5v2h-2c0 1.37-.74 3.15-1.7 4.12L7.4 9zm3.84 8L10 20H8l5-12h2l5 12h-2l-1.25-3h-5.5zm.83-2h3.84L14 10.4 12.08 15z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-trash">
<path d="M6 2l2-2h4l2 2h4v2H2V2h4zM3 6h14l-1 14H4L3 6zm5 2v10h1V8H8zm3 0v10h1V8h-1z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-travel-bus">
<path d="M13 18H7v1a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1v-1a2 2 0 0 1-2-2V2c0-1.1.9-2 2-2h12a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2v1a1 1 0 0 1-1 1h-1a1 1 0 0 1-1-1v-1zM4 5v6h5V5H4zm7 0v6h5V5h-5zM5 2v1h10V2H5zm.5 14a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3zm9 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-travel-car">
<path d="M2 14v-3H1a1 1 0 0 1-1-1 1 1 0 0 1 1-1h1l4-7h8l4 7h1a1 1 0 0 1 1 1 1 1 0 0 1-1 1h-1v6a1 1 0 0 1-1 1h-1a1 1 0 0 1-1-1v-1H5v1a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1v-3zm13.86-5L13 4H7L4.14 9h11.72zM5.5 14a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3zm9 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-travel-case">
<path d="M14 5h2v14H4V5h2V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v1zm3 0h1a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2h-1V5zM3 5v14H2a2 2 0 0 1-2-2V7c0-1.1.9-2 2-2h1zm5-1v1h4V4H8z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-travel-taxi-cab">
<path d="M12 3h2l4 7h1a1 1 0 0 1 1 1 1 1 0 0 1-1 1h-1v6a1 1 0 0 1-1 1h-1a1 1 0 0 1-1-1v-1H5v1a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1v-6H1a1 1 0 0 1-1-1 1 1 0 0 1 1-1h1l4-7h2V1h4v2zm3.86 7L13 5H7l-2.86 5h11.72zM5.5 15a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3zm9 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-travel-train">
<path d="M12 18H8l-2 2H3l2-2a2 2 0 0 1-2-2V2c0-1.1.9-2 2-2h10a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2l2 2h-3l-2-2zM5 5v6h10V5H5zm1.5 11a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3zm7 0a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3zM8 2v1h4V2H8z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-travel-walk">
<path d="M11 7l1.44 2.16c.31.47 1.01.84 1.57.84H17V8h-3l-1.44-2.16a5.94 5.94 0 0 0-1.4-1.4l-1.32-.88a1.72 1.72 0 0 0-1.7-.04L4 6v5h2V7l2-1-3 14h2l2.35-7.65L11 14v6h2v-8l-2.7-2.7L11 7zm1-3a2 2 0 1 0 0-4 2 2 0 0 0 0 4z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-trophy">
<path d="M15 9a3 3 0 0 0 3-3h2a5 5 0 0 1-5.1 5 5 5 0 0 1-3.9 3.9V17l5 2v1H4v-1l5-2v-2.1A5 5 0 0 1 5.1 11H5a5 5 0 0 1-5-5h2a3 3 0 0 0 3 3V4H2v2H0V2h5V0h10v2h5v4h-2V4h-3v5z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-tuning">
<path d="M17 16v4h-2v-4h-2v-3h6v3h-2zM1 9h6v3H1V9zm6-4h6v3H7V5zM3 0h2v8H3V0zm12 0h2v12h-2V0zM9 0h2v4H9V0zM3 12h2v8H3v-8zm6-4h2v12H9V8z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-upload">
<path d="M13 10v6H7v-6H2l8-8 8 8h-5zM0 18h20v2H0v-2z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-usb">
<path d="M15 8v2h-4V4h2l-3-4-3 4h2v8H5V9.73a2 2 0 1 0-2 0V12a2 2 0 0 0 2 2h4v2.27a2 2 0 1 0 2 0V12h4a2 2 0 0 0 2-2V8h1V4h-4v4h1z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-user">
<path d="M5 5a5 5 0 0 1 10 0v2A5 5 0 0 1 5 7V5zM0 16.68A19.9 19.9 0 0 1 10 14c3.64 0 7.06.97 10 2.68V20H0v-3.32z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-user-add">
<path d="M2 6H0v2h2v2h2V8h2V6H4V4H2v2zm7 0a3 3 0 0 1 6 0v2a3 3 0 0 1-6 0V6zm11 9.14A15.93 15.93 0 0 0 12 13c-2.91 0-5.65.78-8 2.14V18h16v-2.86z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-user-group">
<path d="M7 8a4 4 0 1 1 0-8 4 4 0 0 1 0 8zm0 1c2.15 0 4.2.4 6.1 1.09L12 16h-1.25L10 20H4l-.75-4H2L.9 10.09A17.93 17.93 0 0 1 7 9zm8.31.17c1.32.18 2.59.48 3.8.92L18 16h-1.25L16 20h-3.96l.37-2h1.25l1.65-8.83zM13 0a4 4 0 1 1-1.33 7.76 5.96 5.96 0 0 0 0-7.52C12.1.1 12.53 0 13 0z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-user-solid-circle">
<path d="M10 20a10 10 0 1 1 0-20 10 10 0 0 1 0 20zM7 6v2a3 3 0 1 0 6 0V6a3 3 0 1 0-6 0zm-3.65 8.44a8 8 0 0 0 13.3 0 15.94 15.94 0 0 0-13.3 0z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-user-solid-square">
<path d="M0 2C0 .9.9 0 2 0h16a2 2 0 0 1 2 2v16a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V2zm7 4v2a3 3 0 1 0 6 0V6a3 3 0 1 0-6 0zm11 9.14A15.93 15.93 0 0 0 10 13c-2.91 0-5.65.78-8 2.14V18h16v-2.86z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-vector">
<path d="M12 4h4.27a2 2 0 1 1 0 2h-2.14a9 9 0 0 1 4.84 7.25 2 2 0 1 1-2 .04 7 7 0 0 0-4.97-6V8H8v-.71a7 7 0 0 0-4.96 6 2 2 0 1 1-2-.04A9 9 0 0 1 5.86 6H3.73a2 2 0 1 1 0-2H8V3h4v1z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-video-camera">
<path d="M16 7l4-4v14l-4-4v3a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V4c0-1.1.9-2 2-2h12a2 2 0 0 1 2 2v3zm-8 7a4 4 0 1 0 0-8 4 4 0 0 0 0 8zm0-2a2 2 0 1 1 0-4 2 2 0 0 1 0 4z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-view-carousel">
<path d="M16 16v2H4v-2H0V4h4V2h12v2h4v12h-4zM14 5.5V4H6v12h8V5.5zm2 .5v8h2V6h-2zM4 6H2v8h2V6z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-view-column">
<path d="M12 4H8v12h4V4zm2 0v12h4V4h-4zM6 4H2v12h4V4zM0 2h20v16H0V2z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-view-hide">
<path d="M12.81 4.36l-1.77 1.78a4 4 0 0 0-4.9 4.9l-2.76 2.75C2.06 12.79.96 11.49.2 10a11 11 0 0 1 12.6-5.64zm3.8 1.85c1.33 1 2.43 2.3 3.2 3.79a11 11 0 0 1-12.62 5.64l1.77-1.78a4 4 0 0 0 4.9-4.9l2.76-2.75zm-.25-3.99l1.42 1.42L3.64 17.78l-1.42-1.42L16.36 2.22z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-view-list">
<path d="M0 3h20v2H0V3zm0 4h20v2H0V7zm0 4h20v2H0v-2zm0 4h20v2H0v-2z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-view-show">
<path d="M.2 10a11 11 0 0 1 19.6 0A11 11 0 0 1 .2 10zm9.8 4a4 4 0 1 0 0-8 4 4 0 0 0 0 8zm0-2a2 2 0 1 1 0-4 2 2 0 0 1 0 4z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-view-tile">
<path d="M0 0h9v9H0V0zm2 2v5h5V2H2zm-2 9h9v9H0v-9zm2 2v5h5v-5H2zm9-13h9v9h-9V0zm2 2v5h5V2h-5zm-2 9h9v9h-9v-9zm2 2v5h5v-5h-5z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-volume-down">
<path d="M7 7H3v6h4l5 5V2L7 7zm8.54 6.54l-1.42-1.42a3 3 0 0 0 0-4.24l1.42-1.42a4.98 4.98 0 0 1 0 7.08z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-volume-mute">
<path d="M9 7H5v6h4l5 5V2L9 7z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-volume-off">
<path d="M15 8.59l-2.12-2.13-1.42 1.42L13.6 10l-2.13 2.12 1.42 1.42L15 11.4l2.12 2.13 1.42-1.42L16.4 10l2.13-2.12-1.42-1.42L15 8.6zM4 7H0v6h4l5 5V2L4 7z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-volume-up">
<path d="M5 7H1v6h4l5 5V2L5 7zm11.36 9.36l-1.41-1.41a6.98 6.98 0 0 0 0-9.9l1.41-1.41a8.97 8.97 0 0 1 0 12.72zm-2.82-2.82l-1.42-1.42a3 3 0 0 0 0-4.24l1.42-1.42a4.98 4.98 0 0 1 0 7.08z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-wallet">
<path d="M0 4c0-1.1.9-2 2-2h15a1 1 0 0 1 1 1v1H2v1h17a1 1 0 0 1 1 1v10a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V4zm16.5 9a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-watch">
<path d="M11 9h2v2H9V7h2v2zm-5.82 6.08a6.98 6.98 0 0 1 0-10.16L6 0h8l.82 4.92a6.98 6.98 0 0 1 0 10.16L14 20H6l-.82-4.92zM10 15a5 5 0 1 0 0-10 5 5 0 0 0 0 10z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-wrench">
<path d="M6.47 9.8A5 5 0 0 1 .2 3.22l3.95 3.95 2.82-2.83L3.03.41a5 5 0 0 1 6.4 6.68l10 10-2.83 2.83L6.47 9.8z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-zoom-in">
<path fill-rule="evenodd"
d="M12.9 14.32a8 8 0 1 1 1.41-1.41l5.35 5.33-1.42 1.42-5.33-5.34zM8 14A6 6 0 1 0 8 2a6 6 0 0 0 0 12zM7 7V5h2v2h2v2H9v2H7V9H5V7h2z"/>
</symbol>
<symbol viewBox="0 0 20 20" id="zondicon-zoom-out">
<path fill-rule="evenodd"
d="M12.9 14.32a8 8 0 1 1 1.41-1.41l5.35 5.33-1.42 1.42-5.33-5.34zM8 14A6 6 0 1 0 8 2a6 6 0 0 0 0 12zM5 7h6v2H5V7z"/>
</symbol>
</svg>

After

Width:  |  Height:  |  Size: 60 KiB

2
public/vendor/horizon/js/app.js vendored Normal file

File diff suppressed because one or more lines are too long

1
public/vendor/horizon/js/app.js.map vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,5 @@
{
"/app.js": "/app.js?id=fb7fa0b0532e2ebb68df",
"/app.css": "/app.css?id=cefed9132a927b70fdd6",
"/app-dark.css": "/app-dark.css?id=596688837e7ffbb58e37"
}

23
public/web.config Normal file
View File

@ -0,0 +1,23 @@
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="Imported Rule 1" stopProcessing="true">
<match url="^(.*)/$" ignoreCase="false" />
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" ignoreCase="false" negate="true" />
</conditions>
<action type="Redirect" redirectType="Permanent" url="/{R:1}" />
</rule>
<rule name="Imported Rule 2" stopProcessing="true">
<match url="^" ignoreCase="false" />
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" ignoreCase="false" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsFile" ignoreCase="false" negate="true" />
</conditions>
<action type="Rewrite" url="index.php" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>

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