Shop improvements, renamed "shop" to "mall", support for Argon2ID
|
@ -2,7 +2,6 @@
|
|||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Hashing\MySQLHasher;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Account;
|
||||
use App\Models\Enums\AccountStatusEnum;
|
||||
|
@ -10,6 +9,7 @@ use Illuminate\Auth\Events\Registered;
|
|||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use Illuminate\View\View;
|
||||
|
@ -43,7 +43,7 @@ class RegisterController extends Controller
|
|||
$account = new Account();
|
||||
$account->login = $data['login'];
|
||||
$account->email = $data['email'];
|
||||
$account->password = (new MySQLHasher)->make($data['password']);
|
||||
$account->password = Hash::make($data['password']);
|
||||
$account->status = AccountStatusEnum::NOT_AVAILABLE;
|
||||
$account->saveOrFail();
|
||||
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Shop;
|
||||
namespace App\Http\Controllers\Mall;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Shop\ShopCategory;
|
||||
use App\Models\Mall\MallCategory;
|
||||
use Illuminate\View\View;
|
||||
|
||||
class CategoryController extends Controller
|
||||
{
|
||||
public function show(int $id): View
|
||||
{
|
||||
$category = ShopCategory::find($id);
|
||||
$category = MallCategory::find($id);
|
||||
|
||||
return view('shop/category', [
|
||||
return view('mall/category', [
|
||||
'category' => $category
|
||||
]);
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Mall;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Mall\MallItem;
|
||||
use Illuminate\View\View;
|
||||
|
||||
class HomeController extends Controller
|
||||
{
|
||||
public function home(): View
|
||||
{
|
||||
$largeSuggestions = MallItem::getSuggestions(2, frontpageDisplay: 'recommend_desc');
|
||||
$smallSuggestions = MallItem::getSuggestions(8 - (2 * $largeSuggestions->count()), frontpageDisplay: 'recommend');
|
||||
|
||||
return view('mall/home', [
|
||||
'suggestions' => $largeSuggestions->merge($smallSuggestions),
|
||||
]);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Mall;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Mall\MallItem;
|
||||
use App\Utils\ImageHelpers;
|
||||
use Illuminate\View\View;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
|
||||
class ItemController extends Controller
|
||||
{
|
||||
public function show(int $id): View
|
||||
{
|
||||
$item = MallItem::find($id);
|
||||
$suggestions = MallItem::getSuggestions(7, $item);
|
||||
|
||||
return view('mall/item/show', [
|
||||
'item' => $item,
|
||||
'suggestions' => $suggestions,
|
||||
]);
|
||||
}
|
||||
|
||||
public function generateImage(int $id, bool $isLarge = false, float $maxIconRatio = 0.8): Response
|
||||
{
|
||||
$item = MallItem::find($id);
|
||||
|
||||
// Return an error image if the item or its image is not found
|
||||
if (!$item || !$item->image) {
|
||||
return response()->file(public_path('assets/mall/img/error.png'));
|
||||
}
|
||||
|
||||
// Return an error if the item image is not available on the server
|
||||
if (!file_exists(public_path("assets/mall/img/item/icon/{$item->image}.png"))) {
|
||||
return response()->file(public_path('assets/mall/img/error.png'));
|
||||
}
|
||||
|
||||
// Load the proper background
|
||||
if (!$isLarge)
|
||||
$imageData = imagecreatefrompng(public_path('assets/mall/img/item/background.png'));
|
||||
else
|
||||
$imageData = imagecreatefrompng(public_path('assets/mall/img/item/background-lg.png'));
|
||||
|
||||
|
||||
// Get the max width or height we can work with
|
||||
$maxSquareSize = (int) (min(imagesx($imageData), imagesy($imageData)) * $maxIconRatio);
|
||||
|
||||
// Load the item icon
|
||||
$itemIcon = imagecreatefrompng(public_path("assets/mall/img/item/icon/{$item->image}.png"));
|
||||
|
||||
// Get the max dimension of the icon
|
||||
$maxIconDimension = max(imagesx($itemIcon), imagesy($itemIcon));
|
||||
|
||||
// Resize the icon
|
||||
$scalingFactor = (float) $maxSquareSize / $maxIconDimension;
|
||||
|
||||
// Select the best resizing algorithm based on whether we have to enlarge or reduce the icon size
|
||||
$mode = IMG_BILINEAR_FIXED;
|
||||
if ($scalingFactor < 1)
|
||||
$mode = IMG_BICUBIC_FIXED;
|
||||
|
||||
$itemIcon = imagescale($itemIcon, imagesx($itemIcon) * $scalingFactor, mode: $mode);
|
||||
|
||||
$destX = (imagesx($imageData) - imagesx($itemIcon)) / 2;
|
||||
$destY = (imagesy($imageData) - imagesy($itemIcon)) / 2;
|
||||
|
||||
// Apply the icon onto the background
|
||||
ImageHelpers::imagecopymerge_alpha($imageData, $itemIcon, $destX, $destY, 0, 0, imagesx($itemIcon), imagesy($itemIcon), 100);
|
||||
|
||||
return response()->streamDownload(
|
||||
function () use ($imageData) {
|
||||
echo imagejpeg($imageData);
|
||||
},
|
||||
headers: [
|
||||
'Content-Type' => 'image/jpeg',
|
||||
'Cache-Control' => 'max-age=3600',
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
public function generateLargeImage(int $id): Response
|
||||
{
|
||||
return $this->generateImage($id, true, 0.7);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Shop;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Shop\ShopCategory;
|
||||
use App\Models\Shop\ShopItem;
|
||||
use Illuminate\View\View;
|
||||
|
||||
class ItemController extends Controller
|
||||
{
|
||||
public function show(int $id): View
|
||||
{
|
||||
$item = ShopItem::find($id);
|
||||
|
||||
return view('shop/item/show', [
|
||||
'item' => $item
|
||||
]);
|
||||
}
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace App\Models\Enums;
|
||||
|
||||
enum ShopItemPricingEnum: string
|
||||
enum MallItemPricingEnum: string
|
||||
{
|
||||
case CASH = 'CASH';
|
||||
case MILEAGE = 'MILEAGE';
|
||||
|
@ -10,8 +10,8 @@ enum ShopItemPricingEnum: string
|
|||
public function description(): string
|
||||
{
|
||||
return match($this) {
|
||||
self::CASH => __('shop/main.currency.cash'),
|
||||
self::MILEAGE => __('shop/main.currency.mileage')
|
||||
self::CASH => __('mall/main.currency.cash'),
|
||||
self::MILEAGE => __('mall/main.currency.mileage')
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models\Game;
|
||||
|
||||
use App\Models\Mall\MallItem;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
|
||||
class ItemProto extends Model
|
||||
{
|
||||
/**
|
||||
* The connection name for the model.
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
protected $connection = 'player';
|
||||
|
||||
/**
|
||||
* The table associated with the model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $table = 'item_proto';
|
||||
|
||||
/**
|
||||
* The primary key for the model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $primaryKey = 'vnum';
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $fillable = [
|
||||
'name',
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be hidden for serialization.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $hidden = [
|
||||
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be cast.
|
||||
*
|
||||
* @var array<string, string>
|
||||
*/
|
||||
protected $casts = [
|
||||
|
||||
];
|
||||
}
|
|
@ -1,11 +1,11 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models\Shop;
|
||||
namespace App\Models\Mall;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
|
||||
class ShopCategory extends Model
|
||||
class MallCategory extends Model
|
||||
{
|
||||
/**
|
||||
* The connection name for the model.
|
||||
|
@ -48,6 +48,6 @@ class ShopCategory extends Model
|
|||
*/
|
||||
public function items(): HasMany
|
||||
{
|
||||
return $this->hasMany(ShopItem::class, 'category_id', 'id');
|
||||
return $this->hasMany(MallItem::class, 'category_id', 'id');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,100 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models\Mall;
|
||||
|
||||
use App\Models\Enums\MallItemPricingEnum;
|
||||
use App\Models\Game\ItemProto;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\HasOne;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class MallItem extends Model
|
||||
{
|
||||
/**
|
||||
* The connection name for the model.
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
protected $connection = 'website';
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $fillable = [
|
||||
'id',
|
||||
'category_id',
|
||||
'old_price',
|
||||
'price',
|
||||
'pricing',
|
||||
'quantity',
|
||||
'image',
|
||||
'description',
|
||||
'other',
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be hidden for serialization.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $hidden = [
|
||||
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be cast.
|
||||
*
|
||||
* @var array<string, string>
|
||||
*/
|
||||
protected $casts = [
|
||||
'pricing' => MallItemPricingEnum::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* Get the associated item_proto entry
|
||||
*
|
||||
* @return HasOne
|
||||
*/
|
||||
public function proto(): HasOne
|
||||
{
|
||||
return $this->hasOne(ItemProto::class, 'vnum', 'vnum');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function userCanBuy(): bool
|
||||
{
|
||||
$user = Auth::user();
|
||||
|
||||
if ($this->pricing == MallItemPricingEnum::CASH)
|
||||
return $user->cash >= $this->price;
|
||||
elseif ($this->pricing == MallItemPricingEnum::MILEAGE)
|
||||
return $user->mileage >= $this->price;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function getSuggestions(int $maxCount, MallItem $forItem = null, string $frontpageDisplay = null)
|
||||
{
|
||||
$query = MallItem::query();
|
||||
|
||||
// Ignore the current item if specified
|
||||
if ($forItem)
|
||||
$query = $query->whereNotIn('vnum', [$forItem->vnum]);
|
||||
|
||||
// Select items that are to be shown on the frontpage
|
||||
if ($frontpageDisplay)
|
||||
$query = $query->where('other', $frontpageDisplay);
|
||||
|
||||
$items = $query->get();
|
||||
|
||||
// Just return what we selected if we don't have enough items in the database
|
||||
if ($items->count() <= $maxCount)
|
||||
return $items;
|
||||
|
||||
return $items->random($maxCount);
|
||||
}
|
||||
}
|
|
@ -1,67 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models\Shop;
|
||||
|
||||
use App\Models\Enums\ShopItemPricingEnum;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class ShopItem extends Model
|
||||
{
|
||||
/**
|
||||
* The connection name for the model.
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
protected $connection = 'website';
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $fillable = [
|
||||
'id',
|
||||
'category_id',
|
||||
'old_price',
|
||||
'price',
|
||||
'pricing',
|
||||
'quantity',
|
||||
'image',
|
||||
'description',
|
||||
'other',
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be hidden for serialization.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $hidden = [
|
||||
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be cast.
|
||||
*
|
||||
* @var array<string, string>
|
||||
*/
|
||||
protected $casts = [
|
||||
'pricing' => ShopItemPricingEnum::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function userCanBuy(): bool
|
||||
{
|
||||
$user = Auth::user();
|
||||
|
||||
if ($this->pricing == ShopItemPricingEnum::CASH)
|
||||
return $user->cash >= $this->price;
|
||||
elseif ($this->pricing == ShopItemPricingEnum::MILEAGE)
|
||||
return $user->mileage >= $this->price;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
namespace App\Providers;
|
||||
|
||||
// use Illuminate\Support\Facades\Gate;
|
||||
use App\Hashing\MySQLHasher;
|
||||
use Illuminate\Auth\EloquentUserProvider;
|
||||
use Illuminate\Foundation\Application;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace App\Providers;
|
||||
|
||||
use App\View\Composers\ShopComposer;
|
||||
use App\View\Composers\MallComposer;
|
||||
use Illuminate\Support\Facades;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
|
@ -21,6 +21,6 @@ class ViewServiceProvider extends ServiceProvider
|
|||
*/
|
||||
public function boot(): void
|
||||
{
|
||||
Facades\View::composer('layouts.shop', ShopComposer::class);
|
||||
Facades\View::composer('layouts.mall', MallComposer::class);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
|
||||
namespace App\Utils;
|
||||
|
||||
use GdImage;
|
||||
|
||||
class ImageHelpers
|
||||
{
|
||||
public static function imagecopymerge_alpha(GDImage $dst_im, GDImage $src_im, int $dst_x, int $dst_y, int $src_x, int $src_y, int $src_w, int $src_h, int $pct): bool
|
||||
{
|
||||
// creating a cut resource
|
||||
$cut = imagecreatetruecolor($src_w, $src_h);
|
||||
|
||||
// copying relevant section from background to the cut resource
|
||||
imagecopy($cut, $dst_im, 0, 0, $dst_x, $dst_y, $src_w, $src_h);
|
||||
|
||||
// copying relevant section from watermark to the cut resource
|
||||
imagecopy($cut, $src_im, 0, 0, $src_x, $src_y, $src_w, $src_h);
|
||||
|
||||
// insert cut resource to destination image
|
||||
return imagecopymerge($dst_im, $cut, $dst_x, $dst_y, 0, 0, $src_w, $src_h, $pct);
|
||||
}
|
||||
}
|
|
@ -2,10 +2,10 @@
|
|||
|
||||
namespace App\View\Composers;
|
||||
|
||||
use App\Models\Shop\ShopCategory;
|
||||
use App\Models\Mall\MallCategory;
|
||||
use Illuminate\View\View;
|
||||
|
||||
class ShopComposer
|
||||
class MallComposer
|
||||
{
|
||||
/**
|
||||
* Bind data to the view.
|
||||
|
@ -18,7 +18,7 @@ class ShopComposer
|
|||
// Fetch the amount of items in storage
|
||||
$view->with('discountDesc', "20% reducere la chipsuri");
|
||||
|
||||
// Fetch the shop categories
|
||||
$view->with('categories', ShopCategory::all());
|
||||
// Fetch the mall categories
|
||||
$view->with('categories', MallCategory::all());
|
||||
}
|
||||
}
|
|
@ -9,7 +9,8 @@
|
|||
"guzzlehttp/guzzle": "^7.2",
|
||||
"laravel/framework": "^10.10",
|
||||
"laravel/sanctum": "^3.2",
|
||||
"laravel/tinker": "^2.8"
|
||||
"laravel/tinker": "^2.8",
|
||||
"ext-gd": "*"
|
||||
},
|
||||
"require-dev": {
|
||||
"fakerphp/faker": "^1.9.1",
|
||||
|
|
|
@ -61,8 +61,7 @@ return [
|
|||
|
||||
'providers' => [
|
||||
'users' => [
|
||||
// 'driver' => 'eloquent',
|
||||
'driver' => 'legacy',
|
||||
'driver' => 'eloquent', // use "legacy" for MySQL password hashing
|
||||
'model' => App\Models\Account::class,
|
||||
],
|
||||
],
|
||||
|
|
|
@ -15,7 +15,7 @@ return [
|
|||
|
|
||||
*/
|
||||
|
||||
'driver' => 'bcrypt',
|
||||
'driver' => 'argon2id',
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
|
@ -16,7 +16,7 @@ return new class extends Migration
|
|||
Schema::connection('account')->create('account', function (Blueprint $table) {
|
||||
$table->integer('id', true);
|
||||
$table->string('login', 30)->default('')->unique('login');
|
||||
$table->string('password', 45)->default('');
|
||||
$table->text('password')->default('');
|
||||
$table->string('social_id', 13)->default('')->index('social_id');
|
||||
$table->string('email', 64)->default('');
|
||||
$table->dateTime('create_time')->default('0000-00-00 00:00:00');
|
||||
|
|
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 4.5 KiB |
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 3.4 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 8.4 KiB After Width: | Height: | Size: 8.4 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 201 B After Width: | Height: | Size: 201 B |
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 65 KiB After Width: | Height: | Size: 65 KiB |
Before Width: | Height: | Size: 7.5 KiB After Width: | Height: | Size: 7.5 KiB |
Before Width: | Height: | Size: 7.4 KiB After Width: | Height: | Size: 7.4 KiB |
Before Width: | Height: | Size: 7.5 KiB After Width: | Height: | Size: 7.5 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 6.3 KiB After Width: | Height: | Size: 6.3 KiB |
Before Width: | Height: | Size: 6.2 KiB After Width: | Height: | Size: 6.2 KiB |
Before Width: | Height: | Size: 178 KiB After Width: | Height: | Size: 178 KiB |
Before Width: | Height: | Size: 6.9 KiB After Width: | Height: | Size: 6.9 KiB |
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 2.7 KiB |
Before Width: | Height: | Size: 6.2 KiB After Width: | Height: | Size: 6.2 KiB |
Before Width: | Height: | Size: 6.2 KiB After Width: | Height: | Size: 6.2 KiB |
Before Width: | Height: | Size: 8.1 KiB After Width: | Height: | Size: 8.1 KiB |
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.5 KiB |
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.5 KiB |
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 3.4 KiB |
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB |
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 4.5 KiB |
Before Width: | Height: | Size: 6.6 KiB After Width: | Height: | Size: 6.6 KiB |
Before Width: | Height: | Size: 9.9 KiB After Width: | Height: | Size: 9.9 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.8 KiB |
Before Width: | Height: | Size: 270 B After Width: | Height: | Size: 270 B |
Before Width: | Height: | Size: 5.1 KiB After Width: | Height: | Size: 5.1 KiB |
Before Width: | Height: | Size: 43 B After Width: | Height: | Size: 43 B |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 107 B After Width: | Height: | Size: 107 B |
Before Width: | Height: | Size: 106 B After Width: | Height: | Size: 106 B |
Before Width: | Height: | Size: 347 B After Width: | Height: | Size: 347 B |
Before Width: | Height: | Size: 324 B After Width: | Height: | Size: 324 B |
Before Width: | Height: | Size: 111 B After Width: | Height: | Size: 111 B |
Before Width: | Height: | Size: 352 B After Width: | Height: | Size: 352 B |
Before Width: | Height: | Size: 340 B After Width: | Height: | Size: 340 B |
Before Width: | Height: | Size: 103 B After Width: | Height: | Size: 103 B |
Before Width: | Height: | Size: 503 B After Width: | Height: | Size: 503 B |
Before Width: | Height: | Size: 96 B After Width: | Height: | Size: 96 B |
Before Width: | Height: | Size: 70 B After Width: | Height: | Size: 70 B |
Before Width: | Height: | Size: 506 B After Width: | Height: | Size: 506 B |
Before Width: | Height: | Size: 203 B After Width: | Height: | Size: 203 B |
Before Width: | Height: | Size: 176 B After Width: | Height: | Size: 176 B |
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 8.7 KiB After Width: | Height: | Size: 8.7 KiB |
Before Width: | Height: | Size: 6.3 KiB After Width: | Height: | Size: 6.3 KiB |
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 4.4 KiB |
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 4.5 KiB |
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 3.0 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 146 B After Width: | Height: | Size: 146 B |
Before Width: | Height: | Size: 269 B After Width: | Height: | Size: 269 B |
Before Width: | Height: | Size: 128 B After Width: | Height: | Size: 128 B |
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 6.2 KiB After Width: | Height: | Size: 6.2 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |