feat(ui): show status of processing sessions on initial setup

This commit is contained in:
Shekar Siri 2023-07-03 14:08:16 +02:00
parent 4ae22abbaa
commit 402d2aadd3
8 changed files with 374 additions and 172 deletions

View file

@ -28,7 +28,7 @@ const siteIdRequiredPaths = [
'/unprocessed',
'/notes',
'/feature-flags',
// '/custom_metrics/sessions',
'/check-recording-status'
];
const noStoringFetchPathStarts = [

View file

@ -25,6 +25,7 @@ export enum ICONS {
NO_DASHBOARDS = 'ca-no-dashboards',
NO_PROJECTS = 'ca-no-projects',
NO_FFLAGS = 'no-fflags',
PROCESSING = 'ca-processing',
}
const ICONS_SVGS = {
@ -52,6 +53,7 @@ const ICONS_SVGS = {
[ICONS.NO_DASHBOARDS]: require('../../../svg/ca-no-dashboards.svg').default,
[ICONS.NO_PROJECTS]: require('../../../svg/ca-no-projects.svg').default,
[ICONS.NO_FFLAGS]: require('../../../svg/no-fflags.svg').default,
[ICONS.PROCESSING]: require('../../../svg/ca-processing.svg').default,
};
interface Props {

View file

@ -2,31 +2,42 @@ import React from 'react';
import SessionList from './components/SessionList';
import SessionHeader from './components/SessionHeader';
import NotesList from './components/Notes/NoteList';
import { connect } from 'react-redux';
import { connect, DefaultRootState } from 'react-redux';
import LatestSessionsMessage from './components/LatestSessionsMessage';
import RecordingStatus from 'Shared/SessionsTabOverview/components/RecordingStatus';
function SessionsTabOverview({
activeTab,
members,
}: {
activeTab,
members,
sites,
siteId
}: {
activeTab: string;
members: object[];
sites: object[];
siteId: string;
}) {
const activeSite: any = sites.find((s: any) => s.id === siteId);
const hasNoRecordings = !activeSite || !activeSite.recorded;
return (
<div className="widget-wrapper">
<div className='widget-wrapper'>
<SessionHeader />
<div className="border-b" />
<div className='border-b' />
<LatestSessionsMessage />
{activeTab !== 'notes' ? <SessionList /> : <NotesList members={members} />}
{activeTab !== 'notes' ? <SessionList /> :
<NotesList members={members} />}
</div>
);
}
export default connect(
(state) => ({
(state: any) => ({
// @ts-ignore
activeTab: state.getIn(['search', 'activeTab', 'type']),
// @ts-ignore
members: state.getIn(['members', 'list']),
}),
siteId: state.getIn(['site', 'siteId']),
sites: state.getIn(['site', 'list'])
})
)(SessionsTabOverview);

View file

@ -0,0 +1,37 @@
import React from 'react';
import AnimatedSVG, { ICONS } from 'Shared/AnimatedSVG/AnimatedSVG';
import { Icon } from 'UI';
interface Props {
data: any;
}
function RecordingStatus(props: Props) {
const { data } = props;
return (
<div className='flex items-center gap-8 justify-center m-20'>
<AnimatedSVG name={ICONS.PROCESSING} size={180} />
<div className='flex flex-col gap-4 w-3/6'>
<div className='text-lg font-medium'>Processing your first session.</div>
<div className='flex items-start'>
<div className='mr-2'>
<Icon name='check-circle-fill' size={20} color='tealx' />
</div>
<div>Your tracker seems to be correctly setup!</div>
</div>
<div className='flex items-start'>
<div className='mr-2'>
<Icon name='check-circle' size={20} color='tealx' />
</div>
<div>There are {data.count} ongoing session(s). <br />Once they're complete they'll show up here within a few
minutes.
</div>
</div>
</div>
</div>
);
}
export default RecordingStatus;

View file

@ -10,12 +10,15 @@ import {
addFilterByKeyAndValue,
updateCurrentPage,
setScrollPosition,
checkForLatestSessions,
checkForLatestSessions
} from 'Duck/search';
import { numberWithCommas } from 'App/utils';
import { fetchListActive as fetchMetadata } from 'Duck/customField';
import { toggleFavorite } from 'Duck/sessions';
import SessionDateRange from './SessionDateRange';
import RecordingStatus from 'Shared/SessionsTabOverview/components/RecordingStatus';
import { sessionService } from 'App/services';
import { updateProjectRecordingStatus } from 'Duck/site';
enum NoContentType {
Bookmarked,
@ -23,8 +26,17 @@ enum NoContentType {
ToDate,
}
type SessionStatus = {
status: number;
count: number;
}
const AUTOREFRESH_INTERVAL = 5 * 60 * 1000;
let sessionTimeOut: any = null;
let sessionStatusTimeOut: any = null;
const STATUS_FREQUENCY = 5000;
interface Props extends RouteComponentProps {
loading: boolean;
list: any;
@ -40,11 +52,15 @@ interface Props extends RouteComponentProps {
setScrollPosition: (scrollPosition: number) => void;
fetchSessions: (filters: any, force: boolean) => void;
fetchMetadata: () => void;
updateProjectRecordingStatus: (siteId: string, status: boolean) => void;
activeTab: any;
isEnterprise?: boolean;
checkForLatestSessions: () => void;
toggleFavorite: (sessionId: string) => Promise<void>;
sites: object[];
siteId: string;
}
function SessionList(props: Props) {
const [noContentType, setNoContentType] = React.useState<NoContentType>(NoContentType.ToDate);
const {
@ -58,48 +74,91 @@ function SessionList(props: Props) {
metaList,
activeTab,
isEnterprise = false,
sites,
siteId
} = props;
const _filterKeys = filters.map((i: any) => i.key);
const hasUserFilter =
_filterKeys.includes(FilterKey.USERID) || _filterKeys.includes(FilterKey.USERANONYMOUSID);
const isBookmark = activeTab.type === 'bookmark';
const isVault = isBookmark && isEnterprise;
const activeSite: any = sites.find((s: any) => s.id === siteId);
const hasNoRecordings = !activeSite || !activeSite.recorded;
const NO_CONTENT = React.useMemo(() => {
if (isBookmark && !isEnterprise) {
setNoContentType(NoContentType.Bookmarked);
return {
icon: ICONS.NO_BOOKMARKS,
message: 'No sessions bookmarked.',
message: 'No sessions bookmarked.'
};
} else if (isVault) {
setNoContentType(NoContentType.Vaulted);
return {
icon: ICONS.NO_SESSIONS_IN_VAULT,
message: 'No sessions found in vault.',
message: 'No sessions found in vault.'
};
}
setNoContentType(NoContentType.ToDate);
return {
icon: ICONS.NO_SESSIONS,
message: <SessionDateRange />,
message: <SessionDateRange />
};
}, [isBookmark, isVault, activeTab]);
const [statusData, setStatusData] = React.useState<SessionStatus>({ status: 0, count: 0 });
const fetchStatus = async () => {
const response = await sessionService.getRecordingStatus();
setStatusData({
status: response.recording_status,
count: response.sessions_count
});
};
useEffect(() => {
if (!hasNoRecordings) {
return;
}
fetchStatus();
sessionStatusTimeOut = setInterval(() => {
fetchStatus();
}, STATUS_FREQUENCY);
return () => clearInterval(sessionStatusTimeOut);
}, [hasNoRecordings]);
useEffect(() => {
if (!hasNoRecordings && statusData.status === 0) {
return;
}
if (statusData.status === 2) { // recording && processed
props.updateProjectRecordingStatus(activeSite.id, true);
props.fetchSessions(null, true);
clearInterval(sessionStatusTimeOut);
}
}, [statusData]);
useEffect(() => {
const id = setInterval(() => {
if (!document.hidden) {
props.checkForLatestSessions()
props.checkForLatestSessions();
}
}, AUTOREFRESH_INTERVAL)
return () => clearInterval(id)
}, [])
}, AUTOREFRESH_INTERVAL);
return () => clearInterval(id);
}, []);
useEffect(() => {
// handle scroll position
const { scrollY } = props;
window.scrollTo(0, scrollY);
if (total === 0 && !loading) {
if (total === 0 && !loading && !hasNoRecordings) {
setTimeout(() => {
props.fetchSessions(null, true);
}, 300);
@ -117,7 +176,7 @@ function SessionList(props: Props) {
return;
}
sessionTimeOut = setTimeout(function () {
sessionTimeOut = setTimeout(function() {
if (!document.hidden) {
props.checkForLatestSessions();
}
@ -147,73 +206,73 @@ function SessionList(props: Props) {
return (
<Loader loading={loading}>
<NoContent
title={
<div className="flex items-center justify-center flex-col">
<AnimatedSVG name={NO_CONTENT.icon} size={180} />
<div className="mt-4" />
<div className="text-center relative">
{NO_CONTENT.message}
{/* {noContentType === NoContentType.ToDate ? (
<div style={{ position: 'absolute', right: -160, top: -170 }}>
<Icon name="pointer-sessions-search" size={250} width={240} />
{hasNoRecordings && statusData.status >= 1 ? <RecordingStatus data={statusData} /> : (
<>
<NoContent
title={
<div className='flex items-center justify-center flex-col'>
<AnimatedSVG name={NO_CONTENT.icon} size={180} />
<div className='mt-4' />
<div className='text-center relative'>
{NO_CONTENT.message}
</div>
) : null} */}
</div>
</div>
}
subtext={
<div className="flex flex-col items-center">
{(isVault || isBookmark) && (
<div>
{isVault
? 'Extend the retention period of any session by adding it to your vault directly from the player screen.'
: 'Effortlessly find important sessions by bookmarking them directly from the player screen.'}
</div>
)}
<Button
variant="text-primary"
className="mt-4"
icon="arrow-repeat"
iconSize={20}
onClick={() => props.fetchSessions(null, true)}
>
Refresh
</Button>
</div>
}
show={!loading && list.length === 0}
>
{list.map((session: any) => (
<div key={session.sessionId} className="border-b">
<SessionItem
session={session}
hasUserFilter={hasUserFilter}
onUserClick={onUserClick}
metaList={metaList}
lastPlayedSessionId={lastPlayedSessionId}
bookmarked={isBookmark}
toggleFavorite={toggleFavorite}
/>
</div>
))}
</NoContent>
}
subtext={
<div className='flex flex-col items-center'>
{(isVault || isBookmark) && (
<div>
{isVault
? 'Extend the retention period of any session by adding it to your vault directly from the player screen.'
: 'Effortlessly find important sessions by bookmarking them directly from the player screen.'}
</div>
)}
<Button
variant='text-primary'
className='mt-4'
icon='arrow-repeat'
iconSize={20}
onClick={() => props.fetchSessions(null, true)}
>
Refresh
</Button>
</div>
}
show={!loading && list.length === 0}
>
{list.map((session: any) => (
<div key={session.sessionId} className='border-b'>
<SessionItem
session={session}
hasUserFilter={hasUserFilter}
onUserClick={onUserClick}
metaList={metaList}
lastPlayedSessionId={lastPlayedSessionId}
bookmarked={isBookmark}
toggleFavorite={toggleFavorite}
/>
</div>
))}
</NoContent>
{total > 0 && (
<div className='flex items-center justify-between p-5'>
<div>
Showing <span className='font-medium'>{(currentPage - 1) * pageSize + 1}</span> to{' '}
<span className='font-medium'>{(currentPage - 1) * pageSize + list.length}</span> of{' '}
<span className='font-medium'>{numberWithCommas(total)}</span> sessions.
</div>
<Pagination
page={currentPage}
totalPages={Math.ceil(total / pageSize)}
onPageChange={(page) => props.updateCurrentPage(page)}
limit={pageSize}
debounceRequest={1000}
/>
</div>
)}
</>
{total > 0 && (
<div className="flex items-center justify-between p-5">
<div>
Showing <span className="font-medium">{(currentPage - 1) * pageSize + 1}</span> to{' '}
<span className="font-medium">{(currentPage - 1) * pageSize + list.length}</span> of{' '}
<span className="font-medium">{numberWithCommas(total)}</span> sessions.
</div>
<Pagination
page={currentPage}
totalPages={Math.ceil(total / pageSize)}
onPageChange={(page) => props.updateCurrentPage(page)}
limit={pageSize}
debounceRequest={1000}
/>
</div>
)}
</Loader>
);
@ -232,6 +291,8 @@ export default connect(
activeTab: state.getIn(['search', 'activeTab']),
pageSize: state.getIn(['search', 'pageSize']),
isEnterprise: state.getIn(['user', 'account', 'edition']) === 'ee',
siteId: state.getIn(['site', 'siteId']),
sites: state.getIn(['site', 'list'])
}),
{
updateCurrentPage,
@ -241,5 +302,6 @@ export default connect(
fetchMetadata,
checkForLatestSessions,
toggleFavorite,
updateProjectRecordingStatus
}
)(withRouter(SessionList));

View file

@ -1,30 +1,30 @@
import Site from 'Types/site';
import GDPR from 'Types/site/gdpr';
import {
mergeReducers,
createItemInListUpdater,
success,
array,
createListUpdater,
import {
mergeReducers,
createItemInListUpdater,
success,
array,
createListUpdater
} from './funcTools/tools';
import {
createCRUDReducer,
getCRUDRequestTypes,
createInit,
createEdit,
createRemove,
createUpdate,
saveType,
import {
createCRUDReducer,
getCRUDRequestTypes,
createInit,
createEdit,
createRemove,
createUpdate,
saveType
} from './funcTools/crud';
import { createRequestReducer } from './funcTools/request';
import { Map, List, fromJS } from "immutable";
import { Map, List, fromJS } from 'immutable';
import { GLOBAL_HAS_NO_RECORDINGS, SITE_ID_STORAGE_KEY } from 'App/constants/storageKeys';
const storedSiteId = localStorage.getItem(SITE_ID_STORAGE_KEY);
const name = 'project';
const idKey = 'id';
const itemInListUpdater = createItemInListUpdater(idKey)
const itemInListUpdater = createItemInListUpdater(idKey);
const updateItemInList = createListUpdater(idKey);
const EDIT_GDPR = 'sites/EDIT_GDPR';
@ -37,94 +37,101 @@ const SAVE_GDPR_SUCCESS = success(SAVE_GDPR);
const FETCH_LIST_SUCCESS = success(FETCH_LIST);
const SAVE = saveType('sites/SAVE');
const UPDATE_PROJECT_RECORDING_STATUS = 'sites/UPDATE_PROJECT_RECORDING_STATUS';
const initialState = Map({
list: List(),
instance: fromJS(),
remainingSites: undefined,
siteId: null,
active: null,
list: List(),
instance: fromJS(),
remainingSites: undefined,
siteId: null,
active: null
});
const reducer = (state = initialState, action = {}) => {
switch(action.type) {
case EDIT_GDPR:
return state.mergeIn([ 'instance', 'gdpr' ], action.gdpr);
case FETCH_GDPR_SUCCESS:
return state.mergeIn([ 'instance', 'gdpr' ], action.data);
case success(SAVE):
const newSite = Site(action.data);
return updateItemInList(state, newSite)
.set('siteId', newSite.get('id'))
.set('active', newSite);
case SAVE_GDPR_SUCCESS:
const gdpr = GDPR(action.data);
return state.setIn([ 'instance', 'gdpr' ], gdpr);
case FETCH_LIST_SUCCESS:
let siteId = state.get("siteId");
const siteIds = action.data.map(s => parseInt(s.projectId))
const siteExists = siteIds.includes(siteId);
if (action.siteIdFromPath && siteIds.includes(parseInt(action.siteIdFromPath))) {
siteId = action.siteIdFromPath;
} else if (!siteId || !siteExists) {
siteId = siteIds.includes(parseInt(storedSiteId))
? storedSiteId
: action.data[0].projectId;
}
const list = List(action.data.map(Site));
const hasRecordings = list.some(s => s.recorded);
if (!hasRecordings) {
localStorage.setItem(GLOBAL_HAS_NO_RECORDINGS, true)
} else {
localStorage.removeItem(GLOBAL_HAS_NO_RECORDINGS)
}
return state.set('list', list)
.set('siteId', siteId)
.set('active', list.find(s => parseInt(s.id) === parseInt(siteId)));
case SET_SITE_ID:
const _siteId = action.siteId ? action.siteId : state.get('list').get(0).id;
localStorage.setItem(SITE_ID_STORAGE_KEY, _siteId)
const site = state.get('list').find(s => parseInt(s.id) == _siteId);
return state.set('siteId', _siteId).set('active', site);
}
return state;
switch (action.type) {
case EDIT_GDPR:
return state.mergeIn(['instance', 'gdpr'], action.gdpr);
case FETCH_GDPR_SUCCESS:
return state.mergeIn(['instance', 'gdpr'], action.data);
case success(SAVE):
const newSite = Site(action.data);
return updateItemInList(state, newSite)
.set('siteId', newSite.get('id'))
.set('active', newSite);
case SAVE_GDPR_SUCCESS:
const gdpr = GDPR(action.data);
return state.setIn(['instance', 'gdpr'], gdpr);
case FETCH_LIST_SUCCESS:
let siteId = state.get('siteId');
const siteIds = action.data.map(s => parseInt(s.projectId));
const siteExists = siteIds.includes(siteId);
if (action.siteIdFromPath && siteIds.includes(parseInt(action.siteIdFromPath))) {
siteId = action.siteIdFromPath;
} else if (!siteId || !siteExists) {
siteId = siteIds.includes(parseInt(storedSiteId))
? storedSiteId
: action.data[0].projectId;
}
const list = List(action.data.map(Site));
const hasRecordings = list.some(s => s.recorded);
if (!hasRecordings) {
localStorage.setItem(GLOBAL_HAS_NO_RECORDINGS, true);
} else {
localStorage.removeItem(GLOBAL_HAS_NO_RECORDINGS);
}
return state.set('list', list)
.set('siteId', siteId)
.set('active', list.find(s => parseInt(s.id) === parseInt(siteId)));
case SET_SITE_ID:
const _siteId = action.siteId ? action.siteId : state.get('list').get(0).id;
localStorage.setItem(SITE_ID_STORAGE_KEY, _siteId);
const site = state.get('list').find(s => parseInt(s.id) == _siteId);
return state.set('siteId', _siteId).set('active', site);
case UPDATE_PROJECT_RECORDING_STATUS:
const { siteId: _siteIdToUpdate, status } = action;
const siteToUpdate = state.get('list').find(s => parseInt(s.id) === parseInt(_siteIdToUpdate));
const updatedSite = siteToUpdate.set('recorded', status);
return updateItemInList(state, updatedSite);
}
return state;
};
export function editGDPR(gdpr) {
return {
type: EDIT_GDPR,
gdpr,
gdpr
};
}
export function fetchGDPR(siteId) {
return {
types: array(FETCH_GDPR),
call: client => client.get(`/${ siteId }/gdpr`),
}
call: client => client.get(`/${siteId}/gdpr`)
};
}
export const saveGDPR = (siteId, gdpr) => (dispatch, getState) => {
const g = getState().getIn(['site', 'instance', 'gdpr']);
return dispatch({
types: array(SAVE_GDPR),
call: client => client.post(`/${ siteId }/gdpr`, g.toData()),
call: client => client.post(`/${siteId}/gdpr`, g.toData())
});
}
};
export function fetchList(siteId) {
return {
types: array(FETCH_LIST),
call: client => client.get('/projects'),
siteIdFromPath: siteId
};
return {
types: array(FETCH_LIST),
call: client => client.get('/projects'),
siteIdFromPath: siteId
};
}
export function save(site) {
return {
types: array(SAVE),
call: client => client.post(`/projects`, site.toData()),
}
return {
types: array(SAVE),
call: client => client.post(`/projects`, site.toData())
};
}
// export const fetchList = createFetchList(name);
@ -135,18 +142,26 @@ export const update = createUpdate(name);
export const remove = createRemove(name);
export function setSiteId(siteId) {
return {
type: SET_SITE_ID,
siteId,
};
}
return {
type: SET_SITE_ID,
siteId
};
}
export const updateProjectRecordingStatus = (siteId, status) => {
return {
type: UPDATE_PROJECT_RECORDING_STATUS,
siteId,
status
};
};
export default mergeReducers(
reducer,
createCRUDReducer(name, Site, idKey),
createRequestReducer({
saveGDPR: SAVE_GDPR,
...getCRUDRequestTypes(name),
}),
reducer,
createCRUDReducer(name, Site, idKey),
createRequestReducer({
saveGDPR: SAVE_GDPR,
...getCRUDRequestTypes(name)
})
);

View file

@ -78,4 +78,12 @@ export default class SettingsService {
.then(j => j.data || [])
.catch(Promise.reject)
}
getRecordingStatus(): Promise<any> {
return this.client
.get('/check-recording-status')
.then(r => r.json())
.then(j => j.data || {})
.catch(Promise.reject)
}
}

View file

@ -0,0 +1,67 @@
<svg width="304" height="184" viewBox="0 0 304 184" fill="none" xmlns="http://www.w3.org/2000/svg">
<path opacity="0.1" d="M90.7554 166.275C140.176 166.275 180.239 137.966 180.239 103.045C180.239 68.123 140.176 39.8136 90.7554 39.8136C41.3347 39.8136 1.27136 68.123 1.27136 103.045C1.27136 137.966 41.3347 166.275 90.7554 166.275Z" fill="url(#paint0_linear_336_5039)"/>
<path opacity="0.05" d="M97.3639 111.158C96.3898 140.021 124.79 164.404 160.798 165.619C196.805 166.835 226.785 144.422 227.759 115.559C228.733 86.6957 200.333 62.3125 164.325 61.0972C128.318 59.882 98.338 82.295 97.3639 111.158Z" fill="#122AF5"/>
<path opacity="0.05" d="M252.678 162.665C290.569 148.12 308.854 101.969 293.519 59.584C278.184 17.1986 235.036 -5.37066 197.146 9.17415C159.255 23.719 140.97 69.87 156.305 112.255C171.64 154.641 214.788 177.21 252.678 162.665Z" fill="#122AF5"/>
<path d="M103.79 88.6453C103.79 88.6453 75.9564 98.1175 94.7135 77.8087C113.476 57.4999 120.278 71.0308 120.278 71.0308C120.278 71.0308 128.725 79.1583 103.79 88.6453Z" fill="white"/>
<path d="M103.998 89.2259C78.4534 96.5148 87.9707 82.6118 100.233 71.6362C104.974 67.5179 112.371 63.2507 118.38 67.3889C119.565 68.2224 120.58 69.2446 121.313 70.5099L121.081 70.1973C124.182 73.6011 122.493 78.1858 119.465 80.9049C115.081 84.9488 109.487 87.1766 103.998 89.2259ZM103.582 88.0698C109.051 85.7476 117.023 82.3736 119.976 77.0098C120.645 75.6702 120.803 74.2411 120.189 72.9263C119.976 72.4152 119.56 71.9835 119.243 71.5518C114.893 64.1587 106.183 68.4408 101.05 72.6385C99.0981 74.1816 97.2749 75.9034 95.5409 77.7144C93.0291 80.4186 90.3289 83.1973 88.907 86.6308C86.4249 93.6766 100.629 89.1217 103.577 88.0698H103.582Z" fill="#231F20"/>
<path d="M94.717 76.3298C101.044 76.3298 106.173 71.193 106.173 64.8565C106.173 58.5199 101.044 53.3831 94.717 53.3831C88.39 53.3831 83.261 58.5199 83.261 64.8565C83.261 71.193 88.39 76.3298 94.717 76.3298Z" fill="#2D2D2D"/>
<path d="M104.945 64.8565C104.668 57.7663 97.4501 52.729 90.7408 55.2431C85.2446 57.2146 82.4061 63.6235 84.6034 69.0527C86.1536 73.1133 90.3676 75.959 94.717 75.7842C100.448 75.7329 105.231 70.4605 104.945 64.8565ZM107.398 64.8565C107.329 69.8063 104.003 74.4517 99.3675 76.1037C87.0205 80.3994 77.226 65.9266 85.979 56.1083C93.7478 47.8786 107.696 53.3711 107.398 64.8565Z" fill="#231F20"/>
<path d="M136.147 69.2744L104.142 61.3046C93.6918 57.2738 90.7061 67.5746 93.6918 72.5011L128.775 82.3091C128.775 82.3091 130.023 72.1225 136.152 69.2744H136.147Z" fill="white" stroke="#231F20" stroke-width="1.39544" stroke-miterlimit="10"/>
<path d="M231.419 77.2679L258.45 68.6343C264.212 66.7935 270.093 71.1004 270.093 77.1538V147.701C270.093 150.088 268.71 152.256 266.55 153.263L215.748 176.916C211.691 178.807 207.043 175.84 207.043 171.354V110.681C207.043 95.4183 216.903 81.9072 231.424 77.2679H231.419Z" fill="white" stroke="#231F20" stroke-width="1.39544" stroke-miterlimit="10"/>
<path d="M148.28 55.5946L175.311 46.961C181.073 45.1201 186.954 49.427 186.954 55.4804V126.028C186.954 128.414 185.571 130.583 183.411 131.59L132.609 155.243C128.552 157.134 123.905 154.166 123.905 149.681V89.0075C123.905 73.7449 133.764 60.2339 148.285 55.5946H148.28Z" fill="white" stroke="#231F20" stroke-width="1.39544" stroke-miterlimit="10"/>
<path d="M234.689 78.5679L261.72 69.9343C267.482 68.0935 273.363 72.4004 273.363 78.4538V148.996C273.363 151.383 271.98 153.551 269.82 154.558L219.018 178.211C214.961 180.102 210.313 177.135 210.313 172.649V111.976C210.313 96.7133 220.173 83.2023 234.694 78.5629L234.689 78.5679Z" fill="#F0F0F0"/>
<path d="M234.149 76.8759C240.233 74.8813 255.096 69.9641 261.046 68.0836C262.592 67.6172 264.291 67.4137 265.896 67.6618C269.647 68.1381 272.971 70.7332 274.403 74.2213C275.126 75.8736 275.29 77.7194 275.23 79.4958L275.156 88.7496C275.111 103.129 274.671 134.274 274.552 148.887C274.596 151.621 272.936 154.35 270.439 155.511L268.314 156.484L264.108 158.394C251.955 163.862 234.149 172.059 222.1 177.631C220.827 178.147 219.103 179.189 217.656 179.442C215.08 179.913 212.345 178.782 210.834 176.643C209.808 175.279 209.481 173.478 209.555 171.821C209.546 156.652 209.382 138.522 209.199 123.249C209.303 117.717 208.53 109.907 209.749 104.523C212.147 91.6969 221.808 80.9595 234.149 76.8859V76.8759ZM235.224 80.2599C220.445 84.9091 211.126 98.5641 211.542 113.99L211.418 123.244L211.22 141.747C211.091 151.477 211.081 162.051 211.057 171.816C211.047 172.57 211.047 173.23 211.21 173.939C211.81 176.634 214.668 178.489 217.373 177.948C218.458 177.735 220.361 176.723 221.446 176.232L229.814 172.312C241.065 166.978 258.272 158.875 269.439 153.487C271.143 152.633 272.233 150.802 272.164 148.882C272.134 147.106 271.752 110.026 271.708 107.247C271.653 101.194 271.534 85.3607 271.485 79.4908C271.802 75.6454 269.28 72.0282 265.361 71.532C264.306 71.3782 263.251 71.5172 262.23 71.8248C256.359 73.7152 241.298 78.3694 235.219 80.25L235.224 80.2599Z" fill="#231F20"/>
<path d="M151.55 56.8946L178.581 48.2611C184.343 46.4202 190.223 50.7271 190.223 56.7805V127.328C190.223 129.714 188.841 131.883 186.681 132.89L135.879 156.543C131.822 158.434 127.174 155.466 127.174 150.981V90.3076C127.174 75.045 137.034 61.534 151.555 56.8946H151.55Z" fill="#F0F0F0"/>
<path d="M150.955 55.0141C157.039 53.0046 171.892 48.0675 177.833 46.1622C179.413 45.671 181.152 45.4725 182.797 45.7256C186.632 46.2217 190.05 48.8614 191.521 52.4439C192.255 54.1259 192.433 56.0164 192.369 57.8225L192.294 67.0763C192.215 81.4557 191.71 112.601 191.546 127.214C191.586 129.992 189.892 132.766 187.355 133.942L185.225 134.91L181.013 136.81C168.845 142.243 151.02 150.4 138.971 155.968C137.692 156.484 135.973 157.526 134.522 157.779C131.945 158.25 129.201 157.114 127.7 154.97C126.679 153.606 126.352 151.805 126.426 150.147C126.426 134.979 126.238 116.848 126.01 101.576C126.104 96.0336 125.307 88.2236 126.511 82.8252C128.874 69.9492 138.584 59.1275 150.955 55.024V55.0141ZM152.154 58.7752C137.425 63.3649 128.121 76.9603 128.492 92.3122L128.344 101.566C128.254 112.437 127.947 127.844 127.947 138.571L127.927 147.825C127.962 148.505 127.863 151.021 127.982 151.765C128.279 153.973 130.063 155.819 132.238 156.25C133.675 156.508 134.883 156.221 136.221 155.526L138.312 154.543L146.675 150.619C157.921 145.275 175.103 137.118 186.255 131.709C187.92 130.871 188.97 129.084 188.901 127.209C188.861 125.432 188.4 88.3527 188.346 85.574C188.276 79.5206 188.118 63.6874 188.078 57.8175C188.385 54.1111 185.983 50.5931 182.192 50.1217C181.177 49.9729 180.161 50.1168 179.18 50.4046C173.304 52.2702 158.233 56.9046 152.149 58.7702L152.154 58.7752Z" fill="#231F20"/>
<path d="M129.749 67.3636C130.542 64.3166 127.7 60.9377 123.403 59.8166C119.105 58.6955 114.979 60.2567 114.187 63.3037C113.394 66.3507 116.235 69.7296 120.533 70.8507C124.83 71.9718 128.957 70.4106 129.749 67.3636Z" fill="white"/>
<path d="M128.656 67.0763C129.181 62.6057 121.987 60.1248 118.42 61.132C115.007 61.8961 114.085 64.9973 116.473 67.6122C118.663 69.9988 122.572 71.1202 125.654 70.0236C127.184 69.4877 128.408 68.3713 128.656 67.0763ZM130.836 67.6469C128.958 72.9412 121.789 72.698 117.632 70.5446C111.895 67.7164 111.023 60.8045 117.647 58.4923C121.67 57.2668 126.194 58.3484 129.082 61.4595C130.543 63.0671 131.495 65.4389 130.836 67.6469Z" fill="#231F20"/>
<path d="M198.922 156.007L154.457 144.977C151.995 144.277 150.296 142.025 150.296 139.464V105.893C150.296 102.211 153.714 99.482 157.301 100.306L201.766 110.537C204.367 111.137 206.205 113.45 206.205 116.124V150.49C206.205 154.29 202.579 157.039 198.922 156.002V156.007Z" fill="#E8F5F5" stroke="#231F20" stroke-width="2.32573" stroke-miterlimit="10"/>
<path d="M173.222 112.5C172.603 112.096 171.783 112.539 171.783 113.279V131.387C171.783 132.106 172.565 132.553 173.185 132.188L187.757 123.608C188.352 123.257 188.372 122.405 187.794 122.027L173.222 112.5Z" fill="white" stroke="#231F20" stroke-width="2.32573" stroke-miterlimit="10"/>
<path d="M156.367 139.983C155.741 139.84 155.117 140.231 154.974 140.857C154.83 141.483 155.221 142.106 155.847 142.25L156.367 139.983ZM155.847 142.25L199.47 152.263L199.99 149.996L156.367 139.983L155.847 142.25Z" fill="#231F20"/>
<path d="M166.522 71.0209L223.497 80.6965C211.606 87.2461 207.643 99.965 207.147 105.506L160.081 95.8301C146.209 81.7385 158.595 73.4192 166.522 71.0209Z" fill="white" stroke="black" stroke-width="0.465147"/>
<path d="M240.837 112.204C227.956 98.1125 238.112 88.3046 244.801 85.1621L285.426 92.6049C299.695 109.475 285.591 117.828 276.756 119.895L240.837 112.204Z" fill="white" stroke="black" stroke-width="0.465147"/>
<path d="M223.393 81.7137C204.527 78.4389 185.903 74.0129 166.988 71.5121H167.206C164.59 72.4499 162.028 73.5465 159.873 75.2236C157.852 76.6179 156.019 79.4163 155.479 81.148C154.057 86.7996 157.312 91.1015 160.765 93.4534C164.491 94.9072 168.499 95.4431 172.432 96.495C174.662 96.8572 178.432 97.661 181.137 98.2763C189.842 100.306 198.408 102.826 207.202 104.399C208.094 104.558 207.97 105.947 206.999 105.873C204.006 105.59 201.029 105.163 198.076 104.652C189.267 103.119 180.577 100.946 171.739 99.6705C167.666 98.7228 163.415 98.187 159.397 96.6835C156.638 95.0957 154.265 92.7091 152.863 89.732C148.126 79.3667 156.316 69.9988 166.958 70.0484C186.052 72.4599 204.764 77.0099 223.641 80.2549C224.552 80.4335 224.413 81.8526 223.388 81.7236L223.393 81.7137Z" fill="#231F20"/>
<path d="M172.408 70.7728C168.999 69.2297 165.476 71.8495 163.574 74.5686C159.546 80.1904 159.318 88.2186 162.93 94.0786C164.515 96.7182 167.795 99.2438 170.768 97.3087C171.114 97.0904 171.575 97.1995 171.793 97.5469C172.016 97.9041 171.897 98.3755 171.536 98.5839C167.78 100.846 163.797 97.9686 161.979 94.6591C158.407 88.4171 158.882 80.0316 163.277 74.3453C165.308 71.6461 168.999 69.0858 172.408 70.7728Z" fill="#231F20"/>
<path d="M182.336 100.822C178.526 103.109 174.528 100.147 172.72 96.7927C169.128 90.4366 169.816 82.0411 174.127 76.2259C176.113 73.4919 179.73 70.624 183.213 72.311C179.73 70.7679 176.287 73.6904 174.429 76.4442C170.475 82.19 170.039 90.2431 173.676 96.2171C175.256 98.8915 178.551 101.496 181.563 99.5465C182.41 99.0205 183.188 100.306 182.336 100.817V100.822Z" fill="#231F20"/>
<path d="M193.885 74.2511C190.337 72.6881 186.859 75.7049 185.002 78.5133C181.003 84.403 180.795 92.595 184.561 98.6037C186.181 101.243 189.441 104.161 192.542 102.221C192.894 102.008 193.35 102.117 193.563 102.469C193.781 102.826 193.662 103.293 193.3 103.501C189.47 105.803 185.403 102.469 183.609 99.1843C179.879 92.7438 180.349 84.274 184.699 78.2999C186.686 75.5114 190.337 72.5442 193.885 74.2511Z" fill="#231F20"/>
<path d="M203.868 105.744C200.023 108.066 196.01 104.662 194.286 101.348C190.709 94.8675 191.185 86.4621 195.53 80.5129C197.511 77.7343 201.163 74.7919 204.695 76.4938C201.163 74.9358 197.695 77.9327 195.837 80.7263C191.839 86.5911 191.63 94.7335 195.252 100.782C196.808 103.437 200.003 106.414 203.1 104.469C203.947 103.943 204.725 105.228 203.873 105.739L203.868 105.744Z" fill="#231F20"/>
<path d="M245.494 113.117C241.788 116.198 236.879 113.201 234.718 109.788C230.25 103.119 230.696 93.6369 235.709 87.395C237.587 85.0579 240.431 82.8747 243.656 82.9144C244.632 82.9144 247.699 83.6637 246.842 85.0034C246.663 85.2366 246.381 85.3358 246.113 85.2911C240.376 84.3534 236.512 94.0438 236.319 98.6931C235.967 103.154 237.627 110.894 242.581 112.08C243.26 112.194 244.018 112.095 244.771 111.827C245.554 111.549 246.133 112.596 245.499 113.117H245.494Z" fill="#231F20"/>
<path d="M254.942 86.4175C251.4 84.8545 247.922 87.8663 246.064 90.6747C242.066 96.5595 241.858 104.742 245.593 110.76C247.198 113.405 250.448 116.332 253.545 114.392C253.897 114.179 254.353 114.288 254.566 114.64C254.784 114.998 254.665 115.464 254.303 115.672C250.468 117.975 246.416 114.63 244.637 111.341C240.941 104.89 241.412 96.4354 245.762 90.4663C247.748 87.6778 251.4 84.7156 254.942 86.4224V86.4175Z" fill="#231F20"/>
<path d="M238.563 111.559C251.88 114.154 263.939 116.377 277.093 119.721Z" fill="white"/>
<path d="M238.563 111.559C251.88 114.154 263.939 116.377 277.093 119.721" stroke="#231F20" stroke-width="1.39544" stroke-miterlimit="10" stroke-linecap="round"/>
<path d="M281.037 91.7961C267.918 89.9999 255.859 86.6805 242.839 84.3534Z" fill="white"/>
<path d="M281.037 91.7961C267.918 89.9999 255.859 86.6805 242.839 84.3534" stroke="#231F20" stroke-width="1.39544" stroke-miterlimit="10" stroke-linecap="round"/>
<path d="M280.294 91.6572C287.026 92.198 290.42 97.4576 291.594 104.121C292.08 106.875 291.773 109.842 289.9 112.69C287.363 116.546 281.205 120.059 276.617 119.627" fill="white"/>
<path d="M280.353 90.9129C287.413 90.769 291.723 96.5098 293.165 102.891C295.394 110.894 290.088 118.168 282.444 120.356C280.541 120.872 278.436 121.021 276.543 120.366C276.147 120.227 275.934 119.791 276.077 119.389C276.176 119.111 276.414 118.932 276.682 118.883C279.857 118.129 282.721 116.506 285.302 114.571C287.809 112.705 289.588 110.2 289.885 107.108C290.049 105.545 289.766 103.963 289.434 102.405C288.726 99.2686 287.348 96.1873 284.713 94.2721C283.435 93.3392 281.889 92.714 280.219 92.3965C279.352 92.2328 279.461 90.9278 280.343 90.9129H280.353Z" fill="#231F20"/>
<path d="M214.995 88.0549C214.42 83.9366 218.751 78.9152 223.021 80.0515C221.981 79.8579 220.906 79.987 219.964 80.4186C217.363 81.6541 215.258 84.9686 215.783 87.8465C215.956 88.3973 215.119 88.6255 214.995 88.0598V88.0549Z" fill="#231F20"/>
<path d="M214.633 78.0866C210.888 76.4343 207.405 79.8232 205.527 82.7656C202.753 87.1518 202.035 92.714 203.303 97.7057C204.031 100.534 205.304 103.313 207.405 105.178C207.712 105.451 207.742 105.922 207.47 106.23C207.192 106.548 206.702 106.567 206.399 106.275C205.23 105.148 204.343 103.799 203.67 102.38C200.746 96.0732 201.168 88.2534 205.136 82.5076C207.172 79.585 210.883 76.2507 214.629 78.0816L214.633 78.0866Z" fill="#231F20"/>
<path d="M264.454 117.905C258.385 121.145 254.154 113.092 253.342 108.145C252.257 102.801 253.396 97.0011 256.632 92.6148C258.618 89.861 262.25 86.9633 265.752 88.6553C262.25 87.1072 258.792 90.0595 256.934 92.8331C253.936 97.2293 253.03 102.821 254.253 107.957C255.051 111.906 258.772 119.429 263.687 116.635C264.534 116.109 265.316 117.394 264.459 117.905H264.454Z" fill="#231F20"/>
<path d="M56.1934 128.509C56.1934 128.509 35.3158 137.41 43.5153 143.821C51.7147 150.232 67.7767 150.589 68.6982 145.959C69.6197 141.33 66.013 132.329 66.013 132.329" fill="white"/>
<path d="M56.3916 128.965C52.3389 131.258 44.6548 135.267 42.891 139.583C42.2816 141.29 43.4954 142.481 44.8232 143.409C49.7924 147.071 61.2271 149.785 66.8948 146.922C67.5191 146.52 67.8411 146.158 67.9055 145.518C68.183 143.771 67.9451 142.02 67.6479 140.248C67.1723 137.638 66.4192 135.043 65.5572 132.513L66.4787 132.146C68.0442 135.976 69.4315 139.936 69.6693 144.124C69.6594 144.888 69.6693 145.622 69.4661 146.386C68.2325 149.929 62.5201 150.083 59.4583 150.063C53.85 149.835 48.2467 148.435 43.5499 145.215C36.381 140.323 43.4459 134.324 48.5291 131.496C50.9319 130.131 53.4091 128.975 56.0052 128.057L56.3916 128.97V128.965Z" fill="#231F20"/>
<path d="M93.3015 130.121C93.3015 130.121 109.824 144.957 107.099 152.162C104.994 157.729 86.7915 151.12 78.6416 147.835C76.2189 146.857 74.802 144.203 75.3073 141.543C75.8127 138.884 76.754 135.535 78.4731 133.019" fill="white"/>
<path d="M93.6334 129.754C99.1377 134.111 108.923 143.32 108.838 150.767C108.759 152.097 108.308 153.546 107.208 154.395C103.052 157.645 93.0934 154.266 88.4958 152.832C85.5331 151.849 82.6348 150.713 79.7662 149.527L78.6961 149.07C77.4426 148.589 76.2635 147.766 75.5055 146.649C73.3057 143.722 74.6286 139.995 75.7829 136.929C76.3626 135.45 77.1008 134.016 78.0718 132.731L78.8893 133.292C77.3683 135.852 76.6351 138.854 76.1793 141.796C75.8572 144.104 77.3138 146.366 79.5383 146.967L80.6184 147.364C86.3109 149.423 92.1719 151.407 98.1023 152.469C100.247 152.767 103.943 153.457 105.559 151.948C107.54 148.167 101.328 140.472 98.9841 137.435C97.0718 135.068 95.0504 132.746 92.9795 130.488L93.6433 129.749L93.6334 129.754Z" fill="#231F20"/>
<path d="M80.1923 123.12L78.4682 133.014L93.3015 130.121L92.2859 117.573L80.1923 123.12Z" fill="white" stroke="#231F20" stroke-width="0.930293" stroke-miterlimit="10"/>
<path d="M58.6904 120.55L56.1934 128.509L66.0179 133.014L72.4932 120.143L58.6904 120.55Z" fill="white" stroke="#231F20" stroke-width="0.930293" stroke-miterlimit="10"/>
<path d="M25.6747 112.785C25.6747 112.785 18.367 117.865 24.337 123.755C24.337 123.755 29.9106 126.693 31.6991 120.292" fill="white"/>
<path d="M25.8877 113.087C23.9902 114.611 22.2413 116.977 22.6228 119.513C22.8655 120.986 23.7573 122.207 24.8473 123.234L24.6788 123.11C25.858 123.74 27.4632 124.078 28.7463 123.542C30.1088 122.991 30.9064 121.567 31.3474 120.188L32.0608 120.386C31.2037 124.509 27.6861 126.102 23.9109 124.351C21.1315 121.656 20.5023 117.89 23.029 114.789C23.7276 113.896 24.5252 113.132 25.4616 112.477L25.8877 113.087Z" fill="#231F20"/>
<path d="M44.9221 93.5575C44.9221 93.5575 26.2591 106.483 25.5407 109.693C24.8768 112.661 25.9965 119.18 34.2851 121.284C35.6575 121.632 37.1388 121.259 38.2337 120.287C41.246 117.617 47.2952 110.998 50.3471 98.8716C50.3471 98.8716 52.4131 91.7067 44.9221 93.5575Z" fill="white"/>
<path d="M45.0757 93.8999C42.98 95.7159 39.5467 98.4499 37.3519 100.256C34.7608 102.365 32.1647 104.483 29.7222 106.687C28.7164 107.619 27.7058 108.547 26.918 109.649L26.8189 109.822C26.8041 109.847 26.7793 109.887 26.7743 109.902C26.7743 109.927 26.7644 109.946 26.7496 109.961C26.7397 109.986 26.7347 110.041 26.7298 110.075L26.6852 110.324C26.0807 114.799 29.4299 118.585 33.5717 119.845C35.063 120.446 36.5096 120.446 37.7086 119.255C41.2113 116.114 43.9412 112.224 46.0913 108.026C47.5677 105.079 48.7469 101.988 49.6733 98.7774C50.7534 94.793 49.1284 93.0861 45.0807 93.8999H45.0757ZM44.7685 93.2201C49.5792 91.7018 52.0911 94.3266 50.9813 99.1346C50.2282 102.454 49.163 105.729 47.7312 108.825C45.9427 112.715 43.5597 116.407 40.6019 119.543C38.3477 122.058 36.2371 123.329 32.8385 122.073C27.359 120.515 23.1973 115.251 24.3418 109.401C25.6745 105.124 40.3938 95.6861 44.7636 93.2201H44.7685Z" fill="#231F20"/>
<path d="M42.1774 75.68C42.1774 75.68 48.8756 108.989 48.841 116.823C48.8112 123.616 65.2844 130.047 87.9011 121.924C94.1534 119.677 97.9287 112.948 96.7941 106.061C95.3623 97.3532 94.3913 85.1769 92.8802 76.7468C90.9876 66.1582 85.6766 57.6288 76.4416 54.5326C70.1744 52.4288 62.0294 52.7365 51.9969 59.0926C51.9969 59.0926 40.1411 66.7288 42.1724 75.68H42.1774Z" fill="white"/>
<path d="M56.0398 97.5667L51.0855 76.727C64.7595 75.1392 78.7473 72.096 84.0319 70.7728L86.2614 91.8606C78.7307 95.8301 62.9759 97.3186 56.0398 97.5667Z" fill="#5BC3C8" stroke="black" stroke-width="0.465147"/>
<path d="M69.6473 88.1614L68.9436 83.3827C68.9189 83.2146 69.0838 83.0822 69.2424 83.1428L74.1527 85.0181C74.3199 85.0819 74.3472 85.3073 74.2 85.4089L69.9934 88.3124C69.8579 88.4058 69.6713 88.3245 69.6473 88.1614Z" fill="white" stroke="black" stroke-width="0.222265"/>
<path d="M43.7133 75.3475C45.3036 83.9911 46.7949 92.5701 48.1078 101.233C48.8311 106.384 49.6833 111.589 49.7923 116.848C49.8171 119.007 51.6948 120.689 53.4833 121.765C58.0809 124.445 63.5604 125.095 68.8764 125.08C75.3419 125.001 81.7974 123.621 87.8912 121.458C89.8631 120.724 91.6764 119.513 93.0636 117.91C95.9173 114.744 97.1212 110.234 96.4127 106.041C95.7042 101.72 95.1939 97.383 94.6688 93.0464C93.4401 84.517 93.1082 75.5956 89.4419 67.6815C83.0607 53.9918 68.8418 51.114 56.1685 58.1498C54.8358 58.8941 53.3842 59.7128 52.1456 60.6059C47.6817 64.0643 42.5094 69.2296 43.7133 75.3426V75.3475ZM40.6367 76.0075C38.9423 68.272 46.0567 61.1964 52.0614 57.5197C61.3557 51.8334 73.1174 49.8487 82.4216 56.6464C93.8513 64.9773 93.8711 80.2201 95.4714 92.9521C95.9767 97.2838 96.4672 101.62 97.1559 105.917C97.8842 110.333 96.6654 115.077 93.6631 118.436C92.1966 120.133 90.2891 121.438 88.1934 122.257C82.0005 124.524 75.5301 126.043 68.9111 126.315C62.5943 126.698 48.5587 124.976 47.8898 116.853C47.6074 111.753 46.6017 106.701 45.7347 101.625C44.1889 93.0662 42.445 84.4823 40.6416 76.0025L40.6367 76.0075Z" fill="#231F20"/>
<path d="M90.5915 68.6789C89.3678 67.5923 79.9644 74.1121 42.6285 77.2976Z" fill="white"/>
<path d="M90.3438 68.9568C90.1109 68.9469 89.5412 69.0957 89.2291 69.2099C87.8022 69.711 86.3704 70.2618 84.9237 70.7431C71.2497 75.0152 56.9019 76.6923 42.6631 77.6698L42.5987 76.9305C54.618 75.5808 66.9394 73.9881 78.6565 71.006C81.4953 70.2766 84.6265 69.3984 87.4752 68.6343C88.3868 68.4308 89.2984 68.1133 90.2596 68.1579C90.4627 68.1828 90.6708 68.2572 90.8392 68.4011L90.3487 68.9568H90.3438Z" fill="#231F20"/>
<path d="M94.3615 88.6305C86.3206 93.498 76.9668 95.6018 67.7864 97.0358C64.8138 97.4179 61.5043 97.7503 58.5069 97.9339C56.7283 98.0629 54.0975 98.0877 52.2991 98.1621L46.0864 98.1076L46.1111 97.3633L52.2942 97.4377C62.5348 97.2839 72.9736 96.1774 82.7634 93.0564C86.6179 91.7614 90.5467 90.2629 93.9355 88.0202L94.3665 88.6255L94.3615 88.6305Z" fill="#231F20"/>
<path d="M73.8705 53.8578C73.058 56.2594 70.9574 57.8819 68.8468 59.0876C63.5506 61.9357 57.4221 62.5907 51.5115 62.7346L47.9692 62.7097L47.9741 61.9655L51.4818 61.8365C58.0612 61.4147 65.8891 60.5662 71.1456 56.2445C71.9284 55.525 72.7607 54.6368 73.1521 53.6693L73.8705 53.8578Z" fill="#231F20"/>
<path d="M58.4724 55.7335C54.39 50.0621 37.8722 30.4281 17.4058 51.0942C17.4058 51.0942 4.47491 67.9594 38.8086 56.7506C38.8086 56.7506 49.9162 50.206 55.8862 57.8125C56.4361 58.5121 57.3973 58.6659 58.1057 58.1449C58.8588 57.5892 59.0223 56.4976 58.4724 55.7335Z" fill="white"/>
<path d="M58.1404 55.9716C53.632 49.5659 46.7851 43.959 38.9027 42.8674C30.7726 41.6865 23.3658 46.8022 18.4363 51.8881C17.3859 53.3965 15.751 56.2445 16.623 57.9018C17.1382 58.651 18.1885 58.9636 19.1497 59.1075C23.024 59.569 26.8686 58.651 30.7032 57.8422C33.2547 57.2568 35.9895 56.4926 38.4915 55.7632C39.2495 55.2472 42.4401 54.0613 44.1543 53.7537C48.1822 52.8209 52.9978 53.5006 55.7822 56.8449C55.9407 57.0335 56.4262 57.7033 56.664 57.8075C57.7788 58.4426 58.8439 56.9541 58.1404 55.9667V55.9716ZM58.7994 55.4953C60.3847 57.7777 57.2833 60.3083 55.4453 58.1152C52.8095 54.8106 48.415 54.2995 44.5506 55.4308C42.7225 55.9319 40.8547 56.7209 39.2495 57.6884C33.988 59.5144 28.7265 61.2262 23.1132 61.8216C14.0517 62.8487 10.9106 57.7529 16.3753 50.3003C19.3875 47.3033 22.801 44.6636 26.715 42.9369C39.6954 37.0968 51.2093 45.2491 58.7994 55.4903V55.4953Z" fill="#231F20"/>
<path d="M50.7139 76.5136L56.1389 97.7105" stroke="#231F20" stroke-width="0.930293" stroke-miterlimit="10"/>
<path d="M86.1722 92.2129L83.7544 70.3808" stroke="#231F20" stroke-width="0.930293" stroke-miterlimit="10"/>
<defs>
<linearGradient id="paint0_linear_336_5039" x1="90.7554" y1="39.8136" x2="90.7554" y2="166.275" gradientUnits="userSpaceOnUse">
<stop stop-color="#009490"/>
<stop offset="1" stop-color="#009490" stop-opacity="0"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 22 KiB