Add fishing spot timer
|
@ -8,20 +8,24 @@
|
|||
let px = 'px-4';
|
||||
let py = 'py-2';
|
||||
let textColor = 'white';
|
||||
let borderColor = 'white';
|
||||
let borderColorHover = 'white';
|
||||
let borderColorFocus = 'white';
|
||||
|
||||
$: switch (color) {
|
||||
case 'blue':
|
||||
textColor = 'text-white';
|
||||
borderColor = 'border-primary';
|
||||
borderColorHover = 'hover:border-primary';
|
||||
borderColorFocus = 'focus:border-primary';
|
||||
break;
|
||||
case 'red':
|
||||
textColor = 'text-red-400';
|
||||
borderColor = 'border-red-400';
|
||||
borderColorHover = 'hover:border-red-400';
|
||||
borderColorFocus = 'focus:border-red-400';
|
||||
break;
|
||||
case 'green':
|
||||
textColor = 'text-green-400';
|
||||
borderColor = 'border-green-400';
|
||||
borderColorHover = 'hover:border-green-400';
|
||||
borderColorFocus = 'focus:border-green-400';
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -42,7 +46,7 @@
|
|||
class="{textColor} border-2 border-white border-opacity-25 {rounded
|
||||
? 'rounded-xl'
|
||||
: 'rounded-none'} {px} {py} transition duration-100
|
||||
hover:{borderColor} focus:outline-none focus:{borderColor} disabled:opacity-50 disabled:border-gray-600 {className}"
|
||||
{borderColorHover} {borderColorFocus} focus:outline-none disabled:opacity-50 disabled:border-gray-600 {className}"
|
||||
on:click
|
||||
>
|
||||
<slot />
|
||||
|
|
|
@ -196,7 +196,6 @@
|
|||
const data = await getData();
|
||||
remoteSave = data;
|
||||
|
||||
console.log(JSON.stringify(remoteSave));
|
||||
const remoteSize = new Blob([JSON.stringify(remoteSave)]).size / 1000;
|
||||
|
||||
const localSave = await getLocalSaveJson();
|
||||
|
|
|
@ -1,16 +1,15 @@
|
|||
{
|
||||
"cider_lake": {
|
||||
"name": "Cider Lake",
|
||||
"17668": {
|
||||
"name": "Windrise",
|
||||
"fish": [
|
||||
"medaka",
|
||||
"aizen_medaka",
|
||||
"crystalfish",
|
||||
"venomspine_fish",
|
||||
"rusty_koi",
|
||||
"tea-colored_shirakodai"
|
||||
],
|
||||
"location": "mondstadt"
|
||||
},
|
||||
"stormbearer_mountains": {
|
||||
"17669": {
|
||||
"name": "Stormbearer Mountains",
|
||||
"fish": [
|
||||
"medaka",
|
||||
|
@ -23,7 +22,17 @@
|
|||
],
|
||||
"location": "mondstadt"
|
||||
},
|
||||
"stormterrors_lair": {
|
||||
"17670": {
|
||||
"name": "Stormterror's Lair",
|
||||
"fish": [
|
||||
"medaka",
|
||||
"aizen_medaka",
|
||||
"dawncatcher",
|
||||
"tea-colored_shirakodai"
|
||||
],
|
||||
"location": "mondstadt"
|
||||
},
|
||||
"17671": {
|
||||
"name": "Stormterror's Lair",
|
||||
"fish": [
|
||||
"medaka",
|
||||
|
@ -33,17 +42,31 @@
|
|||
],
|
||||
"location": "mondstadt"
|
||||
},
|
||||
"windrise": {
|
||||
"name": "Windrise",
|
||||
"17672": {
|
||||
"name": "Cider Lake",
|
||||
"fish": [
|
||||
"medaka",
|
||||
"aizen_medaka",
|
||||
"venomspine_fish",
|
||||
"akai_maou",
|
||||
"tea-colored_shirakodai",
|
||||
"pufferfish",
|
||||
"bitter_pufferfish"
|
||||
],
|
||||
"location": "mondstadt"
|
||||
},
|
||||
"17673": {
|
||||
"name": "Cider Lake",
|
||||
"fish": [
|
||||
"aizen_medaka",
|
||||
"crystalfish",
|
||||
"venomspine_fish",
|
||||
"rusty_koi",
|
||||
"tea-colored_shirakodai"
|
||||
],
|
||||
"location": "mondstadt"
|
||||
},
|
||||
"near_dawn_winery": {
|
||||
"17674": {
|
||||
"name": "Near Dawn Winery",
|
||||
"fish": [
|
||||
"aizen_medaka",
|
||||
|
@ -56,7 +79,7 @@
|
|||
],
|
||||
"location": "mondstadt"
|
||||
},
|
||||
"dragonspine": {
|
||||
"17676": {
|
||||
"name": "Dragonspine",
|
||||
"fish": [
|
||||
"medaka",
|
||||
|
@ -66,7 +89,7 @@
|
|||
],
|
||||
"location": "mondstadt"
|
||||
},
|
||||
"qingce_village": {
|
||||
"17675": {
|
||||
"name": "Qingce Village",
|
||||
"fish": [
|
||||
"sweet-flower_medaka",
|
||||
|
@ -78,7 +101,7 @@
|
|||
],
|
||||
"location": "liyue"
|
||||
},
|
||||
"dihua_marsh": {
|
||||
"17677": {
|
||||
"name": "Dihua Marsh",
|
||||
"fish": [
|
||||
"medaka",
|
||||
|
@ -88,31 +111,16 @@
|
|||
],
|
||||
"location": "liyue"
|
||||
},
|
||||
"beside_wangshu_inn": {
|
||||
"name": "Beside Wangshu Inn",
|
||||
"17678": {
|
||||
"name": "Bishui Plain",
|
||||
"fish": [
|
||||
"sweet-flower_medaka",
|
||||
"medaka",
|
||||
"betta",
|
||||
"akai_maou",
|
||||
"golden_koi",
|
||||
"rusty_koi",
|
||||
"brown_shirakodai"
|
||||
],
|
||||
"location": "liyue"
|
||||
},
|
||||
"beside_guili_plains": {
|
||||
"name": "Beside Guili Plains",
|
||||
"fish": [
|
||||
"sweet-flower_medaka",
|
||||
"betta",
|
||||
"akai_maou",
|
||||
"golden_koi",
|
||||
"rusty_koi",
|
||||
"brown_shirakodai"
|
||||
],
|
||||
"location": "liyue"
|
||||
},
|
||||
"bishui_plain": {
|
||||
"17679": {
|
||||
"name": "Bishui Plain",
|
||||
"fish": [
|
||||
"medaka",
|
||||
|
@ -122,7 +130,18 @@
|
|||
],
|
||||
"location": "liyue"
|
||||
},
|
||||
"mt._hulao": {
|
||||
"17680": {
|
||||
"name": "Mt. Aocang",
|
||||
"fish": [
|
||||
"medaka",
|
||||
"sweet-flower_medaka",
|
||||
"dawncatcher",
|
||||
"crystalfish",
|
||||
"abiding_angelfish"
|
||||
],
|
||||
"location": "liyue"
|
||||
},
|
||||
"17681": {
|
||||
"name": "Mt. Hulao",
|
||||
"fish": [
|
||||
"medaka",
|
||||
|
@ -134,7 +153,28 @@
|
|||
],
|
||||
"location": "liyue"
|
||||
},
|
||||
"luhua_pool": {
|
||||
"17682": {
|
||||
"name": "Beside Wangshu Inn",
|
||||
"fish": [
|
||||
"sweet-flower_medaka",
|
||||
"betta",
|
||||
"akai_maou",
|
||||
"golden_koi",
|
||||
"rusty_koi",
|
||||
"brown_shirakodai"
|
||||
],
|
||||
"location": "liyue"
|
||||
},
|
||||
"17683": {
|
||||
"name": "Tianqiu Valley",
|
||||
"fish": [
|
||||
"medaka",
|
||||
"crystalfish",
|
||||
"betta"
|
||||
],
|
||||
"location": "liyue"
|
||||
},
|
||||
"17684": {
|
||||
"name": "Luhua Pool",
|
||||
"fish": [
|
||||
"sweet-flower_medaka",
|
||||
|
@ -146,16 +186,19 @@
|
|||
],
|
||||
"location": "liyue"
|
||||
},
|
||||
"tianqiu_valley": {
|
||||
"name": "Tianqiu Valley",
|
||||
"17685": {
|
||||
"name": "Beside Guili Plains",
|
||||
"fish": [
|
||||
"medaka",
|
||||
"crystalfish",
|
||||
"betta"
|
||||
"sweet-flower_medaka",
|
||||
"betta",
|
||||
"akai_maou",
|
||||
"golden_koi",
|
||||
"rusty_koi",
|
||||
"brown_shirakodai"
|
||||
],
|
||||
"location": "liyue"
|
||||
},
|
||||
"liyue_harbor": {
|
||||
"17686": {
|
||||
"name": "Liyue Harbor",
|
||||
"fish": [
|
||||
"sweet-flower_medaka",
|
||||
|
@ -166,48 +209,7 @@
|
|||
],
|
||||
"location": "liyue"
|
||||
},
|
||||
"mt._aocang": {
|
||||
"name": "Mt. Aocang",
|
||||
"fish": [
|
||||
"medaka",
|
||||
"sweet-flower_medaka",
|
||||
"dawncatcher",
|
||||
"crystalfish",
|
||||
"abiding_angelfish"
|
||||
],
|
||||
"location": "liyue"
|
||||
},
|
||||
"ritou": {
|
||||
"name": "Ritou",
|
||||
"fish": [
|
||||
"glaze_medaka",
|
||||
"lunged_stickleback",
|
||||
"akai_maou",
|
||||
"pufferfish",
|
||||
"bitter_pufferfish"
|
||||
],
|
||||
"location": "inazuma"
|
||||
},
|
||||
"near_amakane_island": {
|
||||
"name": "Near Amakane Island",
|
||||
"fish": [
|
||||
"glaze_medaka",
|
||||
"lunged_stickleback",
|
||||
"purple_shirakodai"
|
||||
],
|
||||
"location": "inazuma"
|
||||
},
|
||||
"nazuchi_beach": {
|
||||
"name": "Nazuchi Beach",
|
||||
"fish": [
|
||||
"medaka",
|
||||
"lunged_stickleback",
|
||||
"purple_shirakodai",
|
||||
"bitter_pufferfish"
|
||||
],
|
||||
"location": "inazuma"
|
||||
},
|
||||
"sangonomiya_shrine": {
|
||||
"17687": {
|
||||
"name": "Sangonomiya Shrine",
|
||||
"fish": [
|
||||
"medaka",
|
||||
|
@ -219,7 +221,7 @@
|
|||
],
|
||||
"location": "inazuma"
|
||||
},
|
||||
"suigetsu_pool": {
|
||||
"17688": {
|
||||
"name": "Suigetsu Pool",
|
||||
"fish": [
|
||||
"medaka",
|
||||
|
@ -231,7 +233,35 @@
|
|||
],
|
||||
"location": "inazuma"
|
||||
},
|
||||
"koseki_village": {
|
||||
"17689": {
|
||||
"name": "Nazuchi Beach",
|
||||
"fish": [
|
||||
"medaka",
|
||||
"lunged_stickleback",
|
||||
"purple_shirakodai",
|
||||
"bitter_pufferfish"
|
||||
],
|
||||
"location": "inazuma"
|
||||
},
|
||||
"17690": {
|
||||
"name": "Tatarasuna",
|
||||
"fish": [
|
||||
"raimei_angelfish"
|
||||
],
|
||||
"location": "inazuma"
|
||||
},
|
||||
"17691": {
|
||||
"name": "Near Koseki Village",
|
||||
"fish": [
|
||||
"medaka",
|
||||
"dawncatcher",
|
||||
"crystalfish",
|
||||
"purple_shirakodai",
|
||||
"pufferfish"
|
||||
],
|
||||
"location": "inazuma"
|
||||
},
|
||||
"17694": {
|
||||
"name": "Koseki Village",
|
||||
"fish": [
|
||||
"glaze_medaka",
|
||||
|
@ -243,21 +273,33 @@
|
|||
],
|
||||
"location": "inazuma"
|
||||
},
|
||||
"near_koseki_village": {
|
||||
"name": "Near Koseki Village",
|
||||
"17692": {
|
||||
"name": "Ritou",
|
||||
"fish": [
|
||||
"medaka",
|
||||
"dawncatcher",
|
||||
"crystalfish",
|
||||
"purple_shirakodai",
|
||||
"pufferfish"
|
||||
"glaze_medaka",
|
||||
"lunged_stickleback",
|
||||
"akai_maou",
|
||||
"pufferfish",
|
||||
"bitter_pufferfish"
|
||||
],
|
||||
"location": "inazuma"
|
||||
},
|
||||
"tatarasuna": {
|
||||
"name": "Tatarasuna",
|
||||
"17693": {
|
||||
"name": "Near Amakane Island",
|
||||
"fish": [
|
||||
"raimei_angelfish"
|
||||
"glaze_medaka",
|
||||
"lunged_stickleback",
|
||||
"purple_shirakodai"
|
||||
],
|
||||
"location": "inazuma"
|
||||
},
|
||||
"18686": {
|
||||
"name": "Chirai Shrine",
|
||||
"fish": [
|
||||
"medaka",
|
||||
"glaze_medaka",
|
||||
"dawncatcher",
|
||||
"crystalfish"
|
||||
],
|
||||
"location": "inazuma"
|
||||
}
|
||||
|
|
|
@ -761,8 +761,14 @@
|
|||
},
|
||||
"fishing": {
|
||||
"title": "Fishing Book",
|
||||
"subtitle": "Mark the fishing spot as empty when you already fish out all the fish to start the respawn timer",
|
||||
"mondstadt": "Mondstadt",
|
||||
"liyue": "Liyue",
|
||||
"inazuma": "Inazuma"
|
||||
"inazuma": "Inazuma",
|
||||
"setEmpty": "Set as empty",
|
||||
"emptyTime": "Time when the spot is empty:",
|
||||
"clear": "Clear",
|
||||
"save": "Save",
|
||||
"cancel": "Cancel"
|
||||
}
|
||||
}
|
|
@ -9,6 +9,9 @@
|
|||
<h1 class="font-display px-4 md:px-8 font-black text-5xl text-white">{$t('settings.changelog')}</h1>
|
||||
<pre
|
||||
class="text-white px-4 md:px-8">
|
||||
2021/10/15
|
||||
- Add fishing spot timer
|
||||
|
||||
2021/10/13
|
||||
- Update weapons
|
||||
- Update achievements
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
<script>
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
import { t } from 'svelte-i18n';
|
||||
|
||||
import Button from '../../components/Button.svelte';
|
||||
import Input from '../../components/Input.svelte';
|
||||
|
||||
export let time;
|
||||
export let close;
|
||||
export let clear;
|
||||
export let edit;
|
||||
|
||||
function save() {
|
||||
const updatedTime = dayjs(time);
|
||||
edit(updatedTime);
|
||||
}
|
||||
</script>
|
||||
|
||||
<div>
|
||||
<p class="text-white mb-4">{$t('fishing.emptyTime')}</p>
|
||||
<Input type="datetime-local" pattern="[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}" bind:value={time} />
|
||||
<div class="flex space-x-2 mt-4">
|
||||
<Button on:click={clear} color="red">{$t('fishing.clear')}</Button>
|
||||
<div class="flex-1" />
|
||||
<Button on:click={save} color="green">{$t('fishing.save')}</Button>
|
||||
<Button on:click={close}>{$t('fishing.cancel')}</Button>
|
||||
</div>
|
||||
</div>
|
|
@ -18,22 +18,137 @@
|
|||
|
||||
<script>
|
||||
import { locale, t } from 'svelte-i18n';
|
||||
import { onMount } from 'svelte';
|
||||
import { getContext, onMount } from 'svelte';
|
||||
import { mdiCheck, mdiPencil } from '@mdi/js';
|
||||
import dayjs from 'dayjs';
|
||||
import duration from 'dayjs/plugin/duration';
|
||||
dayjs.extend(duration);
|
||||
|
||||
import Button from '../../components/Button.svelte';
|
||||
import Icon from '../../components/Icon.svelte';
|
||||
import { readSave, updateSave } from '../../stores/saveManager';
|
||||
import { getAccountPrefix } from '../../stores/account';
|
||||
import EditModal from './_editModal.svelte';
|
||||
|
||||
const { open: openModal, close: closeModal } = getContext('simple-modal');
|
||||
|
||||
export let data;
|
||||
export let spots;
|
||||
|
||||
let fishList = data;
|
||||
let timer = {};
|
||||
let now = dayjs();
|
||||
|
||||
async function setAsEmpty(id) {
|
||||
timer[id] = {
|
||||
time: dayjs(),
|
||||
text: '3d',
|
||||
};
|
||||
|
||||
await save();
|
||||
}
|
||||
|
||||
async function setEditing(id) {
|
||||
openModal(
|
||||
EditModal,
|
||||
{
|
||||
time: timer[id].time.format('YYYY-MM-DDTHH:mm'),
|
||||
close: closeModal,
|
||||
edit: (time) => edit(id, time),
|
||||
clear: () => clear(id),
|
||||
},
|
||||
{
|
||||
closeButton: false,
|
||||
styleWindow: { background: '#25294A', width: '500px' },
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
async function clear(id) {
|
||||
delete timer[id];
|
||||
closeModal();
|
||||
await save();
|
||||
}
|
||||
|
||||
async function edit(id, time) {
|
||||
timer[id] = {
|
||||
time,
|
||||
text: '...',
|
||||
};
|
||||
closeModal();
|
||||
await save();
|
||||
}
|
||||
|
||||
async function changeLocale(locale) {
|
||||
const _data = await import(`../../data/fishing/${locale}.json`);
|
||||
fishList = _data.default;
|
||||
}
|
||||
|
||||
function getDuration(time) {
|
||||
const diff = time.add(3, 'days').diff(now);
|
||||
const duration = dayjs.duration(diff);
|
||||
let format = 'D[d] HH:mm:ss';
|
||||
if (duration.days() === 0) {
|
||||
format = 'HH:mm:ss';
|
||||
}
|
||||
|
||||
return duration.format(format);
|
||||
}
|
||||
|
||||
async function load() {
|
||||
const prefix = getAccountPrefix();
|
||||
const data = await readSave(`${prefix}fishing`);
|
||||
const timerData = {};
|
||||
if (data !== null) {
|
||||
for (const [id, item] of Object.entries(data)) {
|
||||
timerData[id] = {
|
||||
...item,
|
||||
text: '...',
|
||||
time: dayjs(item.time),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
timer = timerData;
|
||||
}
|
||||
|
||||
async function save() {
|
||||
const prefix = getAccountPrefix();
|
||||
const formattedTimer = {};
|
||||
for (const [id, item] of Object.entries(timer)) {
|
||||
formattedTimer[id] = {
|
||||
...item,
|
||||
time: item.time.toISOString(),
|
||||
};
|
||||
}
|
||||
|
||||
await updateSave(`${prefix}fishing`, formattedTimer);
|
||||
}
|
||||
|
||||
onMount(async () => {
|
||||
await load();
|
||||
|
||||
locale.subscribe((val) => {
|
||||
changeLocale(val);
|
||||
});
|
||||
|
||||
const interval = setInterval(() => {
|
||||
now = dayjs();
|
||||
for (const [id, item] of Object.entries(timer)) {
|
||||
if (item.time.add(3, 'days').isBefore(now)) {
|
||||
delete timer[id];
|
||||
save();
|
||||
} else {
|
||||
item.text = getDuration(item.time);
|
||||
}
|
||||
}
|
||||
|
||||
timer = timer;
|
||||
}, 1000);
|
||||
|
||||
return () => {
|
||||
clearInterval(interval);
|
||||
};
|
||||
});
|
||||
</script>
|
||||
|
||||
|
@ -44,12 +159,15 @@
|
|||
</svelte:head>
|
||||
<div class="lg:ml-64 pt-20 lg:pt-8 max-w-screen-xl">
|
||||
<h1 class="font-display px-4 md:px-8 font-black text-5xl text-white">{$t('fishing.title')}</h1>
|
||||
<p class="text-gray-400 px-4 md:px-8 font-medium pb-4" style="margin-top: -1rem;">
|
||||
※ {$t('fishing.subtitle')}
|
||||
</p>
|
||||
{#each Object.entries(spots) as [id, location]}
|
||||
<h3 class="font-display px-4 md:px-8 font-black text-2xl text-white mt-4 mb-2">{$t(`fishing.${id}`)}</h3>
|
||||
<div class="px-4 md:px-8 w-full">
|
||||
{#each location as spot}
|
||||
<div class="flex flex-col items-center md:items-start md:flex-row w-full bg-item rounded-xl p-4 mb-2">
|
||||
<div class="mr-4">
|
||||
<div class="mr-4 flex flex-col">
|
||||
<img
|
||||
class="w-48 h-48 rounded-md"
|
||||
style="min-width: 192px;"
|
||||
|
@ -57,6 +175,21 @@
|
|||
alt={spot.name}
|
||||
title={spot.name}
|
||||
/>
|
||||
{#if timer[spot.id]}
|
||||
<div class="flex mt-2 items-center">
|
||||
<p class="text-white text-center mr-1 flex-1">
|
||||
{timer[spot.id].text}
|
||||
</p>
|
||||
<Button on:click={() => setEditing(spot.id)} size="sm">
|
||||
<Icon path={mdiPencil} color="white" />
|
||||
</Button>
|
||||
</div>
|
||||
{:else}
|
||||
<Button on:click={() => setAsEmpty(spot.id)} size="sm" className="mt-2 flex-1">
|
||||
{$t('fishing.setEmpty')}
|
||||
<Icon path={mdiCheck} color="white" />
|
||||
</Button>
|
||||
{/if}
|
||||
</div>
|
||||
<div
|
||||
class="flex flex-wrap pt-6 md:pt-0 justify-center md:justify-start"
|
||||
|
|
After Width: | Height: | Size: 76 KiB |
After Width: | Height: | Size: 66 KiB |
After Width: | Height: | Size: 78 KiB |
After Width: | Height: | Size: 57 KiB |
After Width: | Height: | Size: 60 KiB |
After Width: | Height: | Size: 67 KiB |
After Width: | Height: | Size: 54 KiB |
After Width: | Height: | Size: 90 KiB |
After Width: | Height: | Size: 100 KiB |
After Width: | Height: | Size: 63 KiB |
After Width: | Height: | Size: 82 KiB |
After Width: | Height: | Size: 80 KiB |
After Width: | Height: | Size: 84 KiB |
After Width: | Height: | Size: 78 KiB |
After Width: | Height: | Size: 70 KiB |
After Width: | Height: | Size: 66 KiB |
After Width: | Height: | Size: 73 KiB |
After Width: | Height: | Size: 58 KiB |
After Width: | Height: | Size: 58 KiB |
After Width: | Height: | Size: 78 KiB |
After Width: | Height: | Size: 52 KiB |
After Width: | Height: | Size: 51 KiB |
After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 68 KiB |
After Width: | Height: | Size: 54 KiB |
After Width: | Height: | Size: 23 KiB |
After Width: | Height: | Size: 69 KiB |
After Width: | Height: | Size: 65 KiB |
Before Width: | Height: | Size: 234 KiB |
Before Width: | Height: | Size: 230 KiB |
Before Width: | Height: | Size: 168 KiB |
Before Width: | Height: | Size: 144 KiB |
Before Width: | Height: | Size: 171 KiB |
Before Width: | Height: | Size: 206 KiB |
Before Width: | Height: | Size: 205 KiB |
Before Width: | Height: | Size: 216 KiB |
Before Width: | Height: | Size: 141 KiB |
Before Width: | Height: | Size: 161 KiB |
Before Width: | Height: | Size: 198 KiB |
Before Width: | Height: | Size: 130 KiB |
Before Width: | Height: | Size: 159 KiB |
Before Width: | Height: | Size: 117 KiB |
Before Width: | Height: | Size: 205 KiB |
Before Width: | Height: | Size: 167 KiB |
Before Width: | Height: | Size: 118 KiB |
Before Width: | Height: | Size: 141 KiB |
Before Width: | Height: | Size: 182 KiB |
Before Width: | Height: | Size: 143 KiB |
Before Width: | Height: | Size: 157 KiB |
Before Width: | Height: | Size: 193 KiB |
Before Width: | Height: | Size: 122 KiB |
Before Width: | Height: | Size: 130 KiB |