46 Commits

Author SHA1 Message Date
b0245a1714 build(python): update pyproject.toml format 2026-07-30 15:18:28 +03:00
91b530f84c build(docker): add DOCKER_TAG env variable 2026-07-29 11:31:27 +03:00
2b1dfad929 build(npm): add babel and postcss webpack rules 2026-07-24 14:00:24 +03:00
1df83ec34d ci(version): 0.5.2 2026-07-22 22:16:16 +03:00
1c4dac74ca feat(weather): inline weather svg icons 2026-07-22 22:16:16 +03:00
75343a21b9 ci(version): 0.5.1 2026-07-22 22:16:16 +03:00
83fabdd538 fix(static): fix bootstrap usage 2026-07-22 22:16:16 +03:00
29364bb7d4 ci(version): 0.5.0 2026-07-22 22:16:15 +03:00
195bd76608 build(scripts): add save docker action 2026-07-22 22:15:08 +03:00
436c6c7364 fix(gismeteo): add heavy_rain variant 2026-07-22 22:15:08 +03:00
0a734f9c43 feat(static): colorize weather icons 2026-07-22 22:15:08 +03:00
6171ec8a26 refactor(static): refactor static module 2026-07-22 22:15:08 +03:00
72fd148a54 build(static): fix webpack build warngins 2026-07-22 22:15:06 +03:00
12774db70f refactor(static): refactor weather-icons lib 2026-07-22 22:14:41 +03:00
0008e99c66 feat(static): use webpack instead of vite 2026-07-22 22:14:41 +03:00
bad5dff2b2 ci(version): 0.4.2 2026-07-22 21:52:30 +03:00
e2af31b812 fix(gismeteo): fix empty wind direction value in parser 2026-07-22 21:52:15 +03:00
6c76dae760 ci(version): 0.4.1 2026-07-02 14:17:55 +03:00
28951df9b5 fix(openweather): optional visability field in forecast model 2026-07-02 14:17:48 +03:00
5aa290c772 ci(version): 0.4.0 2026-07-02 14:06:15 +03:00
13a70990e5 feat(weather): add hail precipitation variant 2026-07-02 02:59:49 +03:00
a3fab92e3d feat(view): fix index page 2026-07-02 02:43:43 +03:00
4fdb7e9717 fix(view): fix index pages api resolving 2026-07-02 01:30:38 +03:00
1d13f6e05d refactor(doc): update docs static 2026-07-01 22:48:24 +03:00
fcb000afb0 test: fix tests 2026-07-01 21:05:49 +03:00
0730b9f567 build(poetry): update python dependencies 2026-07-01 20:53:01 +03:00
081aa8d17f feat(openweather): add location name to forecast response 2026-07-01 16:40:16 +03:00
29fe06462e feat(schedule): implement multiple schedule providers 2026-06-27 16:03:28 +03:00
8b20eb1220 test(openweather): add openweather location seacrh test 2026-06-26 16:27:36 +03:00
5333690c47 feat(weather): implement provider in weather api endpoints 2026-06-25 19:19:21 +03:00
d82fc4ea46 feat(weather): improve weather locations list 2026-06-24 21:02:06 +03:00
df2f1d0d81 refactor(easel): add view root module 2026-06-24 16:00:39 +03:00
9192ca3e4a feat(easel): implement multiple weather providers 2026-06-24 16:00:39 +03:00
e37ca6eeac feat(easel): add api provider 2026-06-24 16:00:39 +03:00
657a62eab5 ci(version): 0.3.4 2026-06-24 15:54:43 +03:00
d8e2be013a fix(gismeteo): fix precipitation parser 2026-06-24 15:54:35 +03:00
a91ec12d22 ci(version): 0.3.3 2026-06-22 15:33:36 +03:00
9c862863e5 fix(gismeteo): fix precipitation parser 2026-06-22 15:33:19 +03:00
fc59e52337 ci(version): 0.3.2 2026-06-20 18:59:43 +03:00
3e93a41400 fix(gismeteo): fix date-time row parsing 2026-06-20 18:59:27 +03:00
c2cd18386b refactor(easel): update api router 2026-06-16 21:18:16 +03:00
2bca3dd75a ci(version): 0.3.1 2026-06-16 20:17:37 +03:00
469bd9bc1f feat(easel): add version to header 2026-06-16 20:17:12 +03:00
027d1e2d55 build(docker): add docker build caches mount 2026-06-16 20:01:29 +03:00
7cf0012229 feat(schedule): update navigate icons 2026-06-16 20:00:46 +03:00
edc014d98c docs: update screenshot 2026-06-15 23:37:31 +03:00
163 changed files with 14562 additions and 8747 deletions

View File

@@ -2,4 +2,8 @@ DOCKER_REPO=git.shmyga.ru
DOCKER_GROUP=infernalgames DOCKER_GROUP=infernalgames
DOCKER_ROOT="$DOCKER_REPO/$DOCKER_GROUP" DOCKER_ROOT="$DOCKER_REPO/$DOCKER_GROUP"
VERSION=$(grep -m 1 'version' ./pyproject.toml | grep -oP 'version\s*=\s*"\K[^"]+') VERSION=$(grep -m 1 'version' ./pyproject.toml | grep -oP 'version\s*=\s*"\K[^"]+')
DOCKER_PROJECTS=("gallery") PYTHON_VERSION=$(grep -m 1 'python' ./pyproject.toml | grep -oP 'python\s*=\s*"\^?\K[^"]+')
DOCKER_PROJECTS=("gallery")
DOCKER_TAG=latest
OPENWEATHER_KEY="<EMPTY>"

4
.gitignore vendored
View File

@@ -4,4 +4,6 @@
.venv .venv
#.vscode #.vscode
static/node_modules static/node_modules
static/dist static/dist
.env
dist

View File

@@ -1,13 +1,15 @@
FROM python:3.12 AS builder FROM python:3.14 AS builder
ENV POETRY_HOME="/opt/poetry" ENV POETRY_HOME="/opt/poetry"
ENV PATH="$POETRY_HOME/bin:$PATH" ENV PATH="$POETRY_HOME/bin:$PATH"
RUN apt update && \ RUN apt update && \
apt install -y gettext apt install -y gettext
WORKDIR /app WORKDIR /app
RUN curl -sSL https://install.python-poetry.org | python3 - RUN curl -sSL https://install.python-poetry.org | python3 -
COPY pyproject.toml poetry.lock README.md ./ COPY pyproject.toml poetry.lock README.md ./
RUN poetry config virtualenvs.in-project true RUN poetry config virtualenvs.in-project true
RUN poetry install --with app --no-root RUN --mount=type=cache,target=/root/.cache/pypoetry/cache \
--mount=type=cache,target=/root/.cache/pypoetry/artifacts \
poetry install --extras app --no-root
COPY locales ./locales COPY locales ./locales
RUN cd locales/ru/LC_MESSAGES && msgfmt messages.po RUN cd locales/ru/LC_MESSAGES && msgfmt messages.po
@@ -15,11 +17,12 @@ FROM node:24 AS node-builder
ENV PATH=/app/node_modules/.bin:$PATH ENV PATH=/app/node_modules/.bin:$PATH
WORKDIR /app WORKDIR /app
COPY static/package.json static/package-lock.json ./ COPY static/package.json static/package-lock.json ./
RUN npm ci RUN --mount=type=cache,target=/root/.npm \
npm ci
COPY static ./ COPY static ./
RUN npm run build RUN npm run build
FROM python:3.12-slim FROM python:3.14-slim
ENV PATH="/app/.venv/bin:$PATH" ENV PATH="/app/.venv/bin:$PATH"
WORKDIR /app WORKDIR /app
@@ -27,7 +30,6 @@ ENV TZ="Europe/Moscow"
COPY --from=builder /app ./ COPY --from=builder /app ./
COPY --from=node-builder /app/dist ./static/dist COPY --from=node-builder /app/dist ./static/dist
COPY gallery gallery/ COPY gallery gallery/
#COPY --from=builder /app/gallery/easel/route/view/locales /app/gallery/easel/route/view/locales
COPY --from=builder --parents locales/**/*.mo ./ COPY --from=builder --parents locales/**/*.mo ./
CMD ["uvicorn", "gallery.main:app", "--host", "0.0.0.0", "--port", "80", "--log-config", "gallery/logging.yaml"] CMD ["uvicorn", "gallery.main:app", "--host", "0.0.0.0", "--port", "80", "--log-config", "gallery/logging.yaml"]

View File

@@ -12,6 +12,7 @@ services:
build: . build: .
environment: environment:
- REDIS_HOST=redis - REDIS_HOST=redis
- OPENWEATHER_KEY=$OPENWEATHER_KEY
- DEBUG=1 - DEBUG=1
ports: ports:
- 8000:80 - 8000:80

View File

@@ -1,17 +1,18 @@
name: gallery name: gallery-${DOCKER_TAG}
services: services:
redis: redis:
container_name: gallery-redis container_name: gallery-${DOCKER_TAG}-redis
image: redis:alpine image: redis:alpine
stop_grace_period: 3s stop_grace_period: 3s
volumes: volumes:
- redis_data:/data - redis_data:/data
app: app:
container_name: gallery-app container_name: gallery-${DOCKER_TAG}-app
image: ${DOCKER_ROOT}/gallery image: ${DOCKER_ROOT}/gallery:${DOCKER_TAG}
environment: environment:
- REDIS_HOST=redis - REDIS_HOST=redis
- OPENWEATHER_KEY=$OPENWEATHER_KEY
depends_on: depends_on:
- redis - redis
ports: ports:

Binary file not shown.

Before

Width:  |  Height:  |  Size: 237 KiB

After

Width:  |  Height:  |  Size: 182 KiB

View File

@@ -8,6 +8,7 @@
"python.testing.pytestArgs": ["tests", "-s"], "python.testing.pytestArgs": ["tests", "-s"],
"python.testing.unittestEnabled": false, "python.testing.unittestEnabled": false,
"python.testing.pytestEnabled": true, "python.testing.pytestEnabled": true,
"python.terminal.useEnvFile": true,
"python-envs.pythonProjects": [ "python-envs.pythonProjects": [
{ {
"path": ".", "path": ".",

View File

@@ -4,8 +4,7 @@ from fastapi.staticfiles import StaticFiles
from gallery.sketch.bundle import ApiBundle from gallery.sketch.bundle import ApiBundle
from gallery.util import root_path from gallery.util import root_path
from .route import api, doc from .route import api, doc, view
from .route.view import router as view_router
def build_app(api_bundle: ApiBundle) -> FastAPI: def build_app(api_bundle: ApiBundle) -> FastAPI:
@@ -17,6 +16,6 @@ def build_app(api_bundle: ApiBundle) -> FastAPI:
app.state.api = api_bundle app.state.api = api_bundle
app.mount("/static", StaticFiles(directory=root_path / "static/dist")) app.mount("/static", StaticFiles(directory=root_path / "static/dist"))
doc.mount(app) doc.mount(app)
api.mount(app) app.include_router(api.router)
app.include_router(view_router) app.include_router(view.router)
return app return app

View File

View File

@@ -0,0 +1,17 @@
from fastapi import HTTPException, status
from gallery.easel.core import AppRequest
from gallery.sketch.api import API
def api_resolver(api_type: type[API]):
def get_api(request: AppRequest, provider: str) -> API:
providers = request.app.state.api.get_api_providers(api_type)
if provider not in providers:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail={"provider": f"'{provider}' not in {providers}"},
)
return request.app.state.api.get_api(api_type, provider)
return get_api

View File

@@ -0,0 +1,9 @@
from typing import Annotated
from fastapi import Depends
from gallery.sketch.schedule.api import ScheduleApi
from .api import api_resolver
ScheduleApiDepends = Annotated[ScheduleApi, Depends(api_resolver(ScheduleApi))]

View File

@@ -0,0 +1,9 @@
from typing import Annotated
from fastapi import Depends
from gallery.sketch.weather.api import WeatherApi
from .api import api_resolver
WeatherApiDepends = Annotated[WeatherApi, Depends(api_resolver(WeatherApi))]

View File

@@ -1,8 +1,7 @@
from fastapi import FastAPI from fastapi import APIRouter
from . import schedule, weather from . import schedule, weather
router = APIRouter(prefix="/api")
def mount(app: FastAPI): router.include_router(weather.router)
weather.mount(app) router.include_router(schedule.router)
schedule.mount(app)

View File

@@ -1,18 +1,27 @@
import datetime import datetime
from fastapi import FastAPI from fastapi import APIRouter
from gallery.easel.core import AppRequest from gallery.easel.core import AppRequest
from gallery.sketch.schedule.model import ChannelId, Schedule from gallery.easel.depends.schedule import ScheduleApiDepends
from gallery.sketch.schedule.api import ScheduleApi
from gallery.sketch.schedule.model import Channel, Schedule
router = APIRouter(prefix="/schedule", tags=["Schedule"])
def mount(app: FastAPI): @router.get("/providers")
@app.get("/api/schedule/channels", tags=["API"]) async def get_api_weather_providers(request: AppRequest) -> list[str]:
async def get_api_schedule_channels(request: AppRequest) -> list[ChannelId]: return request.app.state.api.get_api_providers(ScheduleApi)
schedule_api = request.app.state.api.schedule
return await schedule_api.get_channels()
@app.get("/api/schedule/{channel}/{date}", tags=["API"])
async def get_api_schedule_channel_schedule(request: AppRequest, channel: str, date: datetime.date) -> Schedule: @router.get("/{provider}/channels")
schedule_api = request.app.state.api.schedule async def find_api_schedule_channels(schedule_api: ScheduleApiDepends, query: str) -> list[Channel]:
return await schedule_api.get_channel_schedule(ChannelId(channel), date) return await schedule_api.find_channels(query)
@router.get("/{provider}/{channel}/{date}")
async def get_api_schedule_channel_schedule(
schedule_api: ScheduleApiDepends, channel: str, date: datetime.date
) -> Schedule:
return await schedule_api.get_schedule(channel, date)

View File

@@ -1,23 +1,30 @@
import datetime import datetime
from fastapi import FastAPI from fastapi import APIRouter
from gallery.easel.core import AppRequest from gallery.easel.core import AppRequest
from gallery.easel.depends.weather import WeatherApiDepends
from gallery.sketch.weather.api import WeatherApi
from gallery.sketch.weather.model import Location, WeatherResponse from gallery.sketch.weather.model import Location, WeatherResponse
router = APIRouter(prefix="/weather", tags=["Weather"])
def mount(app: FastAPI):
@app.get("/api/weather/locations", tags=["API"])
async def get_api_weather_locations(request: AppRequest, query: str) -> list[Location]:
weather_api = request.app.state.api.weather
return await weather_api.find_locations(query)
@app.get("/api/weather/{location}/day/{date}", tags=["API"]) @router.get("/providers")
async def get_api_weather_day(request: AppRequest, location: str, date: datetime.date) -> WeatherResponse: async def get_api_weather_providers(request: AppRequest) -> list[str]:
weather_api = request.app.state.api.weather return request.app.state.api.get_api_providers(WeatherApi)
return await weather_api.get_day(location, date)
@app.get("/api/weather/{location}/days/{days}", tags=["API"])
async def get_api_weather_days(request: AppRequest, location: str, days: int) -> WeatherResponse: @router.get("/{provider}/locations")
weather_api = request.app.state.api.weather async def find_api_weather_locations(weather_api: WeatherApiDepends, query: str) -> list[Location]:
return await weather_api.get_days(location, days) return await weather_api.find_locations(query)
@router.get("/{provider}/{location}/day/{date}")
async def get_api_weather_day(weather_api: WeatherApiDepends, location: str, date: datetime.date) -> WeatherResponse:
return await weather_api.get_day(location, date)
@router.get("/{provider}/{location}/days/{days}")
async def get_api_weather_days(weather_api: WeatherApiDepends, location: str, days: int) -> WeatherResponse:
return await weather_api.get_days(location, days)

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,11 +1,11 @@
from fastapi import APIRouter, Depends from fastapi import APIRouter, Depends
from .common import router as common_router from .root import router as root_router
from .schedule import router as schedule_router from .schedule import router as schedule_router
from .translation import set_language from .translation import set_language
from .weather import router as weather_router from .weather import router as weather_router
router = APIRouter(dependencies=[Depends(set_language)]) router = APIRouter(tags=["view"], dependencies=[Depends(set_language)], include_in_schema=False)
router.include_router(common_router) router.include_router(root_router)
router.include_router(weather_router) router.include_router(weather_router)
router.include_router(schedule_router) router.include_router(schedule_router)

View File

@@ -1,36 +0,0 @@
from pathlib import Path
from typing import NamedTuple
from fastapi import APIRouter, Request
from fastapi.responses import HTMLResponse
from ..common.utils.template import build_templates
class Section(NamedTuple):
link: str
title: str
icon: str
SECTIONS = [
Section("weather", "Weather", "brightness-high"),
Section("schedule", "TV program", "tv"),
]
base_dir = Path(__file__).parent
router = APIRouter()
templates = build_templates()
@router.get("/", response_class=HTMLResponse)
async def get_section_list(request: Request):
return templates.TemplateResponse(
request=request,
name="root_index.html",
context={
"sections": SECTIONS,
},
)

View File

@@ -12,7 +12,7 @@
<link rel="stylesheet" <link rel="stylesheet"
href="/static/gallery.css?v={{version}}"> href="/static/gallery.css?v={{version}}">
<script type="module" <script type="module"
src="/static/gallery.es.js?v={{version}}"></script> src="/static/gallery.js?v={{version}}"></script>
<link rel="icon" <link rel="icon"
href="/favicon.ico?v={{version}}" href="/favicon.ico?v={{version}}"
type="image/x-icon"> type="image/x-icon">
@@ -112,8 +112,11 @@
{% block content %}{% endblock %} {% block content %}{% endblock %}
</main> </main>
{% if not is_widget %} {% if not is_widget %}
<footer class="pt-5 my-5 text-muted border-top"> <footer class="app-footer pt-5 my-5 text-muted border-top">
Created by shmyga &middot; &copy; 2026 <div class="d-flex justify-content-between">
<span>Created by shmyga &middot; &copy; 2026</span>
<span>v{{ version }}</span>
</div>
</footer> </footer>
{% endif %} {% endif %}
</div> </div>

View File

@@ -1,26 +0,0 @@
{% extends "base.html" %}
{% block title %}{{_("Index")}}{% endblock %}
{% block head %}
{{ super() }}
{% endblock %}
{% block content %}
<h1>{{_("View")}}</h1>
<div class="list-group mb-5">
{% for section in sections %}
<a href="{{section.link}}"
class="list-group-item list-group-item-action px-4">
<app-link href="{{section.link}}"
icon="{{section.icon}}">
{{_(section.title)}}
</app-link>
</a>
{% endfor %}
</div>
<hr class="col-3 col-md-2 mb-5">
<h1>{{_("Docs")}}</h1>
<a href="/docs"
target="_blank">
<h4>Swagger</h4>
</a>
{% endblock %}

View File

@@ -1,15 +1,19 @@
import datetime import datetime
import typing
from pathlib import Path from pathlib import Path
from babel.dates import format_date from babel.dates import format_date
from fastapi import Request from fastapi import Request
from fastapi.templating import Jinja2Templates from fastapi.templating import Jinja2Templates
from gallery.easel.core import AppRequest
from gallery.version import __version__ from gallery.version import __version__
from ...translation import _ from ...translation import _
from .tag import TagUtil from .tag import TagUtil
ContextProcessor = typing.Callable[[AppRequest], dict[str, typing.Any]]
def is_widget(request: Request) -> bool: def is_widget(request: Request) -> bool:
return (request.url.hostname and request.url.hostname.startswith("weather")) or ( return (request.url.hostname and request.url.hostname.startswith("weather")) or (
@@ -17,17 +21,23 @@ def is_widget(request: Request) -> bool:
) )
def context_processor(request: Request) -> dict: def base_context_processor(request: Request) -> dict:
return { return {
"is_widget": is_widget(request), "is_widget": is_widget(request),
"provider": request.query_params.get("provider"),
} }
def build_templates(templates_dir: Path | None = None, filters: dict | None = None) -> Jinja2Templates: def build_templates(
templates_dir: Path | None = None, filters: dict | None = None, context_processor: ContextProcessor | None = None
) -> Jinja2Templates:
directory = [Path(__file__).parent.parent / "templates"] directory = [Path(__file__).parent.parent / "templates"]
if templates_dir: if templates_dir:
directory.append(templates_dir) directory.append(templates_dir)
templates = Jinja2Templates(directory=directory, context_processors=[context_processor]) context_processors: list[ContextProcessor] = [base_context_processor]
if context_processor:
context_processors.append(context_processor)
templates = Jinja2Templates(directory=directory, context_processors=context_processors)
templates.env.globals.update( templates.env.globals.update(
{ {
"_": _, "_": _,

View File

@@ -0,0 +1,36 @@
from pathlib import Path
from typing import NamedTuple
from fastapi import APIRouter, Request
from fastapi.responses import HTMLResponse
from ..common.utils.template import build_templates
class Section(NamedTuple):
link: str
title: str
icon: str
SECTIONS = [
Section("weather", "Weather", "brightness-high"),
Section("schedule", "TV program", "tv"),
]
base_dir = Path(__file__).parent
router = APIRouter()
templates = build_templates(Path(__file__).parent / "templates")
@router.get("/", response_class=HTMLResponse)
async def get_section_list(request: Request):
return templates.TemplateResponse(
request=request,
name="root_index.html",
context={
"sections": SECTIONS,
},
)

View File

@@ -0,0 +1,33 @@
{% extends "base.html" %}
{% block title %}{{_("Index")}}{% endblock %}
{% block head %}
{{ super() }}
{% endblock %}
{% block content %}
<h1>{{_("View")}}</h1>
<div class="list-group mb-3">
{% for section in sections %}
<app-link href="{{section.link}}"
icon="{{section.icon}}"
class="list-group-item list-group-item-action">
{{_(section.title)}}
</app-link>
{% endfor %}
</div>
<h1>{{_("Docs")}}</h1>
<div class="list-group mb-3">
<app-link href="/docs"
target="_blank"
icon="file-earmark-text"
class="list-group-item list-group-item-action">
Swagger UI
</app-link>
<app-link href="/redoc"
target="_blank"
icon="file-earmark-text"
class="list-group-item list-group-item-action">
ReDoc
</app-link>
</div>
{% endblock %}

View File

@@ -5,65 +5,58 @@ from fastapi import APIRouter
from fastapi.responses import HTMLResponse, RedirectResponse from fastapi.responses import HTMLResponse, RedirectResponse
from gallery.easel.core import AppRequest from gallery.easel.core import AppRequest
from gallery.sketch.schedule.catalog import BUNDLE from gallery.easel.depends.api import api_resolver
from gallery.easel.depends.schedule import ScheduleApiDepends
from gallery.sketch.schedule.api import ScheduleApi
from ..common.utils.tag import TagType, TagUtil from ..common.utils.tag import TagType, TagUtil
from ..common.utils.template import build_templates from ..common.utils.template import build_templates
from .filters import timedelta_format from .filters import timedelta_format
def context_procesor(request: AppRequest) -> dict:
return {
"providers": request.app.state.api.get_api_providers(ScheduleApi),
}
templates = build_templates( templates = build_templates(
Path(__file__).parent / "templates", Path(__file__).parent / "templates",
{ {
"timedelta_format": timedelta_format, "timedelta_format": timedelta_format,
}, },
context_procesor,
) )
router = APIRouter() router = APIRouter(prefix="/schedule")
@router.get("/schedule", response_class=HTMLResponse) @router.get("/", response_class=HTMLResponse)
async def get_schedule_list(request: AppRequest): async def get_schedule_index(request: AppRequest, provider: str | None = None, query: str | None = None):
schedule_api = request.app.state.api.schedule if query and provider:
channels = await schedule_api.get_channels() schedule_api = api_resolver(ScheduleApi)(request, provider)
channels_data = BUNDLE.select_items(channels) channels = await schedule_api.find_channels(query)
else:
channels = []
return templates.TemplateResponse( return templates.TemplateResponse(
request=request, request=request,
name="index.html", name="index.html",
context={ context={
"channels": channels_data, "channels": channels,
}, },
) )
@router.get("/schedule/tag/{tag}", response_class=HTMLResponse) @router.get("/{provider}/{channel}", response_class=RedirectResponse)
async def get_schedule_tag(request: AppRequest, tag: str, live: bool = False):
tag_value = TagUtil.parse_tag(tag)
schedule_api = request.app.state.api.schedule
results = await schedule_api.get_all_schedules(tag_value.date)
return templates.TemplateResponse(
request=request,
name="schedule.html",
context={
"tag_util": TagUtil,
"datetime": datetime,
"response": results[0],
"responses": results,
"live": live,
},
)
@router.get("/schedule/{channel}", response_class=RedirectResponse)
async def get_channel_default(channel: str): async def get_channel_default(channel: str):
return RedirectResponse(f"{channel}/tag/today") return RedirectResponse(f"{channel}/tag/today")
@router.get("/schedule/{channel}/tag/{tag}", response_class=HTMLResponse) @router.get("/{provider}/{channel}/tag/{tag}", response_class=HTMLResponse)
async def get_channel_tag(request: AppRequest, channel: str, tag: str): async def get_channel_tag(request: AppRequest, schedule_api: ScheduleApiDepends, channel: str, tag: str):
tag_value = TagUtil.parse_tag(tag) tag_value = TagUtil.parse_tag(tag)
schedule_api = request.app.state.api.schedule
if tag_value.type == TagType.DAY: if tag_value.type == TagType.DAY:
response = await schedule_api.get_channel_schedule(channel, tag_value.date) response = await schedule_api.get_schedule(channel, tag_value.date)
else: else:
raise ValueError(tag) raise ValueError(tag)
return templates.TemplateResponse( return templates.TemplateResponse(

View File

@@ -1,6 +1,7 @@
{% extends "base.html" %} {% extends "base.html" %}
{% block title %} {% block title %}
{{_("TV program")}} | {{response.channel.name}} | {{format_date(response.date, 'E, d MMMM Y', locale=request.state.language)}} {{_("TV program")}} | {{response.channel.name}} | {{format_date(response.date, DATE_FORMAT,
locale=request.state.language)}}
{% endblock %} {% endblock %}
{% block header %} {% block header %}
@@ -10,27 +11,34 @@
{% block content %} {% block content %}
<h4> <h4>
<a class="button {{'disabled' if response.date == datetime.date.today() else ''}}" <a class="icon-link {{'disabled' if response.date == datetime.date.today() else ''}}"
href="../tag/{{tag_util.create_tag('day', response.date, -1)}}">⬅️</a> href="../tag/{{tag_util.create_tag('day', response.date, -1)}}">
<a class="button" <i class="bi bi-arrow-left-square"></i>
href="../..">⬆️</a> </a>
<span>{{response.channel.name}} | {{format_date(response.date, 'E, d MMMM Y', locale=request.state.language)}}</span> <a class="icon-link"
<a class="button" href="../../..">
href="../tag/{{tag_util.create_tag('day', response.date, 1)}}">➡️</a> <i class="bi bi-arrow-up-square"></i>
</a>
<span>{{response.channel.name}} | {{format_date(response.date, DATE_FORMAT, locale=request.state.language)}}</span>
<a class="icon-link"
href="../tag/{{tag_util.create_tag('day', response.date, 1)}}">
<i class="bi bi-arrow-right-square"></i>
</a>
</h4> </h4>
<table class="table"> <table class="table">
<thead> <thead>
<tr> <tr>
<td></td> <td></td>
<td></td> <td></td>
<td></td>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{% for value in response.values %} {% for value in response.values %}
<tr class="{{'table-success' if value.live else ''}}"> <tr class="{{'table-success' if value.live else ''}}">
<td>{{value.start.strftime('%H:%M')}}</td> <td>
<td>{{(value.end - value.start) | timedelta_format}}</td> <span>{{value.start.strftime('%H:%M')}}</span>
<span class="small ms-1">({{(value.end - value.start) | timedelta_format}})</span>
</td>
<td>{{value.label}}</td> <td>{{value.label}}</td>
</tr> </tr>
{% endfor %} {% endfor %}

View File

@@ -3,16 +3,60 @@
{% block content %} {% block content %}
<h1>{{_("TV program")}}</h1> <h1>{{_("TV program")}}</h1>
<div class="list-group mb-5"> <form action=""
<a href="schedule/tag/today" method="get"
class="list-group-item list-group-item-action px-4"> class="mb-4">
<span class="fw-bold">Все</span> <div class="input-group mb-3">
</a> <input type="text"
class="form-control"
id="query"
name="query"
placeholder="{{_('Enter the channel name')}}">
<input type="hidden"
class="form-control"
id="provider"
name="provider"
value="{{provider or providers[0]}}">
<button id="providerBtn"
class="btn btn-secondary dropdown-toggle"
type="text"
data-bs-toggle="dropdown"
aria-expanded="false">{{provider or providers[0]}}</button>
<ul class="dropdown-menu dropdown-menu-end">
{% for provider in providers %}
<li>
<a class="dropdown-item"
onclick="provider.value='{{provider}}'; providerBtn.innerText='{{provider}}'">{{provider}}</a>
</li>
{% endfor %}
</ul>
<button class="btn btn-primary"
type="submit">{{_("Search")}}</button>
</div>
</form>
{% if channels %}
<ul id="channels"
class="list-group mb-5">
{% for channel in channels %} {% for channel in channels %}
<a href="schedule/{{channel.id}}" <schedule-channel channel="{{channel.model_dump() | tojson | forceescape}}"></schedule-channel>
class="list-group-item list-group-item-action px-4">
<span class="text-primary">{{channel.name}}</span>
</a>
{% endfor %} {% endfor %}
</div> </ul>
<hr>
{% endif %}
<ul id="storedChannels"
class="list-group mb-5">
</ul>
<script>
(function () {
const params = new URLSearchParams(window.location.search);
const searchQuery = params.get('query');
if (searchQuery) {
document.querySelector('#query').value = searchQuery;
}
document.addEventListener("DOMContentLoaded", (event) => {
scheduleChannelManager.loadChannels('#storedChannels');
});
})();
</script>
{% endblock %} {% endblock %}

View File

@@ -1,51 +0,0 @@
{% extends "base.html" %}
{% block title %}
{{_("Live broadcasts") if live else _("TV program")}} | {{format_date(response.date, 'E, d MMMM Y', locale=request.state.language)}}
{% endblock %}
{% block header %}
<app-link href="/schedule"
icon="tv">{{_("TV program")}}</app-link>
{% endblock %}
{% block content %}
<h4>
<a class="button {{'disabled' if response.date == datetime.date.today() else ''}}"
href="../tag/{{tag_util.create_tag('day', response.date, -1)}}">⬅️</a>
<a class="button"
href="..">⬆️</a>
<span>{{_("Live broadcasts") if live else _("TV program")}} | {{format_date(response.date, 'E, d MMMM Y', locale=request.state.language)}}</span>
<a class="button"
href="../tag/{{tag_util.create_tag('day', response.date, 1)}}">➡️</a>
</h4>
<div>
<table class="table">
<thead>
<tr>
<td></td>
<td></td>
<td></td>
</tr>
</thead>
<tbody>
{% for response in responses %}
{% set values = (response.values|selectattr('live') if live else response.values)|list %}
{% if values|length > 0 %}
<tr class="table-primary fs-4">
<td colspan="3">
<div>{{response.channel.name}}</div>
</td>
</tr>
{% for value in values %}
<tr class="{{'table-success' if not live and value.live else ''}}">
<td>{{value.start.strftime('%H:%M')}}</td>
<td>{{(value.end - value.start) | timedelta_format}}</td>
<td>{{value.label}}</td>
</tr>
{% endfor %}
{% endif %}
{% endfor %}
</tbody>
</table>
</div>
{% endblock %}

View File

@@ -5,18 +5,30 @@ from fastapi import APIRouter
from fastapi.responses import HTMLResponse, RedirectResponse from fastapi.responses import HTMLResponse, RedirectResponse
from gallery.easel.core import AppRequest from gallery.easel.core import AppRequest
from gallery.easel.depends.api import api_resolver
from gallery.easel.depends.weather import WeatherApiDepends
from gallery.sketch.weather.api import WeatherApi
from gallery.sketch.weather.model import WeatherResponse from gallery.sketch.weather.model import WeatherResponse
from ..common.utils.tag import TagType, TagUtil from ..common.utils.tag import TagType, TagUtil
from ..common.utils.template import build_templates from ..common.utils.template import build_templates
from .filters import cloudness_icon, wind_direction_icon from .filters import cloudness_icon, weather_icon_svg, wind_direction_icon
def context_procesor(request: AppRequest) -> dict:
return {
"providers": request.app.state.api.get_api_providers(WeatherApi),
}
templates = build_templates( templates = build_templates(
Path(__file__).parent / "templates", Path(__file__).parent / "templates",
{ {
"wind_direction_icon": wind_direction_icon, "wind_direction_icon": wind_direction_icon,
"cloudness_icon": cloudness_icon, "cloudness_icon": cloudness_icon,
"weather_icon_svg": weather_icon_svg,
}, },
context_procesor,
) )
@@ -30,13 +42,16 @@ def build_weather_response(request: AppRequest, response: WeatherResponse):
) )
router = APIRouter() router = APIRouter(prefix="/weather")
@router.get("/weather", response_class=HTMLResponse) @router.get("/", response_class=HTMLResponse)
async def get_weather_index(request: AppRequest, query: str | None = None): async def get_weather_index(request: AppRequest, provider: str | None = None, query: str | None = None):
weather_api = request.app.state.api.weather if query and provider:
locations = (await weather_api.find_locations(query)) if query else [] weather_api = api_resolver(WeatherApi)(request, provider)
locations = await weather_api.find_locations(query)
else:
locations = []
return templates.TemplateResponse( return templates.TemplateResponse(
request=request, request=request,
name="index.html", name="index.html",
@@ -46,29 +61,31 @@ async def get_weather_index(request: AppRequest, query: str | None = None):
) )
@router.get("/weather/{location}", response_class=RedirectResponse) @router.get("/{provider}/{location}", response_class=RedirectResponse)
async def get_weather_default(location: str): async def get_weather(location: str):
return RedirectResponse(f"{location}/tag/today") return RedirectResponse(f"{location}/tag/today")
@router.get("/weather/{location}/day/{date}", response_class=HTMLResponse) @router.get("/{provider}/{location}/day/{date}", response_class=HTMLResponse)
async def get_weather_day(request: AppRequest, location: str, date: datetime.date): async def get_weather_day(
weather_api = request.app.state.api.weather request: AppRequest,
weather_api: WeatherApiDepends,
location: str,
date: datetime.date,
):
response = await weather_api.get_day(location, date) response = await weather_api.get_day(location, date)
return build_weather_response(request, response) return build_weather_response(request, response)
@router.get("/weather/{location}/days/{days}", response_class=HTMLResponse) @router.get("/{provider}/{location}/days/{days}", response_class=HTMLResponse)
async def get_weather_days(request: AppRequest, location: str, days: int): async def get_weather_days(request: AppRequest, weather_api: WeatherApiDepends, location: str, days: int):
weather_api = request.app.state.api.weather
response = await weather_api.get_days(location, days) response = await weather_api.get_days(location, days)
return build_weather_response(request, response) return build_weather_response(request, response)
@router.get("/weather/{location}/tag/{tag}", response_class=HTMLResponse) @router.get("/{provider}/{location}/tag/{tag}", response_class=HTMLResponse)
async def get_weather_tag(request: AppRequest, location: str, tag: str): async def get_weather_tag(request: AppRequest, weather_api: WeatherApiDepends, location: str, tag: str):
tag_value = TagUtil.parse_tag(tag) tag_value = TagUtil.parse_tag(tag)
weather_api = request.app.state.api.weather
if tag_value.type == TagType.DAY: if tag_value.type == TagType.DAY:
response = await weather_api.get_day(location, tag_value.date) response = await weather_api.get_day(location, tag_value.date)
elif tag_value.type == TagType.DAYS: elif tag_value.type == TagType.DAYS:
@@ -76,3 +93,10 @@ async def get_weather_tag(request: AppRequest, location: str, tag: str):
else: else:
raise ValueError(tag) raise ValueError(tag)
return build_weather_response(request, response) return build_weather_response(request, response)
@router.get("/zmiyevka-184640/tag/{tag}", response_class=RedirectResponse)
async def get_zmiyevka_weather_compat(request: AppRequest):
path_parts = request.url.path.split("/")
path_parts.insert(2, "gismeteo")
return RedirectResponse("/".join(path_parts))

View File

@@ -1,5 +1,7 @@
import datetime import datetime
from markupsafe import Markup
from gallery.sketch.weather.model import ( from gallery.sketch.weather.model import (
Cloudness, Cloudness,
Precipitation, Precipitation,
@@ -7,6 +9,7 @@ from gallery.sketch.weather.model import (
WindDirection, WindDirection,
WindDirectionDeg, WindDirectionDeg,
) )
from gallery.util import root_path
def wind_direction_icon(wind_direction_deg: float) -> str: def wind_direction_icon(wind_direction_deg: float) -> str:
@@ -48,8 +51,31 @@ def cloudness_icon(sky: Sky, date: datetime.datetime, period: str) -> list[str]:
Precipitation.SHOWER: "rain", Precipitation.SHOWER: "rain",
Precipitation.SNOW: "snow", Precipitation.SNOW: "snow",
Precipitation.HEAVY_SNOW: "snow", Precipitation.HEAVY_SNOW: "snow",
Precipitation.HAIL: "hail",
}[sky.precipitation] }[sky.precipitation]
if sky.cloudness == Cloudness.PARTLY_CLOUDY: if sky.cloudness == Cloudness.PARTLY_CLOUDY:
main_icon = f"{day_prefix}-{main_icon}" main_icon = f"{day_prefix}-{main_icon}"
icons = [main_icon] icons = [main_icon]
return icons return icons
class WeatherIconBundle:
def __init__(self):
self._icon_path = root_path / "static/dist/weather-icons/icons"
self._cache = {}
def _load_icon(self, icon: str) -> Markup:
icon_file = self._icon_path / f"wi-{icon}.svg"
return Markup(icon_file.read_text())
def get(self, icon: str) -> Markup:
if icon not in self._cache:
self._cache[icon] = self._load_icon(icon)
return self._cache[icon]
WEATHER_ICON_BUNDLE = WeatherIconBundle()
def weather_icon_svg(icon: str) -> Markup:
return WEATHER_ICON_BUNDLE.get(icon)

View File

@@ -12,63 +12,51 @@
id="query" id="query"
name="query" name="query"
placeholder="{{_('Enter the city name')}}"> placeholder="{{_('Enter the city name')}}">
<input type="hidden"
class="form-control"
id="provider"
name="provider"
value="{{provider or providers[0]}}">
<button id="providerBtn"
class="btn btn-secondary dropdown-toggle"
type="text"
data-bs-toggle="dropdown"
aria-expanded="false">{{provider or providers[0]}}</button>
<ul class="dropdown-menu dropdown-menu-end">
{% for provider in providers %}
<li>
<a class="dropdown-item"
onclick="provider.value='{{provider}}'; providerBtn.innerText='{{provider}}'">{{provider}}</a>
</li>
{% endfor %}
</ul>
<button class="btn btn-primary" <button class="btn btn-primary"
type="submit">{{_("Search")}}</button> type="submit">{{_("Search")}}</button>
</div> </div>
</form> </form>
{% if locations %}
<ul id="locations" <ul id="locations"
class="list-group mb-5"> class="list-group mb-5">
{% for location in locations %} {% for location in locations %}
<a href="weather/{{location.id}}" <weather-location location="{{location.model_dump() | tojson | forceescape}}"></weather-location>
class="list-group-item list-group-item-action px-4"
onclick="saveLocation({id:'{{location.id}}', name:'{{location.name}}'});">
<span class="fi fi-{{location.country_code}} me-1"></span>
<span class="text-primary">{{location.name}}</span>
<span class="small ms-1 text-secondary">
{{location.country}}, {{location.district}}, {{location.subdistrict}}
</span>
<span></span>
</a>
{% endfor %} {% endfor %}
</ul> </ul>
<hr>
{% endif %}
<ul id="storedLocations"
class="list-group mb-5">
</ul>
<script> <script>
(function () { (function () {
document.loadLocations = () => {
const locations = JSON.parse(window.localStorage.getItem('locations') || '{}');
const container = document.querySelector('#locations');
container.innerHTML = '';
for (const [id, name] of Object.entries(locations)) {
const element = document.createElement('a');
element.href = `weather/${id}`;
element.className = 'list-group-item list-group-item-action px-4 d-flex justify-content-between align-items-start';
element.innerHTML = `
<span class="text-primary me-auto">${name}</span>
<span class="text-danger" onclick="removeLocation('${id}'); event.preventDefault();">&#x2715;</span>
`;
container.appendChild(element);
}
}
document.saveLocation = (location) => {
const locations = JSON.parse(window.localStorage.getItem('locations') || '{}');
locations[location.id] = location.name;
window.localStorage.setItem('locations', JSON.stringify(locations));
}
document.removeLocation = (id) => {
const locations = JSON.parse(window.localStorage.getItem('locations') || '{}');
delete locations[id];
window.localStorage.setItem('locations', JSON.stringify(locations));
document.loadLocations();
}
const params = new URLSearchParams(window.location.search); const params = new URLSearchParams(window.location.search);
const searchQuery = params.get('query'); const searchQuery = params.get('query');
if (searchQuery) { if (searchQuery) {
document.querySelector('#query').value = searchQuery; document.querySelector('#query').value = searchQuery;
} else {
document.loadLocations();
} }
document.addEventListener("DOMContentLoaded", (event) => {
weatherLocationManager.loadLocations('#storedLocations');
});
})(); })();
</script> </script>
{% endblock %} {% endblock %}

View File

@@ -66,7 +66,8 @@
data-bs-toggle="tooltip" data-bs-toggle="tooltip"
data-bs-title="{{ value.sky }}"> data-bs-title="{{ value.sky }}">
{% for icon in value.sky | cloudness_icon(value.date, response.period) %} {% for icon in value.sky | cloudness_icon(value.date, response.period) %}
<div class="wi wi-{{icon}} wi-xl text-primary"></div> <div class="wi-svg wi-l wi-border"
style="margin: 0 auto;">{{ icon | weather_icon_svg }}</div>
{% endfor %} {% endfor %}
</td> </td>
{% endfor %} {% endfor %}
@@ -102,7 +103,8 @@
<td class="wind" <td class="wind"
data-bs-toggle="tooltip" data-bs-toggle="tooltip"
data-bs-title="{{ value.wind_direction }}"> data-bs-title="{{ value.wind_direction }}">
<div class="wi wi-wind-deg wi-{{value.wind_direction | wind_direction_icon}} wi-l text-primary"></div> <div class="wi-svg wi-s wi-{{value.wind_direction | wind_direction_icon}}"
style="margin: 0 auto;">{{ 'wind-deg' | weather_icon_svg }}</div>
</td> </td>
{% endfor %} {% endfor %}
</tr> </tr>
@@ -137,7 +139,7 @@
{% for value in response.values %} {% for value in response.values %}
<td class="precipitation" <td class="precipitation"
style="background-color: rgba(0, 128, 255, {{value.precipitation * 0.1}});"> style="background-color: rgba(0, 128, 255, {{value.precipitation * 0.1}});">
<span class="value">{{value.precipitation or ''}}</span> <span class="value">{{(value.precipitation | round(2)) if value.precipitation else ''}}</span>
</td> </td>
{% endfor %} {% endfor %}
</tr> </tr>

View File

@@ -85,11 +85,14 @@ class GismeteoApi(WeatherApi):
Location( Location(
id=f"{item['slug']}-{item['id']}", id=f"{item['slug']}-{item['id']}",
name=item["translations"]["kk"]["city"]["name"], name=item["translations"]["kk"]["city"]["name"],
provider=self.provider,
lat=item["coordinates"]["latitude"], lat=item["coordinates"]["latitude"],
lon=item["coordinates"]["longitude"], lon=item["coordinates"]["longitude"],
country=item["translations"]["kk"]["country"]["name"], country=item["translations"]["kk"]["country"]["name"],
country_code=item["country"]["code"].lower(), country_code=item["country"]["code"].lower(),
district=item["translations"]["kk"]["district"]["name"], district=(
item["translations"]["kk"]["district"]["name"] if item["translations"]["kk"]["district"] else ""
),
subdistrict=( subdistrict=(
item["translations"]["kk"]["subdistrict"]["name"] item["translations"]["kk"]["subdistrict"]["name"]
if "subdistrict" in item["translations"]["kk"] if "subdistrict" in item["translations"]["kk"]

View File

@@ -39,14 +39,11 @@ class DateParser(RowParser[datetime.datetime]):
KEY = "date" KEY = "date"
def parse_row(self, tag: Tag) -> Iterable[datetime.datetime]: def parse_row(self, tag: Tag) -> Iterable[datetime.datetime]:
datetime_date_tag = tag.select_one(".widget-row.widget-row-datetime-date > .row-item") datetime_time_row = tag.select_one(".widget-row.widget-row-datetime-time")
if datetime_date_tag: if datetime_time_row:
date_str = datetime_date_tag.find(text=True, recursive=False).text for item in datetime_time_row.select(".row-item > time-value"):
date = dateparser.parse(date_str, languages=["ru"]) timestamp = int(item.attrs["timestamp"])
for item in tag.select(".widget-row.widget-row-datetime-time > .row-item"): time = datetime.datetime.fromtimestamp(timestamp)
time_str = item.text
time = dateparser.parse(time_str, languages=["ru"])
time = time.replace(year=date.year, month=date.month, day=date.day)
yield time yield time
else: else:
for item in tag.select(".widget-row.widget-row-date > .row-item"): for item in tag.select(".widget-row.widget-row-date > .row-item"):
@@ -68,21 +65,21 @@ class SkyParser(RowParser[Sky]):
PRECIPITATION_MAP: dict[str, Precipitation] = { PRECIPITATION_MAP: dict[str, Precipitation] = {
"без осадков": Precipitation.NO, "без осадков": Precipitation.NO,
"небольшой дождь": Precipitation.SMALL_RAIN, # TODO: remove it?
"небольшой дождь": Precipitation.SMALL_RAIN, "небольшой дождь": Precipitation.SMALL_RAIN,
"сильный дождь": Precipitation.HEAVY_RAIN, # TODO: remove it?
"сильный дождь": Precipitation.HEAVY_RAIN, "сильный дождь": Precipitation.HEAVY_RAIN,
"очень сильный дождь": Precipitation.HEAVY_RAIN,
"ливневый дождь": Precipitation.SHOWER, "ливневый дождь": Precipitation.SHOWER,
"дождь": Precipitation.RAIN, "дождь": Precipitation.RAIN,
"ливень": Precipitation.SHOWER, "ливень": Precipitation.SHOWER,
"снег": Precipitation.SNOW, "снег": Precipitation.SNOW,
"небольшой снег": Precipitation.SNOW, "небольшой снег": Precipitation.SNOW,
"сильный снег": Precipitation.HEAVY_SNOW, "сильный снег": Precipitation.HEAVY_SNOW,
"мокрый снег": Precipitation.SNOW, "мокрый снег": Precipitation.SNOW,
"снег с дождём": Precipitation.SNOW, "снег с дождём": Precipitation.SNOW,
"сильный снег с дождём": Precipitation.HEAVY_SNOW, "сильный снег с дождём": Precipitation.HEAVY_SNOW,
"небольшой снег с дождём": Precipitation.SNOW, "небольшой снег с дождём": Precipitation.SNOW,
"небольшой мокрый снег": Precipitation.SNOW, "небольшой мокрый снег": Precipitation.SNOW,
"град": Precipitation.HAIL,
} }
THUNDER = "гроза" THUNDER = "гроза"
@@ -152,6 +149,7 @@ class WindDirectionParser(RowParser[WindDirection]):
WIND_DIRECTION_MAP: dict[str, WindDirection] = { WIND_DIRECTION_MAP: dict[str, WindDirection] = {
"": WindDirection.CALM, "": WindDirection.CALM,
"": WindDirection.CALM,
"штиль": WindDirection.CALM, "штиль": WindDirection.CALM,
"с": WindDirection.N, "с": WindDirection.N,
"св": WindDirection.NE, "св": WindDirection.NE,
@@ -173,8 +171,12 @@ class PrecipitationParser(RowParser[float]):
KEY = "precipitation" KEY = "precipitation"
def parse_row(self, tag: Tag) -> Iterable[float]: def parse_row(self, tag: Tag) -> Iterable[float]:
for item in tag.select(".widget-row[data-row=precipitation-bars] > .row-item > .item-unit"): for item in tag.select(".widget-row[data-row=precipitation-bars] > .row-item"):
yield float(item.text.replace(",", ".")) value = item.select_one("precipitation-value")
if value:
yield float(value.attrs["value"])
else:
yield 0
class PressureParser(RowParser[list[int]]): class PressureParser(RowParser[list[int]]):

View File

@@ -1,10 +1,9 @@
import datetime import datetime
import json
import logging import logging
from bs4 import BeautifulSoup
from gallery.sketch.schedule.api import ScheduleApi from gallery.sketch.schedule.api import ScheduleApi
from gallery.sketch.schedule.model import Channel, ChannelId, Schedule, ScheduleValue from gallery.sketch.schedule.model import Channel, Schedule, ScheduleValue
from gallery.sketch.source import ApiSource from gallery.sketch.source import ApiSource
logger = logging.getLogger("matchtv") logger = logging.getLogger("matchtv")
@@ -14,31 +13,30 @@ class MatchTvApi(ScheduleApi):
PROVIDER = "matchtv" PROVIDER = "matchtv"
SOURCE = ApiSource("https://matchtv.ru") SOURCE = ApiSource("https://matchtv.ru")
async def get_channels(self) -> list[ChannelId]: async def find_channels(self, query: str) -> list[Channel]:
return [ endpoint = "api/v1/channels"
ChannelId.MATCH_TV, data = json.loads(await self.SOURCE.request(endpoint))
ChannelId.MATCH_IGRA, result = []
ChannelId.MATCH_ARENA, query = query.lower()
ChannelId.MATCH_FUTBOL_1, for item in data["result"]:
ChannelId.MATCH_FUTBOL_2, if query in item["name"].lower() or query in item["alias"]:
ChannelId.MATCH_FUTBOL_3, channel_id = item["alias"]
ChannelId.MATCH_STRANA, name = item["name"].split("|")[0].strip()
] result.append(Channel(id=channel_id, name=name, provider=self.provider))
return result
async def get_channel_schedule(self, channel_id: ChannelId, date: datetime.date) -> Schedule: async def get_schedule(self, channel_id: str, date: datetime.date) -> Schedule:
endpoint = f"tvguide/{channel_id}?date={date:%Y%m%d}" endpoint = f"api/v1/channels/{channel_id}/tv-schedule?date={date:%Y%m%d}"
data = await self.SOURCE.request(endpoint) data = json.loads(await self.SOURCE.request(endpoint))
soup = BeautifulSoup(data, features="html.parser") channel_data = data["result"]["channels"][0]
channel = Channel(id=channel_data["alias"], name=channel_data["name"], provider=self.provider)
values = [] values = []
channel_name = soup.select_one(".p-tv-guide-header__title").text.replace("Телепрограмма ", "").strip()
current_day = datetime.datetime.combine(date.today(), datetime.datetime.min.time()) current_day = datetime.datetime.combine(date.today(), datetime.datetime.min.time())
end = current_day + datetime.timedelta(days=1, hours=6) end = current_day + datetime.timedelta(days=1, hours=6)
prev_value: ScheduleValue | None = None prev_value: ScheduleValue | None = None
for item in soup.select( for item in channel_data["schedule"]:
".p-tv-guide-schedule-channel-carcass__transmissions .p-tv-guide-schedule-channel-transmission" title = item["title"]
): time_str = item["time"]
title = item.select_one(".p-tv-guide-schedule-channel-transmission__title").text.strip()
time_str = item.select_one(".p-tv-guide-schedule-channel-transmission__time-block").text.strip()
hours, minutes = map(int, time_str.split(":")) hours, minutes = map(int, time_str.split(":"))
item_date = current_day.replace(hour=hours, minute=minutes) item_date = current_day.replace(hour=hours, minute=minutes)
if prev_value is not None and item_date.hour < prev_value.start.hour: if prev_value is not None and item_date.hour < prev_value.start.hour:
@@ -50,4 +48,8 @@ class MatchTvApi(ScheduleApi):
if prev_value is not None: if prev_value is not None:
prev_value.end = item_date prev_value.end = item_date
prev_value = value prev_value = value
return Schedule(channel=Channel(id=channel_id, name=channel_name), date=date, values=values) return Schedule(
channel=channel,
date=date,
values=values,
)

View File

@@ -1,6 +1,7 @@
import datetime import datetime
import logging import logging
from collections import defaultdict from collections import defaultdict
from os import environ
from aiocache import cached from aiocache import cached
@@ -9,7 +10,9 @@ from gallery.sketch.weather.model import Location, WeatherResponse, WeatherValue
from gallery.sketch.weather.util import merge_weather_values from gallery.sketch.weather.util import merge_weather_values
from gallery.util import TimeUnit from gallery.util import TimeUnit
from .openweather import Forecast, OpenWeather from .openweather import Forecast
from .openweather import Location as OpenWeatherLocation
from .openweather import OpenWeather
from .parser import FORECAST_ITEM_PARSER from .parser import FORECAST_ITEM_PARSER
logger = logging.getLogger("openweather") logger = logging.getLogger("openweather")
@@ -17,12 +20,20 @@ logger = logging.getLogger("openweather")
class OpenWeatherApi(WeatherApi): class OpenWeatherApi(WeatherApi):
PROVIDER = "openweather" PROVIDER = "openweather"
SOURCE = OpenWeather("517a6bccceaa1c48127f6199ec3fb7cf") SOURCE = OpenWeather(environ["OPENWEATHER_KEY"])
@classmethod @classmethod
def _parse_location(cls, location_id: str) -> tuple[float, float]: def _parse_location(cls, location_id: str) -> tuple[float, float]:
return tuple(map(float, location_id.split(":", maxsplit=2))) return tuple(map(float, location_id.split(":", maxsplit=2)))
@cached(
key_builder=lambda fun, self, location_id: f"api.weather.{self.provider}.source.{location_id}.location",
alias="redis",
ttl=TimeUnit.DAY,
)
async def _get_location(self, location_id: str) -> OpenWeatherLocation:
return await self.SOURCE.get_location(*self._parse_location(location_id))
@cached( @cached(
key_builder=lambda fun, self, location_id: f"api.weather.{self.provider}.source.{location_id}.forecast", key_builder=lambda fun, self, location_id: f"api.weather.{self.provider}.source.{location_id}.forecast",
alias="redis", alias="redis",
@@ -32,9 +43,24 @@ class OpenWeatherApi(WeatherApi):
return await self.SOURCE.get_forecast(*self._parse_location(location_id)) return await self.SOURCE.get_forecast(*self._parse_location(location_id))
async def find_locations(self, query: str) -> list[Location]: async def find_locations(self, query: str) -> list[Location]:
raise NotImplementedError result = await self.SOURCE.find_locations(query)
return [
Location(
id=f"{item.lat}:{item.lon}",
name=item.name,
provider=self.provider,
lat=item.lat,
lon=item.lon,
country=item.country,
country_code=item.country.lower(),
district=item.state or "",
subdistrict="",
)
for item in result
]
async def get_day(self, location_id: str, date: datetime.date) -> WeatherResponse: async def get_day(self, location_id: str, date: datetime.date) -> WeatherResponse:
location: OpenWeatherLocation = await self._get_location(location_id)
data: Forecast = await self._get_location_forecast(location_id) data: Forecast = await self._get_location_forecast(location_id)
values = [] values = []
for item in data.list: for item in data.list:
@@ -42,13 +68,14 @@ class OpenWeatherApi(WeatherApi):
if value.date.date() == date: if value.date.date() == date:
values.append(value) values.append(value)
return WeatherResponse( return WeatherResponse(
location=location_id, location=location.name,
date=date, date=date,
period="day", period="day",
values=values, values=values,
) )
async def get_days(self, location_id: str, days: int) -> WeatherResponse: async def get_days(self, location_id: str, days: int) -> WeatherResponse:
location: OpenWeatherLocation = await self._get_location(location_id)
data: Forecast = await self._get_location_forecast(location_id) data: Forecast = await self._get_location_forecast(location_id)
values_by_date: dict[datetime.datetime, list[WeatherValue]] = defaultdict(list) values_by_date: dict[datetime.datetime, list[WeatherValue]] = defaultdict(list)
for item in data.list: for item in data.list:
@@ -57,7 +84,7 @@ class OpenWeatherApi(WeatherApi):
values_by_date[item_date].append(value) values_by_date[item_date].append(value)
values = [merge_weather_values(date, values) for date, values in values_by_date.items()] values = [merge_weather_values(date, values) for date, values in values_by_date.items()]
return WeatherResponse( return WeatherResponse(
location=location_id, location=location.name,
date=datetime.date.today(), date=datetime.date.today(),
period="days", period="days",
values=list(sorted(values, key=lambda item: item.date)), values=list(sorted(values, key=lambda item: item.date)),

View File

@@ -53,7 +53,7 @@ class ForecastItem(Model):
weather: list[Weather] weather: list[Weather]
clouds: Clouds clouds: Clouds
wind: Wind wind: Wind
visibility: int visibility: int | None = None
pop: float pop: float
rain: Rain | None = None rain: Rain | None = None
sys: Sys sys: Sys
@@ -67,6 +67,15 @@ class Forecast(Model):
list: list[ForecastItem] list: list[ForecastItem]
class Location(Model):
name: str
lat: float
lon: float
country: str
state: str | None = None
local_names: dict[str, str] | None = None
class OpenWeather: class OpenWeather:
BASE_URL = "https://api.openweathermap.org" BASE_URL = "https://api.openweathermap.org"
@@ -78,4 +87,17 @@ class OpenWeather:
endpoint = f"data/2.5/forecast?lat={lat}&lon={lon}&appid={self._api_key}&units=metric" endpoint = f"data/2.5/forecast?lat={lat}&lon={lon}&appid={self._api_key}&units=metric"
response = await self._source.request(endpoint) response = await self._source.request(endpoint)
response_data = json.loads(response) response_data = json.loads(response)
return Forecast(**response_data) return Forecast.model_validate(response_data)
async def find_locations(self, query: str, limit: int = 5) -> list[Location]:
endpoint = f"geo/1.0/direct?q={query}&limit={limit}&appid={self._api_key}"
response = await self._source.request(endpoint)
response_data = json.loads(response)
return [Location.model_validate(item) for item in response_data]
async def get_location(self, lat: float, lon: float) -> Location:
limit = 1
endpoint = f"geo/1.0/reverse?lat={lat}&lon={lon}&limit={limit}&appid={self._api_key}"
response = await self._source.request(endpoint)
response_data = json.loads(response)
return Location.model_validate(response_data[0])

View File

@@ -1,27 +1,15 @@
import datetime import datetime
import json
import logging import logging
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
from gallery.sketch.schedule.api import ScheduleApi from gallery.sketch.schedule.api import ScheduleApi
from gallery.sketch.schedule.model import Channel, ChannelId, Schedule, ScheduleValue from gallery.sketch.schedule.model import Channel, Schedule, ScheduleValue
from gallery.sketch.source import ApiSource from gallery.sketch.source import ApiSource
logger = logging.getLogger("matchtv") logger = logging.getLogger("matchtv")
CHANNELS_MAP: dict[ChannelId, str] = {
ChannelId.MATCH_TV: "match-tv-49",
ChannelId.MATCH_IGRA: "match-igra-1174",
ChannelId.MATCH_ARENA: "match-arena-1173",
ChannelId.MATCH_FUTBOL_1: "match-futbol-1-646",
ChannelId.MATCH_FUTBOL_2: "match-futbol-2-593",
ChannelId.MATCH_FUTBOL_3: "match-futbol-3-797",
ChannelId.MATCH_STRANA: "match-strana-1356",
ChannelId.MATCH_PLANETA: "match-planeta-1177",
# ChannelId.EUROSPORT: "eurosport-677",
# ChannelId.EUROSPORT_2: "eurosport-2-720",
ChannelId.START: "start-103",
}
HEADERS: dict[str, str] = { HEADERS: dict[str, str] = {
"Accept": ( "Accept": (
@@ -57,11 +45,21 @@ class YandexTvApi(ScheduleApi):
PROVIDER = "yandextv" PROVIDER = "yandextv"
SOURCE = ApiSource("https://tv.yandex.ru", headers=HEADERS) SOURCE = ApiSource("https://tv.yandex.ru", headers=HEADERS)
async def get_channels(self) -> list[ChannelId]: async def find_channels(self, query: str) -> list[Channel]:
return list(CHANNELS_MAP.keys()) url = (
"https://suggest-multi.yandex.ru/suggest-tv2?"
f"v=4&uil=ru&lr=10&count_channels=4&count_programs=4&sn=50&part={query}"
)
_, values = json.loads(await self.SOURCE.request(url))
result = []
for _, name, content in values:
if content["label"] == "Каналы":
channel_id = content["url"].split("/")[-1]
result.append(Channel(id=channel_id, name=name, provider=self.provider))
return result
async def get_channel_schedule(self, channel_id: ChannelId, date: datetime.date) -> Schedule: async def get_schedule(self, channel_id: str, date: datetime.date) -> Schedule:
endpoint = f"channel/{CHANNELS_MAP[channel_id]}?date={date:%Y-%m-%d}" endpoint = f"channels/{channel_id}?date={date:%Y-%m-%d}"
data = await self.SOURCE.request(endpoint) data = await self.SOURCE.request(endpoint)
soup = BeautifulSoup(data, features="html.parser") soup = BeautifulSoup(data, features="html.parser")
if soup.select_one(".CheckboxCaptcha") is not None: if soup.select_one(".CheckboxCaptcha") is not None:
@@ -85,4 +83,8 @@ class YandexTvApi(ScheduleApi):
if prev_value is not None: if prev_value is not None:
prev_value.end = item_date prev_value.end = item_date
prev_value = value prev_value = value
return Schedule(channel=Channel(id=channel_id, name=channel_name), date=date, values=values) return Schedule(
channel=Channel(id=channel_id, name=channel_name, provider=self.provider),
date=date,
values=values,
)

View File

@@ -2,8 +2,13 @@ from typing import TypeVar
class Api: class Api:
TYPE: str
PROVIDER: str PROVIDER: str
@property
def type(self) -> str:
return self.TYPE
@property @property
def provider(self) -> str: def provider(self) -> str:
return self.PROVIDER return self.PROVIDER

View File

@@ -1,28 +1,19 @@
from collections import defaultdict
from .api import API, Api from .api import API, Api
from .schedule.api import ScheduleApi
from .weather.api import WeatherApi
class ApiBundle(list[Api]): class ApiBundle:
def __init__(self, values: list[Api]) -> None: def __init__(self, values: list[Api]):
super().__init__(values) self._values = values
self._providers_by_api = defaultdict(list)
self._api_map = {}
for value in self._values:
self._providers_by_api[value.type].append(value.provider)
self._api_map[(value.type, value.provider)] = value
def get_api_by_provider(self, provider: str) -> Api: def get_api_providers(self, api_type: type[API]) -> list[str]:
for value in self: return self._providers_by_api[api_type.TYPE]
if value.PROVIDER == provider:
return value
raise ValueError(provider)
def get_api_by_type(self, api_type: type[API]) -> API: def get_api(self, api_type: type[API], provider: str) -> API:
for value in self: return self._api_map[(api_type.TYPE, provider)]
if isinstance(value, api_type):
return value
raise ValueError(api_type)
@property
def weather(self) -> WeatherApi:
return self.get_api_by_type(WeatherApi)
@property
def schedule(self) -> ScheduleApi:
return self.get_api_by_type(ScheduleApi)

View File

@@ -1,14 +0,0 @@
from typing import Generic, TypeVar
T = TypeVar("T")
class CatalogBundle(Generic[T]):
def __init__(self, items: list[T]) -> None:
self._items_by_id = {item.id: item for item in items}
def get_item(self, item_id: str) -> T:
return self._items_by_id[item_id]
def select_items(self, ids: list[str]) -> list[T]:
return [self._items_by_id[id_] for id_ in ids]

View File

@@ -1,24 +1,14 @@
import asyncio
import datetime import datetime
from ..api import Api from ..api import Api
from .model import ChannelId, Schedule from .model import Channel, Schedule
class ScheduleApi(Api): class ScheduleApi(Api):
INTERVAL: float = 0.5 TYPE = "schedule"
async def get_channels(self) -> list[ChannelId]: async def find_channels(self, query: str) -> list[Channel]:
raise NotImplementedError raise NotImplementedError
async def get_channel_schedule(self, channel_id: ChannelId, date: datetime.date) -> Schedule: async def get_schedule(self, channel_id: str, date: datetime.date) -> Schedule:
raise NotImplementedError raise NotImplementedError
async def get_all_schedules(self, date: datetime.date) -> list[Schedule]:
channels = await self.get_channels()
results = []
for channel in channels:
results.append(await self.get_channel_schedule(channel_id=channel, date=date))
if self.INTERVAL > 0:
await asyncio.sleep(self.INTERVAL)
return results

View File

@@ -6,20 +6,20 @@ from gallery.sketch.cached import CachedApi, CachePreset
from gallery.util import TimeUnit from gallery.util import TimeUnit
from .api import ScheduleApi from .api import ScheduleApi
from .model import ChannelId, Schedule from .model import Channel, Schedule
CACHE_PRESET = CachePreset(ttl=TimeUnit.HOUR * 6) CACHE_PRESET = CachePreset(ttl=TimeUnit.HOUR * 6)
class CachedScheduleApi(ScheduleApi, CachedApi[ScheduleApi]): class CachedScheduleApi(ScheduleApi, CachedApi[ScheduleApi]):
CACHE_KEY = "schedule" CACHE_KEY = ScheduleApi.TYPE
@cached( @cached(
key_builder=lambda fun, self: f"api.{self.CACHE_KEY}.{self.provider}.channels", key_builder=lambda fun, self, query: f"api.{self.CACHE_KEY}.{self.provider}.find.{query}",
**CACHE_PRESET._asdict(), **CACHE_PRESET._asdict(),
) )
async def get_channels(self) -> list[ChannelId]: async def find_channels(self, query: str) -> list[Channel]:
return await self._api.get_channels() return await self._api.find_channels(query)
@cached( @cached(
key_builder=lambda fun, self, channel_id, date: ( key_builder=lambda fun, self, channel_id, date: (
@@ -27,12 +27,5 @@ class CachedScheduleApi(ScheduleApi, CachedApi[ScheduleApi]):
), ),
**CACHE_PRESET._asdict(), **CACHE_PRESET._asdict(),
) )
async def get_channel_schedule(self, channel_id: ChannelId, date: datetime.date) -> Schedule: async def get_schedule(self, channel_id: str, date: datetime.date) -> Schedule:
return await self._api.get_channel_schedule(channel_id, date) return await self._api.get_schedule(channel_id, date)
@cached(
key_builder=lambda fun, self, date: (f"api.{self.CACHE_KEY}.{self.provider}.all.{date}"),
**CACHE_PRESET._asdict(),
)
async def get_all_schedules(self, date: datetime.date) -> list[Schedule]:
return await self._api.get_all_schedules(date)

View File

@@ -1,21 +0,0 @@
from gallery.sketch.catalog import CatalogBundle
from .model import Channel, ChannelId
BUNDLE = CatalogBundle(
[
Channel(id=ChannelId.MATCH_TV, name="Матч ТВ"),
Channel(id=ChannelId.MATCH_IGRA, name="Матч! Игра"),
Channel(id=ChannelId.MATCH_ARENA, name="Матч! Арена"),
Channel(id=ChannelId.MATCH_FUTBOL_1, name="Футбол 1"),
Channel(id=ChannelId.MATCH_FUTBOL_2, name="Футбол 2"),
Channel(id=ChannelId.MATCH_FUTBOL_3, name="Футбол 3"),
Channel(id=ChannelId.MATCH_STRANA, name="Матч! Страна"),
Channel(id=ChannelId.MATCH_PLANETA, name="Матч! Планета"),
Channel(id=ChannelId.MATCH_PLANETA, name="Матч! Планета"),
Channel(id=ChannelId.EUROSPORT, name="Europsort"),
Channel(id=ChannelId.EUROSPORT_2, name="Europsort 2"),
Channel(id=ChannelId.START, name="Старт!"),
Channel(id=ChannelId.TEST, name="Тест"),
]
)

View File

@@ -1,5 +1,4 @@
import datetime import datetime
from enum import StrEnum
from pydantic import BaseModel from pydantic import BaseModel
@@ -9,27 +8,10 @@ class Model(BaseModel):
use_enum_values = True use_enum_values = True
class ChannelId(StrEnum):
MATCH_TV = "matchtv"
MATCH_IGRA = "igra"
MATCH_ARENA = "arena"
MATCH_FUTBOL_1 = "futbol-1"
MATCH_FUTBOL_2 = "futbol-2"
MATCH_FUTBOL_3 = "futbol-3"
MATCH_STRANA = "strana"
MATCH_PLANETA = "planeta"
EUROSPORT = "eurosport"
EUROSPORT_2 = "eurosport-2"
START = "start"
TEST = "test"
def __str__(self) -> str:
return self.value
class Channel(Model): class Channel(Model):
id: ChannelId id: str
name: str name: str
provider: str
class ScheduleValue(Model): class ScheduleValue(Model):

View File

@@ -26,7 +26,10 @@ class ApiSource:
self._headers = headers self._headers = headers
async def request(self, endpoint: str) -> str: async def request(self, endpoint: str) -> str:
url = f"{self._base_url}/{endpoint}" if endpoint.startswith("https:"):
url = endpoint
else:
url = f"{self._base_url}/{endpoint}"
logger.info(url) logger.info(url)
headers = {"User-Agent": self._user_agent, **(self._headers or {})} headers = {"User-Agent": self._user_agent, **(self._headers or {})}
async with aiohttp.ClientSession( async with aiohttp.ClientSession(

View File

@@ -5,6 +5,7 @@ from .model import Location, WeatherResponse
class WeatherApi(Api): class WeatherApi(Api):
TYPE = "weather"
async def find_locations(self, query: str) -> list[Location]: async def find_locations(self, query: str) -> list[Location]:
raise NotImplementedError raise NotImplementedError

View File

@@ -11,7 +11,7 @@ CACHE_PRESET = DEFAULT_CACHE_PRESET
class CachedWeatherApi(WeatherApi, CachedApi[WeatherApi]): class CachedWeatherApi(WeatherApi, CachedApi[WeatherApi]):
CACHE_KEY = "weather" CACHE_KEY = WeatherApi.TYPE
@cached( @cached(
key_builder=lambda fun, self, query: f"api.{self.CACHE_KEY}.{self.provider}.locations.{query}", key_builder=lambda fun, self, query: f"api.{self.CACHE_KEY}.{self.provider}.locations.{query}",

View File

@@ -1,5 +1,6 @@
import datetime import datetime
from enum import Enum from enum import StrEnum, auto
from typing import Self
from pydantic import BaseModel from pydantic import BaseModel
@@ -12,6 +13,7 @@ class Model(BaseModel):
class Location(Model): class Location(Model):
id: str id: str
name: str name: str
provider: str
lat: float lat: float
lon: float lon: float
country: str country: str
@@ -20,21 +22,22 @@ class Location(Model):
subdistrict: str subdistrict: str
class Cloudness(str, Enum): class Cloudness(StrEnum):
CLEAR = "clear" CLEAR = auto()
PARTLY_CLOUDY = "party_cloudy" PARTLY_CLOUDY = auto()
CLOUDY = "cloudy" CLOUDY = auto()
MAINLY_CLOUDY = "mainly_cloudy" MAINLY_CLOUDY = auto()
class Precipitation(str, Enum): class Precipitation(StrEnum):
NO = "no" NO = auto()
SMALL_RAIN = "small_rain" SMALL_RAIN = auto()
RAIN = "rain" RAIN = auto()
HEAVY_RAIN = "heavy_rain" HEAVY_RAIN = auto()
SHOWER = "shower" SHOWER = auto()
SNOW = "snow" SNOW = auto()
HEAVY_SNOW = "heavy_snow" HEAVY_SNOW = auto()
HAIL = auto()
class Sky(Model): class Sky(Model):
@@ -44,16 +47,16 @@ class Sky(Model):
fog: bool fog: bool
class WindDirection(str, Enum): class WindDirection(StrEnum):
CALM = "calm" CALM = auto()
N = "N" N = auto()
NE = "NE" NE = auto()
E = "E" E = auto()
SE = "SE" SE = auto()
S = "S" S = auto()
SW = "SW" SW = auto()
W = "W" W = auto()
NW = "NW" NW = auto()
class WindDirectionDeg(float): class WindDirectionDeg(float):
@@ -89,7 +92,7 @@ class WindDirectionDeg(float):
raise ValueError(self) raise ValueError(self)
@classmethod @classmethod
def from_direction(cls, direction: WindDirection) -> "WindDirectionDeg": def from_direction(cls, direction: WindDirection) -> Self:
return cls( return cls(
{ {
WindDirection.CALM: -1, WindDirection.CALM: -1,

View File

@@ -1,5 +1,3 @@
__version__ = "0.2.2"
import tomllib import tomllib
from pathlib import Path from pathlib import Path

2989
poetry.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,40 +1,40 @@
[tool.poetry] [project]
name = "gallery" name = "gallery"
version = "0.3.0"
description = "" description = ""
authors = ["shmyga <shmyga.z@gmail.com>"] version = "0.5.2"
readme = "README.md" readme = "README.md"
authors = [{ name = "shmyga", email = "shmyga.z@gmail.com" }]
requires-python = '>=3.14,<4.0'
dependencies = [
'aiohttp (>=3.14,<4.0)',
'beautifulsoup4 (>=4.15,<5.0)',
'dateparser (>=1.4,<2.0)',
'pydantic (>=2.13,<3.0)',
'aiocache[redis] (>=0.12,<0.13)',
]
[project.optional-dependencies]
app = [
"fastapi[standard] (>=0.139,<0.140)",
"jinja2 (>=3.1,<4.0)",
"babel (>=2.18,<3.0)",
]
[dependency-groups]
test = ["pytest (>=9.1,<10.0)", "pytest-asyncio (>=1.4,<2.0)"]
dev = ["pylint (>=4.0.6,<5.0.0)", "black (>=26.5,<27.0)", "isort (>=8.0,<9.0)"]
[project.scripts]
gallery = "gallery.main:run"
[tool.poetry]
packages = [{ include = "gallery" }] packages = [{ include = "gallery" }]
requires-poetry = '>=2.0.0,<3.0.0'
[tool.poetry.dependencies]
python = "^3.12"
aiohttp = "^3.9.5"
beautifulsoup4 = "^4.12.3"
dateparser = "^1.2.0"
pydantic = "^2.8.2"
aiocache = { extras = ["redis"], version = "^0.12.2" }
[tool.poetry.group.app.dependencies]
fastapi = "^0.111.1"
jinja2 = "^3.1.4"
babel = "^2.18.0"
[tool.poetry.group.test.dependencies]
pytest = "^8.3.1"
pytest-asyncio = "^0.23.8"
[tool.poetry.group.dev.dependencies]
pylint = "^3.2.6"
black = "^24.4.2"
isort = "^5.13.2"
[build-system] [build-system]
requires = ["poetry-core"] requires = ['poetry-core (>=2.0.0,<3.0.0)']
build-backend = "poetry.core.masonry.api" build-backend = "poetry.core.masonry.api"
[tool.poetry.scripts]
gallery = "gallery.main:run"
[tool.black] [tool.black]
line-length = 120 line-length = 120

View File

@@ -29,9 +29,19 @@ publish () {
for PROJECT in "${DOCKER_PROJECTS[@]}"; do for PROJECT in "${DOCKER_PROJECTS[@]}"; do
IFS=: read -r PROJECT_NAME PROJECT_TARGET <<< "$PROJECT" IFS=: read -r PROJECT_NAME PROJECT_TARGET <<< "$PROJECT"
docker tag $DOCKER_GROUP/$PROJECT_NAME $DOCKER_ROOT/$PROJECT_NAME:$VERSION docker tag $DOCKER_GROUP/$PROJECT_NAME $DOCKER_ROOT/$PROJECT_NAME:$VERSION
docker tag $DOCKER_GROUP/$PROJECT_NAME $DOCKER_ROOT/$PROJECT_NAME:latest docker tag $DOCKER_GROUP/$PROJECT_NAME $DOCKER_ROOT/$PROJECT_NAME:$DOCKER_TAG
docker push $DOCKER_ROOT/$PROJECT_NAME:$VERSION docker push $DOCKER_ROOT/$PROJECT_NAME:$VERSION
docker push $DOCKER_ROOT/$PROJECT_NAME:latest docker push $DOCKER_ROOT/$PROJECT_NAME:$DOCKER_TAG
done
}
save () {
echo "save: $1"
. "$1/.env"
mkdir -p "$1/dist"
for PROJECT in "${DOCKER_PROJECTS[@]}"; do
IFS=: read -r PROJECT_NAME PROJECT_TARGET <<< "$PROJECT"
docker save --output "$1/dist/$PROJECT_NAME-$VERSION.tar" "$DOCKER_GROUP/$PROJECT_NAME"
done done
} }

View File

@@ -4,6 +4,6 @@ cd "$(dirname $(dirname "$0"))" || exit
TARGET="gallery" TARGET="gallery"
poetry run pylint $TARGET poetry run pylint $TARGET -sn
poetry run isort $TARGET --check-only poetry run isort $TARGET --check-only
poetry run black $TARGET -q --check --diff poetry run black $TARGET -q --check --diff

View File

@@ -2,14 +2,21 @@
set -e set -e
cd "$(dirname $(dirname "$0"))" || exit cd "$(dirname $(dirname "$0"))" || exit
PYTHON_VERSION=3.12 # env
if [[ ! -f .env ]]; then
cp .env-base .env
fi
source .env
# python
poetry env use ${PYTHON_VERSION} poetry env use ${PYTHON_VERSION}
poetry install poetry install
# static
cd static || exit cd static || exit
if [[ -f $HOME/.nvm/nvm.sh ]]; then if [[ -f $HOME/.nvm/nvm.sh ]]; then
source "$HOME/.nvm/nvm.sh" source "$HOME/.nvm/nvm.sh"
nvm use nvm use
fi fi
npm ci npm ci

View File

@@ -2,4 +2,4 @@
set -e set -e
cd "$(dirname $(dirname "$0"))" || exit cd "$(dirname $(dirname "$0"))" || exit
poetry run pytest tests OPENWEATHER_KEY="" poetry run pytest tests

4599
static/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,9 +1,10 @@
{ {
"name": "gallery", "name": "gallery",
"version": "0.3.0", "version": "0.5.2",
"type": "module",
"scripts": { "scripts": {
"build": "vite build", "build": "webpack --mode production",
"dev": "vite build --watch" "dev": "webpack --watch --mode development"
}, },
"author": "shmyga <shmyga.z@gmail.com>", "author": "shmyga <shmyga.z@gmail.com>",
"license": "ISC", "license": "ISC",
@@ -12,10 +13,32 @@
"@popperjs/core": "^2.11.8", "@popperjs/core": "^2.11.8",
"bootstrap": "^5.3.8", "bootstrap": "^5.3.8",
"bootstrap-icons": "^1.13.1", "bootstrap-icons": "^1.13.1",
"flag-icons": "^7.5.0", "flag-icons": "^7.5.0"
"sass": "^1.99.0"
}, },
"devDependencies": { "devDependencies": {
"vite": "^8.0.9" "@babel/core": "^8.0.1",
} "@babel/preset-env": "^8.0.2",
"@types/bootstrap": "^5.2.11",
"@types/node": "^26.1.0",
"babel-loader": "^10.1.1",
"copy-webpack-plugin": "^14.0.0",
"core-js": "^3.49.0",
"css-loader": "^7.1.4",
"file-loader": "^6.2.0",
"mini-css-extract-plugin": "^2.10.2",
"postcss": "^8.5.22",
"postcss-loader": "^8.2.1",
"sass": "^1.101.0",
"sass-loader": "^17.0.0",
"style-loader": "^4.0.0",
"ts-loader": "^9.6.2",
"ts-node": "^10.9.2",
"typescript": "^6.0.3",
"webpack": "^5.108.3",
"webpack-cli": "^7.1.0"
},
"browserslist": [
"> 0.5%",
"last 2 versions"
]
} }

View File

@@ -19,7 +19,7 @@
setLanguage(getPreferredLanguage()); setLanguage(getPreferredLanguage());
const showActiveLanguage = (language: string, focus = false) => { const showActiveLanguage = (language: string, focus = false) => {
const languageSwitcher = document.querySelector("#bd-language"); const languageSwitcher = document.querySelector<HTMLElement>("#bd-language");
if (!languageSwitcher) { if (!languageSwitcher) {
return; return;
@@ -27,24 +27,26 @@
const languageSwitcherText = document.querySelector("#bd-language-text"); const languageSwitcherText = document.querySelector("#bd-language-text");
const activeLanguageIcon = document.querySelector(".language-icon-active"); const activeLanguageIcon = document.querySelector(".language-icon-active");
const btnToActive = document.querySelector(`[data-bs-language-value="${language}"]`); const btnToActive = document.querySelector<HTMLElement>(`[data-bs-language-value="${language}"]`);
const activeLanguageIconClass = btnToActive.querySelector(".fi").className.match(/fi-[\w-]+/)[0]; const activeLanguageIconClass = (btnToActive?.querySelector(".fi")?.className.match(/fi-[\w-]+/) || [])[0] || "";
document.querySelectorAll("[data-bs-language-value]").forEach((element) => { document.querySelectorAll("[data-bs-language-value]").forEach((element) => {
element.classList.remove("active"); element.classList.remove("active");
element.setAttribute("aria-pressed", "false"); element.setAttribute("aria-pressed", "false");
}); });
btnToActive.classList.add("active"); btnToActive?.classList.add("active");
btnToActive.setAttribute("aria-pressed", "true"); btnToActive?.setAttribute("aria-pressed", "true");
const classesToRemove = Array.from(activeLanguageIcon.classList).filter((className) => className.startsWith("fi-")); const classesToRemove = Array.from(activeLanguageIcon?.classList || []).filter((className) =>
activeLanguageIcon.classList.remove(...classesToRemove); className.startsWith("fi-"),
activeLanguageIcon.classList.add(activeLanguageIconClass); );
const languageSwitcherLabel = `${languageSwitcherText.textContent} (${btnToActive.dataset.bsLanguageValue})`; activeLanguageIcon?.classList.remove(...classesToRemove);
activeLanguageIcon?.classList.add(activeLanguageIconClass);
const languageSwitcherLabel = `${languageSwitcherText?.textContent} (${btnToActive?.dataset.bsLanguageValue})`;
languageSwitcher.setAttribute("aria-label", languageSwitcherLabel); languageSwitcher.setAttribute("aria-label", languageSwitcherLabel);
if (focus) { if (focus) {
languageSwitcher.focus(); languageSwitcher?.focus();
} }
}; };

View File

@@ -25,7 +25,7 @@
setTheme(getPreferredTheme()); setTheme(getPreferredTheme());
const showActiveTheme = (theme: string, focus = false) => { const showActiveTheme = (theme: string, focus = false) => {
const themeSwitcher = document.querySelector("#bd-theme"); const themeSwitcher = document.querySelector<HTMLElement>("#bd-theme");
if (!themeSwitcher) { if (!themeSwitcher) {
return; return;
@@ -33,24 +33,26 @@
const themeSwitcherText = document.querySelector("#bd-theme-text"); const themeSwitcherText = document.querySelector("#bd-theme-text");
const activeThemeIcon = document.querySelector(".theme-icon-active"); const activeThemeIcon = document.querySelector(".theme-icon-active");
const btnToActive = document.querySelector(`[data-bs-theme-value="${theme}"]`); const btnToActive = document.querySelector<HTMLElement>(`[data-bs-theme-value="${theme}"]`);
const activeThemeIconClass = btnToActive.querySelector(".bi").className.match(/bi-[\w-]+/)[0]; const activeThemeIconClass = (btnToActive?.querySelector(".bi")?.className.match(/bi-[\w-]+/) || [])[0] || "";
document.querySelectorAll("[data-bs-theme-value]").forEach((element) => { document.querySelectorAll("[data-bs-theme-value]").forEach((element) => {
element.classList.remove("active"); element.classList.remove("active");
element.setAttribute("aria-pressed", "false"); element.setAttribute("aria-pressed", "false");
}); });
btnToActive.classList.add("active"); btnToActive?.classList.add("active");
btnToActive.setAttribute("aria-pressed", "true"); btnToActive?.setAttribute("aria-pressed", "true");
const classesToRemove = Array.from(activeThemeIcon.classList).filter((className) => className.startsWith("bi-")); const classesToRemove = Array.from(activeThemeIcon?.classList || []).filter((className) =>
activeThemeIcon.classList.remove(...classesToRemove); className.startsWith("bi-"),
activeThemeIcon.classList.add(activeThemeIconClass); );
const themeSwitcherLabel = `${themeSwitcherText.textContent} (${btnToActive.dataset.bsThemeValue})`; activeThemeIcon?.classList.remove(...classesToRemove);
activeThemeIcon?.classList.add(activeThemeIconClass);
const themeSwitcherLabel = `${themeSwitcherText?.textContent} (${btnToActive?.dataset.bsThemeValue})`;
themeSwitcher.setAttribute("aria-label", themeSwitcherLabel); themeSwitcher.setAttribute("aria-label", themeSwitcherLabel);
if (focus) { if (focus) {
themeSwitcher.focus(); themeSwitcher?.focus();
} }
}; };
@@ -66,7 +68,7 @@
document.querySelectorAll("[data-bs-theme-value]").forEach((toggle) => { document.querySelectorAll("[data-bs-theme-value]").forEach((toggle) => {
toggle.addEventListener("click", () => { toggle.addEventListener("click", () => {
const theme = toggle.getAttribute("data-bs-theme-value") || ''; const theme = toggle.getAttribute("data-bs-theme-value") || "";
setStoredTheme(theme); setStoredTheme(theme);
setTheme(theme); setTheme(theme);
showActiveTheme(theme, true); showActiveTheme(theme, true);

View File

@@ -0,0 +1,6 @@
import { Tooltip } from "bootstrap";
document.addEventListener("DOMContentLoaded", (event) => {
const tooltipTriggerList = document.querySelectorAll('[data-bs-toggle="tooltip"]');
const tooltipList = [...tooltipTriggerList].map((tooltipTriggerEl) => new Tooltip(tooltipTriggerEl));
});

View File

@@ -1,10 +1,10 @@
class AppLinkElement extends HTMLElement { class AppLinkElement extends HTMLElement {
static observedAttributes = ["icon", "href"]; static observedAttributes = ["icon", "href", "target"];
constructor() { constructor() {
super(); super();
this.innerHTML = ` this.innerHTML = `
<a href="${this.getAttribute("href")}" <a href="${this.getAttribute("href")}" target="${this.getAttribute("target") || ""}"
class="d-flex align-items-center text-body text-decoration-none"> class="d-flex align-items-center text-body text-decoration-none">
<span class="fs-4"> <span class="fs-4">
<span class="bi bi-${this.getAttribute("icon")} me-1"></span> <span class="bi bi-${this.getAttribute("icon")} me-1"></span>

110
static/src/app/schedule.ts Normal file
View File

@@ -0,0 +1,110 @@
export interface Channel {
id: string;
name: string;
provider: string;
}
export class ScheduleChannelStorage {
private storageKey: string = "schedule:channels";
getAll(): Channel[] {
const objects = JSON.parse(window.localStorage.getItem(this.storageKey) || "{}");
return Object.values(objects);
}
add(object: Channel) {
const objects = JSON.parse(window.localStorage.getItem(this.storageKey) || "{}");
objects[object.id] = object;
window.localStorage.setItem(this.storageKey, JSON.stringify(objects));
}
remove(id: string) {
const objects = JSON.parse(window.localStorage.getItem(this.storageKey) || "{}");
delete objects[id];
window.localStorage.setItem(this.storageKey, JSON.stringify(objects));
}
}
export class ScheduleChannelManager {
loadChannels(selector: string) {
const channels = window.scheduleChannelStorage.getAll();
const container = document.querySelector(selector);
if (container) {
container.innerHTML = "";
for (const channel of channels) {
const element = new ScheduleChannelElement();
element.setAttribute("channel", JSON.stringify(channel));
element.setAttribute("removable", "");
container.appendChild(element);
}
}
}
}
class ScheduleChannelElement extends HTMLElement {
static observedAttributes = ["channel", "removable"];
channel: Channel | null = null;
constructor() {
super();
this.handleClick = this.handleClick.bind(this);
this.handleRemoveClick = this.handleRemoveClick.bind(this);
}
connectedCallback() {
this.channel = JSON.parse(this.getAttribute("channel") || "{}");
this.innerHTML = `
<a href="${this.channel?.provider}/${this.channel?.id}"
class="d-flex justify-content-between align-items-start text-decoration-none">
<span>
<span class="text-primary">${this.channel?.name}</span>
</span>
<span>
<span class="badge text-bg-secondary">${this.channel?.provider}</span>
<span class="text-danger ms-2" data-remove>
&#x2715;
</span>
</span>
</a>`;
this.classList = "list-group-item list-group-item-action";
this.addEventListener("click", this.handleClick);
if (this.hasAttribute("removable")) {
this.querySelector<HTMLElement>("[data-remove]")?.addEventListener("click", this.handleRemoveClick);
} else {
this.querySelector("[data-remove]")?.remove();
}
}
disconnectedCallback() {
this.removeEventListener("click", this.handleClick);
this.querySelector<HTMLElement>("[data-remove]")?.removeEventListener("click", this.handleRemoveClick);
}
handleClick(event: MouseEvent) {
if (this.channel) {
window.scheduleChannelStorage.add(this.channel);
}
}
handleRemoveClick(event: MouseEvent) {
event.preventDefault();
event.stopPropagation();
if (this.channel) {
window.scheduleChannelStorage.remove(this.channel.id);
}
this.remove();
}
}
customElements.define("schedule-channel", ScheduleChannelElement);
declare global {
interface Window {
scheduleChannelStorage: ScheduleChannelStorage;
scheduleChannelManager: ScheduleChannelManager;
}
}
window.scheduleChannelStorage = new ScheduleChannelStorage();
window.scheduleChannelManager = new ScheduleChannelManager();

118
static/src/app/weather.ts Normal file
View File

@@ -0,0 +1,118 @@
export interface Location {
id: string;
name: string;
provider: string;
country_code: string;
country?: string;
district?: string;
subdistrict?: string;
}
export class WeatherLocationStorage {
private storageKey: string = "weather:locations";
getAll(): Location[] {
const locations = JSON.parse(window.localStorage.getItem(this.storageKey) || "{}");
return Object.values(locations);
}
add(location: Location) {
const locations = JSON.parse(window.localStorage.getItem(this.storageKey) || "{}");
locations[location.id] = location;
window.localStorage.setItem(this.storageKey, JSON.stringify(locations));
}
remove(id: string) {
const locations = JSON.parse(window.localStorage.getItem(this.storageKey) || "{}");
delete locations[id];
window.localStorage.setItem(this.storageKey, JSON.stringify(locations));
}
}
export class WeatherLocationManager {
loadLocations(selector: string) {
const locations = window.weatherLocationStorage.getAll();
const container = document.querySelector(selector);
if (container) {
container.innerHTML = "";
for (const location of locations) {
const element = new WeatherLocationElement();
element.setAttribute("location", JSON.stringify(location));
element.setAttribute("removable", "");
container.appendChild(element);
}
}
}
}
class WeatherLocationElement extends HTMLElement {
static observedAttributes = ["location", "removable"];
location: Location | null = null;
constructor() {
super();
this.handleClick = this.handleClick.bind(this);
this.handleRemoveClick = this.handleRemoveClick.bind(this);
}
connectedCallback() {
this.location = JSON.parse(this.getAttribute("location") || "{}");
this.innerHTML = `
<a href="${this.location?.provider}/${this.location?.id}"
class="d-flex justify-content-between align-items-start text-decoration-none">
<span>
<span class="fi fi-${this.location?.country_code} me-1"></span>
<span class="text-primary">${this.location?.name}</span>
<span class="small ms-1 text-secondary">
${this.location?.country}, ${this.location?.district}, ${this.location?.subdistrict}
</span>
</span>
<span>
<span class="badge text-bg-secondary">${this.location?.provider}</span>
<span class="text-danger ms-2" data-remove>
&#x2715;
</span>
</span>
</a>`;
this.classList = 'list-group-item list-group-item-action';
this.addEventListener("click", this.handleClick);
if (this.hasAttribute("removable")) {
this.querySelector<HTMLElement>("[data-remove]")?.addEventListener("click", this.handleRemoveClick);
} else {
this.querySelector("[data-remove]")?.remove();
}
}
disconnectedCallback() {
this.removeEventListener("click", this.handleClick);
this.querySelector<HTMLElement>("[data-remove]")?.removeEventListener("click", this.handleRemoveClick);
}
handleClick(event: MouseEvent) {
if (this.location) {
window.weatherLocationStorage.add(this.location);
}
}
handleRemoveClick(event: MouseEvent) {
event.preventDefault();
event.stopPropagation();
if (this.location) {
window.weatherLocationStorage.remove(this.location.id);
}
this.remove();
}
}
customElements.define("weather-location", WeatherLocationElement);
declare global {
interface Window {
weatherLocationStorage: WeatherLocationStorage;
weatherLocationManager: WeatherLocationManager;
}
}
window.weatherLocationStorage = new WeatherLocationStorage();
window.weatherLocationManager = new WeatherLocationManager();

View File

@@ -1,10 +1,8 @@
import * as bootstrap from "bootstrap"; import "./app/common/language";
import "./components"; import "./app/common/theme";
import "./language"; import "./app/common/tooltips";
import "./main.scss"; import "./app/components/app-link";
import "./theme"; import "./app/schedule";
import "./app/weather";
document.addEventListener("DOMContentLoaded", (event) => { import { init } from "./lib/weather-icons";
const tooltipTriggerList = document.querySelectorAll('[data-bs-toggle="tooltip"]'); init("/static/weather-icons/icons");
const tooltipList = [...tooltipTriggerList].map((tooltipTriggerEl) => new bootstrap.Tooltip(tooltipTriggerEl));
});

View File

@@ -42,4 +42,7 @@
&.bi-arrow-up-square { &.bi-arrow-up-square {
mask-image: url(bootstrap-icons/icons/arrow-up-square.svg); mask-image: url(bootstrap-icons/icons/arrow-up-square.svg);
} }
&.bi-file-earmark-text {
mask-image: url(bootstrap-icons/icons/file-earmark-text.svg);
}
} }

View File

@@ -1,7 +1,3 @@
@import "bootstrap/scss/mixins/banner";
@include bsBanner("");
// scss-docs-start import-stack // scss-docs-start import-stack
// Configuration // Configuration
@import "bootstrap/scss/functions"; @import "bootstrap/scss/functions";
@@ -30,7 +26,7 @@
//@import "bootstrap/scss/accordion"; //@import "bootstrap/scss/accordion";
//@import "bootstrap/scss/breadcrumb"; //@import "bootstrap/scss/breadcrumb";
//@import "bootstrap/scss/pagination"; //@import "bootstrap/scss/pagination";
//@import "bootstrap/scss/badge"; @import "bootstrap/scss/badge";
//@import "bootstrap/scss/alert"; //@import "bootstrap/scss/alert";
//@import "bootstrap/scss/progress"; //@import "bootstrap/scss/progress";
@import "bootstrap/scss/list-group"; @import "bootstrap/scss/list-group";

View File

@@ -1,12 +1,5 @@
@use "flag-icons/sass/flag-icons" with ( @use "flag-icons/sass/flag-icons" with (
$flag-icons-path: "flag-icons/flags", $flag-icons-path: "flag-icons/flags",
$flag-icons-included-countries: (
"gb",
"ru",
"by",
"ua",
"kz",
)
); );
.fir { .fir {

View File

@@ -0,0 +1,3 @@
@use "./weather-icons/sass/weather-icons" with (
$weather-icons-path: "weather-icons/icons"
);

View File

@@ -1,22 +0,0 @@
from pathlib import Path
from string import Template
LIST_ITEM = Template(
""".$name {
mask-image: url(./svg/$name.svg);
}
"""
)
def generate():
work_dir = Path(__file__).parent
data = ""
for item in (work_dir / "svg").glob("*.svg"):
data += LIST_ITEM.substitute({"name": item.stem})
target = work_dir / "classes-list.scss"
target.write_text(data)
if __name__ == "__main__":
generate()

View File

@@ -1,84 +0,0 @@
.wi-day-snow {
mask-image: url(./svg/wi-day-snow.svg);
}
.wi-rain-mix {
mask-image: url(./svg/wi-rain-mix.svg);
}
.wi-thunderstorm {
mask-image: url(./svg/wi-thunderstorm.svg);
}
.wi-day-rain {
mask-image: url(./svg/wi-day-rain.svg);
}
.wi-cloudy {
mask-image: url(./svg/wi-cloudy.svg);
}
.wi-night-clear {
mask-image: url(./svg/wi-night-clear.svg);
}
.wi-day-cloudy {
mask-image: url(./svg/wi-day-cloudy.svg);
}
.wi-day-storm-showers {
mask-image: url(./svg/wi-day-storm-showers.svg);
}
.wi-lightning {
mask-image: url(./svg/wi-lightning.svg);
}
.wi-day-rain-mix {
mask-image: url(./svg/wi-day-rain-mix.svg);
}
.wi-day-showers {
mask-image: url(./svg/wi-day-showers.svg);
}
.wi-storm-showers {
mask-image: url(./svg/wi-storm-showers.svg);
}
.wi-snow {
mask-image: url(./svg/wi-snow.svg);
}
.wi-cloud {
mask-image: url(./svg/wi-cloud.svg);
}
.wi-night-alt-snow {
mask-image: url(./svg/wi-night-alt-snow.svg);
}
.wi-night-alt-lightning {
mask-image: url(./svg/wi-night-alt-lightning.svg);
}
.wi-day-sunny {
mask-image: url(./svg/wi-day-sunny.svg);
}
.wi-night-alt-cloudy {
mask-image: url(./svg/wi-night-alt-cloudy.svg);
}
.wi-night-alt-storm-showers {
mask-image: url(./svg/wi-night-alt-storm-showers.svg);
}
.wi-day-thunderstorm {
mask-image: url(./svg/wi-day-thunderstorm.svg);
}
.wi-wind-deg {
mask-image: url(./svg/wi-wind-deg.svg);
}
.wi-showers {
mask-image: url(./svg/wi-showers.svg);
}
.wi-night-alt-rain-mix {
mask-image: url(./svg/wi-night-alt-rain-mix.svg);
}
.wi-rain {
mask-image: url(./svg/wi-rain.svg);
}
.wi-night-alt-thunderstorm {
mask-image: url(./svg/wi-night-alt-thunderstorm.svg);
}
.wi-night-alt-showers {
mask-image: url(./svg/wi-night-alt-showers.svg);
}
.wi-day-lightning {
mask-image: url(./svg/wi-day-lightning.svg);
}
.wi-night-alt-rain {
mask-image: url(./svg/wi-night-alt-rain.svg);
}

View File

@@ -0,0 +1,3 @@
<!-- Generator: Adobe Illustrator 22.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) --><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Layer_1" x="0px" y="0px" viewBox="0 0 30 30" style="enable-background:new 0 0 30 30;" xml:space="preserve">
<path id="cloud" d="M4.61,16.88c0-1.15,0.36-2.17,1.08-3.07c0.72-0.9,1.63-1.48,2.74-1.73c0.31-1.37,1.02-2.49,2.11-3.37s2.35-1.32,3.76-1.32 c1.38,0,2.61,0.43,3.69,1.28s1.78,1.95,2.1,3.29h0.33c0.9,0,1.73,0.22,2.49,0.65s1.37,1.03,1.81,1.79c0.44,0.76,0.67,1.58,0.67,2.48 c0,0.88-0.21,1.7-0.63,2.45s-1,1.35-1.73,1.8c-0.73,0.45-1.54,0.69-2.41,0.72H9.41c-1.34-0.06-2.47-0.57-3.4-1.53 C5.08,19.37,4.61,18.22,4.61,16.88z M6.32,16.88c0,0.87,0.3,1.62,0.9,2.26s1.33,0.98,2.19,1.03h11.19c0.86-0.04,1.59-0.39,2.19-1.03 c0.61-0.64,0.91-1.4,0.91-2.26c0-0.88-0.33-1.63-0.98-2.27c-0.65-0.64-1.42-0.96-2.32-0.96H18.8c-0.11,0-0.17-0.06-0.17-0.18 l-0.07-0.57c-0.11-1.08-0.58-1.99-1.4-2.72c-0.82-0.73-1.77-1.1-2.86-1.1c-1.09,0-2.05,0.37-2.85,1.1 c-0.81,0.73-1.27,1.64-1.37,2.72l-0.08,0.57c0,0.12-0.07,0.18-0.2,0.18H9.27c-0.84,0.1-1.54,0.46-2.1,1.07S6.32,16.05,6.32,16.88z"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,3 @@
<!-- Generator: Adobe Illustrator 22.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) --><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Layer_1" x="0px" y="0px" viewBox="0 0 30 30" style="enable-background:new 0 0 30 30;" xml:space="preserve">
<path id="cloud" d="M3.89,17.6c0-0.99,0.31-1.88,0.93-2.65s1.41-1.27,2.38-1.49c0.26-1.17,0.85-2.14,1.78-2.88c0.93-0.75,2-1.12,3.22-1.12 c1.18,0,2.24,0.36,3.16,1.09c0.93,0.73,1.53,1.66,1.8,2.8h0.27c1.18,0,2.18,0.41,3.01,1.24s1.25,1.83,1.25,3 c0,1.18-0.42,2.18-1.25,3.01s-1.83,1.25-3.01,1.25H8.16c-0.58,0-1.13-0.11-1.65-0.34S5.52,21,5.14,20.62 c-0.38-0.38-0.68-0.84-0.91-1.36S3.89,18.17,3.89,17.6z M5.34,17.6c0,0.76,0.28,1.42,0.82,1.96s1.21,0.82,1.99,0.82h9.28 c0.77,0,1.44-0.27,1.99-0.82c0.55-0.55,0.83-1.2,0.83-1.96c0-0.76-0.27-1.42-0.83-1.96c-0.55-0.54-1.21-0.82-1.99-0.82h-1.39 c-0.1,0-0.15-0.05-0.15-0.15l-0.07-0.49c-0.1-0.94-0.5-1.73-1.19-2.35s-1.51-0.93-2.45-0.93c-0.94,0-1.76,0.31-2.46,0.94 c-0.7,0.62-1.09,1.41-1.18,2.34l-0.07,0.42c0,0.1-0.05,0.15-0.16,0.15l-0.45,0.07c-0.72,0.06-1.32,0.36-1.81,0.89 C5.59,16.24,5.34,16.87,5.34,17.6z M14.19,8.88c-0.1,0.09-0.08,0.16,0.07,0.21c0.43,0.19,0.79,0.37,1.08,0.55 c0.11,0.03,0.19,0.02,0.22-0.03c0.61-0.57,1.31-0.86,2.12-0.86c0.81,0,1.5,0.27,2.1,0.81c0.59,0.54,0.92,1.21,0.99,2l0.09,0.64h1.42 c0.65,0,1.21,0.23,1.68,0.7c0.47,0.47,0.7,1.02,0.7,1.66c0,0.6-0.21,1.12-0.62,1.57s-0.92,0.7-1.53,0.77c-0.1,0-0.15,0.05-0.15,0.16 v1.13c0,0.11,0.05,0.16,0.15,0.16c1.01-0.06,1.86-0.46,2.55-1.19s1.04-1.6,1.04-2.6c0-1.06-0.37-1.96-1.12-2.7 c-0.75-0.75-1.65-1.12-2.7-1.12h-0.15c-0.26-1-0.81-1.82-1.65-2.47c-0.83-0.65-1.77-0.97-2.8-0.97C16.28,7.29,15.11,7.82,14.19,8.88 z"/>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -0,0 +1,11 @@
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" id="Layer_1" x="0px" y="0px" viewBox="0 0 30 30" style="enable-background:new 0 0 30 30;">
<path id="cloud" d="M 2.63 13.83 C 3.34 12.93 4.25 12.36 5.37 12.10 C 5.67 10.74 6.37 9.62 7.45 8.75 C 8.53 7.88 9.77 7.44 11.18 7.44 C 12.21 7.44 13.11 7.66 13.88 8.10 C 13.97 8.01 15.37 9.00 15.31 9.06 C 16.19 9.93 16.75 10.91 17.00 12.00 L 17.32 12.00 C 18.68 12.00 19.84 12.48 20.81 13.44 C 20.84 13.38 22.01 14.72 21.86 14.90 C 22.14 15.57 22.28 16.24 22.28 16.90 C 22.28 17.80 22.05 18.63 21.61 19.39 C 21.17 20.15 20.56 20.75 19.80 21.19 C 19.04 21.63 18.21 21.85 17.32 21.85 L 6.49 21.85 C 5.60 21.85 4.78 21.63 4.02 21.19 C 3.26 20.75 2.66 20.15 2.22 19.39 C 1.78 18.63 1.56 17.80 1.56 16.90 C 1.56 15.75 1.92 14.73 2.63 13.83 Z M 4.22 19.22 C 4.86 19.87 5.61 20.19 6.49 20.19 L 17.33 20.19 C 18.21 20.19 18.98 19.87 19.61 19.23 C 20.24 18.59 20.56 17.82 20.56 16.91 C 20.56 16.03 20.24 15.28 19.60 14.64 C 18.96 14.00 18.20 13.68 17.32 13.68 L 15.71 13.68 C 15.59 13.68 15.52 13.62 15.50 13.51 L 15.43 12.93 C 15.33 11.85 14.88 10.95 14.06 10.22 C 13.25 9.49 12.29 9.12 11.19 9.12 C 10.12 9.12 9.18 9.48 8.38 10.21 C 7.58 10.93 7.11 11.84 6.97 12.92 L 6.90 13.46 C 6.90 13.58 6.83 13.64 6.71 13.64 L 6.21 13.67 C 5.37 13.77 4.67 14.12 4.11 14.73 C 3.55 15.34 3.27 16.06 3.27 16.90 C 3.27 17.80 3.59 18.57 4.22 19.22 Z"/>
<g id="sun">
<path d="M 17.89 6.23 C 18.60 6.23 19.28 6.36 19.93 6.64 C 20.58 6.91 21.13 7.29 21.60 7.76 C 22.07 8.23 22.45 8.78 22.72 9.43 C 22.99 10.08 23.13 10.76 23.13 11.47 C 23.13 12.49 22.36 14.03 21.87 14.83 L 20.85 13.50 C 21.12 12.95 21.45 12.02 21.45 11.47 C 21.45 10.48 21.10 9.65 20.41 8.96 C 19.72 8.27 18.88 7.93 17.89 7.93 C 17.03 7.93 15.96 8.51 15.31 9.07 L 13.92 8.12 C 14.96 7.14 16.54 6.23 17.89 6.23 Z"/>
<path d="M 24.72 11.60 C 24.72 11.83 24.81 12.02 24.98 12.18 C 25.14 12.34 25.35 12.42 25.59 12.42 L 27.63 12.42 C 27.86 12.42 28.05 12.34 28.21 12.19 C 28.37 12.04 28.44 11.84 28.44 11.60 C 28.44 11.36 28.36 11.16 28.21 11.00 C 28.06 10.84 27.86 10.75 27.63 10.75 L 25.59 10.75 C 25.35 10.75 25.15 10.83 24.98 11.00 C 24.80 11.17 24.72 11.37 24.72 11.60 Z"/>
<path d="M 23.25 17.91 C 23.25 18.15 23.33 18.36 23.50 18.54 L 24.15 19.17 C 24.30 19.33 24.49 19.41 24.73 19.41 C 24.97 19.41 25.17 19.33 25.33 19.16 C 25.49 18.99 25.57 18.79 25.57 18.54 C 25.57 18.32 25.49 18.12 25.33 17.96 L 24.68 17.31 C 24.52 17.15 24.33 17.07 24.11 17.07 C 23.87 17.07 23.67 17.15 23.51 17.31 C 23.34 17.47 23.25 17.67 23.25 17.91 Z"/>
<path d="M 22.46 6.07 C 22.46 6.33 22.53 6.53 22.68 6.69 C 22.89 6.85 23.10 6.93 23.30 6.93 C 23.48 6.93 23.68 6.85 23.89 6.69 L 25.32 5.26 C 25.48 5.08 25.56 4.87 25.56 4.62 C 25.56 4.38 25.48 4.18 25.32 4.02 C 25.16 3.86 24.96 3.78 24.73 3.78 C 24.49 3.78 24.30 3.86 24.15 4.02 L 22.68 5.45 C 22.53 5.64 22.46 5.84 22.46 6.07 Z"/>
<path d="M 16.94 3.78 C 16.94 4.04 17.02 4.24 17.17 4.40 C 17.32 4.56 17.52 4.63 17.76 4.63 C 18.02 4.63 18.22 4.55 18.38 4.40 C 18.54 4.24 18.61 4.04 18.61 3.78 L 18.61 1.73 C 18.61 1.49 18.53 1.30 18.37 1.14 C 18.21 0.98 18.01 0.91 17.76 0.91 C 17.52 0.91 17.33 0.99 17.17 1.14 C 17.01 1.29 16.94 1.49 16.94 1.73 L 16.94 3.78 L 16.94 3.78 Z"/>
<path d="M 9.97 4.63 C 9.97 4.87 10.05 5.08 10.21 5.26 L 10.87 5.90 C 11.12 6.09 11.33 6.17 11.51 6.15 C 11.72 6.15 11.90 6.06 12.06 5.89 C 12.22 5.72 12.30 5.51 12.30 5.27 C 12.30 5.03 12.21 4.83 12.04 4.68 L 11.45 4.02 C 11.27 3.86 11.07 3.78 10.84 3.78 C 10.60 3.78 10.39 3.86 10.22 4.03 C 10.05 4.19 9.97 4.39 9.97 4.63 Z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

@@ -0,0 +1,19 @@
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" id="Layer_1" x="0px" y="0px" viewBox="0 0 30 30" style="enable-background:new 0 0 30 30;">
<path id="cloud" d="M 2.55 13.78 C 3.27 12.88 4.18 12.30 5.29 12.04 C 5.60 10.67 6.31 9.54 7.40 8.67 C 8.49 7.80 9.75 7.36 11.16 7.36 C 12.17 7.36 13.07 7.58 13.87 8.02 C 13.94 7.94 15.35 8.96 15.30 9.00 C 16.14 9.81 16.70 10.80 17.00 11.96 L 17.29 11.96 C 18.68 11.96 19.84 12.44 20.80 13.40 C 20.84 13.33 22.02 14.68 21.86 14.87 C 22.13 15.47 22.27 16.14 22.27 16.88 C 22.27 18.22 21.81 19.37 20.88 20.34 C 19.96 21.30 18.83 21.81 17.49 21.85 C 17.36 21.85 17.29 21.79 17.29 21.68 L 17.29 20.34 C 17.29 20.22 17.36 20.16 17.49 20.16 C 18.34 20.11 19.07 19.77 19.68 19.13 C 20.29 18.49 20.59 17.74 20.59 16.87 C 20.59 16.00 20.26 15.24 19.61 14.60 C 18.96 13.96 18.18 13.64 17.29 13.64 L 15.67 13.64 C 15.56 13.64 15.50 13.57 15.50 13.45 L 15.43 12.87 C 15.32 11.79 14.85 10.89 14.03 10.16 C 13.21 9.43 12.26 9.07 11.17 9.07 C 10.07 9.07 9.12 9.43 8.31 10.16 C 7.50 10.88 7.05 11.79 6.94 12.87 L 6.87 13.42 C 6.87 13.54 6.80 13.60 6.67 13.60 L 6.14 13.64 C 5.31 13.74 4.61 14.09 4.04 14.71 C 3.47 15.33 3.19 16.05 3.19 16.88 C 3.19 17.74 3.49 18.50 4.09 19.14 C 4.69 19.78 5.42 20.13 6.28 20.17 C 6.40 20.17 6.46 20.23 6.46 20.35 L 6.46 21.69 C 6.46 21.80 6.40 21.86 6.28 21.86 C 4.95 21.80 3.81 21.29 2.88 20.33 C 1.95 19.37 1.48 18.22 1.48 16.88 C 1.48 15.73 1.84 14.70 2.55 13.78 Z"/>
<g id="sun">
<path d="M 17.77 6.27 C 18.71 6.27 19.59 6.51 20.40 6.98 C 21.21 7.46 21.85 8.10 22.33 8.91 C 22.80 9.72 23.04 10.60 23.04 11.54 C 23.04 12.55 22.38 14.09 21.88 14.91 L 20.82 13.45 C 21.09 12.91 21.32 12.10 21.32 11.55 C 21.32 10.57 20.97 9.74 20.28 9.06 C 19.59 8.37 18.76 8.03 17.78 8.03 C 16.87 8.03 15.97 8.45 15.33 9.00 L 13.88 8.00 C 14.88 6.98 16.31 6.27 17.77 6.27 Z"/>
<path d="M 24.74 11.55 C 24.74 11.79 24.83 11.99 25.00 12.15 C 25.18 12.33 25.38 12.41 25.62 12.41 L 27.65 12.41 C 27.89 12.41 28.09 12.33 28.26 12.16 C 28.43 11.99 28.52 11.79 28.52 11.55 C 28.52 11.32 28.44 11.12 28.27 10.96 C 28.10 10.80 27.89 10.72 27.65 10.72 L 25.62 10.72 C 25.37 10.72 25.16 10.80 24.99 10.96 C 24.83 11.12 24.74 11.32 24.74 11.55 Z"/>
<path d="M 23.28 17.92 C 23.28 18.15 23.36 18.35 23.52 18.52 L 24.18 19.15 C 24.32 19.33 24.52 19.42 24.78 19.42 C 25.02 19.42 25.21 19.33 25.35 19.15 C 25.53 18.99 25.62 18.79 25.62 18.55 C 25.62 18.31 25.53 18.11 25.35 17.94 L 24.70 17.32 C 24.54 17.14 24.35 17.06 24.12 17.06 C 23.89 17.06 23.69 17.14 23.52 17.31 C 23.36 17.48 23.28 17.69 23.28 17.92 Z"/>
<path d="M 22.47 6.02 C 22.47 6.26 22.55 6.46 22.72 6.62 C 22.87 6.79 23.06 6.88 23.30 6.88 C 23.53 6.88 23.74 6.79 23.90 6.62 L 25.34 5.18 C 25.52 5.03 25.61 4.83 25.61 4.58 C 25.61 4.34 25.52 4.14 25.35 3.97 C 25.18 3.80 24.97 3.72 24.74 3.72 C 24.52 3.72 24.33 3.81 24.17 3.99 L 22.72 5.42 C 22.56 5.57 22.47 5.78 22.47 6.02 Z"/>
<path d="M 16.92 3.73 C 16.92 3.97 17.00 4.17 17.17 4.34 C 17.34 4.51 17.54 4.59 17.78 4.59 C 18.01 4.59 18.21 4.51 18.37 4.34 C 18.53 4.17 18.61 3.97 18.61 3.73 L 18.61 1.67 C 18.61 1.43 18.53 1.23 18.37 1.06 C 18.21 0.89 18.02 0.81 17.78 0.81 C 17.54 0.81 17.34 0.89 17.17 1.06 C 17.00 1.23 16.92 1.43 16.92 1.67 L 16.92 3.73 Z"/>
<path d="M 9.94 4.57 C 9.94 4.82 10.02 5.02 10.18 5.17 L 10.83 5.82 C 10.99 5.98 11.17 6.07 11.37 6.09 C 11.58 6.12 11.78 6.04 11.98 5.86 C 12.18 5.68 12.28 5.46 12.28 5.22 C 12.28 4.98 12.20 4.78 12.04 4.62 L 11.40 3.98 C 11.21 3.81 11.01 3.73 10.78 3.73 C 10.54 3.73 10.33 3.81 10.17 3.97 C 10.02 4.14 9.94 4.34 9.94 4.57 Z"/>
</g>
<g id="rain">
<path d="M 14.23 21.08 C 14.23 21.24 14.28 21.39 14.38 21.53 C 14.48 21.68 14.64 21.78 14.84 21.84 C 14.93 21.86 15.01 21.87 15.09 21.87 C 15.48 21.87 15.74 21.67 15.88 21.26 L 16.91 18.08 C 16.99 17.85 16.96 17.63 16.84 17.43 C 16.72 17.23 16.55 17.10 16.32 17.04 C 16.08 16.97 15.87 16.99 15.68 17.10 C 15.49 17.21 15.36 17.37 15.28 17.61 L 14.26 20.81 C 14.25 20.94 14.23 21.03 14.23 21.08 Z"/>
<path d="M 13.51 23.64 C 13.51 23.77 13.53 23.87 13.58 23.95 C 13.67 24.16 13.82 24.30 14.03 24.39 C 14.14 24.44 14.25 24.47 14.38 24.47 C 14.44 24.47 14.54 24.45 14.68 24.41 C 14.91 24.32 15.06 24.18 15.14 23.97 C 15.22 23.75 15.22 23.54 15.14 23.34 C 15.06 23.14 14.92 22.99 14.72 22.89 C 14.49 22.78 14.28 22.77 14.06 22.86 C 13.85 22.95 13.69 23.10 13.58 23.33 C 13.53 23.41 13.51 23.51 13.51 23.64 Z"/>
<path d="M 10.06 24.03 C 10.06 24.19 10.11 24.35 10.22 24.51 C 10.33 24.67 10.49 24.78 10.70 24.84 C 10.81 24.86 10.89 24.88 10.94 24.88 C 11.09 24.88 11.22 24.85 11.32 24.80 C 11.52 24.72 11.66 24.53 11.75 24.23 L 13.55 18.09 C 13.62 17.85 13.60 17.64 13.49 17.44 C 13.38 17.24 13.22 17.11 12.99 17.05 C 12.75 16.98 12.53 17.00 12.33 17.11 C 12.13 17.22 11.99 17.38 11.92 17.62 L 10.08 23.81 C 10.07 23.92 10.06 24.00 10.06 24.03 Z"/>
<path d="M 9.33 26.72 C 9.33 26.85 9.35 26.95 9.38 27.01 C 9.47 27.23 9.62 27.38 9.83 27.46 C 9.92 27.51 10.04 27.53 10.18 27.53 C 10.24 27.53 10.34 27.51 10.48 27.47 C 10.70 27.39 10.86 27.24 10.95 27.02 C 11.04 26.80 11.05 26.58 10.95 26.36 C 10.85 26.14 10.70 25.99 10.50 25.91 C 10.30 25.83 10.09 25.83 9.88 25.91 C 9.69 25.98 9.55 26.10 9.46 26.26 C 9.37 26.42 9.33 26.58 9.33 26.72 Z"/>
<path d="M 7.46 21.10 C 7.46 21.24 7.49 21.37 7.55 21.48 C 7.74 21.79 8.04 21.94 8.44 21.94 C 8.76 21.94 8.99 21.72 9.13 21.29 L 10.17 18.07 C 10.25 17.83 10.23 17.60 10.10 17.40 C 9.97 17.20 9.79 17.07 9.55 17.03 C 9.34 16.98 9.13 17.00 8.93 17.10 C 8.73 17.21 8.59 17.38 8.52 17.60 L 7.49 20.82 C 7.47 20.92 7.46 21.02 7.46 21.10 Z"/>
<path d="M 6.82 23.94 C 6.92 24.16 7.07 24.31 7.28 24.39 C 7.48 24.49 7.69 24.50 7.91 24.41 C 8.13 24.33 8.28 24.18 8.36 23.96 C 8.46 23.74 8.47 23.53 8.38 23.31 C 8.30 23.10 8.15 22.95 7.93 22.87 C 7.73 22.76 7.52 22.75 7.31 22.84 C 7.09 22.93 6.94 23.08 6.84 23.31 C 6.74 23.49 6.73 23.70 6.82 23.94 Z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.8 KiB

View File

@@ -0,0 +1,12 @@
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" id="Layer_1" x="0px" y="0px" viewBox="0 0 30 30" style="enable-background:new 0 0 30 30;">
<path id="cloud" d="M 2.64 13.83 C 3.36 12.93 4.27 12.36 5.37 12.10 C 5.68 10.72 6.38 9.60 7.47 8.73 C 8.56 7.86 9.81 7.43 11.23 7.43 C 12.14 7.43 13.02 7.64 13.88 8.05 C 13.93 8.00 15.31 8.99 15.28 9.02 C 16.16 9.84 16.74 10.82 17.00 11.96 L 17.31 11.96 C 18.64 11.96 19.79 12.43 20.77 13.37 C 20.80 13.31 21.98 14.64 21.82 14.83 C 22.13 15.53 22.29 16.22 22.29 16.90 C 22.29 18.24 21.83 19.39 20.91 20.35 C 19.99 21.31 18.86 21.82 17.53 21.86 C 17.40 21.86 17.33 21.80 17.33 21.69 L 17.33 20.32 C 17.33 20.20 17.40 20.14 17.53 20.14 C 18.40 20.07 19.13 19.72 19.72 19.10 C 20.31 18.48 20.61 17.74 20.61 16.89 C 20.61 16.00 20.29 15.24 19.65 14.61 C 19.01 13.98 18.24 13.66 17.33 13.66 L 15.73 13.66 C 15.60 13.66 15.54 13.60 15.54 13.49 L 15.47 12.91 C 15.35 11.82 14.89 10.91 14.08 10.19 C 13.27 9.46 12.32 9.10 11.23 9.10 C 10.13 9.10 9.18 9.46 8.37 10.19 C 7.56 10.91 7.11 11.82 7.00 12.90 L 6.94 13.41 C 6.94 13.52 6.87 13.58 6.74 13.58 L 6.22 13.66 C 5.38 13.73 4.69 14.08 4.12 14.70 C 3.55 15.32 3.27 16.05 3.27 16.89 C 3.27 17.74 3.57 18.48 4.16 19.10 C 4.75 19.73 5.48 20.07 6.35 20.14 C 6.46 20.14 6.52 20.20 6.52 20.32 L 6.52 21.69 C 6.52 21.80 6.46 21.86 6.35 21.86 C 5.01 21.80 3.88 21.29 2.95 20.33 C 2.02 19.37 1.56 18.23 1.56 16.90 C 1.56 15.75 1.92 14.73 2.64 13.83 Z"/>
<g id="sun">
<path d="M 17.76 6.32 C 18.47 6.32 19.14 6.46 19.79 6.73 C 20.43 7.01 20.99 7.38 21.46 7.85 C 21.93 8.32 22.30 8.87 22.58 9.52 C 22.86 10.17 23.00 10.85 23.00 11.56 C 23.00 12.55 22.32 14.09 21.82 14.89 L 20.81 13.42 C 21.08 12.88 21.28 12.11 21.28 11.56 C 21.28 10.57 20.94 9.73 20.25 9.04 C 19.57 8.35 18.74 8.00 17.76 8.00 C 16.83 8.00 15.88 8.39 15.22 9.01 L 13.89 8.03 C 14.90 6.99 16.29 6.32 17.76 6.32 Z"/>
<path d="M 24.68 11.56 C 24.68 11.78 24.77 11.97 24.94 12.13 C 25.11 12.30 25.31 12.38 25.54 12.38 L 27.58 12.38 C 27.82 12.38 28.02 12.30 28.19 12.14 C 28.36 11.98 28.44 11.79 28.44 11.55 C 28.44 11.31 28.35 11.11 28.18 10.94 C 28.01 10.77 27.81 10.69 27.58 10.69 L 25.54 10.69 C 25.31 10.69 25.11 10.77 24.94 10.94 C 24.77 11.12 24.68 11.32 24.68 11.56 Z"/>
<path d="M 23.23 17.87 C 23.23 18.10 23.31 18.30 23.47 18.48 L 24.12 19.14 C 24.28 19.30 24.48 19.38 24.70 19.38 C 24.94 19.38 25.14 19.30 25.30 19.13 C 25.47 18.96 25.55 18.75 25.55 18.50 C 25.55 18.27 25.47 18.08 25.30 17.93 L 24.68 17.27 C 24.49 17.11 24.29 17.04 24.06 17.04 C 23.83 17.04 23.63 17.12 23.47 17.28 C 23.31 17.44 23.23 17.64 23.23 17.87 Z"/>
<path d="M 22.42 6.05 C 22.42 6.28 22.51 6.48 22.69 6.65 C 22.87 6.82 23.06 6.90 23.24 6.90 C 23.40 6.90 23.61 6.82 23.86 6.65 L 25.30 5.22 C 25.47 5.04 25.55 4.83 25.55 4.59 C 25.55 4.35 25.47 4.14 25.30 3.98 C 25.13 3.82 24.93 3.74 24.70 3.74 C 24.48 3.74 24.29 3.82 24.12 3.99 L 22.69 5.42 C 22.51 5.61 22.42 5.82 22.42 6.05 Z"/>
<path d="M 16.90 3.73 C 16.90 3.98 16.98 4.19 17.14 4.35 C 17.30 4.51 17.50 4.59 17.75 4.59 C 17.99 4.59 18.18 4.51 18.34 4.35 C 18.50 4.19 18.57 3.98 18.57 3.73 L 18.57 1.69 C 18.57 1.45 18.49 1.26 18.34 1.10 C 18.18 0.94 17.99 0.87 17.75 0.87 C 17.51 0.87 17.31 0.95 17.15 1.10 C 16.99 1.25 16.90 1.45 16.90 1.69 L 16.90 3.73 Z"/>
<path d="M 9.94 4.59 C 9.94 4.84 10.02 5.05 10.18 5.21 L 10.84 5.86 C 11.26 6.18 11.66 6.18 12.05 5.86 C 12.21 5.68 12.29 5.47 12.29 5.22 C 12.29 4.99 12.21 4.79 12.05 4.63 L 11.41 3.98 C 11.22 3.81 11.02 3.73 10.79 3.73 C 10.56 3.73 10.36 3.81 10.19 3.98 C 10.02 4.15 9.94 4.36 9.94 4.59 Z"/>
</g>
<path id="lightning" d="M 9.06 28.17 L 9.36 28.17 L 14.68 20.32 C 14.72 20.28 14.73 20.23 14.70 20.18 C 14.67 20.13 14.63 20.11 14.56 20.11 L 12.38 20.11 L 14.68 15.90 C 14.75 15.76 14.71 15.68 14.54 15.68 L 11.60 15.68 C 11.52 15.68 11.45 15.73 11.38 15.82 L 9.22 21.54 C 9.20 21.68 9.24 21.75 9.36 21.75 L 11.53 21.75 L 9.06 28.17 Z"/>
</svg>

After

Width:  |  Height:  |  Size: 3.8 KiB

View File

@@ -0,0 +1,22 @@
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" id="Layer_1" x="0px" y="0px" viewBox="0 0 30 30" style="enable-background:new 0 0 30 30;">
<path id="cloud" d="M 2.54 13.86 C 3.25 12.96 4.17 12.39 5.29 12.13 C 5.60 10.75 6.29 9.62 7.37 8.75 C 8.45 7.88 9.70 7.44 11.11 7.44 C 12.04 7.44 12.96 7.66 13.85 8.10 C 13.88 8.06 15.25 9.07 15.23 9.09 C 16.07 9.94 16.64 10.91 16.92 12.01 L 17.23 12.01 C 18.58 12.01 19.75 12.50 20.73 13.48 C 20.76 13.44 21.93 14.78 21.79 14.95 C 22.04 15.62 22.17 16.28 22.17 16.96 C 22.17 18.29 21.71 19.43 20.80 20.38 C 19.88 21.33 18.76 21.83 17.43 21.87 C 17.30 21.87 17.23 21.81 17.23 21.70 L 17.23 20.37 C 17.23 20.25 17.30 20.19 17.43 20.19 C 18.29 20.14 19.01 19.82 19.60 19.19 C 20.19 18.56 20.48 17.82 20.48 16.95 C 20.48 16.05 20.16 15.28 19.52 14.64 C 18.88 14.00 18.12 13.68 17.23 13.68 L 15.63 13.68 C 15.51 13.68 15.43 13.62 15.41 13.51 L 15.34 12.93 C 15.24 11.86 14.78 10.96 13.96 10.24 C 13.15 9.52 12.20 9.16 11.10 9.16 C 10.00 9.16 9.06 9.51 8.27 10.23 C 7.48 10.95 7.01 11.86 6.89 12.95 L 6.81 13.50 C 6.81 13.59 6.76 13.64 6.65 13.64 L 6.12 13.72 C 5.28 13.79 4.58 14.13 4.02 14.75 C 3.46 15.36 3.18 16.10 3.18 16.94 C 3.18 17.81 3.47 18.56 4.06 19.18 C 4.65 19.80 5.37 20.14 6.23 20.18 C 6.35 20.18 6.41 20.24 6.41 20.36 L 6.41 21.69 C 6.41 21.80 6.35 21.86 6.23 21.86 C 4.89 21.80 3.76 21.29 2.85 20.35 C 1.94 19.41 1.48 18.27 1.48 16.95 C 1.48 15.79 1.83 14.76 2.54 13.86 L 2.54 13.86 Z"/>
<g id="sun">
<path d="M 17.71 6.36 C 18.42 6.36 19.11 6.50 19.75 6.78 C 20.39 7.06 20.95 7.43 21.42 7.90 C 21.89 8.37 22.27 8.92 22.54 9.57 C 22.81 10.22 22.95 10.89 22.95 11.60 C 22.95 12.64 22.33 14.15 21.81 14.98 L 20.73 13.53 C 21.02 12.98 21.26 12.21 21.26 11.60 C 21.26 10.62 20.91 9.80 20.22 9.12 C 19.53 8.44 18.69 8.10 17.70 8.10 C 16.74 8.10 15.87 8.45 15.22 9.08 L 13.85 8.11 C 14.86 7.03 16.22 6.36 17.71 6.36 L 17.71 6.36 Z"/>
<path d="M 24.66 11.60 C 24.66 11.84 24.75 12.03 24.92 12.19 C 25.10 12.37 25.31 12.46 25.54 12.46 L 27.57 12.46 C 27.80 12.46 28.00 12.38 28.16 12.21 C 28.32 12.04 28.40 11.84 28.40 11.60 C 28.40 11.36 28.32 11.16 28.16 11.00 C 28.00 10.83 27.81 10.75 27.57 10.75 L 25.54 10.75 C 25.30 10.75 25.10 10.83 24.92 11.00 C 24.74 11.17 24.66 11.37 24.66 11.60 Z"/>
<path d="M 23.18 17.94 C 23.18 18.17 23.27 18.37 23.45 18.53 L 24.06 19.16 C 24.26 19.32 24.46 19.40 24.67 19.40 C 24.87 19.40 25.07 19.32 25.27 19.16 C 25.44 19.00 25.52 18.81 25.52 18.57 C 25.52 18.34 25.44 18.14 25.27 17.95 L 24.62 17.34 C 24.47 17.17 24.28 17.09 24.05 17.09 C 23.82 17.09 23.62 17.17 23.45 17.34 C 23.27 17.51 23.18 17.71 23.18 17.94 Z"/>
<path d="M 22.40 6.09 C 22.40 6.34 22.48 6.54 22.63 6.69 C 22.99 7.05 23.39 7.05 23.84 6.69 L 25.27 5.26 C 25.44 5.09 25.52 4.88 25.52 4.63 C 25.52 4.39 25.44 4.19 25.27 4.03 C 25.10 3.86 24.90 3.78 24.67 3.78 C 24.44 3.78 24.24 3.86 24.06 4.02 L 22.63 5.50 C 22.48 5.65 22.40 5.84 22.40 6.09 Z"/>
<path d="M 16.88 3.83 C 16.88 4.06 16.96 4.25 17.11 4.41 C 17.26 4.56 17.46 4.64 17.70 4.64 C 17.94 4.64 18.15 4.56 18.32 4.41 C 18.49 4.26 18.57 4.06 18.57 3.83 L 18.57 1.76 C 18.57 1.53 18.48 1.33 18.31 1.16 C 18.14 0.99 17.93 0.91 17.70 0.91 C 17.47 0.91 17.27 0.99 17.12 1.16 C 16.96 1.33 16.89 1.53 16.89 1.76 L 16.89 3.83 L 16.88 3.83 Z"/>
<path d="M 9.92 4.66 C 9.92 4.90 10.00 5.10 10.16 5.26 L 10.82 5.90 C 10.96 6.06 11.14 6.14 11.36 6.16 C 11.58 6.18 11.79 6.09 11.98 5.90 C 12.14 5.74 12.22 5.54 12.22 5.31 C 12.22 5.07 12.14 4.87 11.98 4.71 L 11.35 4.06 C 11.20 3.90 11.00 3.82 10.77 3.80 C 10.54 3.80 10.34 3.88 10.17 4.05 C 10.01 4.22 9.92 4.42 9.92 4.66 Z"/>
</g>
<g id="rain">
<path d="M 14.88 18.81 C 14.88 18.98 14.93 19.14 15.04 19.29 C 15.15 19.44 15.31 19.55 15.53 19.61 C 15.55 19.61 15.59 19.62 15.65 19.63 C 15.71 19.64 15.76 19.65 15.79 19.65 C 15.90 19.65 16.02 19.62 16.16 19.56 C 16.37 19.45 16.50 19.28 16.56 19.04 L 16.80 18.14 C 16.86 17.91 16.84 17.70 16.73 17.51 C 16.62 17.32 16.45 17.18 16.23 17.11 C 16.00 17.04 15.78 17.06 15.59 17.17 C 15.39 17.28 15.26 17.44 15.19 17.68 L 14.91 18.59 C 14.91 18.61 14.91 18.64 14.90 18.70 C 14.89 18.73 14.88 18.77 14.88 18.81 Z"/>
<path d="M 14.27 21.12 C 14.27 21.35 14.35 21.54 14.51 21.69 C 14.66 21.85 14.85 21.93 15.09 21.93 C 15.33 21.93 15.52 21.85 15.68 21.70 C 15.84 21.54 15.91 21.35 15.91 21.12 C 15.91 20.88 15.83 20.69 15.68 20.53 C 15.52 20.37 15.33 20.30 15.09 20.30 C 14.85 20.30 14.66 20.38 14.50 20.53 C 14.34 20.68 14.27 20.88 14.27 21.12 Z"/>
<path d="M 13.53 24.08 C 13.53 24.25 13.58 24.41 13.68 24.56 C 13.78 24.71 13.93 24.82 14.14 24.88 C 14.17 24.88 14.22 24.89 14.28 24.90 C 14.34 24.91 14.39 24.92 14.42 24.92 C 14.83 24.92 15.08 24.70 15.18 24.26 L 15.32 23.66 C 15.39 23.45 15.37 23.24 15.25 23.03 C 15.13 22.82 14.96 22.69 14.74 22.62 C 14.49 22.56 14.26 22.58 14.06 22.70 C 13.86 22.82 13.72 22.99 13.65 23.23 L 13.56 23.82 C 13.56 23.83 13.56 23.87 13.55 23.93 C 13.54 24.00 13.53 24.04 13.53 24.08 Z"/>
<path d="M 10.77 21.93 C 10.76 22.08 10.80 22.24 10.91 22.40 C 11.01 22.56 11.16 22.66 11.36 22.70 C 11.59 22.76 11.80 22.74 12.00 22.64 C 12.20 22.54 12.33 22.35 12.41 22.08 L 12.67 21.18 C 12.74 20.96 12.72 20.75 12.60 20.55 C 12.48 20.35 12.31 20.22 12.07 20.15 C 11.85 20.08 11.64 20.11 11.43 20.23 C 11.22 20.35 11.09 20.53 11.02 20.76 L 10.80 21.66 C 10.78 21.74 10.77 21.83 10.77 21.93 Z"/>
<path d="M 10.15 24.20 C 10.15 24.43 10.23 24.62 10.39 24.78 C 10.55 24.94 10.75 25.02 10.97 25.02 C 11.21 25.02 11.40 24.94 11.56 24.79 C 11.72 24.63 11.79 24.44 11.79 24.20 C 11.79 23.97 11.71 23.78 11.56 23.62 C 11.40 23.46 11.21 23.39 10.97 23.39 C 10.73 23.39 10.54 23.47 10.38 23.62 C 10.22 23.77 10.15 23.97 10.15 24.20 Z"/>
<path d="M 9.36 27.10 C 9.36 27.27 9.41 27.43 9.52 27.59 C 9.63 27.75 9.79 27.86 10.01 27.92 C 10.10 27.94 10.18 27.95 10.25 27.95 C 10.68 27.95 10.95 27.75 11.05 27.34 L 11.18 26.75 C 11.24 26.49 11.21 26.27 11.10 26.07 C 10.99 25.87 10.81 25.75 10.58 25.70 C 10.37 25.63 10.16 25.65 9.95 25.77 C 9.74 25.89 9.61 26.06 9.54 26.28 L 9.40 26.88 C 9.37 26.99 9.36 27.07 9.36 27.10 Z"/>
<path d="M 8.21 18.81 C 8.20 18.97 8.24 19.12 8.34 19.26 C 8.44 19.41 8.60 19.51 8.82 19.58 C 9.03 19.64 9.23 19.62 9.44 19.51 C 9.65 19.40 9.79 19.23 9.86 19.00 L 10.13 18.10 C 10.20 17.86 10.18 17.64 10.06 17.45 C 9.94 17.26 9.76 17.13 9.52 17.06 C 9.30 16.99 9.09 17.01 8.89 17.13 C 8.69 17.24 8.55 17.41 8.48 17.63 L 8.24 18.55 C 8.22 18.71 8.21 18.80 8.21 18.81 Z"/>
<path d="M 7.60 21.08 C 7.60 21.30 7.68 21.49 7.84 21.65 C 8.00 21.83 8.19 21.91 8.40 21.91 C 8.64 21.91 8.84 21.83 9.00 21.67 C 9.17 21.51 9.25 21.32 9.25 21.08 C 9.25 20.85 9.17 20.65 9.00 20.49 C 8.83 20.33 8.63 20.25 8.40 20.25 C 8.17 20.25 7.98 20.33 7.82 20.48 C 7.66 20.63 7.60 20.85 7.60 21.08 Z"/>
<path d="M 6.83 23.98 C 6.83 24.15 6.88 24.32 6.99 24.49 C 7.10 24.66 7.26 24.77 7.46 24.84 C 7.69 24.91 7.91 24.90 8.10 24.80 C 8.30 24.71 8.43 24.52 8.50 24.24 L 8.64 23.63 C 8.69 23.40 8.66 23.19 8.54 23.00 C 8.42 22.80 8.25 22.67 8.02 22.60 C 7.79 22.53 7.58 22.56 7.38 22.68 C 7.18 22.80 7.06 22.97 7.00 23.20 L 6.86 23.79 C 6.84 23.85 6.83 23.91 6.83 23.98 Z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 7.0 KiB

View File

@@ -0,0 +1,16 @@
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" id="Layer_1" x="0px" y="0px" viewBox="0 0 30 30" style="enable-background:new 0 0 30 30;">
<path id="cloud" d="M 2.59 13.82 C 3.31 12.92 4.22 12.34 5.33 12.08 C 5.64 10.72 6.34 9.60 7.43 8.72 C 8.52 7.84 9.78 7.40 11.19 7.40 C 12.18 7.40 13.08 7.62 13.90 8.06 C 13.95 8.01 15.32 9.01 15.30 9.03 C 16.14 9.83 16.70 10.81 16.97 11.99 L 17.30 11.99 C 18.66 11.99 19.82 12.47 20.79 13.44 C 20.82 13.39 21.99 14.72 21.86 14.89 C 22.14 15.51 22.28 16.18 22.28 16.90 C 22.28 18.23 21.82 19.38 20.89 20.35 C 19.96 21.31 18.83 21.82 17.50 21.86 C 17.37 21.86 17.31 21.80 17.31 21.69 L 17.31 20.35 C 17.31 20.24 17.38 20.18 17.50 20.18 C 18.35 20.13 19.08 19.79 19.68 19.15 C 20.28 18.51 20.58 17.76 20.58 16.89 C 20.58 16.01 20.26 15.26 19.61 14.62 C 18.96 13.98 18.20 13.66 17.31 13.66 L 15.69 13.66 C 15.58 13.66 15.52 13.59 15.52 13.47 L 15.45 12.90 C 15.33 11.82 14.87 10.91 14.05 10.18 C 13.23 9.45 12.28 9.08 11.19 9.08 C 10.10 9.08 9.15 9.45 8.34 10.18 C 7.53 10.91 7.08 11.82 6.97 12.90 L 6.90 13.44 C 6.90 13.55 6.83 13.61 6.70 13.61 L 6.17 13.66 C 5.34 13.76 4.64 14.11 4.07 14.73 C 3.50 15.35 3.22 16.07 3.22 16.89 C 3.22 17.75 3.52 18.51 4.12 19.15 C 4.72 19.79 5.45 20.14 6.31 20.18 C 6.42 20.18 6.48 20.24 6.48 20.35 L 6.48 21.69 C 6.48 21.80 6.42 21.86 6.31 21.86 C 4.96 21.80 3.83 21.29 2.90 20.33 C 1.97 19.37 1.51 18.22 1.51 16.89 C 1.51 15.74 1.87 14.72 2.59 13.82 L 2.59 13.82 Z"/>
<g id="sun">
<path d="M 17.78 6.32 C 18.72 6.32 19.59 6.55 20.40 7.02 C 21.21 7.49 21.85 8.13 22.32 8.94 C 22.79 9.75 23.03 10.63 23.03 11.58 C 23.03 12.61 22.43 14.13 21.90 14.97 L 20.81 13.48 C 21.11 12.92 21.31 12.16 21.31 11.59 C 21.31 10.60 20.97 9.76 20.28 9.07 C 19.60 8.38 18.76 8.03 17.78 8.03 C 16.86 8.03 15.99 8.43 15.30 9.05 L 13.91 8.07 C 14.92 7.01 16.29 6.32 17.78 6.32 L 17.78 6.32 Z"/>
<path d="M 24.72 11.58 C 24.72 11.82 24.81 12.01 24.98 12.17 C 25.16 12.35 25.36 12.43 25.60 12.43 L 27.63 12.43 C 27.87 12.43 28.07 12.35 28.24 12.18 C 28.41 12.01 28.49 11.81 28.49 11.58 C 28.49 11.34 28.41 11.14 28.24 10.97 C 28.07 10.80 27.87 10.71 27.63 10.71 L 25.60 10.71 C 25.36 10.71 25.16 10.80 24.98 10.97 C 24.80 11.14 24.72 11.34 24.72 11.58 Z"/>
<path d="M 23.26 17.91 C 23.26 18.15 23.34 18.36 23.50 18.54 L 24.15 19.17 C 24.33 19.31 24.53 19.38 24.75 19.38 L 24.77 19.40 C 25.00 19.40 25.19 19.32 25.35 19.16 C 25.51 19.00 25.59 18.79 25.59 18.55 C 25.59 18.31 25.50 18.12 25.33 17.97 L 24.71 17.31 C 24.53 17.15 24.32 17.07 24.09 17.07 C 23.86 17.07 23.66 17.15 23.50 17.32 C 23.34 17.49 23.26 17.67 23.26 17.91 Z"/>
<path d="M 22.45 6.06 C 22.45 6.30 22.54 6.50 22.72 6.65 C 22.86 6.81 23.04 6.89 23.27 6.91 C 23.50 6.93 23.71 6.84 23.89 6.65 L 25.33 5.22 C 25.51 5.05 25.59 4.84 25.59 4.59 C 25.59 4.35 25.51 4.14 25.34 3.98 C 25.17 3.82 24.97 3.74 24.73 3.74 C 24.52 3.74 24.33 3.82 24.15 3.99 L 22.72 5.43 C 22.54 5.60 22.45 5.81 22.45 6.06 Z"/>
<path d="M 16.92 3.78 C 16.92 4.01 17.00 4.21 17.17 4.37 C 17.34 4.53 17.54 4.61 17.78 4.61 C 18.01 4.61 18.21 4.53 18.37 4.38 C 18.53 4.22 18.61 4.03 18.61 3.79 L 18.61 1.73 C 18.61 1.47 18.53 1.26 18.38 1.10 C 18.22 0.94 18.03 0.86 17.79 0.86 C 17.54 0.86 17.33 0.94 17.17 1.11 C 17.01 1.28 16.93 1.48 16.93 1.73 L 16.93 3.78 L 16.92 3.78 Z"/>
<path d="M 9.94 4.60 C 9.94 4.84 10.02 5.04 10.19 5.21 L 10.84 5.87 C 11.03 6.02 11.24 6.09 11.46 6.09 C 11.67 6.09 11.87 6.01 12.04 5.86 C 12.21 5.70 12.30 5.51 12.30 5.27 C 12.30 5.03 12.22 4.81 12.06 4.63 L 11.42 3.98 C 11.24 3.81 11.04 3.73 10.82 3.73 C 10.58 3.73 10.37 3.82 10.20 3.99 C 10.03 4.16 9.94 4.37 9.94 4.60 Z"/>
</g>
<g id="rain">
<path d="M 13.67 23.77 C 13.67 23.93 13.72 24.09 13.82 24.24 C 13.92 24.39 14.08 24.50 14.28 24.56 C 14.39 24.58 14.48 24.60 14.53 24.60 C 14.70 24.60 14.87 24.55 15.02 24.45 C 15.17 24.35 15.27 24.19 15.32 23.96 L 16.90 18.08 C 16.96 17.85 16.94 17.63 16.83 17.44 C 16.72 17.24 16.55 17.11 16.33 17.04 C 16.09 16.97 15.88 16.99 15.68 17.11 C 15.48 17.22 15.35 17.39 15.29 17.62 L 13.71 23.53 C 13.69 23.68 13.67 23.76 13.67 23.77 Z"/>
<path d="M 9.52 26.83 C 9.52 27.02 9.57 27.19 9.67 27.35 C 9.77 27.51 9.94 27.61 10.19 27.65 C 10.30 27.67 10.39 27.69 10.45 27.69 C 10.61 27.69 10.76 27.63 10.90 27.52 C 11.04 27.40 11.13 27.24 11.17 27.04 L 13.57 18.11 C 13.63 17.88 13.61 17.66 13.50 17.47 C 13.39 17.28 13.22 17.14 13.00 17.07 C 12.77 17.00 12.55 17.02 12.35 17.14 C 12.15 17.25 12.01 17.42 11.95 17.65 L 9.55 26.58 C 9.53 26.73 9.52 26.82 9.52 26.83 Z"/>
<path d="M 6.91 23.75 C 6.91 23.92 6.96 24.08 7.07 24.24 C 7.18 24.40 7.34 24.51 7.56 24.57 C 7.67 24.59 7.76 24.61 7.83 24.61 C 8.22 24.61 8.48 24.40 8.60 23.97 L 10.18 18.09 C 10.25 17.85 10.22 17.63 10.10 17.42 C 9.98 17.21 9.80 17.09 9.57 17.04 C 9.35 16.97 9.14 16.99 8.94 17.11 C 8.74 17.22 8.60 17.39 8.53 17.62 L 6.95 23.53 C 6.93 23.66 6.91 23.73 6.91 23.75 Z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.8 KiB

View File

@@ -0,0 +1,19 @@
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" id="Layer_1" x="0px" y="0px" viewBox="0 0 30 30" style="enable-background:new 0 0 30 30;">
<path id="cloud" d="M 2.63 13.81 C 3.35 12.92 4.28 12.35 5.40 12.09 C 5.70 10.73 6.38 9.61 7.47 8.74 C 8.56 7.87 9.81 7.43 11.22 7.43 C 12.25 7.43 13.16 7.64 13.95 8.07 C 13.99 8.02 15.39 9.03 15.36 9.06 C 16.21 9.87 16.77 10.84 17.03 11.98 L 17.37 11.98 C 18.73 11.98 19.88 12.45 20.84 13.41 C 20.88 13.34 22.03 14.71 21.86 14.92 C 22.13 15.51 22.27 16.17 22.27 16.88 C 22.27 17.76 22.07 18.57 21.65 19.32 C 21.24 20.07 20.67 20.66 19.94 21.12 C 19.21 21.58 18.42 21.82 17.54 21.84 C 17.43 21.84 17.37 21.78 17.37 21.67 L 17.37 20.33 C 17.37 20.21 17.43 20.15 17.54 20.15 C 18.38 20.08 19.10 19.73 19.70 19.10 C 20.30 18.47 20.60 17.73 20.60 16.88 C 20.60 16.00 20.28 15.25 19.64 14.61 C 19.00 13.97 18.25 13.65 17.37 13.65 L 15.70 13.65 C 15.58 13.65 15.52 13.59 15.52 13.47 L 15.45 12.90 C 15.35 11.82 14.89 10.92 14.08 10.19 C 13.27 9.46 12.31 9.10 11.22 9.10 C 10.12 9.10 9.17 9.46 8.36 10.19 C 7.55 10.91 7.10 11.82 6.99 12.90 L 6.93 13.43 C 6.93 13.55 6.86 13.61 6.73 13.61 L 6.23 13.65 C 5.39 13.75 4.69 14.10 4.13 14.71 C 3.57 15.32 3.29 16.04 3.29 16.88 C 3.29 17.74 3.58 18.49 4.18 19.13 C 4.78 19.77 5.50 20.11 6.35 20.15 C 6.46 20.15 6.52 20.21 6.52 20.33 L 6.52 21.67 C 6.52 21.78 6.46 21.84 6.35 21.84 C 5.01 21.77 3.88 21.27 2.95 20.31 C 2.02 19.35 1.56 18.21 1.56 16.88 C 1.56 15.73 1.92 14.70 2.63 13.81 Z"/>
<g id="sun">
<path d="M 17.78 6.41 C 18.49 6.41 19.17 6.54 19.82 6.82 C 20.46 7.09 21.02 7.46 21.48 7.93 C 21.95 8.40 22.33 8.95 22.60 9.60 C 22.87 10.25 23.01 10.93 23.01 11.64 C 23.01 12.61 22.34 14.13 21.89 14.91 L 20.88 13.46 C 21.13 12.92 21.33 12.14 21.33 11.65 C 21.33 10.67 20.98 9.83 20.29 9.14 C 19.60 8.45 18.76 8.10 17.78 8.10 C 16.88 8.10 16.02 8.47 15.37 9.06 L 13.98 8.07 C 14.98 7.06 16.34 6.41 17.78 6.41 Z"/>
<path d="M 24.71 11.64 C 24.71 11.86 24.79 12.06 24.95 12.22 C 25.11 12.38 25.31 12.46 25.53 12.46 L 27.57 12.46 C 27.83 12.46 28.04 12.38 28.20 12.23 C 28.36 12.07 28.44 11.88 28.44 11.64 C 28.44 11.39 28.36 11.18 28.19 11.02 C 28.02 10.86 27.82 10.78 27.57 10.78 L 25.53 10.78 C 25.30 10.78 25.10 10.86 24.94 11.03 C 24.79 11.20 24.71 11.41 24.71 11.64 Z"/>
<path d="M 23.24 17.95 C 23.24 18.18 23.33 18.39 23.50 18.58 L 24.12 19.22 C 24.33 19.43 24.53 19.53 24.74 19.53 C 24.93 19.53 25.13 19.43 25.32 19.22 C 25.50 19.04 25.59 18.83 25.58 18.61 C 25.57 18.38 25.49 18.18 25.32 18.01 L 24.67 17.35 C 24.51 17.19 24.32 17.11 24.10 17.11 C 23.86 17.11 23.66 17.19 23.49 17.36 C 23.33 17.52 23.24 17.72 23.24 17.95 Z"/>
<path d="M 22.45 6.12 C 22.45 6.37 22.53 6.57 22.68 6.73 C 22.89 6.90 23.09 6.98 23.30 6.98 C 23.49 6.98 23.68 6.90 23.89 6.73 L 25.32 5.30 C 25.48 5.12 25.56 4.91 25.56 4.67 C 25.56 4.43 25.48 4.23 25.32 4.07 C 25.16 3.91 24.96 3.83 24.73 3.83 C 24.50 3.83 24.30 3.91 24.12 4.07 L 22.68 5.50 C 22.53 5.68 22.45 5.88 22.45 6.12 Z"/>
<path d="M 16.90 3.83 C 16.90 4.08 16.98 4.28 17.14 4.44 C 17.30 4.60 17.50 4.68 17.75 4.68 C 18.00 4.68 18.20 4.60 18.36 4.44 C 18.52 4.28 18.60 4.08 18.60 3.83 L 18.60 1.81 C 18.60 1.56 18.52 1.35 18.36 1.19 C 18.20 1.03 18.00 0.95 17.75 0.95 C 17.50 0.95 17.30 1.03 17.14 1.19 C 16.98 1.35 16.90 1.56 16.90 1.81 L 16.90 3.83 Z"/>
<path d="M 9.96 4.68 C 9.96 4.93 10.04 5.14 10.21 5.30 L 10.87 5.95 C 11.21 6.29 11.60 6.29 12.04 5.95 C 12.20 5.78 12.28 5.57 12.28 5.34 C 12.28 5.11 12.20 4.91 12.04 4.73 L 11.41 4.07 C 11.25 3.91 11.05 3.83 10.81 3.83 C 10.58 3.83 10.38 3.91 10.21 4.08 C 10.04 4.24 9.96 4.44 9.96 4.68 Z"/>
</g>
<g id="rain">
<path d="M 15.03 18.92 C 15.03 19.08 15.08 19.24 15.18 19.40 C 15.28 19.56 15.43 19.67 15.63 19.72 L 15.88 19.75 C 16.07 19.75 16.25 19.69 16.40 19.57 C 16.55 19.45 16.64 19.29 16.68 19.10 L 16.95 18.11 C 17.02 17.87 17.00 17.66 16.88 17.46 C 16.77 17.26 16.60 17.13 16.37 17.07 C 16.14 17.00 15.92 17.02 15.73 17.13 C 15.53 17.24 15.40 17.41 15.34 17.63 L 15.04 18.69 C 15.04 18.77 15.03 18.85 15.03 18.92 Z"/>
<path d="M 13.63 23.68 C 13.65 24.06 13.86 24.33 14.26 24.51 L 14.51 24.55 C 14.67 24.55 14.83 24.50 14.98 24.39 C 15.13 24.28 15.24 24.12 15.30 23.89 L 15.59 22.88 C 15.65 22.64 15.62 22.42 15.50 22.22 C 15.38 22.02 15.20 21.89 14.97 21.85 C 14.76 21.78 14.56 21.80 14.35 21.92 C 14.14 22.04 14.01 22.21 13.94 22.43 L 13.67 23.45 C 13.66 23.47 13.66 23.50 13.65 23.53 C 13.64 23.56 13.64 23.59 13.63 23.61 C 13.62 23.63 13.63 23.66 13.63 23.68 Z"/>
<path d="M 10.85 21.96 C 10.85 22.13 10.90 22.30 11.01 22.47 C 11.12 22.64 11.27 22.75 11.48 22.82 C 11.71 22.89 11.92 22.87 12.12 22.77 C 12.31 22.67 12.45 22.48 12.52 22.21 L 12.76 21.20 C 12.83 20.97 12.81 20.75 12.70 20.55 C 12.59 20.35 12.42 20.21 12.20 20.14 C 11.95 20.07 11.72 20.10 11.52 20.22 C 11.32 20.34 11.19 20.52 11.15 20.75 L 10.87 21.78 C 10.85 21.81 10.85 21.87 10.85 21.96 Z"/>
<path d="M 9.50 26.75 C 9.50 26.91 9.56 27.08 9.67 27.25 C 9.78 27.42 9.95 27.54 10.16 27.61 C 10.17 27.61 10.20 27.61 10.26 27.62 C 10.32 27.63 10.37 27.63 10.41 27.63 C 10.55 27.63 10.67 27.61 10.78 27.56 C 10.97 27.48 11.11 27.29 11.19 26.98 L 11.46 25.99 C 11.53 25.76 11.51 25.54 11.39 25.34 C 11.27 25.14 11.10 25.00 10.88 24.94 C 10.65 24.87 10.43 24.89 10.23 25.01 C 10.03 25.13 9.89 25.30 9.83 25.52 L 9.55 26.54 C 9.51 26.63 9.50 26.70 9.50 26.75 Z"/>
<path d="M 8.28 18.86 C 8.28 19.24 8.49 19.50 8.92 19.65 C 9.14 19.73 9.35 19.71 9.56 19.60 C 9.77 19.49 9.90 19.31 9.97 19.07 L 10.21 18.04 C 10.28 17.83 10.26 17.63 10.14 17.42 C 10.03 17.21 9.86 17.07 9.63 17.00 C 9.39 16.94 9.16 16.96 8.96 17.08 C 8.76 17.20 8.64 17.37 8.59 17.60 L 8.29 18.62 C 8.29 18.70 8.28 18.78 8.28 18.86 Z"/>
<path d="M 6.97 23.58 C 6.97 23.76 7.02 23.94 7.13 24.11 C 7.24 24.29 7.39 24.40 7.58 24.47 C 7.77 24.54 7.98 24.52 8.19 24.41 C 8.41 24.30 8.55 24.12 8.63 23.86 L 8.88 22.81 C 8.95 22.60 8.93 22.40 8.81 22.19 C 8.69 21.98 8.52 21.84 8.30 21.77 C 8.05 21.71 7.83 21.74 7.63 21.85 C 7.43 21.96 7.31 22.15 7.26 22.38 L 6.98 23.37 C 6.98 23.42 6.97 23.49 6.97 23.58 Z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.0 KiB

View File

@@ -0,0 +1,20 @@
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" id="Layer_1" x="0px" y="0px" viewBox="0 0 30 30" style="enable-background:new 0 0 30 30;">
<path id="cloud" d="M 2.64 13.85 C 3.35 12.96 4.26 12.38 5.38 12.10 C 5.69 10.75 6.38 9.63 7.47 8.76 C 8.56 7.89 9.80 7.45 11.21 7.45 C 12.19 7.45 13.09 7.67 13.90 8.11 C 13.93 8.08 15.31 9.05 15.30 9.06 C 16.12 9.85 16.68 10.83 16.98 12.00 L 17.30 12.00 C 18.66 12.00 19.82 12.48 20.77 13.44 C 20.82 13.36 22.01 14.68 21.85 14.88 C 22.14 15.48 22.28 16.15 22.28 16.91 C 22.28 18.23 21.82 19.36 20.89 20.32 C 19.96 21.28 18.84 21.78 17.51 21.82 C 17.38 21.82 17.32 21.76 17.32 21.65 L 17.32 20.32 C 17.32 20.19 17.39 20.13 17.51 20.13 C 18.35 20.08 19.08 19.74 19.68 19.11 C 20.28 18.47 20.58 17.74 20.58 16.90 C 20.58 16.01 20.26 15.25 19.62 14.61 C 18.98 13.97 18.21 13.65 17.31 13.65 L 15.70 13.65 C 15.59 13.65 15.53 13.59 15.53 13.48 L 15.46 12.90 C 15.36 11.83 14.90 10.93 14.08 10.20 C 13.27 9.47 12.32 9.11 11.23 9.11 C 10.13 9.11 9.18 9.47 8.38 10.20 C 7.58 10.93 7.13 11.84 7.02 12.93 L 6.94 13.44 C 6.94 13.57 6.88 13.63 6.76 13.63 L 6.23 13.69 C 5.39 13.79 4.70 14.15 4.13 14.76 C 3.56 15.38 3.28 16.10 3.28 16.92 C 3.28 17.76 3.58 18.49 4.18 19.13 C 4.78 19.77 5.51 20.11 6.36 20.15 C 6.47 20.15 6.53 20.22 6.53 20.34 L 6.53 21.67 C 6.53 21.78 6.47 21.84 6.36 21.84 C 5.50 21.82 4.69 21.58 3.96 21.13 C 3.22 20.68 2.64 20.08 2.22 19.34 C 1.79 18.60 1.58 17.79 1.58 16.93 C 1.58 15.77 1.93 14.75 2.64 13.85 Z"/>
<g id="sun">
<path d="M 17.77 6.38 C 18.71 6.38 19.59 6.61 20.39 7.08 C 21.19 7.55 21.83 8.19 22.30 8.99 C 22.77 9.79 23.00 10.66 23.00 11.60 C 23.00 12.58 22.65 13.82 21.87 14.96 C 21.53 15.47 20.78 13.48 20.78 13.48 C 21.03 12.96 21.28 12.14 21.28 11.60 C 21.28 10.64 20.94 9.80 20.25 9.11 C 19.57 8.42 18.74 8.07 17.77 8.07 C 16.83 8.07 15.99 8.45 15.30 9.09 L 13.94 8.12 C 14.97 7.03 16.27 6.38 17.77 6.38 Z"/>
<path d="M 24.67 11.60 C 24.67 11.84 24.76 12.03 24.93 12.19 C 25.10 12.37 25.31 12.46 25.55 12.46 L 27.57 12.46 C 27.80 12.46 28.00 12.38 28.17 12.21 C 28.34 12.04 28.42 11.84 28.42 11.60 C 28.42 11.36 28.34 11.16 28.17 11.00 C 28.00 10.84 27.80 10.75 27.57 10.75 L 25.55 10.75 C 25.31 10.75 25.11 10.83 24.93 11.00 C 24.75 11.17 24.67 11.37 24.67 11.60 Z"/>
<path d="M 23.22 17.91 C 23.22 18.16 23.30 18.37 23.46 18.53 L 24.10 19.16 C 24.34 19.32 24.56 19.40 24.74 19.40 C 24.95 19.40 25.13 19.31 25.30 19.14 C 25.47 18.97 25.55 18.76 25.55 18.53 C 25.55 18.30 25.46 18.11 25.29 17.95 L 24.67 17.30 C 24.49 17.14 24.29 17.06 24.06 17.06 C 23.83 17.06 23.63 17.14 23.47 17.31 C 23.30 17.47 23.22 17.67 23.22 17.91 Z"/>
<path d="M 22.42 6.11 C 22.42 6.34 22.50 6.54 22.67 6.70 C 22.82 6.86 23.01 6.94 23.23 6.96 C 23.45 6.98 23.66 6.89 23.85 6.70 L 25.28 5.27 C 25.46 5.09 25.54 4.89 25.54 4.66 C 25.54 4.42 25.45 4.22 25.28 4.05 C 25.11 3.88 24.91 3.80 24.68 3.80 C 24.46 3.80 24.27 3.88 24.10 4.05 L 22.67 5.51 C 22.50 5.67 22.42 5.87 22.42 6.11 Z"/>
<path d="M 16.90 3.84 C 16.90 4.07 16.98 4.27 17.15 4.42 C 17.32 4.57 17.52 4.65 17.76 4.65 C 18.00 4.65 18.19 4.57 18.35 4.42 C 18.51 4.26 18.58 4.07 18.58 3.84 L 18.58 1.80 C 18.58 1.56 18.50 1.36 18.34 1.19 C 18.18 1.02 18.00 0.94 17.77 0.94 C 17.54 0.94 17.34 1.03 17.17 1.20 C 17.00 1.37 16.91 1.57 16.91 1.80 L 16.91 3.84 L 16.90 3.84 Z"/>
<path d="M 9.97 4.68 C 9.97 4.92 10.05 5.12 10.21 5.27 L 10.87 5.93 C 11.03 6.09 11.21 6.18 11.40 6.18 C 11.61 6.21 11.81 6.14 12.01 5.96 C 12.21 5.78 12.31 5.57 12.31 5.33 C 12.31 5.09 12.23 4.87 12.07 4.69 L 11.43 4.08 C 11.28 3.91 11.09 3.83 10.85 3.83 C 10.60 3.83 10.39 3.91 10.22 4.08 C 10.05 4.24 9.97 4.44 9.97 4.68 Z"/>
</g>
<g id="snow">
<path d="M 14.32 24.61 C 14.32 24.82 14.40 25.01 14.55 25.18 C 14.73 25.34 14.93 25.42 15.15 25.42 C 15.39 25.42 15.58 25.34 15.74 25.19 C 15.90 25.03 15.97 24.84 15.97 24.61 C 15.97 24.37 15.89 24.18 15.73 24.02 C 15.57 23.86 15.38 23.79 15.14 23.79 C 14.90 23.79 14.70 23.87 14.54 24.03 C 14.40 24.18 14.32 24.38 14.32 24.61 Z"/>
<path d="M 14.32 20.98 C 14.32 21.22 14.40 21.42 14.56 21.59 C 14.72 21.76 14.92 21.84 15.15 21.84 C 15.38 21.84 15.58 21.76 15.74 21.59 C 15.90 21.42 15.98 21.22 15.98 20.98 C 15.98 20.75 15.90 20.56 15.74 20.40 C 15.58 20.24 15.39 20.16 15.15 20.16 C 14.91 20.16 14.72 20.24 14.56 20.40 C 14.40 20.56 14.32 20.76 14.32 20.98 Z"/>
<path d="M 11.10 26.56 C 11.10 26.78 11.18 26.97 11.34 27.13 C 11.51 27.30 11.70 27.38 11.92 27.38 C 12.16 27.38 12.36 27.30 12.52 27.15 C 12.69 26.99 12.77 26.80 12.77 26.56 C 12.77 26.32 12.69 26.12 12.52 25.96 C 12.35 25.79 12.15 25.71 11.92 25.71 C 11.70 25.71 11.51 25.79 11.34 25.96 C 11.18 26.13 11.10 26.33 11.10 26.56 Z"/>
<path d="M 11.10 19.30 C 11.10 19.53 11.18 19.72 11.34 19.88 C 11.50 20.04 11.70 20.12 11.92 20.12 C 12.16 20.12 12.36 20.04 12.52 19.88 C 12.69 19.72 12.77 19.53 12.77 19.29 C 12.77 19.06 12.69 18.86 12.52 18.70 C 12.35 18.54 12.15 18.46 11.92 18.46 C 11.69 18.46 11.50 18.54 11.34 18.70 C 11.18 18.86 11.10 19.07 11.10 19.30 Z"/>
<path d="M 11.10 22.90 C 11.10 23.12 11.18 23.32 11.34 23.50 C 11.50 23.66 11.70 23.74 11.92 23.74 C 12.16 23.74 12.36 23.66 12.52 23.50 C 12.68 23.34 12.77 23.14 12.77 22.90 C 12.77 22.67 12.69 22.47 12.52 22.30 C 12.35 22.13 12.15 22.05 11.92 22.05 C 11.69 22.05 11.50 22.13 11.34 22.30 C 11.18 22.47 11.10 22.67 11.10 22.90 Z"/>
<path d="M 7.92 24.61 C 7.92 24.82 8.00 25.01 8.16 25.18 C 8.34 25.34 8.53 25.42 8.74 25.42 C 8.98 25.42 9.17 25.34 9.33 25.19 C 9.49 25.03 9.56 24.84 9.56 24.61 C 9.56 24.37 9.48 24.18 9.32 24.02 C 9.16 23.86 8.97 23.79 8.73 23.79 C 8.50 23.79 8.30 23.87 8.14 24.02 C 8.00 24.17 7.92 24.37 7.92 24.61 Z"/>
<path d="M 7.92 20.98 C 7.92 21.22 8.00 21.42 8.16 21.59 C 8.32 21.76 8.51 21.84 8.75 21.84 C 8.98 21.84 9.18 21.76 9.34 21.59 C 9.50 21.42 9.58 21.22 9.58 20.98 C 9.58 20.75 9.50 20.56 9.34 20.40 C 9.18 20.24 8.99 20.16 8.75 20.16 C 8.52 20.16 8.32 20.24 8.16 20.40 C 8.00 20.56 7.92 20.76 7.92 20.98 Z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.8 KiB

View File

@@ -0,0 +1,18 @@
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" id="Layer_1" x="0px" y="0px" viewBox="0 0 30 30" style="enable-background:new 0 0 30 30;">
<path id="cloud" d="M 2.56 13.78 C 3.28 12.88 4.19 12.30 5.30 12.04 C 5.60 10.67 6.31 9.55 7.40 8.67 C 8.49 7.79 9.75 7.35 11.17 7.35 C 12.18 7.35 13.08 7.57 13.89 8.00 C 13.95 7.94 15.36 8.98 15.31 9.02 C 16.15 9.78 16.72 10.76 17.01 11.95 L 17.32 11.95 C 18.71 11.95 19.88 12.43 20.84 13.39 C 20.88 13.32 22.04 14.66 21.88 14.86 C 22.17 15.48 22.31 16.15 22.31 16.88 C 22.31 17.76 22.10 18.58 21.67 19.33 C 21.24 20.08 20.66 20.69 19.93 21.14 C 19.20 21.60 18.39 21.84 17.51 21.86 C 17.38 21.86 17.31 21.80 17.31 21.69 L 17.31 20.35 C 17.31 20.23 17.38 20.17 17.51 20.17 C 18.37 20.12 19.09 19.78 19.69 19.14 C 20.29 18.50 20.59 17.75 20.59 16.88 C 20.59 15.99 20.27 15.23 19.62 14.59 C 18.97 13.95 18.20 13.63 17.31 13.63 L 15.70 13.63 C 15.58 13.63 15.52 13.57 15.52 13.46 L 15.44 12.87 C 15.33 11.79 14.86 10.88 14.04 10.15 C 13.22 9.42 12.27 9.05 11.18 9.05 C 10.08 9.05 9.13 9.42 8.32 10.15 C 7.51 10.88 7.06 11.79 6.95 12.87 L 6.88 13.46 C 6.85 13.55 6.78 13.60 6.66 13.60 L 6.15 13.63 C 5.31 13.73 4.60 14.09 4.04 14.70 C 3.48 15.31 3.20 16.04 3.20 16.88 C 3.20 17.64 3.43 18.31 3.90 18.90 C 4.31 19.44 5.07 19.86 5.69 20.05 L 5.07 21.67 C 4.10 21.36 3.12 20.71 2.49 19.88 C 1.82 19.00 1.49 18.00 1.49 16.88 C 1.49 15.73 1.85 14.70 2.56 13.78 L 2.56 13.78 Z"/>
<path id="lightning" d="M 5.68 20.06 L 6.75 17.18 C 6.81 17.08 6.89 17.03 6.98 17.03 L 9.94 17.03 C 10.11 17.03 10.15 17.11 10.08 17.25 L 7.59 21.90 L 9.78 21.90 C 9.85 21.90 9.90 21.92 9.92 21.97 C 9.94 22.02 9.94 22.07 9.90 22.11 L 5.54 27.77 L 5.25 27.77 L 6.68 23.56 L 4.55 23.56 C 4.41 23.56 4.36 23.48 4.41 23.34 L 5.07 21.64 C 5.01 21.62 5.60 20.04 5.68 20.06 L 5.68 20.06 Z"/>
<g id="rain">
<path d="M 15.21 18.86 C 15.21 19.04 15.26 19.20 15.37 19.36 C 15.48 19.52 15.64 19.63 15.86 19.69 C 16.03 19.75 16.23 19.73 16.47 19.64 C 16.67 19.55 16.81 19.36 16.90 19.07 L 17.17 18.07 C 17.23 17.82 17.21 17.60 17.09 17.40 C 16.97 17.20 16.80 17.08 16.56 17.03 C 16.33 16.96 16.12 16.98 15.92 17.09 C 15.72 17.20 15.59 17.37 15.52 17.59 L 15.23 18.65 C 15.22 18.79 15.21 18.86 15.21 18.86 Z"/>
<path d="M 13.84 23.68 C 13.84 23.82 13.87 23.96 13.94 24.07 C 14.07 24.28 14.25 24.43 14.48 24.50 C 14.59 24.54 14.69 24.56 14.76 24.56 C 14.89 24.56 14.99 24.54 15.07 24.48 C 15.27 24.41 15.42 24.21 15.52 23.88 L 15.77 22.87 C 15.84 22.63 15.82 22.42 15.70 22.22 C 15.59 22.02 15.42 21.89 15.19 21.83 C 14.96 21.76 14.74 21.78 14.54 21.90 C 14.34 22.01 14.20 22.18 14.13 22.41 L 13.85 23.45 C 13.85 23.53 13.84 23.61 13.84 23.68 Z"/>
<path d="M 11.01 22.00 C 11.00 22.16 11.05 22.32 11.15 22.47 C 11.25 22.62 11.41 22.73 11.63 22.79 C 11.84 22.86 12.05 22.84 12.25 22.73 C 12.45 22.62 12.59 22.43 12.67 22.17 L 12.97 21.14 C 13.04 20.92 13.01 20.71 12.89 20.51 C 12.77 20.31 12.59 20.17 12.35 20.10 C 12.12 20.03 11.91 20.05 11.71 20.17 C 11.51 20.29 11.37 20.46 11.30 20.70 L 11.06 21.75 C 11.03 21.90 11.01 21.98 11.01 22.00 Z"/>
<path d="M 9.67 26.80 C 9.67 26.95 9.72 27.11 9.83 27.27 C 9.94 27.43 10.09 27.54 10.29 27.61 C 10.40 27.64 10.49 27.65 10.54 27.65 C 10.69 27.65 10.82 27.62 10.92 27.57 C 11.13 27.49 11.28 27.30 11.35 27.00 L 11.62 25.97 C 11.68 25.72 11.65 25.50 11.54 25.30 C 11.43 25.10 11.24 24.98 11.01 24.93 C 10.80 24.86 10.60 24.89 10.39 25.00 C 10.18 25.12 10.04 25.29 9.97 25.52 L 9.72 26.56 C 9.69 26.70 9.67 26.78 9.67 26.80 Z"/>
</g>
<g id="sun">
<path d="M 15.68 6.72 C 16.36 6.42 17.06 6.27 17.78 6.27 C 18.73 6.27 19.61 6.51 20.42 6.98 C 21.23 7.45 21.87 8.09 22.34 8.90 C 22.81 9.71 23.05 10.59 23.05 11.54 C 23.05 12.51 22.34 14.04 21.86 14.84 L 20.81 13.46 C 21.05 12.97 21.34 12.12 21.34 11.55 C 21.34 10.57 20.99 9.73 20.30 9.05 C 19.61 8.36 18.77 8.02 17.79 8.02 C 16.89 8.02 15.93 8.45 15.29 9.00 L 13.87 7.98 C 14.33 7.54 15.08 6.98 15.69 6.72 L 15.68 6.72 Z"/>
<path d="M 24.73 11.58 C 24.73 11.82 24.82 12.02 24.99 12.17 C 25.15 12.35 25.35 12.43 25.59 12.43 L 27.65 12.43 C 27.89 12.43 28.09 12.35 28.26 12.18 C 28.43 12.01 28.51 11.81 28.51 11.58 C 28.51 11.35 28.43 11.14 28.26 10.98 C 28.09 10.82 27.89 10.74 27.65 10.74 L 25.59 10.74 C 25.35 10.74 25.14 10.82 24.98 10.98 C 24.81 11.14 24.73 11.34 24.73 11.58 Z"/>
<path d="M 23.26 17.95 C 23.26 18.18 23.34 18.38 23.51 18.55 L 24.16 19.18 C 24.34 19.35 24.55 19.43 24.78 19.43 L 24.80 19.45 C 25.02 19.45 25.20 19.36 25.34 19.18 C 25.52 19.02 25.60 18.82 25.60 18.58 C 25.60 18.35 25.51 18.15 25.34 17.97 L 24.72 17.35 C 24.54 17.17 24.34 17.08 24.11 17.08 C 23.87 17.08 23.67 17.17 23.51 17.34 C 23.35 17.51 23.26 17.72 23.26 17.95 Z"/>
<path d="M 22.49 6.04 C 22.49 6.28 22.57 6.48 22.72 6.64 C 22.86 6.80 23.04 6.88 23.27 6.90 C 23.50 6.92 23.71 6.83 23.90 6.64 L 25.34 5.20 C 25.52 5.04 25.60 4.84 25.60 4.60 C 25.60 4.36 25.51 4.16 25.34 4.00 C 25.18 3.82 24.98 3.74 24.74 3.74 C 24.51 3.74 24.32 3.83 24.16 4.00 L 22.72 5.44 C 22.56 5.59 22.49 5.79 22.49 6.04 Z"/>
<path d="M 16.91 3.75 C 16.91 3.99 16.99 4.19 17.16 4.36 C 17.33 4.53 17.53 4.61 17.76 4.61 C 18.00 4.61 18.20 4.53 18.36 4.36 C 18.52 4.19 18.60 3.99 18.60 3.75 L 18.60 1.69 C 18.60 1.45 18.52 1.24 18.36 1.08 C 18.20 0.91 18.00 0.82 17.76 0.82 C 17.52 0.82 17.32 0.90 17.16 1.07 C 17.00 1.24 16.91 1.44 16.91 1.68 L 16.91 3.75 Z"/>
<path d="M 9.90 4.59 C 9.90 4.82 9.98 5.02 10.15 5.19 L 10.80 5.85 C 10.96 6.01 11.14 6.09 11.35 6.11 C 11.56 6.14 11.76 6.07 11.96 5.88 C 12.16 5.70 12.26 5.49 12.26 5.24 C 12.26 5.01 12.18 4.81 12.01 4.64 L 11.38 3.98 C 11.22 3.82 11.02 3.74 10.78 3.74 C 10.53 3.74 10.32 3.82 10.15 3.98 C 9.99 4.16 9.90 4.36 9.90 4.59 Z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.6 KiB

View File

@@ -0,0 +1,3 @@
<!-- Generator: Adobe Illustrator 22.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) --><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Layer_1" x="0px" y="0px" viewBox="0 0 30 30" style="enable-background:new 0 0 30 30;" xml:space="preserve">
<path id="sun" d="M4.37,14.62c0-0.24,0.08-0.45,0.25-0.62c0.17-0.16,0.38-0.24,0.6-0.24h2.04c0.23,0,0.42,0.08,0.58,0.25 c0.15,0.17,0.23,0.37,0.23,0.61S8,15.06,7.85,15.23c-0.15,0.17-0.35,0.25-0.58,0.25H5.23c-0.23,0-0.43-0.08-0.6-0.25 C4.46,15.06,4.37,14.86,4.37,14.62z M7.23,21.55c0-0.23,0.08-0.43,0.23-0.61l1.47-1.43c0.15-0.16,0.35-0.23,0.59-0.23 c0.24,0,0.44,0.08,0.6,0.23s0.24,0.34,0.24,0.57c0,0.24-0.08,0.46-0.24,0.64L8.7,22.14c-0.41,0.32-0.82,0.32-1.23,0 C7.31,21.98,7.23,21.78,7.23,21.55z M7.23,7.71c0-0.23,0.08-0.43,0.23-0.61C7.66,6.93,7.87,6.85,8.1,6.85 c0.22,0,0.42,0.08,0.59,0.24l1.43,1.47c0.16,0.15,0.24,0.35,0.24,0.59c0,0.24-0.08,0.44-0.24,0.6s-0.36,0.24-0.6,0.24 c-0.24,0-0.44-0.08-0.59-0.24L7.47,8.32C7.31,8.16,7.23,7.95,7.23,7.71z M9.78,14.62c0-0.93,0.23-1.8,0.7-2.6s1.1-1.44,1.91-1.91 s1.67-0.7,2.6-0.7c0.7,0,1.37,0.14,2.02,0.42c0.64,0.28,1.2,0.65,1.66,1.12c0.47,0.47,0.84,1.02,1.11,1.66 c0.27,0.64,0.41,1.32,0.41,2.02c0,0.94-0.23,1.81-0.7,2.61c-0.47,0.8-1.1,1.43-1.9,1.9c-0.8,0.47-1.67,0.7-2.61,0.7 s-1.81-0.23-2.61-0.7c-0.8-0.47-1.43-1.1-1.9-1.9C10.02,16.43,9.78,15.56,9.78,14.62z M11.48,14.62c0,0.98,0.34,1.81,1.03,2.5 c0.68,0.69,1.51,1.04,2.49,1.04s1.81-0.35,2.5-1.04s1.04-1.52,1.04-2.5c0-0.96-0.35-1.78-1.04-2.47c-0.69-0.68-1.52-1.02-2.5-1.02 c-0.97,0-1.8,0.34-2.48,1.02C11.82,12.84,11.48,13.66,11.48,14.62z M14.14,22.4c0-0.24,0.08-0.44,0.25-0.6s0.37-0.24,0.6-0.24 c0.24,0,0.45,0.08,0.61,0.24s0.24,0.36,0.24,0.6v1.99c0,0.24-0.08,0.45-0.25,0.62c-0.17,0.17-0.37,0.25-0.6,0.25 s-0.44-0.08-0.6-0.25c-0.17-0.17-0.25-0.38-0.25-0.62V22.4z M14.14,6.9V4.86c0-0.23,0.08-0.43,0.25-0.6C14.56,4.09,14.76,4,15,4 s0.43,0.08,0.6,0.25c0.17,0.17,0.25,0.37,0.25,0.6V6.9c0,0.23-0.08,0.42-0.25,0.58S15.23,7.71,15,7.71s-0.44-0.08-0.6-0.23 S14.14,7.13,14.14,6.9z M19.66,20.08c0-0.23,0.08-0.42,0.23-0.56c0.15-0.16,0.34-0.23,0.56-0.23c0.24,0,0.44,0.08,0.6,0.23 l1.46,1.43c0.16,0.17,0.24,0.38,0.24,0.61c0,0.23-0.08,0.43-0.24,0.59c-0.4,0.31-0.8,0.31-1.2,0l-1.42-1.42 C19.74,20.55,19.66,20.34,19.66,20.08z M19.66,9.16c0-0.25,0.08-0.45,0.23-0.59l1.42-1.47c0.17-0.16,0.37-0.24,0.59-0.24 c0.24,0,0.44,0.08,0.6,0.25c0.17,0.17,0.25,0.37,0.25,0.6c0,0.25-0.08,0.46-0.24,0.62l-1.46,1.43c-0.18,0.16-0.38,0.24-0.6,0.24 c-0.23,0-0.41-0.08-0.56-0.24S19.66,9.4,19.66,9.16z M21.92,14.62c0-0.24,0.08-0.44,0.24-0.62c0.16-0.16,0.35-0.24,0.57-0.24h2.02 c0.23,0,0.43,0.09,0.6,0.26c0.17,0.17,0.26,0.37,0.26,0.6s-0.09,0.43-0.26,0.6c-0.17,0.17-0.37,0.25-0.6,0.25h-2.02 c-0.23,0-0.43-0.08-0.58-0.25S21.92,14.86,21.92,14.62z"/>
</svg>

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

@@ -0,0 +1,16 @@
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" id="Layer_1" x="0px" y="0px" viewBox="0 0 30 30" style="enable-background:new 0 0 30 30;">
<path id="cloud" d="M 2.61 13.81 C 3.32 12.91 4.23 12.34 5.34 12.08 C 5.65 10.71 6.35 9.59 7.44 8.72 C 8.53 7.85 9.79 7.41 11.20 7.41 C 12.19 7.41 13.09 7.63 13.90 8.06 C 13.93 8.02 15.32 9.02 15.30 9.04 C 16.11 9.81 16.68 10.78 16.99 11.95 L 17.30 11.95 C 18.64 11.95 19.81 12.44 20.80 13.42 C 20.84 13.35 22.02 14.69 21.85 14.90 C 22.14 15.50 22.28 16.17 22.28 16.91 C 22.28 18.25 21.82 19.40 20.89 20.36 C 19.96 21.32 18.83 21.83 17.50 21.87 C 17.37 21.87 17.30 21.81 17.30 21.70 L 17.30 20.33 C 17.30 20.21 17.37 20.15 17.50 20.15 C 18.37 20.08 19.10 19.73 19.69 19.11 C 20.28 18.49 20.58 17.75 20.58 16.90 C 20.58 16.00 20.26 15.24 19.62 14.61 C 18.98 13.98 18.21 13.66 17.30 13.66 L 15.69 13.66 C 15.57 13.66 15.51 13.60 15.51 13.49 L 15.45 12.91 C 15.33 11.83 14.86 10.92 14.05 10.19 C 13.24 9.46 12.29 9.09 11.20 9.09 C 10.11 9.09 9.15 9.46 8.34 10.19 C 7.53 10.92 7.07 11.83 6.96 12.91 L 6.90 13.42 C 6.90 13.54 6.83 13.60 6.70 13.60 L 6.18 13.66 C 5.35 13.76 4.65 14.11 4.08 14.73 C 3.51 15.35 3.23 16.07 3.23 16.90 C 3.23 17.65 3.46 18.32 3.93 18.91 C 4.37 19.46 5.03 19.89 5.68 20.08 L 5.07 21.72 C 4.07 21.40 3.12 20.70 2.50 19.86 C 1.85 18.99 1.52 18.01 1.52 16.90 C 1.52 15.75 1.90 14.71 2.61 13.81 Z"/>
<path id="lightning" d="M 5.70 20.07 L 6.77 17.19 C 6.83 17.10 6.91 17.05 7.00 17.05 L 9.94 17.05 C 10.10 17.05 10.15 17.13 10.08 17.27 L 7.61 21.90 L 9.78 21.90 C 9.85 21.90 9.90 21.92 9.92 21.97 C 9.95 22.02 9.95 22.07 9.91 22.11 L 5.74 27.50 L 5.45 27.50 L 6.70 23.55 L 4.57 23.55 C 4.43 23.55 4.39 23.48 4.43 23.34 L 5.07 21.64 C 5.03 21.63 5.65 20.06 5.70 20.07 Z"/>
<g id="sun">
<path d="M 17.78 6.33 C 18.72 6.33 19.59 6.57 20.40 7.04 C 21.21 7.51 21.85 8.15 22.32 8.96 C 22.79 9.77 23.03 10.64 23.03 11.58 C 23.03 12.56 22.49 14.34 21.87 14.98 L 20.82 13.44 C 21.09 12.90 21.32 12.12 21.32 11.57 C 21.32 10.60 20.97 9.77 20.28 9.09 C 19.59 8.41 18.75 8.07 17.78 8.07 C 16.82 8.07 15.98 8.50 15.32 9.10 L 13.86 8.09 C 14.88 7.01 16.29 6.33 17.78 6.33 Z"/>
<path d="M 24.70 11.58 C 24.70 11.81 24.79 12.01 24.97 12.18 C 25.15 12.36 25.35 12.45 25.58 12.45 L 27.61 12.45 C 27.84 12.45 28.04 12.36 28.21 12.19 C 28.38 12.02 28.47 11.81 28.47 11.58 C 28.47 11.35 28.39 11.15 28.22 10.99 C 28.05 10.83 27.85 10.75 27.61 10.75 L 25.58 10.75 C 25.33 10.75 25.12 10.83 24.95 10.99 C 24.78 11.15 24.70 11.35 24.70 11.58 Z"/>
<path d="M 23.25 17.93 C 23.25 18.15 23.33 18.35 23.49 18.53 L 24.15 19.16 C 24.27 19.30 24.46 19.39 24.69 19.40 L 24.70 19.41 C 24.71 19.41 24.73 19.41 24.75 19.41 C 24.77 19.41 24.78 19.41 24.80 19.41 C 24.99 19.41 25.16 19.32 25.33 19.15 C 25.50 18.99 25.59 18.79 25.59 18.55 C 25.59 18.32 25.50 18.12 25.33 17.94 L 24.68 17.33 C 24.52 17.15 24.32 17.06 24.10 17.06 C 23.87 17.06 23.67 17.14 23.50 17.31 C 23.33 17.49 23.25 17.70 23.25 17.93 Z"/>
<path d="M 22.44 6.07 C 22.44 6.31 22.53 6.51 22.70 6.67 C 22.84 6.84 23.03 6.92 23.27 6.92 C 23.51 6.92 23.71 6.84 23.87 6.67 L 25.31 5.22 C 25.48 5.06 25.57 4.87 25.57 4.63 C 25.57 4.39 25.49 4.19 25.32 4.02 C 25.15 3.85 24.95 3.77 24.71 3.77 C 24.49 3.77 24.30 3.86 24.14 4.03 L 22.70 5.47 C 22.53 5.63 22.44 5.83 22.44 6.07 Z"/>
<path d="M 16.91 3.79 C 16.91 4.02 17.00 4.22 17.17 4.39 C 17.34 4.56 17.54 4.65 17.77 4.65 C 18.01 4.65 18.20 4.57 18.36 4.40 C 18.52 4.23 18.59 4.03 18.59 3.79 L 18.59 1.73 C 18.59 1.49 18.51 1.29 18.36 1.12 C 18.21 0.95 18.01 0.87 17.77 0.87 C 17.54 0.87 17.34 0.95 17.17 1.12 C 17.00 1.29 16.91 1.49 16.91 1.73 L 16.91 3.79 Z"/>
<path d="M 9.94 4.63 C 9.94 4.87 10.02 5.06 10.19 5.22 L 10.83 5.88 C 11.00 6.05 11.20 6.13 11.44 6.14 C 11.68 6.14 11.87 6.06 12.01 5.88 C 12.20 5.73 12.29 5.53 12.29 5.28 C 12.29 5.04 12.21 4.85 12.04 4.69 L 11.41 4.03 C 11.24 3.87 11.03 3.79 10.80 3.79 C 10.55 3.79 10.34 3.87 10.18 4.03 C 10.02 4.19 9.94 4.39 9.94 4.63 Z"/>
</g>
<g id="rain">
<path d="M 13.77 23.43 C 13.77 23.55 13.81 23.67 13.88 23.81 C 14.01 24.01 14.17 24.15 14.38 24.24 C 14.45 24.27 14.55 24.29 14.68 24.29 C 14.83 24.29 14.94 24.27 15.01 24.23 C 15.21 24.15 15.35 23.95 15.42 23.65 L 16.91 18.10 C 16.97 17.86 16.95 17.65 16.84 17.45 C 16.73 17.26 16.56 17.13 16.33 17.06 C 16.10 16.99 15.88 17.01 15.69 17.13 C 15.49 17.24 15.36 17.41 15.30 17.64 L 13.80 23.20 C 13.80 23.22 13.79 23.26 13.78 23.31 C 13.77 23.37 13.77 23.40 13.77 23.43 Z"/>
<path d="M 9.61 26.48 C 9.60 26.63 9.64 26.78 9.75 26.92 C 9.86 27.06 10.01 27.17 10.21 27.25 C 10.28 27.27 10.35 27.28 10.42 27.28 C 10.59 27.28 10.76 27.23 10.93 27.13 C 11.10 27.03 11.21 26.87 11.27 26.66 L 13.56 18.09 C 13.62 17.86 13.60 17.64 13.49 17.45 C 13.38 17.25 13.22 17.12 13.00 17.05 C 12.77 16.98 12.55 17.00 12.35 17.12 C 12.15 17.23 12.01 17.40 11.95 17.63 L 9.64 26.23 C 9.62 26.30 9.61 26.39 9.61 26.48 Z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.8 KiB

View File

@@ -0,0 +1,11 @@
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" id="Layer_1" x="0px" y="0px" viewBox="0 0 30 30" style="enable-background:new 0 0 30 30;">
<path id="cloud" d="M 4.64 16.90 C 4.64 18.23 5.10 19.37 6.03 20.33 C 6.96 21.29 8.09 21.80 9.43 21.86 C 9.54 21.86 9.60 21.80 9.60 21.69 L 9.60 20.35 C 9.60 20.24 9.54 20.18 9.43 20.18 C 8.57 20.14 7.85 19.80 7.25 19.16 C 6.65 18.52 6.35 17.77 6.35 16.90 C 6.35 16.07 6.63 15.36 7.19 14.74 C 7.75 14.13 8.45 13.77 9.28 13.67 L 9.81 13.64 C 9.94 13.64 10.01 13.58 10.01 13.45 L 10.07 12.92 C 10.18 11.84 10.63 10.93 11.44 10.21 C 12.25 9.48 13.20 9.12 14.29 9.12 C 15.38 9.12 16.33 9.48 17.14 10.21 C 17.95 10.94 18.41 11.84 18.53 12.92 L 18.61 13.50 C 18.61 13.61 18.67 13.67 18.79 13.67 L 20.40 13.67 C 21.29 13.67 22.06 13.99 22.71 14.63 C 23.36 15.27 23.69 16.02 23.69 16.90 C 23.69 17.77 23.39 18.52 22.79 19.16 C 22.19 19.80 21.46 20.14 20.61 20.18 C 20.48 20.18 20.41 20.24 20.41 20.35 L 20.41 21.69 C 20.41 21.80 20.48 21.86 20.61 21.86 C 21.48 21.84 22.28 21.60 23.01 21.15 C 23.74 20.70 24.32 20.10 24.74 19.35 C 25.16 18.60 25.37 17.78 25.37 16.91 C 25.37 16.02 25.15 15.19 24.70 14.44 C 24.26 13.69 23.65 13.09 22.89 12.66 C 22.13 12.23 21.29 12.00 20.40 12.00 L 20.08 12.00 C 19.76 10.66 19.05 9.57 17.98 8.72 C 16.91 7.87 15.68 7.44 14.30 7.44 C 12.89 7.44 11.64 7.88 10.55 8.75 C 9.46 9.62 8.76 10.74 8.45 12.10 C 7.34 12.36 6.43 12.93 5.72 13.83 C 5.01 14.73 4.64 15.75 4.64 16.90 Z"/>
<g id="rain">
<path d="M 17.47 21.23 C 17.47 21.37 17.52 21.52 17.63 21.68 C 17.74 21.84 17.89 21.95 18.08 22.01 C 18.24 22.04 18.33 22.06 18.35 22.06 C 18.44 22.06 18.57 22.03 18.72 21.96 C 18.92 21.87 19.05 21.69 19.12 21.44 L 20.02 18.10 C 20.04 17.93 20.05 17.84 20.05 17.84 C 20.05 17.68 20.00 17.53 19.90 17.38 C 19.80 17.23 19.65 17.13 19.45 17.07 C 19.36 17.05 19.27 17.04 19.19 17.04 C 19.03 17.04 18.87 17.09 18.72 17.19 C 18.57 17.29 18.47 17.44 18.41 17.64 L 17.51 21.00 L 17.47 21.23 Z"/>
<path d="M 16.74 23.80 C 16.74 23.92 16.76 24.03 16.82 24.12 C 16.90 24.31 17.05 24.46 17.26 24.56 C 17.37 24.60 17.49 24.63 17.61 24.63 C 17.67 24.63 17.77 24.61 17.91 24.57 C 18.12 24.49 18.28 24.34 18.37 24.13 C 18.44 23.91 18.44 23.70 18.36 23.50 C 18.28 23.30 18.14 23.15 17.94 23.05 C 17.71 22.94 17.50 22.93 17.29 23.02 C 17.08 23.11 16.93 23.26 16.83 23.49 C 16.77 23.59 16.74 23.69 16.74 23.80 Z"/>
<path d="M 13.31 24.26 C 13.31 24.63 13.52 24.87 13.94 24.99 C 14.05 25.02 14.13 25.03 14.18 25.03 C 14.33 25.03 14.46 25.00 14.56 24.95 C 14.77 24.87 14.91 24.68 14.98 24.38 L 16.65 18.09 C 16.71 17.85 16.69 17.64 16.59 17.44 C 16.49 17.25 16.32 17.12 16.10 17.06 C 16.02 17.04 15.93 17.03 15.83 17.03 C 15.67 17.03 15.51 17.08 15.35 17.18 C 15.19 17.28 15.09 17.43 15.05 17.62 L 13.34 23.96 C 13.32 24.10 13.31 24.20 13.31 24.26 Z"/>
<path d="M 12.58 26.87 C 12.58 26.99 12.60 27.09 12.64 27.16 C 12.73 27.38 12.88 27.53 13.09 27.61 C 13.18 27.66 13.29 27.69 13.42 27.69 C 13.48 27.69 13.58 27.67 13.72 27.63 C 13.94 27.55 14.10 27.40 14.19 27.18 C 14.29 26.96 14.29 26.74 14.19 26.52 C 14.09 26.30 13.94 26.15 13.74 26.06 C 13.54 25.97 13.34 25.97 13.12 26.06 C 12.93 26.14 12.80 26.26 12.71 26.42 C 12.62 26.58 12.58 26.73 12.58 26.87 Z"/>
<path d="M 10.72 21.28 C 10.72 21.44 10.77 21.59 10.87 21.73 C 10.97 21.88 11.13 21.98 11.33 22.05 C 11.52 22.16 11.73 22.17 11.95 22.06 C 12.17 21.96 12.32 21.76 12.39 21.46 L 13.29 18.08 C 13.35 17.83 13.33 17.61 13.21 17.41 C 13.09 17.21 12.92 17.09 12.68 17.05 C 12.60 17.03 12.52 17.02 12.44 17.02 C 12.28 17.02 12.12 17.07 11.97 17.17 C 11.82 17.27 11.71 17.42 11.65 17.61 L 10.77 21.00 C 10.73 21.16 10.72 21.25 10.72 21.28 Z"/>
<path d="M 10.09 24.10 C 10.18 24.31 10.34 24.47 10.55 24.56 C 10.75 24.66 10.96 24.67 11.17 24.58 C 11.39 24.49 11.53 24.34 11.62 24.13 C 11.72 23.91 11.73 23.70 11.64 23.49 C 11.56 23.28 11.40 23.14 11.19 23.05 C 10.99 22.94 10.79 22.93 10.58 23.02 C 10.37 23.11 10.22 23.26 10.12 23.49 C 10.01 23.66 10.01 23.86 10.09 24.10 Z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

@@ -0,0 +1,3 @@
<!-- Generator: Adobe Illustrator 22.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) --><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Layer_1" x="0px" y="0px" viewBox="0 0 30 30" style="enable-background:new 0 0 30 30;" xml:space="preserve">
<path id="lightning" d="M7.96,24.51h0.39l6.88-10.18c0.09-0.18,0.04-0.27-0.15-0.27h-2.84l2.99-5.45c0.09-0.18,0.02-0.27-0.2-0.27h-3.81 c-0.11,0-0.2,0.06-0.29,0.18l-2.78,7.4c-0.02,0.18,0.04,0.27,0.19,0.27h2.75L7.96,24.51z M16.46,18.18h0.27l5.22-7.67 c0.05-0.08,0.06-0.15,0.04-0.2s-0.08-0.07-0.17-0.07h-2.1l2.18-4.03c0.12-0.2,0.06-0.3-0.18-0.3h-2.74c-0.13,0-0.23,0.06-0.3,0.19 l-2.08,5.48c-0.03,0.09-0.03,0.16,0.01,0.21c0.04,0.05,0.1,0.07,0.19,0.07h2.04L16.46,18.18z"/>
</svg>

After

Width:  |  Height:  |  Size: 778 B

View File

@@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" id="Layer_1" x="0px" y="0px" viewBox="0 0 30 30" style="enable-background:new 0 0 30 30;">
<path id="cloud" d="M 4.14 16.90 C 4.14 15.74 4.49 14.72 5.20 13.82 C 5.91 12.92 6.82 12.35 7.94 12.10 C 8.17 11.07 8.64 10.17 9.34 9.40 C 10.04 8.63 10.89 8.08 11.87 7.75 C 12.49 7.54 13.13 7.43 13.80 7.43 C 14.61 7.43 15.40 7.59 16.15 7.91 C 16.18 7.86 17.60 8.79 17.60 8.79 C 18.66 9.70 19.32 10.76 19.57 11.97 L 19.89 11.97 C 21.13 11.97 22.19 12.36 23.06 13.15 C 23.11 13.11 24.31 14.31 24.17 14.43 C 24.57 15.13 24.79 15.88 24.82 16.67 C 24.83 16.72 24.83 16.79 24.83 16.90 C 24.83 17.79 24.61 18.62 24.16 19.38 C 23.72 20.14 23.11 20.74 22.36 21.18 C 21.60 21.62 20.77 21.85 19.88 21.85 L 9.07 21.85 C 8.18 21.85 7.35 21.63 6.59 21.18 C 5.83 20.73 5.24 20.13 4.80 19.38 C 4.36 18.63 4.14 17.80 4.14 16.90 L 4.14 16.90 Z M 5.85 16.90 C 5.85 17.79 6.17 18.56 6.81 19.21 C 7.45 19.86 8.20 20.19 9.07 20.19 L 19.88 20.19 C 20.77 20.19 21.53 19.87 22.16 19.22 C 22.79 18.57 23.11 17.80 23.11 16.90 C 23.11 16.02 22.79 15.27 22.15 14.64 C 21.51 14.01 20.75 13.69 19.87 13.69 L 18.09 13.69 L 17.99 12.94 C 17.89 11.93 17.47 11.06 16.73 10.35 C 15.99 9.64 15.11 9.24 14.10 9.15 C 14.07 9.15 14.02 9.15 13.95 9.14 C 13.88 9.13 13.84 9.13 13.80 9.13 C 13.29 9.13 12.78 9.23 12.26 9.42 L 12.26 9.40 C 11.53 9.68 10.91 10.14 10.42 10.77 C 9.92 11.40 9.62 12.12 9.52 12.94 L 9.45 13.66 L 8.77 13.69 C 7.93 13.79 7.23 14.14 6.67 14.75 C 6.11 15.36 5.85 16.07 5.85 16.90 Z"/>
<path id="moon" d="M 17.16 6.67 C 17.54 6.33 17.93 6.06 18.33 5.88 C 18.73 5.70 19.13 5.56 19.51 5.47 C 19.89 5.38 20.27 5.34 20.63 5.34 C 21.01 5.34 21.42 5.39 21.86 5.50 L 22.68 5.75 C 22.82 5.81 22.86 5.88 22.82 5.97 L 22.68 6.57 C 22.61 6.88 22.58 7.17 22.58 7.43 C 22.58 7.74 22.63 8.06 22.73 8.38 C 22.83 8.70 22.97 9.01 23.17 9.32 C 23.36 9.63 23.63 9.90 23.97 10.15 C 24.31 10.40 24.69 10.59 25.12 10.72 L 25.74 10.94 C 25.84 10.97 25.89 11.02 25.89 11.10 C 25.89 11.12 25.88 11.14 25.87 11.17 L 25.69 11.84 C 25.47 12.72 24.70 13.84 24.18 14.42 L 23.09 13.17 C 23.35 12.89 23.68 12.40 23.84 12.06 C 22.93 11.63 22.21 10.97 21.68 10.09 C 21.16 9.21 20.89 8.28 20.89 7.31 L 20.89 7.07 C 20.84 7.06 20.76 7.06 20.65 7.06 C 20.07 7.05 19.50 7.19 18.95 7.50 C 18.40 7.80 17.93 8.26 17.60 8.80 L 16.15 7.92 C 16.41 7.51 16.82 6.97 17.16 6.67 L 17.16 6.67 Z"/>
</svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@@ -0,0 +1,12 @@
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" id="Layer_1" x="0px" y="0px" viewBox="0 0 30 30" style="enable-background:new 0 0 30 30;">
<path id="cloud" d="M 5.19 13.80 C 5.91 12.90 6.82 12.33 7.93 12.07 C 8.24 10.70 8.94 9.58 10.03 8.71 C 11.12 7.84 12.38 7.40 13.79 7.40 C 14.62 7.40 15.41 7.57 16.16 7.89 C 16.20 7.82 17.63 8.81 17.62 8.83 C 18.66 9.69 19.30 10.75 19.56 12.00 L 19.88 12.00 C 21.17 12.00 22.25 12.39 23.13 13.18 C 23.17 13.15 24.34 14.37 24.21 14.49 C 24.64 15.24 24.86 16.04 24.86 16.90 C 24.86 18.24 24.40 19.39 23.47 20.35 C 22.55 21.31 21.42 21.82 20.09 21.86 C 19.96 21.86 19.89 21.80 19.89 21.69 L 19.89 20.35 C 19.89 20.24 19.96 20.18 20.09 20.18 C 20.94 20.14 21.67 19.80 22.27 19.16 C 22.87 18.52 23.17 17.77 23.17 16.90 C 23.17 16.03 22.84 15.27 22.19 14.63 C 21.54 13.99 20.77 13.67 19.88 13.67 L 18.27 13.67 C 18.16 13.67 18.10 13.61 18.10 13.50 L 18.02 12.92 C 17.90 11.84 17.44 10.93 16.62 10.20 C 15.80 9.47 14.85 9.10 13.77 9.10 C 12.68 9.10 11.73 9.47 10.92 10.20 C 10.11 10.93 9.66 11.84 9.55 12.92 L 9.48 13.46 C 9.48 13.58 9.41 13.64 9.28 13.64 L 8.75 13.67 C 7.91 13.77 7.21 14.13 6.65 14.74 C 6.09 15.36 5.81 16.08 5.81 16.91 C 5.81 17.78 6.11 18.53 6.71 19.17 C 7.31 19.81 8.03 20.15 8.89 20.19 C 9.01 20.19 9.07 20.25 9.07 20.36 L 9.07 21.70 C 9.07 21.81 9.01 21.87 8.89 21.87 C 7.55 21.81 6.42 21.29 5.49 20.34 C 4.56 19.39 4.10 18.24 4.10 16.91 C 4.10 15.76 4.47 14.70 5.19 13.80 L 5.19 13.80 Z"/>
<path id="moon" d="M 17.16 6.67 C 17.55 6.32 17.94 6.05 18.35 5.87 C 18.76 5.69 19.15 5.56 19.52 5.47 C 19.89 5.38 20.25 5.34 20.60 5.34 C 21.05 5.34 21.49 5.41 21.91 5.53 L 22.71 5.78 C 22.83 5.84 22.88 5.91 22.85 6.00 L 22.71 6.58 C 22.65 6.86 22.62 7.13 22.63 7.37 C 22.63 7.82 22.71 8.26 22.88 8.69 C 23.05 9.13 23.34 9.54 23.74 9.94 C 24.15 10.34 24.63 10.62 25.20 10.79 L 25.76 10.96 C 25.87 10.99 25.92 11.05 25.92 11.12 C 25.92 11.16 25.91 11.18 25.89 11.19 L 25.76 11.87 C 25.55 12.71 24.90 13.91 24.23 14.50 L 23.15 13.22 C 23.41 12.96 23.71 12.50 23.88 12.11 C 22.96 11.67 22.23 11.02 21.71 10.16 C 21.19 9.30 20.93 8.39 20.93 7.41 L 20.93 7.10 C 20.88 7.09 20.79 7.08 20.68 7.08 C 20.06 7.07 19.47 7.22 18.92 7.52 C 18.39 7.81 17.93 8.29 17.62 8.82 L 16.16 7.92 C 16.41 7.53 16.83 6.97 17.16 6.67 L 17.16 6.67 Z"/>
<g id="rain">
<path d="M 16.97 21.08 C 16.97 21.24 17.02 21.40 17.12 21.54 C 17.22 21.68 17.37 21.79 17.57 21.85 C 17.74 21.87 17.83 21.88 17.84 21.88 C 18.25 21.88 18.50 21.68 18.61 21.27 L 19.48 18.10 C 19.54 17.86 19.52 17.65 19.41 17.45 C 19.30 17.26 19.13 17.13 18.91 17.06 C 18.68 16.99 18.46 17.01 18.27 17.13 C 18.07 17.24 17.94 17.41 17.87 17.64 L 17.00 20.81 C 16.98 20.90 16.97 20.99 16.97 21.08 Z"/>
<path d="M 16.25 23.64 C 16.25 23.77 16.27 23.87 16.32 23.95 C 16.40 24.15 16.55 24.30 16.76 24.39 C 16.88 24.44 16.99 24.47 17.11 24.47 C 17.17 24.47 17.27 24.45 17.41 24.41 C 17.63 24.32 17.78 24.18 17.86 23.97 C 17.94 23.75 17.94 23.54 17.86 23.34 C 17.78 23.14 17.64 22.99 17.44 22.89 C 17.22 22.79 17.00 22.78 16.79 22.87 C 16.57 22.95 16.42 23.11 16.32 23.33 C 16.27 23.41 16.25 23.51 16.25 23.64 Z"/>
<path d="M 12.81 24.06 C 12.81 24.44 13.02 24.70 13.45 24.84 C 13.54 24.87 13.62 24.89 13.68 24.89 C 13.79 24.89 13.91 24.86 14.03 24.81 C 14.26 24.73 14.42 24.54 14.50 24.24 L 16.15 18.12 C 16.21 17.88 16.19 17.67 16.08 17.47 C 15.97 17.28 15.80 17.15 15.58 17.08 C 15.35 17.01 15.13 17.03 14.93 17.15 C 14.73 17.26 14.59 17.43 14.53 17.66 L 12.85 23.83 C 12.82 23.92 12.81 24.00 12.81 24.06 Z"/>
<path d="M 12.07 26.71 C 12.07 26.83 12.09 26.93 12.13 27.00 C 12.22 27.22 12.37 27.37 12.58 27.45 C 12.67 27.50 12.78 27.52 12.91 27.52 C 12.97 27.52 13.07 27.50 13.21 27.46 C 13.44 27.38 13.60 27.23 13.69 27.01 C 13.79 26.79 13.79 26.57 13.69 26.35 C 13.59 26.13 13.44 25.98 13.24 25.89 C 13.04 25.80 12.84 25.80 12.63 25.89 C 12.44 25.97 12.30 26.09 12.21 26.25 C 12.11 26.42 12.07 26.57 12.07 26.71 Z"/>
<path d="M 10.20 21.11 C 10.20 21.26 10.25 21.41 10.36 21.56 C 10.47 21.71 10.62 21.82 10.82 21.88 C 11.08 21.98 11.30 21.98 11.49 21.88 C 11.68 21.78 11.81 21.59 11.89 21.31 L 12.77 18.10 C 12.84 17.85 12.81 17.63 12.69 17.43 C 12.57 17.23 12.39 17.11 12.15 17.06 C 11.93 16.99 11.72 17.01 11.52 17.13 C 11.32 17.24 11.19 17.41 11.12 17.64 L 10.24 20.86 C 10.24 20.88 10.23 20.92 10.22 20.98 C 10.21 21.03 10.20 21.08 10.20 21.11 Z"/>
<path d="M 9.58 23.94 C 9.67 24.15 9.82 24.30 10.04 24.39 C 10.23 24.49 10.44 24.50 10.66 24.41 C 10.88 24.33 11.03 24.18 11.11 23.96 C 11.21 23.74 11.22 23.53 11.13 23.31 C 11.05 23.10 10.90 22.95 10.68 22.87 C 10.48 22.77 10.27 22.76 10.06 22.85 C 9.85 22.94 9.69 23.09 9.59 23.31 C 9.50 23.48 9.49 23.69 9.58 23.94 Z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.6 KiB

View File

@@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" id="Layer_1" x="0px" y="0px" viewBox="0 0 30 30" style="enable-background:new 0 0 30 30;">
<path id="cloud" d="M 5.23 13.85 C 5.95 12.95 6.86 12.37 7.96 12.11 C 8.27 10.75 8.97 9.63 10.06 8.76 C 11.15 7.89 12.40 7.45 13.81 7.45 C 14.66 7.45 15.43 7.60 16.14 7.90 C 16.18 7.83 17.61 8.79 17.60 8.81 C 18.63 9.66 19.29 10.71 19.58 11.97 L 19.90 11.97 C 21.13 11.97 22.20 12.36 23.12 13.15 C 23.16 13.11 24.32 14.31 24.18 14.44 C 24.63 15.20 24.86 16.03 24.86 16.92 C 24.86 18.26 24.40 19.41 23.48 20.37 C 22.56 21.33 21.43 21.84 20.10 21.88 C 19.97 21.88 19.90 21.82 19.90 21.71 L 19.90 20.34 C 19.90 20.22 19.97 20.16 20.10 20.16 C 20.97 20.09 21.70 19.74 22.29 19.12 C 22.88 18.50 23.18 17.76 23.18 16.91 C 23.18 16.02 22.86 15.26 22.22 14.63 C 21.58 14.00 20.81 13.68 19.90 13.68 L 18.29 13.68 C 18.17 13.68 18.11 13.62 18.11 13.50 L 18.04 12.92 C 17.92 11.83 17.46 10.92 16.65 10.20 C 15.84 9.47 14.89 9.11 13.80 9.11 C 12.71 9.11 11.76 9.47 10.95 10.20 C 10.14 10.92 9.69 11.83 9.58 12.91 L 9.51 13.43 C 9.51 13.54 9.44 13.60 9.31 13.60 L 8.78 13.67 C 7.94 13.74 7.25 14.09 6.68 14.71 C 6.11 15.33 5.83 16.06 5.83 16.90 C 5.83 17.75 6.13 18.49 6.72 19.11 C 7.31 19.74 8.04 20.08 8.91 20.15 C 9.02 20.15 9.08 20.21 9.08 20.33 L 9.08 21.70 C 9.08 21.81 9.02 21.87 8.91 21.87 C 7.57 21.81 6.44 21.29 5.51 20.34 C 4.58 19.39 4.12 18.24 4.12 16.91 C 4.12 15.76 4.48 14.74 5.23 13.85 Z"/>
<path id="moon" d="M 17.14 6.68 C 17.53 6.33 17.93 6.06 18.34 5.88 C 18.75 5.69 19.15 5.56 19.53 5.47 C 19.92 5.38 20.29 5.34 20.65 5.34 C 21.05 5.34 21.46 5.39 21.90 5.50 L 22.69 5.74 C 22.81 5.79 22.86 5.87 22.83 5.96 L 22.69 6.58 C 22.63 6.86 22.60 7.13 22.60 7.37 C 22.60 7.82 22.68 8.26 22.85 8.69 C 23.02 9.12 23.30 9.53 23.70 9.92 C 24.10 10.30 24.58 10.58 25.15 10.74 L 25.73 10.91 C 25.84 10.94 25.89 11.00 25.89 11.07 C 25.89 11.11 25.89 11.13 25.88 11.14 L 25.73 11.86 C 25.54 12.69 24.83 13.98 24.17 14.49 L 23.16 13.27 C 23.48 12.99 23.73 12.40 23.87 12.08 C 22.94 11.63 22.22 10.98 21.70 10.12 C 21.18 9.26 20.92 8.35 20.92 7.39 L 20.92 7.08 C 20.87 7.07 20.78 7.06 20.65 7.06 C 20.06 7.06 19.48 7.21 18.93 7.51 C 18.39 7.80 17.93 8.29 17.60 8.82 L 16.17 7.92 C 16.42 7.53 16.81 6.98 17.14 6.68 Z"/>
<path id="lightning" d="M 11.79 21.56 C 11.74 21.70 11.79 21.78 11.93 21.78 L 14.09 21.78 L 12.78 25.92 L 13.08 25.92 L 17.25 20.33 C 17.29 20.29 17.30 20.24 17.28 20.19 C 17.26 20.14 17.22 20.12 17.15 20.12 L 14.95 20.12 L 17.26 15.91 C 17.33 15.77 17.28 15.69 17.12 15.69 L 14.18 15.69 C 14.10 15.69 14.03 15.74 13.96 15.83 L 11.79 21.56 Z"/>
</svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@@ -0,0 +1,15 @@
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" id="Layer_1" x="0px" y="0px" viewBox="0 0 30 30" style="enable-background:new 0 0 30 30;">
<path id="cloud" d="M 5.13 13.87 C 5.84 12.98 6.76 12.39 7.88 12.10 C 8.19 10.73 8.90 9.61 9.99 8.73 C 11.08 7.85 12.34 7.41 13.75 7.41 C 14.50 7.41 15.29 7.56 16.10 7.87 C 16.15 7.78 17.61 8.73 17.59 8.76 C 18.61 9.59 19.27 10.66 19.58 11.97 L 19.89 11.97 C 21.12 11.97 22.20 12.35 23.12 13.11 C 23.14 13.09 24.30 14.32 24.18 14.43 C 24.63 15.22 24.86 16.06 24.86 16.94 C 24.86 17.81 24.65 18.62 24.23 19.37 C 23.81 20.12 23.23 20.72 22.50 21.17 C 21.77 21.62 20.96 21.86 20.08 21.88 C 19.95 21.88 19.88 21.82 19.88 21.71 L 19.88 20.37 C 19.88 20.26 19.95 20.20 20.08 20.20 C 20.64 20.17 21.16 20.00 21.64 19.69 C 22.12 19.38 22.50 18.98 22.77 18.49 C 23.04 18.00 23.18 17.48 23.18 16.93 C 23.18 16.03 22.86 15.26 22.21 14.62 C 21.56 13.97 20.79 13.65 19.88 13.65 L 18.26 13.65 C 18.15 13.65 18.09 13.58 18.09 13.46 L 18.02 12.89 C 17.91 11.81 17.44 10.90 16.62 10.17 C 15.80 9.44 14.85 9.07 13.76 9.07 C 12.66 9.07 11.71 9.44 10.90 10.17 C 10.09 10.90 9.64 11.82 9.53 12.92 L 9.46 13.43 C 9.46 13.55 9.39 13.61 9.26 13.61 L 8.73 13.68 C 7.90 13.75 7.20 14.10 6.63 14.72 C 6.06 15.34 5.78 16.08 5.78 16.93 C 5.78 17.77 6.09 18.52 6.69 19.16 C 7.29 19.80 8.02 20.15 8.87 20.19 C 8.99 20.19 9.05 20.25 9.05 20.36 L 9.05 21.70 C 9.05 21.81 8.99 21.87 8.87 21.87 C 7.54 21.83 6.40 21.32 5.47 20.36 C 4.54 19.40 4.07 18.26 4.07 16.93 C 4.07 15.77 4.42 14.74 5.13 13.87 L 5.13 13.87 Z"/>
<path id="moon" d="M 17.10 6.64 C 17.49 6.29 17.89 6.02 18.30 5.83 C 18.71 5.64 19.11 5.51 19.49 5.42 C 19.87 5.33 20.25 5.29 20.61 5.29 C 21.06 5.29 21.49 5.35 21.90 5.46 L 22.70 5.70 C 22.83 5.75 22.87 5.83 22.83 5.93 L 22.70 6.51 C 22.62 6.84 22.59 7.12 22.61 7.33 C 22.61 7.76 22.70 8.19 22.87 8.62 C 23.04 9.06 23.33 9.47 23.74 9.87 C 24.14 10.27 24.64 10.55 25.21 10.72 L 25.76 10.90 C 25.87 10.95 25.93 11.00 25.93 11.06 C 25.93 11.09 25.92 11.11 25.90 11.13 L 25.76 11.81 C 25.57 12.66 24.90 13.83 24.21 14.43 L 23.09 13.16 C 23.40 12.85 23.74 12.38 23.92 12.00 C 22.97 11.56 22.23 10.92 21.70 10.06 C 21.18 9.20 20.92 8.28 20.93 7.30 L 20.93 6.99 C 20.82 6.97 20.72 6.96 20.63 6.96 C 20.03 6.95 19.46 7.10 18.90 7.42 C 18.38 7.72 17.89 8.20 17.57 8.74 L 16.15 7.85 C 16.35 7.47 16.79 6.92 17.10 6.64 L 17.10 6.64 Z"/>
<g id="rain">
<path d="M 17.52 18.81 C 17.52 18.98 17.57 19.14 17.68 19.29 C 17.79 19.44 17.95 19.55 18.17 19.61 C 18.19 19.61 18.23 19.62 18.29 19.63 C 18.35 19.64 18.40 19.65 18.43 19.65 C 18.53 19.65 18.65 19.62 18.79 19.56 C 19.00 19.45 19.14 19.27 19.20 19.04 L 19.44 18.14 C 19.50 17.91 19.48 17.70 19.36 17.51 C 19.25 17.31 19.08 17.18 18.85 17.11 C 18.62 17.04 18.41 17.06 18.21 17.17 C 18.01 17.28 17.89 17.44 17.82 17.68 L 17.54 18.59 C 17.54 18.61 17.53 18.65 17.52 18.71 C 17.53 18.74 17.52 18.78 17.52 18.81 Z"/>
<path d="M 16.91 21.12 C 16.91 21.34 16.99 21.54 17.16 21.69 C 17.31 21.85 17.50 21.93 17.73 21.93 C 17.97 21.93 18.16 21.85 18.32 21.70 C 18.48 21.55 18.55 21.35 18.55 21.12 C 18.55 20.88 18.47 20.69 18.32 20.53 C 18.17 20.37 17.97 20.30 17.73 20.30 C 17.49 20.30 17.30 20.38 17.14 20.53 C 16.98 20.68 16.91 20.88 16.91 21.12 Z"/>
<path d="M 16.17 24.08 C 16.17 24.24 16.22 24.40 16.32 24.56 C 16.42 24.72 16.58 24.83 16.78 24.89 C 16.81 24.89 16.86 24.90 16.92 24.91 C 16.98 24.92 17.02 24.93 17.06 24.93 C 17.47 24.93 17.72 24.71 17.82 24.27 L 17.96 23.67 C 18.03 23.46 18.01 23.25 17.89 23.04 C 17.78 22.83 17.61 22.70 17.38 22.63 C 17.13 22.57 16.90 22.59 16.70 22.71 C 16.50 22.83 16.36 23.00 16.29 23.24 L 16.20 23.83 C 16.20 23.85 16.19 23.90 16.18 23.95 C 16.18 24.00 16.17 24.04 16.17 24.08 Z"/>
<path d="M 13.42 21.93 C 13.41 22.08 13.45 22.24 13.55 22.40 C 13.65 22.56 13.80 22.66 14.00 22.70 C 14.23 22.76 14.44 22.74 14.64 22.64 C 14.83 22.54 14.97 22.35 15.05 22.08 L 15.32 21.18 C 15.39 20.96 15.37 20.75 15.25 20.55 C 15.13 20.35 14.96 20.22 14.72 20.15 C 14.50 20.08 14.29 20.11 14.08 20.23 C 13.87 20.35 13.74 20.53 13.67 20.76 L 13.45 21.66 C 13.43 21.74 13.42 21.83 13.42 21.93 Z"/>
<path d="M 12.79 24.20 C 12.79 24.42 12.87 24.61 13.04 24.78 C 13.20 24.94 13.39 25.02 13.61 25.02 C 13.85 25.02 14.04 24.94 14.20 24.79 C 14.36 24.63 14.43 24.44 14.43 24.20 C 14.43 23.97 14.35 23.78 14.20 23.62 C 14.05 23.46 13.85 23.39 13.61 23.39 C 13.37 23.39 13.18 23.47 13.02 23.62 C 12.87 23.77 12.79 23.97 12.79 24.20 Z"/>
<path d="M 12.01 27.10 C 12.01 27.28 12.06 27.44 12.16 27.60 C 12.26 27.76 12.42 27.87 12.64 27.93 C 12.72 27.95 12.81 27.96 12.89 27.96 C 13.32 27.96 13.58 27.76 13.68 27.35 L 13.82 26.76 C 13.88 26.50 13.85 26.28 13.74 26.08 C 13.63 25.88 13.45 25.76 13.22 25.71 C 13.01 25.64 12.80 25.66 12.59 25.78 C 12.38 25.90 12.25 26.07 12.18 26.29 L 12.04 26.88 C 12.02 26.97 12.01 27.04 12.01 27.10 Z"/>
<path d="M 10.85 18.81 C 10.84 18.97 10.88 19.12 10.99 19.26 C 11.09 19.41 11.25 19.51 11.47 19.58 C 11.68 19.64 11.88 19.62 12.09 19.51 C 12.30 19.40 12.43 19.23 12.50 19.00 L 12.78 18.10 C 12.85 17.86 12.83 17.64 12.71 17.45 C 12.59 17.26 12.41 17.13 12.17 17.06 C 11.95 16.99 11.74 17.01 11.54 17.13 C 11.34 17.24 11.20 17.41 11.13 17.63 L 10.89 18.55 C 10.89 18.57 10.88 18.61 10.87 18.67 C 10.85 18.72 10.85 18.77 10.85 18.81 Z"/>
<path d="M 10.24 21.08 C 10.24 21.29 10.32 21.48 10.49 21.65 C 10.65 21.82 10.83 21.90 11.05 21.90 C 11.29 21.90 11.49 21.82 11.65 21.66 C 11.81 21.50 11.89 21.31 11.89 21.07 C 11.89 20.84 11.81 20.64 11.65 20.48 C 11.49 20.32 11.29 20.24 11.05 20.24 C 10.82 20.24 10.62 20.32 10.47 20.47 C 10.32 20.62 10.24 20.85 10.24 21.08 Z"/>
<path d="M 9.48 23.98 C 9.48 24.15 9.53 24.32 9.64 24.49 C 9.75 24.66 9.91 24.77 10.11 24.84 C 10.34 24.91 10.55 24.90 10.75 24.80 C 10.95 24.70 11.07 24.52 11.14 24.24 L 11.28 23.63 C 11.33 23.40 11.30 23.19 11.19 23.00 C 11.08 22.80 10.91 22.67 10.67 22.60 C 10.44 22.53 10.23 22.56 10.03 22.68 C 9.83 22.80 9.69 22.98 9.63 23.21 L 9.50 23.79 C 9.48 23.83 9.48 23.89 9.48 23.98 Z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.9 KiB

View File

@@ -0,0 +1,9 @@
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" id="Layer_1" x="0px" y="0px" viewBox="0 0 30 30" style="enable-background:new 0 0 30 30;">
<path id="cloud" d="M 5.17 13.83 C 5.89 12.93 6.80 12.36 7.91 12.10 C 8.22 10.73 8.93 9.61 10.02 8.73 C 11.11 7.85 12.37 7.41 13.78 7.41 C 14.51 7.41 15.29 7.56 16.11 7.86 C 16.16 7.77 17.60 8.74 17.58 8.77 C 18.64 9.64 19.30 10.70 19.57 11.97 L 19.88 11.97 C 21.12 11.97 22.19 12.34 23.11 13.10 C 23.13 13.08 24.32 14.34 24.20 14.45 C 24.65 15.21 24.88 16.03 24.88 16.91 C 24.88 18.24 24.42 19.39 23.49 20.36 C 22.57 21.32 21.44 21.83 20.11 21.87 C 19.97 21.87 19.90 21.81 19.90 21.70 L 19.90 20.36 C 19.90 20.25 19.97 20.19 20.11 20.19 C 20.97 20.14 21.70 19.80 22.30 19.16 C 22.90 18.52 23.20 17.77 23.20 16.90 C 23.20 16.02 22.87 15.26 22.22 14.62 C 21.57 13.98 20.79 13.66 19.90 13.66 L 18.28 13.66 C 18.17 13.66 18.11 13.60 18.11 13.48 L 18.03 12.91 C 17.91 11.83 17.45 10.92 16.63 10.19 C 15.81 9.46 14.86 9.09 13.77 9.09 C 12.68 9.09 11.72 9.46 10.91 10.19 C 10.10 10.92 9.64 11.83 9.53 12.91 L 9.46 13.45 C 9.46 13.56 9.39 13.62 9.26 13.62 L 8.73 13.66 C 7.90 13.76 7.20 14.11 6.63 14.73 C 6.06 15.35 5.78 16.07 5.78 16.90 C 5.78 17.77 6.08 18.52 6.68 19.16 C 7.28 19.80 8.01 20.14 8.87 20.19 C 8.99 20.19 9.05 20.25 9.05 20.36 L 9.05 21.70 C 9.05 21.81 8.99 21.87 8.87 21.87 C 7.54 21.81 6.40 21.30 5.47 20.34 C 4.54 19.38 4.07 18.23 4.07 16.90 C 4.07 15.75 4.43 14.72 5.17 13.83 L 5.17 13.83 Z"/>
<path id="moon" d="M 17.11 6.64 C 17.50 6.29 17.90 6.02 18.31 5.84 C 18.72 5.65 19.12 5.52 19.51 5.43 C 19.89 5.34 20.27 5.30 20.65 5.30 C 21.05 5.30 21.47 5.35 21.92 5.45 L 22.71 5.69 C 22.85 5.75 22.89 5.83 22.85 5.93 L 22.71 6.54 C 22.64 6.86 22.61 7.14 22.63 7.36 C 22.63 7.78 22.72 8.21 22.89 8.64 C 23.06 9.07 23.35 9.48 23.76 9.87 C 24.16 10.26 24.65 10.54 25.22 10.70 L 25.78 10.88 C 25.89 10.91 25.94 10.97 25.94 11.04 C 25.94 11.08 25.93 11.10 25.92 11.11 L 25.78 11.83 C 25.57 12.70 24.89 13.81 24.23 14.43 L 23.08 13.16 C 23.35 12.91 23.70 12.45 23.90 12.03 C 22.95 11.58 22.21 10.92 21.69 10.06 C 21.16 9.19 20.91 8.28 20.92 7.31 L 20.92 7.01 C 20.86 7.00 20.77 7.00 20.65 7.00 C 20.03 6.99 19.44 7.14 18.89 7.44 C 18.36 7.73 17.90 8.26 17.58 8.79 L 16.06 7.84 C 16.31 7.49 16.79 6.92 17.11 6.64 L 17.11 6.64 Z"/>
<g id="rain">
<path d="M 16.40 23.82 C 16.40 24.18 16.61 24.42 17.03 24.56 C 17.17 24.60 17.27 24.62 17.33 24.62 C 17.44 24.62 17.56 24.60 17.68 24.55 C 17.89 24.47 18.02 24.27 18.07 23.97 L 19.50 18.10 C 19.56 17.86 19.54 17.65 19.42 17.45 C 19.31 17.26 19.14 17.13 18.91 17.06 C 18.68 16.99 18.46 17.01 18.25 17.13 C 18.04 17.24 17.92 17.41 17.87 17.64 L 16.44 23.54 C 16.42 23.70 16.40 23.80 16.40 23.82 Z"/>
<path d="M 12.24 26.81 C 12.24 26.97 12.29 27.12 12.39 27.27 C 12.49 27.42 12.64 27.52 12.84 27.58 C 12.95 27.61 13.03 27.62 13.08 27.62 C 13.52 27.62 13.79 27.42 13.90 27.03 L 16.15 18.10 C 16.21 17.86 16.19 17.64 16.08 17.45 C 15.97 17.26 15.80 17.13 15.58 17.06 C 15.35 16.99 15.13 17.01 14.92 17.13 C 14.71 17.25 14.58 17.41 14.53 17.63 L 12.27 26.55 C 12.27 26.56 12.27 26.60 12.26 26.67 C 12.24 26.73 12.24 26.78 12.24 26.81 Z"/>
<path d="M 9.63 23.74 C 9.63 23.91 9.68 24.07 9.79 24.23 C 9.90 24.39 10.06 24.50 10.28 24.56 C 10.51 24.63 10.73 24.61 10.92 24.52 C 11.12 24.42 11.25 24.24 11.32 23.96 L 12.75 18.09 C 12.81 17.84 12.78 17.61 12.67 17.42 C 12.55 17.22 12.38 17.10 12.15 17.05 C 11.93 16.98 11.72 17.00 11.52 17.12 C 11.32 17.23 11.18 17.40 11.11 17.63 L 9.67 23.53 C 9.67 23.54 9.66 23.57 9.65 23.62 C 9.64 23.67 9.63 23.71 9.63 23.74 Z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

@@ -0,0 +1,12 @@
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" id="Layer_1" x="0px" y="0px" viewBox="0 0 30 30" style="enable-background:new 0 0 30 30;">
<path id="cloud" d="M 5.16 13.82 C 5.88 12.93 6.81 12.36 7.93 12.10 C 8.23 10.73 8.91 9.61 10.00 8.74 C 11.09 7.87 12.34 7.43 13.75 7.43 C 14.58 7.43 15.37 7.59 16.11 7.92 C 16.16 7.84 17.59 8.79 17.58 8.81 C 18.63 9.73 19.27 10.78 19.52 11.97 L 19.84 11.97 C 21.07 11.97 22.16 12.37 23.09 13.18 C 23.13 13.14 24.30 14.37 24.17 14.49 C 24.60 15.24 24.82 16.05 24.82 16.92 C 24.82 18.26 24.36 19.41 23.44 20.37 C 22.52 21.33 21.39 21.84 20.06 21.88 C 19.93 21.88 19.86 21.82 19.86 21.71 L 19.86 20.34 C 19.86 20.22 19.93 20.16 20.06 20.16 C 20.92 20.09 21.66 19.74 22.25 19.12 C 22.84 18.50 23.14 17.76 23.14 16.91 C 23.14 16.02 22.81 15.26 22.17 14.63 C 21.52 14.00 20.75 13.68 19.85 13.68 L 18.24 13.68 C 18.12 13.68 18.06 13.62 18.06 13.50 L 17.98 12.92 C 17.87 11.83 17.40 10.92 16.59 10.20 C 15.78 9.47 14.83 9.11 13.74 9.11 C 12.65 9.11 11.70 9.47 10.89 10.20 C 10.08 10.92 9.63 11.83 9.52 12.91 L 9.45 13.43 C 9.45 13.54 9.38 13.60 9.25 13.60 L 8.72 13.67 C 7.88 13.77 7.18 14.12 6.62 14.74 C 6.06 15.36 5.78 16.07 5.78 16.90 C 5.78 17.75 6.08 18.49 6.67 19.11 C 7.26 19.74 7.99 20.08 8.86 20.15 C 8.97 20.15 9.03 20.21 9.03 20.33 L 9.03 21.70 C 9.03 21.81 8.97 21.87 8.86 21.87 C 7.52 21.81 6.39 21.29 5.46 20.34 C 4.53 19.39 4.07 18.24 4.07 16.91 C 4.07 15.76 4.43 14.73 5.16 13.82 Z"/>
<path id="moon" d="M 17.11 6.69 C 17.49 6.34 17.89 6.08 18.31 5.89 C 18.72 5.70 19.12 5.57 19.51 5.48 C 19.89 5.39 20.27 5.35 20.65 5.35 C 21.02 5.35 21.43 5.40 21.90 5.49 L 22.05 5.53 L 22.90 5.78 L 22.70 6.58 C 22.65 6.84 22.62 7.10 22.62 7.36 C 22.62 8.05 22.84 8.73 23.29 9.39 C 23.74 10.04 24.37 10.50 25.18 10.74 L 25.94 10.95 L 25.75 11.74 L 25.75 11.87 C 25.55 12.72 24.89 14.00 24.21 14.54 L 23.07 13.20 C 23.32 12.92 23.68 12.46 23.87 12.08 C 22.95 11.63 22.22 10.98 21.70 10.12 C 21.18 9.26 20.92 8.36 20.92 7.41 C 20.92 7.24 20.92 7.12 20.93 7.03 L 20.72 7.03 C 20.08 7.03 19.48 7.19 18.91 7.50 C 18.37 7.80 17.90 8.29 17.58 8.82 L 16.07 7.91 C 16.32 7.54 16.80 6.98 17.11 6.69 Z"/>
<g id="rain">
<path d="M 17.55 18.98 C 17.55 19.14 17.60 19.29 17.70 19.44 C 17.80 19.59 17.96 19.70 18.16 19.76 C 18.30 19.79 18.38 19.81 18.39 19.81 C 18.48 19.81 18.60 19.78 18.77 19.71 C 18.98 19.63 19.12 19.44 19.21 19.16 L 19.49 18.12 C 19.55 17.90 19.52 17.69 19.41 17.49 C 19.30 17.29 19.11 17.16 18.88 17.09 C 18.66 17.02 18.45 17.04 18.25 17.16 C 18.05 17.28 17.92 17.45 17.85 17.68 L 17.59 18.74 C 17.56 18.83 17.55 18.92 17.55 18.98 Z"/>
<path d="M 16.16 23.79 C 16.16 24.17 16.37 24.41 16.80 24.54 C 16.89 24.56 16.97 24.57 17.04 24.57 C 17.19 24.57 17.31 24.55 17.41 24.50 C 17.62 24.42 17.77 24.23 17.85 23.93 L 18.12 22.91 C 18.18 22.66 18.16 22.44 18.04 22.24 C 17.92 22.04 17.75 21.92 17.51 21.87 C 17.28 21.80 17.06 21.82 16.87 21.94 C 16.68 22.06 16.54 22.23 16.47 22.45 L 16.20 23.49 C 16.20 23.51 16.19 23.56 16.18 23.64 C 16.16 23.71 16.16 23.76 16.16 23.79 Z"/>
<path d="M 13.35 22.03 C 13.35 22.18 13.40 22.33 13.50 22.48 C 13.60 22.63 13.75 22.74 13.96 22.81 C 14.18 22.88 14.40 22.86 14.60 22.75 C 14.80 22.64 14.93 22.47 15.00 22.23 L 15.27 21.19 C 15.34 20.98 15.32 20.77 15.21 20.57 C 15.10 20.37 14.94 20.23 14.72 20.16 C 14.48 20.10 14.25 20.13 14.04 20.24 C 13.83 20.35 13.69 20.54 13.62 20.77 L 13.38 21.77 L 13.35 22.03 Z"/>
<path d="M 12.02 26.80 C 12.02 26.97 12.07 27.13 12.17 27.29 C 12.27 27.45 12.42 27.56 12.62 27.62 C 12.73 27.65 12.80 27.67 12.85 27.67 C 12.94 27.67 13.06 27.64 13.23 27.57 C 13.43 27.49 13.57 27.30 13.66 27.02 L 13.96 25.97 C 14.03 25.76 14.01 25.55 13.89 25.34 C 13.77 25.13 13.60 25.00 13.38 24.93 C 13.14 24.87 12.91 24.89 12.71 25.01 C 12.51 25.13 12.37 25.30 12.30 25.54 L 12.05 26.55 C 12.03 26.63 12.02 26.72 12.02 26.80 Z"/>
<path d="M 10.77 18.95 C 10.77 19.06 10.80 19.18 10.87 19.31 C 10.94 19.48 11.12 19.61 11.40 19.69 C 11.64 19.75 11.86 19.73 12.06 19.63 C 12.25 19.53 12.39 19.35 12.46 19.11 L 12.74 18.08 C 12.81 17.85 12.79 17.63 12.67 17.44 C 12.55 17.24 12.38 17.11 12.16 17.05 C 11.92 16.99 11.69 17.01 11.49 17.12 C 11.29 17.23 11.16 17.40 11.09 17.64 L 10.82 18.65 C 10.79 18.78 10.77 18.88 10.77 18.95 Z"/>
<path d="M 9.47 23.68 C 9.47 23.83 9.52 23.98 9.62 24.13 C 9.72 24.28 9.87 24.39 10.07 24.46 C 10.29 24.53 10.50 24.52 10.71 24.41 C 10.92 24.30 11.05 24.13 11.12 23.90 L 11.40 22.84 C 11.47 22.63 11.45 22.43 11.33 22.22 C 11.21 22.01 11.04 21.88 10.82 21.81 C 10.59 21.75 10.37 21.78 10.17 21.89 C 9.97 22.00 9.83 22.19 9.75 22.42 L 9.52 23.41 C 9.49 23.57 9.47 23.66 9.47 23.68 Z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.5 KiB

View File

@@ -0,0 +1,13 @@
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" id="Layer_1" x="0px" y="0px" viewBox="0 0 30 30" style="enable-background:new 0 0 30 30;">
<path id="cloud" d="M 5.14 13.84 C 5.85 12.95 6.77 12.36 7.89 12.08 C 8.20 10.71 8.91 9.59 10.00 8.71 C 11.09 7.83 12.35 7.39 13.76 7.39 C 14.54 7.39 15.33 7.56 16.14 7.89 C 16.21 7.76 17.62 8.71 17.58 8.77 C 18.64 9.68 19.30 10.74 19.57 11.97 L 19.88 11.97 C 21.15 11.97 22.22 12.36 23.11 13.15 C 23.14 13.12 24.34 14.35 24.22 14.45 C 24.65 15.19 24.87 16.02 24.87 16.93 C 24.87 17.80 24.66 18.61 24.24 19.36 C 23.82 20.11 23.24 20.71 22.51 21.16 C 21.78 21.61 20.98 21.85 20.10 21.87 C 19.96 21.87 19.89 21.81 19.89 21.70 L 19.89 20.36 C 19.89 20.25 19.96 20.19 20.10 20.19 C 20.95 20.14 21.67 19.80 22.28 19.16 C 22.89 18.52 23.19 17.77 23.19 16.92 C 23.19 16.02 22.87 15.25 22.22 14.61 C 21.57 13.96 20.80 13.64 19.89 13.64 L 18.27 13.64 C 18.16 13.64 18.10 13.58 18.10 13.46 L 18.02 12.89 C 17.90 11.81 17.44 10.90 16.62 10.17 C 15.80 9.44 14.85 9.07 13.76 9.07 C 12.66 9.07 11.71 9.44 10.90 10.18 C 10.09 10.92 9.64 11.84 9.53 12.93 L 9.46 13.45 C 9.46 13.56 9.39 13.62 9.26 13.62 L 8.73 13.69 C 7.90 13.76 7.20 14.10 6.63 14.72 C 6.06 15.34 5.78 16.07 5.78 16.92 C 5.78 17.77 6.08 18.52 6.69 19.16 C 7.29 19.80 8.02 20.15 8.87 20.19 C 8.99 20.19 9.05 20.25 9.05 20.36 L 9.05 21.70 C 9.05 21.81 8.99 21.87 8.87 21.87 C 7.54 21.83 6.40 21.32 5.47 20.36 C 4.54 19.40 4.07 18.26 4.07 16.93 C 4.07 15.77 4.43 14.74 5.14 13.84 L 5.14 13.84 Z"/>
<path id="moon" d="M 17.13 6.67 C 17.51 6.32 17.90 6.06 18.31 5.87 C 18.72 5.68 19.11 5.55 19.49 5.46 C 19.87 5.37 20.24 5.33 20.61 5.33 C 21.01 5.33 21.42 5.38 21.86 5.49 L 22.66 5.73 C 22.78 5.78 22.82 5.86 22.80 5.95 L 22.69 6.57 C 22.62 6.87 22.59 7.16 22.59 7.43 C 22.59 7.74 22.64 8.06 22.74 8.38 C 22.84 8.71 22.98 9.02 23.18 9.33 C 23.38 9.64 23.65 9.92 23.99 10.17 C 24.33 10.42 24.72 10.61 25.16 10.74 L 25.77 10.91 C 25.88 10.94 25.93 11.00 25.93 11.07 C 25.93 11.11 25.92 11.14 25.91 11.15 L 25.74 11.87 C 25.50 12.76 24.87 13.96 24.23 14.49 L 23.13 13.19 C 23.43 12.87 23.73 12.40 23.87 12.08 C 22.95 11.63 22.22 10.98 21.70 10.12 C 21.18 9.26 20.92 8.35 20.92 7.38 L 20.92 7.07 C 20.85 7.06 20.74 7.05 20.59 7.05 C 20.00 7.06 19.43 7.21 18.88 7.51 C 18.39 7.78 17.87 8.32 17.57 8.77 L 16.16 7.89 C 16.38 7.57 16.85 6.93 17.13 6.67 L 17.13 6.67 Z"/>
<g id="snow">
<path d="M 16.90 24.66 C 16.90 24.89 16.98 25.08 17.14 25.24 C 17.30 25.40 17.50 25.48 17.74 25.48 C 17.98 25.48 18.17 25.40 18.33 25.24 C 18.49 25.08 18.56 24.89 18.56 24.65 C 18.56 24.41 18.48 24.22 18.33 24.06 C 18.17 23.90 17.98 23.83 17.74 23.83 C 17.50 23.83 17.30 23.91 17.14 24.06 C 16.98 24.22 16.90 24.42 16.90 24.66 Z"/>
<path d="M 16.90 21.02 C 16.90 21.26 16.98 21.46 17.15 21.62 C 17.32 21.78 17.51 21.87 17.75 21.87 C 17.99 21.87 18.18 21.79 18.34 21.62 C 18.50 21.45 18.58 21.25 18.58 21.02 C 18.58 20.80 18.50 20.60 18.34 20.44 C 18.18 20.28 17.99 20.20 17.75 20.20 C 17.51 20.20 17.32 20.28 17.15 20.44 C 16.98 20.60 16.90 20.79 16.90 21.02 Z"/>
<path d="M 13.66 26.63 C 13.66 26.85 13.74 27.04 13.90 27.20 C 14.07 27.37 14.26 27.45 14.48 27.45 C 14.72 27.45 14.92 27.37 15.09 27.21 C 15.26 27.05 15.34 26.86 15.34 26.62 C 15.34 26.38 15.26 26.18 15.09 26.01 C 14.92 25.84 14.72 25.75 14.48 25.75 C 14.26 25.75 14.07 25.84 13.90 26.01 C 13.75 26.19 13.66 26.40 13.66 26.63 Z"/>
<path d="M 13.66 19.32 C 13.66 19.56 13.74 19.75 13.90 19.90 C 14.06 20.06 14.26 20.14 14.48 20.14 C 14.72 20.14 14.93 20.06 15.09 19.91 C 15.25 19.76 15.34 19.56 15.34 19.32 C 15.34 19.09 15.26 18.89 15.09 18.72 C 14.92 18.55 14.72 18.47 14.48 18.47 C 14.26 18.47 14.06 18.55 13.90 18.72 C 13.74 18.89 13.66 19.09 13.66 19.32 Z"/>
<path d="M 13.66 22.96 C 13.66 23.20 13.74 23.40 13.90 23.55 C 14.06 23.71 14.26 23.79 14.48 23.79 C 14.72 23.79 14.92 23.71 15.09 23.55 C 15.26 23.39 15.34 23.19 15.34 22.96 C 15.34 22.72 15.26 22.52 15.09 22.35 C 14.92 22.18 14.72 22.09 14.48 22.09 C 14.26 22.09 14.07 22.18 13.90 22.35 C 13.73 22.52 13.66 22.72 13.66 22.96 Z"/>
<path d="M 10.46 24.66 C 10.46 24.89 10.54 25.08 10.70 25.24 C 10.86 25.40 11.06 25.48 11.28 25.48 C 11.52 25.48 11.72 25.40 11.88 25.25 C 12.04 25.09 12.12 24.90 12.12 24.66 C 12.12 24.42 12.04 24.23 11.88 24.07 C 11.72 23.91 11.52 23.84 11.28 23.84 C 11.04 23.84 10.85 23.92 10.69 24.07 C 10.54 24.22 10.46 24.42 10.46 24.66 Z"/>
<path d="M 10.46 21.02 C 10.46 21.26 10.54 21.46 10.70 21.62 C 10.86 21.79 11.05 21.87 11.29 21.87 C 11.53 21.87 11.73 21.79 11.89 21.62 C 12.05 21.45 12.13 21.25 12.13 21.02 C 12.13 20.80 12.05 20.60 11.89 20.44 C 11.73 20.28 11.53 20.20 11.29 20.20 C 11.06 20.20 10.86 20.28 10.70 20.44 C 10.54 20.60 10.46 20.79 10.46 21.02 Z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.6 KiB

View File

@@ -0,0 +1,11 @@
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" id="Layer_1" x="0px" y="0px" viewBox="0 0 30 30" style="enable-background:new 0 0 30 30;">
<path id="cloud" d="M 5.16 13.82 C 5.88 12.92 6.79 12.34 7.90 12.08 C 8.21 10.72 8.92 9.60 10.01 8.72 C 11.10 7.84 12.36 7.40 13.77 7.40 C 14.51 7.40 15.30 7.55 16.13 7.86 C 16.18 7.77 17.61 8.73 17.59 8.77 C 18.62 9.62 19.28 10.68 19.57 11.94 L 19.90 11.94 C 21.14 11.94 22.21 12.33 23.12 13.11 C 23.15 13.08 24.32 14.32 24.20 14.44 C 24.64 15.21 24.86 16.02 24.86 16.89 C 24.86 18.22 24.40 19.37 23.47 20.34 C 22.54 21.30 21.41 21.81 20.08 21.85 C 19.95 21.85 19.89 21.79 19.89 21.67 L 19.89 20.31 C 19.89 20.18 19.96 20.12 20.08 20.12 C 20.95 20.06 21.68 19.71 22.28 19.09 C 22.88 18.47 23.18 17.73 23.18 16.88 C 23.18 16.00 22.86 15.23 22.21 14.60 C 21.56 13.97 20.79 13.65 19.88 13.65 L 18.26 13.65 C 18.15 13.65 18.09 13.58 18.09 13.46 L 18.02 12.89 C 17.90 11.82 17.44 10.91 16.62 10.18 C 15.80 9.45 14.85 9.08 13.76 9.08 C 12.67 9.08 11.72 9.45 10.91 10.18 C 10.10 10.91 9.65 11.82 9.54 12.90 L 9.47 13.41 C 9.47 13.53 9.40 13.59 9.27 13.59 L 8.74 13.66 C 7.91 13.76 7.21 14.12 6.64 14.73 C 6.07 15.35 5.79 16.07 5.79 16.90 C 5.79 17.64 6.02 18.31 6.50 18.91 C 6.93 19.45 7.63 19.92 8.25 20.12 L 7.67 21.70 C 6.70 21.37 5.70 20.68 5.08 19.86 C 4.42 18.99 4.09 18.00 4.09 16.89 C 4.09 15.74 4.45 14.71 5.16 13.82 Z"/>
<path id="moon" d="M 17.12 6.66 C 17.50 6.32 17.89 6.05 18.30 5.87 C 18.71 5.69 19.11 5.55 19.49 5.47 C 19.87 5.38 20.25 5.34 20.62 5.35 C 20.98 5.35 21.39 5.40 21.86 5.49 L 22.66 5.73 C 22.78 5.78 22.82 5.86 22.80 5.96 L 22.69 6.57 C 22.62 6.86 22.59 7.14 22.59 7.42 C 22.58 7.84 22.66 8.26 22.83 8.68 C 23.00 9.10 23.28 9.51 23.68 9.90 C 24.08 10.29 24.57 10.57 25.14 10.74 L 25.76 10.91 C 25.86 10.94 25.91 10.99 25.91 11.07 C 25.91 11.11 25.91 11.13 25.90 11.14 L 25.71 11.82 C 25.51 12.67 24.91 13.81 24.21 14.41 L 23.07 13.13 C 23.36 12.84 23.73 12.42 23.88 12.08 C 23.26 11.78 22.72 11.38 22.27 10.87 C 21.81 10.36 21.48 9.81 21.25 9.21 C 21.02 8.61 20.91 7.99 20.91 7.35 L 20.91 7.03 L 20.69 7.03 C 20.08 7.03 19.49 7.18 18.93 7.48 C 18.40 7.76 17.93 8.26 17.61 8.77 L 16.15 7.84 C 16.39 7.48 16.81 6.93 17.12 6.66 Z"/>
<path id="lightning" d="M 8.28 20.08 L 9.35 17.20 C 9.41 17.10 9.48 17.05 9.57 17.05 L 12.53 17.05 C 12.69 17.05 12.73 17.13 12.66 17.27 L 10.19 21.91 L 12.37 21.91 C 12.44 21.91 12.48 21.93 12.51 21.98 C 12.53 22.03 12.53 22.08 12.49 22.12 L 8.26 27.74 L 7.98 27.74 L 9.27 23.56 L 7.15 23.56 C 7.01 23.56 6.97 23.49 7.01 23.35 L 7.66 21.65 C 7.59 21.63 8.21 20.06 8.28 20.08 Z"/>
<g id="rain">
<path d="M 17.78 18.87 C 17.78 19.30 18.00 19.58 18.43 19.69 C 18.57 19.71 18.67 19.73 18.73 19.73 C 19.09 19.73 19.34 19.51 19.47 19.08 L 19.75 18.04 C 19.76 17.99 19.76 17.92 19.76 17.82 C 19.77 17.65 19.73 17.49 19.62 17.33 C 19.51 17.17 19.35 17.06 19.13 17.00 C 19.12 17.00 19.08 17.00 19.03 16.99 C 18.98 16.98 18.93 16.98 18.90 16.98 C 18.74 16.98 18.58 17.03 18.42 17.13 C 18.26 17.23 18.15 17.39 18.09 17.60 L 17.80 18.62 C 17.80 18.63 17.80 18.66 17.79 18.72 C 17.79 18.79 17.78 18.84 17.78 18.87 Z"/>
<path d="M 16.41 23.67 C 16.42 23.84 16.48 24.00 16.59 24.15 C 16.70 24.30 16.86 24.42 17.07 24.49 C 17.23 24.53 17.34 24.55 17.40 24.55 C 17.74 24.55 17.98 24.32 18.11 23.87 L 18.35 22.85 C 18.42 22.62 18.40 22.40 18.29 22.19 C 18.18 21.98 18.01 21.85 17.79 21.78 C 17.54 21.72 17.31 21.75 17.11 21.86 C 16.91 21.98 16.78 22.16 16.74 22.39 L 16.45 23.42 C 16.45 23.44 16.44 23.48 16.43 23.54 C 16.41 23.61 16.41 23.65 16.41 23.67 Z"/>
<path d="M 13.60 22.00 C 13.60 22.43 13.80 22.68 14.21 22.75 C 14.35 22.78 14.44 22.80 14.48 22.80 C 14.86 22.80 15.11 22.59 15.25 22.17 L 15.55 21.15 C 15.61 20.93 15.58 20.72 15.47 20.52 C 15.36 20.32 15.17 20.18 14.94 20.11 C 14.72 20.04 14.50 20.06 14.30 20.18 C 14.10 20.30 13.96 20.47 13.89 20.71 L 13.64 21.72 C 13.61 21.81 13.60 21.90 13.60 22.00 Z"/>
<path d="M 12.26 26.76 C 12.26 26.92 12.31 27.07 12.41 27.23 C 12.51 27.39 12.66 27.50 12.86 27.56 C 13.02 27.59 13.11 27.61 13.13 27.61 C 13.22 27.61 13.35 27.58 13.50 27.51 C 13.71 27.41 13.85 27.24 13.92 26.98 L 14.20 25.93 C 14.26 25.71 14.24 25.50 14.12 25.30 C 14.00 25.10 13.83 24.96 13.59 24.89 C 13.37 24.83 13.16 24.86 12.96 24.97 C 12.76 25.09 12.62 25.27 12.55 25.50 L 12.28 26.50 L 12.26 26.76 Z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@@ -0,0 +1,9 @@
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" id="Layer_1" x="0px" y="0px" viewBox="0 0 30 30" style="enable-background:new 0 0 30 30;">
<path id="cloud" d="M 5.12 13.81 C 5.84 12.91 6.75 12.33 7.86 12.07 C 8.17 10.70 8.88 9.58 9.97 8.71 C 11.06 7.84 12.32 7.40 13.73 7.40 C 14.49 7.40 15.29 7.55 16.11 7.85 C 16.18 7.74 17.62 8.70 17.59 8.75 C 18.63 9.61 19.29 10.66 19.57 11.92 L 19.89 11.92 C 21.12 11.92 22.19 12.31 23.11 13.10 C 23.15 13.06 24.31 14.30 24.18 14.43 C 24.62 15.20 24.84 16.01 24.84 16.88 C 24.84 17.76 24.63 18.58 24.21 19.33 C 23.79 20.08 23.21 20.68 22.48 21.13 C 21.75 21.58 20.95 21.82 20.07 21.85 C 19.94 21.85 19.88 21.79 19.88 21.67 L 19.88 20.29 C 19.88 20.18 19.95 20.12 20.07 20.12 C 20.94 20.05 21.67 19.70 22.27 19.08 C 22.87 18.46 23.17 17.72 23.17 16.87 C 23.17 15.98 22.85 15.21 22.20 14.58 C 21.55 13.95 20.78 13.63 19.87 13.63 L 18.25 13.63 C 18.13 13.63 18.07 13.57 18.07 13.46 L 18.00 12.87 C 17.88 11.80 17.41 10.89 16.59 10.16 C 15.77 9.43 14.82 9.06 13.74 9.06 C 12.65 9.06 11.70 9.43 10.89 10.16 C 10.08 10.89 9.63 11.80 9.52 12.88 L 9.45 13.40 C 9.45 13.51 9.38 13.57 9.25 13.57 L 8.73 13.65 C 7.90 13.75 7.20 14.10 6.63 14.72 C 6.06 15.34 5.78 16.06 5.78 16.89 C 5.78 17.63 6.01 18.30 6.48 18.90 C 6.92 19.46 7.60 19.87 8.25 20.07 L 7.65 21.66 C 6.66 21.33 5.70 20.70 5.07 19.86 C 4.41 18.98 4.08 17.99 4.08 16.88 C 4.08 15.72 4.44 14.69 5.12 13.81 L 5.12 13.81 Z"/>
<path id="lightning" d="M 8.26 20.07 L 9.33 17.19 C 9.40 17.10 9.47 17.05 9.56 17.05 L 12.52 17.05 C 12.68 17.05 12.72 17.13 12.65 17.27 L 10.17 21.90 L 12.35 21.90 C 12.42 21.90 12.47 21.92 12.50 21.97 C 12.53 22.02 12.53 22.07 12.49 22.12 L 8.58 27.06 L 8.29 27.06 L 9.26 23.55 L 7.14 23.55 C 7.01 23.55 6.96 23.48 6.99 23.34 L 7.65 21.65 C 7.60 21.64 8.21 20.06 8.26 20.07 Z"/>
<path id="moon" d="M 17.11 6.63 C 17.50 6.28 17.90 6.01 18.31 5.83 C 18.72 5.64 19.12 5.51 19.50 5.42 C 19.89 5.33 20.26 5.29 20.62 5.29 C 21.00 5.29 21.38 5.33 21.77 5.42 C 22.16 5.51 22.46 5.59 22.67 5.68 C 22.81 5.73 22.85 5.81 22.81 5.91 L 22.67 6.52 C 22.62 6.79 22.59 7.06 22.59 7.32 C 22.59 7.76 22.68 8.20 22.85 8.64 C 23.02 9.07 23.31 9.49 23.72 9.87 C 24.12 10.25 24.61 10.53 25.18 10.69 L 25.74 10.87 C 25.85 10.90 25.90 10.95 25.90 11.02 C 25.90 11.05 25.89 11.08 25.88 11.09 L 25.74 11.81 C 25.53 12.63 24.84 13.88 24.18 14.49 L 23.09 13.13 C 23.38 12.86 23.74 12.40 23.90 12.03 C 22.98 11.57 22.25 10.92 21.73 10.06 C 21.21 9.20 20.95 8.29 20.95 7.33 L 20.95 7.01 C 20.90 7.00 20.80 7.00 20.68 7.00 C 20.06 7.00 19.47 7.15 18.92 7.45 C 18.41 7.72 17.89 8.26 17.58 8.75 L 16.09 7.84 C 16.26 7.48 16.82 6.89 17.11 6.63 L 17.11 6.63 Z"/>
<g id="rain">
<path d="M 16.35 23.68 C 16.35 23.84 16.40 24.00 16.50 24.14 C 16.60 24.28 16.75 24.39 16.96 24.45 C 16.99 24.45 17.04 24.45 17.11 24.46 C 17.18 24.47 17.24 24.47 17.27 24.47 C 17.65 24.47 17.89 24.26 17.99 23.84 L 19.49 18.07 C 19.55 17.83 19.53 17.61 19.41 17.41 C 19.30 17.22 19.13 17.09 18.90 17.03 C 18.67 16.96 18.45 16.98 18.25 17.09 C 18.05 17.20 17.92 17.36 17.86 17.59 L 16.36 23.41 C 16.36 23.51 16.35 23.60 16.35 23.68 Z"/>
<path d="M 12.18 26.70 C 12.18 26.86 12.23 27.02 12.33 27.16 C 12.43 27.31 12.58 27.41 12.78 27.46 C 12.89 27.48 12.99 27.49 13.08 27.49 C 13.49 27.49 13.74 27.28 13.84 26.86 L 16.16 18.07 C 16.22 17.83 16.20 17.62 16.09 17.42 C 15.98 17.22 15.81 17.09 15.59 17.03 C 15.36 16.96 15.14 16.98 14.94 17.09 C 14.74 17.20 14.60 17.36 14.54 17.58 L 12.22 26.42 C 12.19 26.52 12.18 26.61 12.18 26.70 Z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

@@ -0,0 +1,3 @@
<!-- Generator: Adobe Illustrator 22.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) --><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Layer_1" x="0px" y="0px" viewBox="0 0 30 30" style="enable-background:new 0 0 30 30;" xml:space="preserve">
<path id="moon" d="M7.91,14.48c0-0.96,0.19-1.87,0.56-2.75s0.88-1.63,1.51-2.26c0.63-0.63,1.39-1.14,2.27-1.52c0.88-0.38,1.8-0.57,2.75-0.57 h1.14c0.16,0.04,0.23,0.14,0.23,0.28l0.05,0.88c0.04,1.27,0.49,2.35,1.37,3.24c0.88,0.89,1.94,1.37,3.19,1.42l0.82,0.07 c0.16,0,0.24,0.08,0.24,0.23v0.98c0.01,1.28-0.3,2.47-0.93,3.56c-0.63,1.09-1.48,1.95-2.57,2.59c-1.08,0.63-2.27,0.95-3.55,0.95 c-0.97,0-1.9-0.19-2.78-0.56s-1.63-0.88-2.26-1.51c-0.63-0.63-1.13-1.39-1.5-2.26C8.1,16.37,7.91,15.45,7.91,14.48z M9.74,14.48 c0,0.76,0.15,1.48,0.45,2.16c0.3,0.67,0.7,1.24,1.19,1.7c0.49,0.46,1.05,0.82,1.69,1.08c0.63,0.27,1.28,0.4,1.94,0.4 c0.58,0,1.17-0.11,1.76-0.34c0.59-0.23,1.14-0.55,1.65-0.96c0.51-0.41,0.94-0.93,1.31-1.57c0.37-0.64,0.6-1.33,0.71-2.09 c-1.63-0.34-2.94-1.04-3.92-2.1s-1.55-2.3-1.7-3.74C13.86,9.08,13,9.37,12.21,9.9c-0.78,0.53-1.39,1.2-1.82,2.02 C9.96,12.74,9.74,13.59,9.74,14.48z"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -0,0 +1,14 @@
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" id="Layer_1" x="0px" y="0px" viewBox="0 0 30 30" style="enable-background:new 0 0 30 30;">
<path id="cloud" d="M 4.65 16.96 C 4.65 18.28 5.12 19.42 6.05 20.37 C 6.98 21.33 8.11 21.83 9.43 21.87 C 9.55 21.87 9.61 21.81 9.61 21.70 L 9.61 20.37 C 9.61 20.25 9.55 20.19 9.43 20.19 C 8.59 20.15 7.86 19.81 7.26 19.17 C 6.66 18.53 6.35 17.80 6.35 16.95 C 6.35 16.11 6.63 15.38 7.20 14.76 C 7.77 14.14 8.46 13.79 9.30 13.72 L 9.83 13.65 C 9.95 13.65 10.02 13.59 10.02 13.47 L 10.09 12.97 C 10.19 11.88 10.64 10.96 11.45 10.22 C 12.26 9.48 13.21 9.11 14.31 9.11 C 15.39 9.11 16.34 9.48 17.15 10.21 C 17.96 10.94 18.43 11.84 18.55 12.92 L 18.62 13.50 C 18.62 13.62 18.68 13.68 18.81 13.68 L 20.41 13.68 C 21.31 13.68 22.08 14.00 22.73 14.65 C 23.37 15.29 23.70 16.06 23.70 16.95 C 23.70 17.79 23.40 18.53 22.80 19.17 C 22.20 19.80 21.47 20.14 20.62 20.19 C 20.49 20.19 20.42 20.25 20.42 20.37 L 20.42 21.70 C 20.42 21.81 20.49 21.87 20.62 21.87 C 21.95 21.83 23.08 21.33 24.00 20.37 C 24.92 19.41 25.38 18.28 25.38 16.95 C 25.38 16.06 25.16 15.23 24.71 14.47 C 24.27 13.71 23.66 13.11 22.90 12.67 C 22.14 12.23 21.31 12.01 20.42 12.01 L 20.11 12.01 C 19.78 10.67 19.08 9.58 18.00 8.72 C 16.93 7.87 15.70 7.44 14.32 7.44 C 12.91 7.44 11.66 7.88 10.57 8.75 C 9.48 9.62 8.78 10.74 8.47 12.10 C 7.34 12.39 6.43 12.98 5.72 13.87 C 5.01 14.76 4.65 15.80 4.65 16.96 Z"/>
<g id="rain">
<path d="M 18.10 18.81 C 18.10 18.98 18.15 19.14 18.26 19.29 C 18.37 19.44 18.53 19.55 18.75 19.61 C 18.77 19.61 18.81 19.62 18.87 19.63 C 18.93 19.64 18.98 19.65 19.01 19.65 C 19.11 19.65 19.23 19.62 19.37 19.56 C 19.58 19.45 19.72 19.27 19.78 19.04 L 20.02 18.14 C 20.08 17.91 20.06 17.70 19.94 17.51 C 19.83 17.31 19.66 17.18 19.43 17.11 C 19.20 17.04 18.99 17.06 18.79 17.17 C 18.60 17.28 18.46 17.44 18.40 17.68 L 18.12 18.59 C 18.12 18.61 18.11 18.65 18.10 18.71 C 18.10 18.74 18.10 18.78 18.10 18.81 Z"/>
<path d="M 17.49 21.12 C 17.49 21.34 17.57 21.54 17.74 21.69 C 17.89 21.85 18.08 21.93 18.31 21.93 C 18.55 21.93 18.74 21.85 18.90 21.70 C 19.06 21.55 19.13 21.35 19.13 21.12 C 19.13 20.88 19.05 20.69 18.90 20.53 C 18.75 20.37 18.55 20.30 18.31 20.30 C 18.07 20.30 17.88 20.38 17.72 20.53 C 17.57 20.69 17.49 20.88 17.49 21.12 Z"/>
<path d="M 16.75 24.08 C 16.75 24.24 16.80 24.40 16.90 24.56 C 17.00 24.72 17.16 24.83 17.36 24.89 C 17.39 24.89 17.44 24.90 17.50 24.91 C 17.56 24.92 17.60 24.93 17.64 24.93 C 18.05 24.93 18.30 24.71 18.40 24.27 L 18.54 23.67 C 18.61 23.46 18.59 23.25 18.47 23.04 C 18.36 22.83 18.19 22.70 17.96 22.63 C 17.71 22.57 17.48 22.59 17.28 22.71 C 17.08 22.83 16.94 23.00 16.87 23.24 L 16.78 23.83 C 16.78 23.85 16.77 23.90 16.76 23.95 C 16.75 24.00 16.75 24.04 16.75 24.08 Z"/>
<path d="M 13.99 21.93 C 13.98 22.08 14.02 22.24 14.12 22.40 C 14.22 22.56 14.37 22.66 14.57 22.70 C 14.80 22.76 15.01 22.74 15.21 22.64 C 15.41 22.54 15.54 22.35 15.62 22.08 L 15.89 21.18 C 15.96 20.96 15.94 20.75 15.82 20.55 C 15.70 20.35 15.53 20.22 15.29 20.15 C 15.07 20.08 14.86 20.11 14.65 20.23 C 14.44 20.35 14.31 20.53 14.24 20.76 L 14.01 21.66 C 14.00 21.74 13.99 21.83 13.99 21.93 Z"/>
<path d="M 13.36 24.20 C 13.36 24.42 13.44 24.61 13.61 24.78 C 13.77 24.94 13.96 25.02 14.18 25.02 C 14.42 25.02 14.61 24.94 14.77 24.79 C 14.93 24.63 15.00 24.44 15.00 24.20 C 15.00 23.97 14.92 23.78 14.77 23.62 C 14.61 23.46 14.42 23.39 14.18 23.39 C 13.94 23.39 13.75 23.47 13.59 23.62 C 13.43 23.77 13.36 23.97 13.36 24.20 Z"/>
<path d="M 12.59 27.10 C 12.59 27.28 12.64 27.44 12.74 27.60 C 12.84 27.76 13.00 27.87 13.22 27.93 C 13.30 27.95 13.39 27.96 13.47 27.96 C 13.90 27.96 14.16 27.76 14.26 27.35 L 14.40 26.76 C 14.46 26.50 14.43 26.28 14.32 26.08 C 14.20 25.88 14.03 25.76 13.80 25.71 C 13.59 25.64 13.38 25.66 13.17 25.78 C 12.96 25.90 12.83 26.07 12.76 26.29 L 12.62 26.88 C 12.60 26.97 12.59 27.04 12.59 27.10 Z"/>
<path d="M 11.42 18.81 C 11.41 18.97 11.45 19.12 11.56 19.26 C 11.66 19.41 11.82 19.51 12.04 19.58 C 12.25 19.64 12.45 19.62 12.66 19.51 C 12.87 19.40 13.00 19.23 13.07 19.00 L 13.35 18.10 C 13.42 17.86 13.40 17.64 13.28 17.45 C 13.16 17.26 12.98 17.13 12.74 17.06 C 12.52 16.99 12.31 17.01 12.11 17.13 C 11.91 17.24 11.77 17.41 11.70 17.63 L 11.46 18.55 C 11.46 18.57 11.45 18.61 11.44 18.67 C 11.43 18.72 11.42 18.77 11.42 18.81 Z"/>
<path d="M 10.81 21.08 C 10.81 21.29 10.89 21.48 11.06 21.65 C 11.22 21.82 11.40 21.90 11.62 21.90 C 11.86 21.90 12.06 21.82 12.22 21.66 C 12.38 21.50 12.46 21.31 12.46 21.07 C 12.46 20.84 12.38 20.64 12.22 20.48 C 12.06 20.32 11.86 20.24 11.62 20.24 C 11.39 20.24 11.20 20.32 11.04 20.47 C 10.89 20.65 10.81 20.85 10.81 21.08 Z"/>
<path d="M 10.05 23.98 C 10.05 24.15 10.10 24.32 10.21 24.49 C 10.32 24.66 10.48 24.77 10.68 24.84 C 10.91 24.91 11.12 24.90 11.32 24.80 C 11.51 24.71 11.65 24.52 11.71 24.24 L 11.85 23.63 C 11.90 23.40 11.87 23.19 11.76 23.00 C 11.65 22.81 11.48 22.67 11.24 22.60 C 11.02 22.53 10.80 22.56 10.60 22.68 C 10.40 22.80 10.26 22.98 10.20 23.21 L 10.06 23.80 C 10.06 23.83 10.05 23.89 10.05 23.98 Z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.0 KiB

View File

@@ -0,0 +1,8 @@
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" id="Layer_1" x="0px" y="0px" viewBox="0 0 30 30" style="enable-background:new 0 0 30 30;">
<path id="cloud" d="M 4.64 16.91 C 4.64 15.76 5.00 14.74 5.72 13.84 C 6.44 12.94 7.35 12.37 8.45 12.11 C 8.76 10.75 9.47 9.63 10.56 8.75 C 11.65 7.87 12.90 7.44 14.31 7.44 C 15.69 7.44 16.91 7.87 17.99 8.72 C 19.07 9.57 19.77 10.67 20.09 12.01 L 20.41 12.01 C 21.30 12.01 22.13 12.23 22.89 12.66 C 23.65 13.09 24.26 13.69 24.70 14.44 C 25.14 15.19 25.37 16.02 25.37 16.91 C 25.37 17.79 25.16 18.60 24.74 19.35 C 24.32 20.10 23.74 20.70 23.01 21.15 C 22.28 21.60 21.48 21.84 20.61 21.86 C 20.48 21.86 20.41 21.80 20.41 21.69 L 20.41 20.36 C 20.41 20.24 20.48 20.18 20.61 20.18 C 21.46 20.14 22.19 19.80 22.79 19.16 C 23.39 18.52 23.69 17.77 23.69 16.90 C 23.69 16.03 23.36 15.28 22.71 14.64 C 22.06 14.00 21.29 13.68 20.40 13.68 L 18.79 13.68 C 18.67 13.68 18.61 13.62 18.61 13.51 L 18.53 12.93 C 18.42 11.85 17.95 10.94 17.14 10.22 C 16.32 9.49 15.38 9.13 14.29 9.13 C 13.20 9.13 12.24 9.49 11.44 10.22 C 10.63 10.95 10.18 11.85 10.08 12.93 L 10.01 13.46 C 10.01 13.58 9.94 13.65 9.81 13.65 L 9.28 13.68 C 8.45 13.78 7.75 14.14 7.18 14.75 C 6.61 15.36 6.33 16.08 6.33 16.91 C 6.33 17.78 6.63 18.53 7.23 19.17 C 7.83 19.81 8.56 20.15 9.41 20.19 C 9.52 20.19 9.58 20.25 9.58 20.37 L 9.58 21.70 C 9.58 21.81 9.52 21.87 9.41 21.87 C 8.07 21.81 6.94 21.30 6.01 20.34 C 5.08 19.38 4.64 18.24 4.64 16.91 Z"/>
<g id="rain">
<path d="M 16.74 23.62 C 16.74 23.58 16.75 23.51 16.78 23.39 L 18.41 17.62 C 18.47 17.43 18.57 17.28 18.71 17.18 C 18.86 17.08 19.01 17.03 19.17 17.03 C 19.25 17.03 19.34 17.04 19.43 17.06 C 19.64 17.12 19.79 17.22 19.89 17.37 C 19.99 17.52 20.04 17.68 20.04 17.84 C 20.04 17.87 20.03 17.92 20.02 17.98 C 20.01 18.04 20.00 18.08 20.00 18.10 L 18.37 23.83 C 18.33 24.02 18.24 24.18 18.09 24.29 C 17.94 24.40 17.77 24.46 17.58 24.46 L 17.34 24.41 C 17.14 24.35 16.99 24.25 16.88 24.09 C 16.79 23.94 16.74 23.78 16.74 23.62 Z"/>
<path d="M 12.61 26.41 L 15.05 17.64 C 15.09 17.45 15.19 17.30 15.35 17.20 C 15.51 17.10 15.67 17.05 15.84 17.05 C 15.93 17.05 16.02 17.06 16.11 17.08 C 16.33 17.14 16.49 17.27 16.60 17.47 C 16.71 17.67 16.73 17.88 16.67 18.11 L 14.24 26.89 C 14.20 27.06 14.11 27.20 13.95 27.32 C 13.79 27.44 13.63 27.50 13.44 27.50 C 13.35 27.50 13.26 27.48 13.19 27.45 C 12.99 27.40 12.82 27.27 12.67 27.06 C 12.56 26.88 12.54 26.67 12.61 26.41 Z"/>
<path d="M 9.99 23.60 C 9.99 23.56 10.00 23.49 10.03 23.40 L 11.66 17.63 C 11.72 17.44 11.83 17.29 11.98 17.19 C 12.13 17.09 12.29 17.04 12.44 17.04 C 12.51 17.04 12.59 17.05 12.68 17.07 C 12.92 17.11 13.10 17.24 13.22 17.44 C 13.34 17.64 13.37 17.86 13.30 18.11 L 11.67 23.84 C 11.55 24.27 11.27 24.48 10.85 24.48 C 10.81 24.48 10.78 24.47 10.74 24.46 C 10.68 24.44 10.65 24.43 10.64 24.43 C 10.42 24.37 10.26 24.26 10.15 24.10 C 10.04 23.93 9.99 23.77 9.99 23.60 Z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

@@ -0,0 +1,11 @@
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" id="Layer_1" x="0px" y="0px" viewBox="0 0 30 30" style="enable-background:new 0 0 30 30;">
<path id="cloud" d="M 4.60 16.93 C 4.60 15.77 4.96 14.75 5.69 13.85 C 6.41 12.95 7.34 12.37 8.47 12.12 C 8.76 10.74 9.45 9.62 10.54 8.73 C 11.63 7.84 12.88 7.40 14.30 7.40 C 15.69 7.40 16.93 7.83 18.02 8.68 C 19.10 9.53 19.81 10.63 20.14 11.98 L 20.48 11.98 C 21.38 11.98 22.21 12.20 22.96 12.64 C 23.72 13.08 24.31 13.68 24.75 14.44 C 25.18 15.20 25.40 16.03 25.40 16.93 C 25.40 18.27 24.94 19.41 24.03 20.37 C 23.11 21.33 21.99 21.83 20.66 21.87 C 20.54 21.87 20.48 21.81 20.48 21.70 L 20.48 20.36 C 20.48 20.25 20.54 20.19 20.66 20.19 C 21.50 20.12 22.23 19.77 22.83 19.14 C 23.43 18.51 23.73 17.77 23.73 16.92 C 23.73 16.03 23.41 15.26 22.77 14.61 C 22.13 13.97 21.37 13.64 20.48 13.64 L 18.85 13.64 C 18.73 13.64 18.66 13.58 18.63 13.46 L 18.56 12.89 C 18.49 12.18 18.26 11.53 17.86 10.95 C 17.46 10.37 16.95 9.92 16.33 9.59 C 15.71 9.26 15.03 9.10 14.31 9.10 C 13.21 9.10 12.26 9.46 11.45 10.19 C 10.64 10.92 10.18 11.83 10.08 12.91 L 10.01 13.45 C 10.01 13.54 9.96 13.59 9.85 13.59 L 9.31 13.70 C 8.47 13.77 7.76 14.11 7.20 14.73 C 6.63 15.35 6.35 16.08 6.35 16.93 C 6.35 17.80 6.65 18.55 7.24 19.18 C 7.83 19.81 8.55 20.15 9.41 20.20 C 9.53 20.20 9.59 20.26 9.59 20.37 L 9.59 21.71 C 9.59 21.82 9.53 21.88 9.41 21.88 C 8.75 21.85 8.13 21.70 7.53 21.43 C 6.93 21.16 6.42 20.80 6.00 20.36 C 5.57 19.92 5.23 19.41 4.98 18.81 C 4.73 18.21 4.60 17.59 4.60 16.93 Z"/>
<g id="rain">
<path d="M 18.11 18.98 C 18.11 18.95 18.13 18.86 18.16 18.72 L 18.46 17.69 C 18.50 17.48 18.59 17.32 18.75 17.22 C 18.91 17.12 19.07 17.07 19.24 17.08 C 19.28 17.07 19.37 17.08 19.48 17.11 C 19.70 17.16 19.87 17.29 20.00 17.49 C 20.12 17.66 20.14 17.87 20.07 18.14 L 19.83 19.17 C 19.70 19.60 19.45 19.82 19.07 19.82 C 19.01 19.82 18.90 19.80 18.73 19.76 C 18.52 19.70 18.37 19.59 18.27 19.45 C 18.16 19.29 18.11 19.14 18.11 18.98 Z"/>
<path d="M 16.73 23.74 C 16.73 23.67 16.74 23.59 16.76 23.50 L 17.04 22.51 C 17.11 22.27 17.24 22.09 17.45 21.97 C 17.66 21.85 17.86 21.82 18.08 21.88 C 18.31 21.95 18.49 22.08 18.61 22.29 C 18.73 22.49 18.76 22.70 18.70 22.92 L 18.41 23.98 C 18.31 24.39 18.05 24.59 17.62 24.59 C 17.53 24.59 17.44 24.58 17.36 24.56 C 17.16 24.52 17.01 24.42 16.90 24.26 C 16.80 24.08 16.74 23.91 16.73 23.74 Z"/>
<path d="M 13.91 22.06 C 13.91 22.00 13.92 21.92 13.95 21.81 L 14.22 20.78 C 14.29 20.55 14.42 20.38 14.63 20.27 C 14.83 20.15 15.05 20.13 15.28 20.20 C 15.51 20.26 15.67 20.39 15.79 20.59 C 15.90 20.79 15.92 21.00 15.85 21.24 L 15.61 22.23 C 15.48 22.68 15.24 22.91 14.89 22.91 C 14.85 22.91 14.74 22.89 14.58 22.85 C 14.36 22.81 14.20 22.71 14.09 22.55 C 13.97 22.40 13.91 22.23 13.91 22.06 Z"/>
<path d="M 12.57 26.83 C 12.57 26.80 12.58 26.76 12.59 26.70 C 12.60 26.64 12.61 26.61 12.61 26.58 L 12.90 25.59 C 12.96 25.35 13.10 25.17 13.30 25.05 C 13.50 24.93 13.72 24.90 13.95 24.97 C 14.18 25.04 14.34 25.17 14.46 25.38 C 14.58 25.59 14.59 25.80 14.53 26.03 L 14.28 27.07 C 14.17 27.48 13.91 27.68 13.48 27.68 C 13.43 27.68 13.35 27.67 13.24 27.64 C 13.02 27.60 12.86 27.50 12.75 27.34 C 12.63 27.18 12.57 27.01 12.57 26.83 Z"/>
<path d="M 11.34 18.88 C 11.34 18.86 11.34 18.82 11.35 18.77 C 11.36 18.72 11.36 18.69 11.36 18.68 L 11.66 17.63 C 11.72 17.44 11.83 17.29 11.98 17.18 C 12.13 17.08 12.29 17.03 12.45 17.03 C 12.47 17.03 12.50 17.03 12.53 17.03 C 12.56 17.03 12.59 17.04 12.62 17.04 C 12.65 17.05 12.68 17.05 12.70 17.05 C 12.93 17.12 13.10 17.25 13.21 17.45 C 13.33 17.65 13.35 17.86 13.28 18.09 L 13.04 19.09 C 12.97 19.37 12.84 19.56 12.64 19.68 C 12.44 19.80 12.22 19.80 11.99 19.70 C 11.77 19.64 11.61 19.53 11.50 19.36 C 11.39 19.19 11.34 19.04 11.34 18.88 Z"/>
<path d="M 10.02 23.70 C 10.02 23.67 10.03 23.62 10.04 23.57 C 10.05 23.52 10.06 23.48 10.06 23.46 L 10.33 22.43 C 10.40 22.21 10.53 22.03 10.73 21.92 C 10.93 21.80 11.14 21.78 11.37 21.85 C 11.60 21.92 11.77 22.05 11.89 22.25 C 12.01 22.45 12.03 22.66 11.96 22.89 L 11.72 23.90 C 11.59 24.34 11.34 24.56 10.96 24.56 C 10.93 24.56 10.91 24.56 10.87 24.56 C 10.84 24.56 10.80 24.55 10.76 24.55 C 10.72 24.54 10.69 24.54 10.66 24.54 C 10.45 24.48 10.29 24.36 10.18 24.20 C 10.07 24.04 10.02 23.86 10.02 23.70 Z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@@ -0,0 +1,12 @@
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" id="Layer_1" x="0px" y="0px" viewBox="0 0 30 30" style="enable-background:new 0 0 30 30;">
<path id="cloud" d="M 4.64 16.95 C 4.64 15.79 4.99 14.77 5.70 13.87 C 6.41 12.97 7.32 12.39 8.44 12.11 C 8.75 10.75 9.45 9.63 10.54 8.75 C 11.63 7.87 12.88 7.44 14.29 7.44 C 15.67 7.44 16.89 7.87 17.97 8.72 C 19.05 9.57 19.75 10.67 20.07 12.01 L 20.39 12.01 C 21.28 12.01 22.11 12.23 22.87 12.67 C 23.63 13.11 24.24 13.71 24.68 14.47 C 25.12 15.23 25.35 16.06 25.35 16.95 C 25.35 18.27 24.89 19.42 23.96 20.37 C 23.04 21.33 21.91 21.83 20.58 21.87 C 20.45 21.87 20.38 21.81 20.38 21.70 L 20.38 20.37 C 20.38 20.25 20.45 20.19 20.58 20.19 C 21.43 20.15 22.16 19.81 22.76 19.17 C 23.36 18.53 23.66 17.79 23.66 16.94 C 23.66 16.05 23.34 15.29 22.69 14.64 C 22.04 13.99 21.27 13.67 20.37 13.67 L 18.76 13.67 C 18.64 13.67 18.58 13.61 18.58 13.50 L 18.50 12.92 C 18.39 11.84 17.92 10.93 17.11 10.20 C 16.29 9.47 15.35 9.10 14.26 9.10 C 13.16 9.10 12.21 9.47 11.40 10.21 C 10.59 10.95 10.13 11.86 10.03 12.96 L 9.97 13.46 C 9.97 13.58 9.90 13.65 9.77 13.65 L 9.24 13.72 C 8.41 13.79 7.71 14.13 7.14 14.76 C 6.57 15.39 6.29 16.11 6.29 16.95 C 6.29 17.80 6.59 18.54 7.19 19.18 C 7.79 19.82 8.52 20.15 9.37 20.20 C 9.48 20.20 9.54 20.26 9.54 20.38 L 9.54 21.71 C 9.54 21.82 9.48 21.88 9.37 21.88 C 8.03 21.84 6.90 21.34 5.97 20.38 C 5.10 19.42 4.64 18.27 4.64 16.95 Z"/>
<g id="snow">
<path d="M 17.41 24.65 C 17.41 24.43 17.49 24.23 17.66 24.05 C 17.82 23.90 18.02 23.82 18.26 23.82 C 18.50 23.82 18.69 23.90 18.85 24.05 C 19.01 24.20 19.08 24.40 19.08 24.64 C 19.08 24.88 19.00 25.07 18.85 25.23 C 18.69 25.39 18.50 25.46 18.26 25.46 C 18.02 25.46 17.82 25.38 17.66 25.22 C 17.50 25.07 17.41 24.88 17.41 24.65 Z"/>
<path d="M 17.41 21.02 C 17.41 20.80 17.49 20.61 17.66 20.44 C 17.83 20.27 18.03 20.19 18.26 20.19 C 18.49 20.19 18.69 20.27 18.85 20.43 C 19.01 20.59 19.09 20.79 19.09 21.01 C 19.09 21.25 19.01 21.45 18.85 21.61 C 18.69 21.78 18.50 21.86 18.26 21.86 C 18.02 21.86 17.82 21.78 17.66 21.61 C 17.50 21.45 17.41 21.25 17.41 21.02 Z"/>
<path d="M 14.19 26.61 C 14.19 26.38 14.27 26.18 14.44 26.00 C 14.60 25.84 14.79 25.76 15.01 25.76 C 15.25 25.76 15.45 25.84 15.62 26.01 C 15.79 26.18 15.87 26.38 15.87 26.61 C 15.87 26.84 15.79 27.04 15.62 27.20 C 15.45 27.36 15.25 27.44 15.01 27.44 C 14.78 27.44 14.59 27.36 14.43 27.20 C 14.27 27.03 14.19 26.84 14.19 26.61 Z"/>
<path d="M 14.19 19.33 C 14.19 19.10 14.27 18.90 14.44 18.73 C 14.62 18.57 14.81 18.49 15.01 18.49 C 15.25 18.49 15.45 18.57 15.62 18.74 C 15.79 18.91 15.87 19.10 15.87 19.34 C 15.87 19.57 15.79 19.77 15.62 19.93 C 15.45 20.09 15.25 20.17 15.01 20.17 C 14.78 20.17 14.59 20.09 14.43 19.93 C 14.27 19.76 14.19 19.56 14.19 19.33 Z"/>
<path d="M 14.19 22.95 C 14.19 22.72 14.27 22.51 14.44 22.33 C 14.60 22.17 14.79 22.09 15.01 22.09 C 15.24 22.09 15.44 22.18 15.61 22.35 C 15.78 22.52 15.87 22.72 15.87 22.95 C 15.87 23.18 15.79 23.38 15.62 23.55 C 15.45 23.72 15.25 23.80 15.01 23.80 C 14.78 23.80 14.59 23.72 14.43 23.55 C 14.27 23.38 14.19 23.18 14.19 22.95 Z"/>
<path d="M 11.00 24.65 C 11.00 24.41 11.08 24.21 11.24 24.05 C 11.40 23.90 11.59 23.82 11.82 23.82 C 12.05 23.82 12.25 23.90 12.41 24.05 C 12.57 24.21 12.65 24.40 12.65 24.64 C 12.65 24.88 12.57 25.07 12.41 25.23 C 12.25 25.39 12.06 25.46 11.82 25.46 C 11.59 25.46 11.39 25.38 11.23 25.23 C 11.08 25.08 11.00 24.88 11.00 24.65 Z"/>
<path d="M 11.00 21.02 C 11.00 20.80 11.08 20.60 11.24 20.44 C 11.40 20.28 11.59 20.20 11.83 20.20 C 12.06 20.20 12.26 20.28 12.42 20.44 C 12.58 20.60 12.66 20.80 12.66 21.02 C 12.66 21.26 12.58 21.46 12.42 21.62 C 12.26 21.79 12.07 21.87 11.83 21.87 C 11.60 21.87 11.40 21.79 11.24 21.62 C 11.08 21.46 11.00 21.26 11.00 21.02 Z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.7 KiB

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