refactor(pc): 从 Gi Admin Pro + Arco 重搭为纯 Vue 3 + Naive UI

旧模板的 193 个文件整体删除,换成纯 Vue 3.5 + Naive UI 2.42 的树。

- 去掉 auto-import(组件与 API 全显式 import)、v-hasPerm(改 user.has('码'),全库 8 处)、
  Stylelint;n-tag 的 type 统一过 utils/tag.ts 转换(Arco 色词直接透传会静默变灰)
- 图标改为构建期抽取:scripts/extract-pc-icons.py -> icons/icon-data.ts(37 个),
  内网离线部署不会白屏
- 重搭后修掉 6 类"编译 / lint / typecheck 全绿、界面上就是坏的"故障:
  ① NGrid 的 cols 写成像素值(不是断点名 -> 永远只 1 列,工作台因此错乱)
  ② n-tab-pane 用 tab 属性(只渲染空注释节点,整排 tab 一个字都不显示)
  ③ 漏 import 被当未知自定义元素(样式整块丢) ④ .n-card__content 类名不存在
  (高度链第一环失效,表格行在 DOM 里但屏幕上没有) ⑤ 填报单状态映射错位一格
  ⑥ 有标题的卡片没有上内边距(naive 的 padding-top 只给"内容区是长子"的卡片)
- 卡片式版面提成全局基线:styles/index.scss 的 xt-* 令牌 + .page-card / .toolbar /
  .section-title,页面只引用、不再各写一套
- 品牌:改名「深学在线」,文字标换成几何标(方 = 卷宗 / 环 = 在线,不用文字字形);
  index.html 的页签图标从 404 的 /favicon.ico 改指真实存在的 /favicon.svg
This commit is contained in:
2026-10-10 16:48:46 +08:00
parent 0bbac7d228
commit 5b877451eb
270 changed files with 12964 additions and 25889 deletions
+68 -25
View File
@@ -1,31 +1,74 @@
<template>
<a-config-provider update-at-scroll>
<router-view></router-view>
<!-- <template #loading>
<img src="/static/images/loading.gif" class="loading-icon" />
</template> -->
</a-config-provider>
</template>
<script setup lang="ts">
import { useTheme } from '@/hooks'
import { dateZhCN, NConfigProvider, NDialogProvider, NLoadingBarProvider, NMessageProvider, NNotificationProvider, zhCN } from 'naive-ui'
defineOptions({ name: 'App' })
/**
* 根组件:只做一件事 —— 把 Naive UI 的各种 Provider 装好。
*
* ⚠️ 提示类能力有两套,别混:
* · 组件里用 `useMessage()` / `useDialog()`(从 Provider 注入);
* · 组件之外(http 拦截器、路由守卫)用 `@/utils/naive` 的离屏实例。
* 少了下面这层 Provider,组件里的 `useMessage()` 会直接抛错。
*/
const themeOverrides = {
common: {
// 客户 2026-10-09 明确要求:外壳保持纯白,不要深色菜单/深蓝顶栏
primaryColor: '#0052d9',
primaryColorHover: '#366ef4',
primaryColorPressed: '#003cab',
borderRadius: '4px'
},
const { initThemeColor } = useTheme()
initThemeColor()
/**
* 卡片式外观。
*
* ⚠️ 描边与阴影**同时**写在 `styles/index.scss` 里(`.n-card.n-card`):
* Naive 的组件样式由 css-render 在运行时注入,与本文件的先后顺序不保证,
* 主题变量负责"正常情况",CSS 那条负责"顺序不利时兜底"。改样式时两处一起改。
*/
Card: {
borderColor: '#e5e8ee',
borderRadius: '10px',
boxShadow: '0 1px 2px rgba(16, 24, 40, 0.04), 0 1px 3px rgba(16, 24, 40, 0.06)',
// 统一左右内边距:Naive 的 small=16 / medium=24 混用会让各页左右不齐
paddingSmall: '12px 18px 12px',
paddingMedium: '16px 18px 16px'
},
// 字典数据:本项目的字典接口属 M1 范围(后端尚未实现),
// 现在启动就请求会稳定 404 并在控制台刷错误。
// 页面用的枚举(组织类型 / 租户状态 / 角色名)目前以常量形式定义在
// @/apis/xt/* 与 @/config/xt-routes 里,不依赖字典。
// 待后端 `/system/dict/*` 落地后,把下面两行恢复即可。
// const dictStore = useDictStore()
// dictStore.getDictData()
Button: {
// 默认按钮原来用的是 common 的 #e0e0e6 描边 —— 白卡片上几乎看不见,
// 这是"按钮不明显"的主因之一,这里加深一档
border: '1px solid #d0d5dd',
borderHover: '1px solid #0052d9',
borderFocus: '1px solid #0052d9',
borderPressed: '1px solid #003cab',
textColor: '#3f4756'
},
DataTable: {
// 表头由 #fafafc 加深到浅灰色带,让"表头 / 表体"和"卡片内容"分得开
thColor: '#f7f8fa',
thTextColor: '#475467',
thFontWeight: '600',
borderColor: '#eef1f5'
},
Tabs: {
// tab 是"当前视图"的切换器,选中态要压得住下面的白底表格
tabFontWeightActive: '600'
}
}
</script>
<style lang="scss" scoped>
.loading-icon {
width: 30px;
}
</style>
<template>
<NConfigProvider :locale="zhCN" :date-locale="dateZhCN" :theme-overrides="themeOverrides">
<NLoadingBarProvider>
<NDialogProvider>
<NNotificationProvider>
<NMessageProvider>
<router-view />
</NMessageProvider>
</NNotificationProvider>
</NDialogProvider>
</NLoadingBarProvider>
</NConfigProvider>
</template>
-9
View File
@@ -1,9 +0,0 @@
import type * as T from './type'
import http from '@/utils/http'
export type * from './type'
/** 获取地区列表 */
export const getProvinceCityArea = (params: { type: 'province' | 'city' | 'area', code?: string }) => {
return http.get<T.AreaItem[]>('/area/getProvinceCityArea', params)
}
-5
View File
@@ -1,5 +0,0 @@
export interface AreaItem {
label: string
code: string
children?: AreaItem[]
}
-39
View File
@@ -1,39 +0,0 @@
import http from '@/utils/http'
interface DefaultP {
GetListParams?: Record<string, any>
GetDetailParams?: { id: string }
AddParams?: Record<string, any>
UpdateParams?: Record<string, any>
DeleteParams?: { ids: string[] }
}
// 获取基础接口
export function getBaseApi<T, P extends DefaultP = DefaultP>(params: { baseUrl: string }) {
const { baseUrl } = params
const baseApi = {
// 获取分页列表
getList(params?: P['GetListParams'] & { page?: number, size?: number }) {
return http.get<PageRes<T[]>>(`${baseUrl}/getList`, params)
},
// 获取详情
getDetail(params: P['GetDetailParams']) {
return http.get<T>(`${baseUrl}/getDetail`, params)
},
// 新增
add(params: P['AddParams']) {
return http.post<T>(`${baseUrl}/add`, params)
},
// 修改
update(params: P['UpdateParams']) {
return http.post<T>(`${baseUrl}/update`, params)
},
// 删除
delete(params: P['DeleteParams']) {
return http.post<boolean>(`${baseUrl}/delete`, params)
}
}
return baseApi
}
-9
View File
@@ -1,9 +0,0 @@
import type * as T from './type'
import http from '@/utils/http'
export type * from './type'
/** 获取分类树 */
export function getCateTree() {
return http.get<T.CateTreeItem[]>('/cate/getCateTree')
}
-8
View File
@@ -1,8 +0,0 @@
export interface CateTreeItem {
id: string
name: string
pid: string | null
type: string | null
disabled: boolean
children: CateTreeItem[]
}
-9
View File
@@ -1,9 +0,0 @@
import type * as T from './type'
import http from '@/utils/http'
export type * from './type'
/** 获取文件列表 */
export function getFileList(params: { fileType: string | number }) {
return http.get<PageRes<T.FileItem[]>>('/file/getFileList', params)
}
-13
View File
@@ -1,13 +0,0 @@
// 文件
export interface FileItem {
id: string
type: string
name: string
extendName: string
src: string
updateTime: string
isDir: boolean
filePath: string
size: number
[propName: string]: any // 一个 interface 中任意属性只能有一个
}
-7
View File
@@ -1,7 +0,0 @@
import type * as T from './type'
import { getBaseApi } from '@/apis/base'
export type * from './type'
/** 人物模块 */
export const baseAPI = getBaseApi<T.ListItem>({ baseUrl: '/person' })
-16
View File
@@ -1,16 +0,0 @@
// 表格项目
export interface ListItem {
id: string
name: string
account: string
avatar: string
gender: Gender
phone: string
email: string
createTime: string
address: string
age: number
status: Status
hobby: string[]
remark: string
}
-15
View File
@@ -1,15 +0,0 @@
import { getBaseApi } from '@/apis/base'
export interface ListItem {
id: string
name: string
sort: number
status: Status
createTime: string
parentId: string
children?: ListItem[]
description: string
}
/** 部门模块 */
export const baseAPI = getBaseApi<ListItem>({ baseUrl: '/system/dept' })
-44
View File
@@ -1,44 +0,0 @@
import type { SelectOptionData } from '@arco-design/web-vue'
import { getBaseApi } from '@/apis/base'
import http from '@/utils/http'
export interface ListItem {
id: string
createUserString: string
createTime: string
name: string
code: string
sort: number
status: Status
description: string
}
export type DictDetail = ListItem
export type DictDataItem = {
id: string
name: string
value: string | number
sort: number
status: Status
remark?: string
createTime?: string
}
/** 字典模块 */
export const baseAPI = getBaseApi<ListItem>({ baseUrl: '/system/dict' })
/** 字典数据列表 */
export function getDictDataList(params: { code: string, name?: string, status?: string } & Pagination) {
return http.get<PageRes<DictDataItem[]>>('/system/dict/getDictDataList', params)
}
/** 字典数据详情 */
export function getDictDataDetail(params: { id: string, code: string }) {
return http.get<DictDataItem>('/system/dict/getDictDataDetail', params)
}
/** 获取字典数据映射 */
export function getDictData() {
return http.get<Record<string, SelectOptionData[]>>('/system/dict/getDictData')
}
-39
View File
@@ -1,39 +0,0 @@
import { getBaseApi } from '@/apis/base'
import http from '@/utils/http'
export interface ListItem {
activeMenu: string
alwaysShow: boolean
breadcrumb: boolean
children: ListItem[]
component: string
hidden: boolean
icon: string
id: string
keepAlive: boolean
parentId: string
path: string
permission: string
redirect: string
roles: string[]
showInTabs: boolean
sort: number
status: Status
title: string
type: 1 | 2 | 3
affix: boolean
}
export interface MenuOptionsItem {
id: string
title: string
children: MenuOptionsItem[]
}
/** 菜单模块 */
export const baseAPI = getBaseApi<ListItem>({ baseUrl: '/system/menu' })
/** 获取角色分配权限菜单树 */
export function getMenuOptions() {
return http.get<MenuOptionsItem[]>('/system/menu/getMenuOptions')
}
-23
View File
@@ -1,23 +0,0 @@
import { getBaseApi } from '@/apis/base'
import http from '@/utils/http'
export interface ListItem {
id: string
createUserString: string
createTime: string
disabled: boolean
name: string
code: string
sort: number
status: Status
type: number
description: string
}
/** 角色模块 */
export const baseAPI = getBaseApi<ListItem>({ baseUrl: '/system/role' })
/** 获取角色权限 */
export function getRoleMenuIds(params: { role: string }) {
return http.get<string[]>('/system/role/getRoleMenuIds', params)
}
-24
View File
@@ -1,24 +0,0 @@
import { getBaseApi } from '@/apis/base'
export interface ListItem {
id: string
createUserString: string
createTime: string
disabled: boolean
deptId: string
deptName: string
username: string
nickname: string
gender: Gender
avatar: string
email: string
phone: string
status: Status
type: 1 | 2
description: string
roleIds: string[]
roleNames: string[]
}
/** 用户模块 */
export const baseAPI = getBaseApi<ListItem>({ baseUrl: '/system/user' })
-11
View File
@@ -1,11 +0,0 @@
import http from '@/utils/http'
/** 请求成功的接口 */
export function getTestSuccess() {
return http.get<string>('/test/success')
}
/** 请求失败的接口 */
export function getTestFail() {
return http.get<any>('/test/fail')
}
+20
View File
@@ -0,0 +1,20 @@
/**
* 后端响应契约(《03-接口设计》§1.3)与分页形状。
*
* ⚠️ 成功判定是 `code === 0`,**业务错误也是 HTTP 200**(只有 401/403/429/5xx 用真状态码)。
* 这层适配在 `@/utils/http` 里做掉了:调用方拿到的直接是 `data`,
* 所以业务代码里几乎不再需要碰 `code`。
*/
/** 分页列表(后端恒为 { list, total }) */
export interface PageData<T> {
list: T[]
total: number
}
/** 带业务码的错误(调用方按码分支时用,例如租户重名 40011) */
export interface BizError extends Error {
bizCode?: number
bizData?: unknown
status?: number
}
-24
View File
@@ -1,24 +0,0 @@
import type * as T from './type'
import http from '@/utils/http'
export type * from './type'
/** 登录 */
export function login(data: { username: string, password: string }) {
return http.post<T.Login>('/user/login', data)
}
/** 退出登录 */
export function logout() {
return http.post('/user/logout')
}
/** 获取用户信息 */
export const getUserInfo = () => {
return http.get<T.UserInfo>('/user/getUserInfo')
}
/** 获取用户路由信息 */
export const getUserRoutes = () => {
return http.get<T.UserRouteItem[]>('/user/getUserRoutes')
}
-34
View File
@@ -1,34 +0,0 @@
export interface UserInfo {
id: string
nickname: string
avatar: string
roles: string[]
permissions: string[]
}
export interface Login {
token: string
}
export interface UserRouteItem {
activeMenu: string
alwaysShow: boolean
breadcrumb: boolean
children: UserRouteItem[]
component: string
hidden: boolean
icon: string
id: string
keepAlive: boolean
parentId: string
path: string
permission: string
redirect: string
roles: string[]
showInTabs: boolean
sort: number
status: Status
title: string
type: 1 | 2 | 3
affix: boolean
}
+24 -3
View File
@@ -17,11 +17,16 @@
*
* ## 状态与分级(不要按直觉写分支)
*
* - 填报单状态:`1` 草稿 / `2` 待初审 / `3` 待终审(初审已过)/ `4` 已驳回 / `5` 已通过
* - **填报单状态**(`collect_submission.status`,权威见后端 `CollectSubmission` 的字段注释):
* `0` 草稿 / `1` 待初审 / `2` 待终审 / `3` 已通过 / `4` 已驳回 / `5` 已归档
* - **名册行状态**(`collect_roster.submit_status`)是**另一套枚举**,别混用:
* `0` 未提交 / `1` 草稿 / `2` 待审 / `3` 已通过 / `4` 已驳回(见 `apis/xt/roster.ts`)
* - 卡片分级 `level`:**只有 0 / 2 / 3**,没有 1(写了"信息级"的分支永远不会触发)
*
* ⚠️ 上面这两个数字口径**以服务端返回的 `statusText` 为准**:界面优先显示 `statusText`,
* 数字只用于选色。这样即便枚举有调整,界面也不会说错话。
* ⚠️ 两套枚举的**起点不同**(填报单从"草稿"起、名册从"未提交"起),
* 照抄对方必然整体错位一格 —— 本文件曾把填报单写成 `1 草稿 / 2 待初审 / 3 待终审 / 4 已驳回 / 5 已通过`,
* 结果是**状态文案被服务端 `statusText` 兜住了,但 tag 的颜色永远取自错的本地表**
* ("已通过"显示成待终审的蓝)。所以:文案优先用服务端的 `statusText`,本地表只负责选色。
*/
import http from '@/utils/http'
import { actingTenantConfig } from './acting-tenant'
@@ -34,6 +39,22 @@ export function bizCodeOf(e: unknown): number | undefined {
return (e as BizError)?.bizCode
}
/**
* 填报单状态 → 文案与色词(`tagOf()` 会把它翻成 `n-tag` 的 type)。
*
* ⚠️ 与 `roster.ts` 的 `SUBMIT_STATUS`(名册行口径)**不是同一套**:起点差一格。
* 改这里之前先看文件头那段说明与后端 `CollectSubmission` 的字段注释。
* 界面文案仍以服务端 `statusText` 为准,本表只负责**选色**与兜底文案。
*/
export const SUBMISSION_STATUS: Record<number, { text: string, color: string }> = {
0: { text: '草稿', color: 'gray' },
1: { text: '待初审', color: 'orange' },
2: { text: '待终审', color: 'arcoblue' },
3: { text: '已通过', color: 'green' },
4: { text: '已驳回', color: 'red' },
5: { text: '已归档', color: 'gray' }
}
// ── 待办列表(§11.1 / §10.2)────────────────────
export interface AuditTodo {
-264
View File
@@ -1,264 +0,0 @@
/**
* 历史数据整理器(《03-接口设计》§13.2)。
*
* ## 这个功能的"卖点"就是报告里的一句话
*
* 契约里写明:**报告里最重要的一句话是 `autoHandled / needManual`** ——
* 「112 个文件里 90 个系统全自动处理,只有 1 个必须你亲自判断」。
* 所以这一屏的核心不是"进度条",而是**那两个数字与重点清单**。
* 进度只是等待时的安抚,报告才是客户付钱的理由。
*
* ## 几个界面必须区分清楚的状态
*
* | status | 界面该显示什么 |
* |---|---|
* | `0` 排队 / `1` 解析中 / `2` 处理中 | 进度条 + 已处理的文件数;**不给"下载"按钮**(还没有产物) |
* | `3` 已完成 | 报告 + 下载结果包 + 导入为正式任务 |
* | `4` 失败 | **`errorMsg` 必须显示出来** |
*
* ⚠️ 失败时 `errorMsg` 是唯一能让用户知道"为什么"的东西。常见原因是
* "传了不是 zip 的文件"与"包里单个文件超过 50MB" —— 这两条都在服务端有明确文案,
* 界面要做的是**把它原样显示**,而不是笼统说"整理失败"。
*
* ## 为什么 `rosterTaskId` 这个参数要在界面上强调
*
* 契约 §13.2 的原话:**没有名册就只能做文件名规范化;有名单才能做证件号校验、
* 疑似串档检测** —— 而"疑似串档 1 例"正是报告里最有价值的一条。
* 也就是说:关联名册与不关联,"体检报告"是两份完全不同的东西。
* 界面必须把这件事说在**上传之前**,而不是等报告出来发现那两项全是 0。
*/
import { getToken } from '@/utils/auth'
import http from '@/utils/http'
/** 整理任务状态。 */
export type CleanupStatus = 0 | 1 | 2 | 3 | 4
export interface CleanupJobVO {
id: number
jobName: string
/** `1` 压缩包 / `2` 文件夹 / `3` 云盘链接(一期只支持 `1`)。 */
sourceType: number
/** 关联的已有名册任务。**有关联才有证件号校验与串档检测**。 */
rosterTaskId?: number | null
status: CleanupStatus
statusText: string
progress: number
totalFiles?: number | null
processedFiles?: number | null
parsedStudents?: number | null
parsedMaterials?: number | null
rawSizeBytes?: number | null
finalSizeBytes?: number | null
/** 形如 `91.5%`;没算出来时是 `—`(**不是 0%** —— 0% 看起来像"没压缩")。 */
compressRatio?: string
resultPath?: string | null
/** 导入成正式任务后的任务 id(有值就说明已导入,导入是幂等的)。 */
targetTaskId?: number | null
errorMsg?: string | null
createTime?: string
finishTime?: string | null
}
export interface CleanupJobPage {
list: CleanupJobVO[]
total: number
}
/** 报告汇总。 */
export interface ReportSummary {
totalFiles: number
nameInvalid: number
sizeExceeded: number
formatConverted: number
idcardMismatch: number
idcardAutoFixed: number
idcardNeedConfirm: number
/** 疑似串档:某人的**多项**材料证件号与名册均不同、且彼此一致 → 整个文件夹可能被换过。 */
crossFileSuspected: number
lowResolution: number
orphanImages: number
}
export interface Highlight {
type: string
/** `1` 提示 / `2` 警告 / `3` 必须人工。 */
level: number
rosterId?: number | null
realName?: string | null
title: string
materialCode?: string | null
detail?: string | null
suggestion?: string | null
}
export interface NameFixSample {
original: string
fixed: string
rule?: string
}
export interface IdcardConflict {
rosterId?: number | null
realName?: string | null
rosterValue?: string | null
fileNameValue?: string | null
verdict: string
verdictText: string
}
export interface CleanupReportVO {
jobId: number
summary: ReportSummary
/** 系统全自动处理了多少(**服务端算的**,不让前端去减)。 */
autoHandled: number
/** 必须人工判断的(串档 + 无法归位 + 待确认的证件号冲突)。 */
needManual: number
highlights: Highlight[]
nameFixedSamples: NameFixSample[]
idcardConflicts: IdcardConflict[]
}
export interface CleanupImportVO {
taskId: number
rosterCount: number
fileCount: number
}
export function getCleanupJobs(params: {
status?: number
keyword?: string
pageNum?: number
pageSize?: number
}) {
return http.get<CleanupJobPage>('/cleanup/jobs', params)
}
export function getCleanupJob(id: number) {
return http.get<CleanupJobVO>(`/cleanup/jobs/${id}`)
}
export function getCleanupReport(id: number) {
return http.get<CleanupReportVO>(`/cleanup/jobs/${id}/report`)
}
/**
* 创建整理任务(multipart)。
*
* ⚠️ 超时给到 600s:大包的解压 + 解析 + 重新打包都在服务端同步做,
* 而默认 30s 在几百 MB 的包上必然超时 —— 超时的表现是"点了没反应",
* 用户会重复点,于是同一个包被整理好几次。
*/
export function createCleanupJob(file: File, opts: {
jobName: string
rosterTaskId?: number
namingTemplate?: string
}) {
const fd = new FormData()
fd.append('file', file)
fd.append('jobName', opts.jobName)
fd.append('sourceType', '1')
if (opts.rosterTaskId !== undefined) {
fd.append('rosterTaskId', String(opts.rosterTaskId))
}
if (opts.namingTemplate) {
fd.append('namingTemplate', opts.namingTemplate)
}
// 不要手动设 Content-Type:axios 会带着 boundary 自己设
return http.request<{ jobId: number, status: number, estimatedSeconds: number }>({
method: 'post',
url: '/cleanup/jobs',
data: fd,
timeout: 600 * 1000
})
}
/**
* 导入为正式任务。
*
* ⚠️ 这条路**不能带 `importFiles`**:一期还做不到把整理结果里的文件自动挂到填报单,
* 而服务端会**如实拒绝**(`40044`)而不是安静忽略。界面因此不要给这个勾选项 ——
* 给了一个必然报错的选项,用户只会以为系统坏了。
*/
export function importCleanupJob(id: number, data: {
taskName: string
collectMode?: number
batchNo: string
importRoster?: boolean
majorName?: string
}) {
return http.post<CleanupImportVO>(`/cleanup/jobs/${id}/import`, {
collectMode: 1,
importRoster: true,
...data
})
}
/**
* 真正下载整理结果包。
*
* ⚠️ 必须带 token 取 blob 再本地触发下载:`/cleanup/jobs/{id}/result` 是要登录的,
* 直接 `window.open` / `<a href>` 都不会带 `Authorization` 头,
* 用户会看到一个 401 页面(或"下载没反应")。
*
* 放在 api 层而不是页面里,与导出中心的 `downloadExportFile` 保持同一写法 ——
* 同一件事在一个项目里有两处实现,改的时候一定会漏一处。
*/
export async function downloadCleanupResult(id: number, jobName?: string): Promise<void> {
const token = getToken()
const base = import.meta.env.VITE_API_PREFIX || '/api/v1'
const res = await fetch(`${base}/cleanup/jobs/${id}/result`, {
headers: token ? { Authorization: `Bearer ${token}` } : {}
})
if (!res.ok) {
throw new Error(`下载失败(HTTP ${res.status})`)
}
const blob = await res.blob()
const href = URL.createObjectURL(blob)
const a = document.createElement('a')
a.href = href
a.download = `${jobName || '整理结果'}-${id}.zip`
document.body.appendChild(a)
a.click()
a.remove()
URL.revokeObjectURL(href)
}
/** 状态 → Tag 颜色(Arco 的 status 只认 normal/warning/success/danger)。 */
export function statusColor(status: CleanupStatus): 'normal' | 'warning' | 'success' | 'danger' {
switch (status) {
case 3:
return 'success'
case 4:
return 'danger'
case 1:
case 2:
return 'warning'
default:
return 'normal'
}
}
/** 重点条目的级别 → Tag 颜色。`3` 是"必须人工",用红色。 */
export function levelColor(level: number): 'normal' | 'warning' | 'danger' {
if (level >= 3) return 'danger'
if (level === 2) return 'warning'
return 'normal'
}
/**
* 报告里"最有说服力的一句话"。
*
* 契约的原话就是这个格式:**「112 个文件里 90 个系统全自动处理,
* 只有 1 个必须你亲自判断」**。所以这句话由前端按同一口径拼 ——
* 但它拼的是**服务端算好的两个数**,不是自己减出来的
* (前端减出来的数字早晚会与服务端分叉)。
*/
export function headlineOf(report: CleanupReportVO): string {
const total = report.summary.totalFiles
const need = report.needManual
return `${total} 个文件里,${report.autoHandled} 个系统全自动处理,`
// ⚠️ 不要在这里写 Markdown 的 `**粗体**`:它落在**文本节点**里,
// 页面上会原样显示两个星号(要粗体得让调用方用富文本渲染)
+ `${need > 0 ? `只有 ${need} 个必须你亲自判断` : '没有需要你判断的'}`
}
+2 -2
View File
@@ -191,7 +191,7 @@ export async function downloadExportFile(id: number, fileIndex = 0): Promise<voi
const base = import.meta.env.VITE_API_PREFIX || '/api/v1'
// 服务端回的是本服务的绝对路径(/api/v1/exports/{id}/file?...),
// 去掉前缀再拼 base,避免出现 /api/v1/api/v1/... 这种双前缀
const res = await fetch(`${base}${info.data.url.replace('/api/v1', '')}`, {
const res = await fetch(`${base}${info.url.replace('/api/v1', '')}`, {
headers: token ? { Authorization: `Bearer ${token}` } : {}
})
if (!res.ok) {
@@ -201,7 +201,7 @@ export async function downloadExportFile(id: number, fileIndex = 0): Promise<voi
const href = URL.createObjectURL(blob)
const a = document.createElement('a')
a.href = href
a.download = info.data.fileName
a.download = info.fileName
document.body.appendChild(a)
a.click()
a.remove()
-125
View File
@@ -1,125 +0,0 @@
/**
* 名单加入申请接口(《03-接口设计》§8.7.3 ~ §8.7.5,FR-509)。
*
* ## 这条通道的边界(界面文案要照着说)
*
* 它**只解决"进名单",不绕过门禁** —— 申请期间学生仍然不能填报。
* 所以审批通过之后,界面要告诉管理员"学生返回重新核验就能进",
* 而不是"他已经可以填了"。
*
* ## 两个刻意的设计,前端要照做
*
* 1. **没有批量通过/一键全通过接口**(契约 §8.7.5 的取舍):身份认定环节的
* 误操作代价极高 —— 放错一个人进名单,等于让一个不是这批的人拿到认定资格。
* 所以这里只有逐条通过、逐条驳回(驳回还必须填原因)。
* 2. **`notifySent` 恒为 false**:通知渠道(M5-12)还没做,
* 服务端如实返回 false,界面必须显示"请口头/群里告知学生",不能假装通知过了。
*/
import http from '@/utils/http'
export interface JoinDupHint {
type: string
taskName: string
realName: string
}
export interface JoinAdminItem {
requestId: number
taskId: number
taskName: string | null
realName: string
idCardMask: string
phoneMask: string | null
orgHint: string | null
reason: string | null
/** `0` 待审 / `1` 已通过 / `2` 已驳回 */
status: number
statusText: string
createTime: string | null
waitHours: number | null
/** 该证件号在**其他任务**的名册里出现过(帮判断是不是本校学生) */
duplicateHint: JoinDupHint | null
rosterId: number | null
}
export interface JoinAdminList {
list: JoinAdminItem[]
total: number
counts: { pending: number, approved: number, rejected: number }
alert: { level: number, text: string } | null
}
export interface JoinListQuery {
taskId?: number
/** 默认 0(待审) */
status?: number
keyword?: string
pageNum?: number
pageSize?: number
}
export function getJoinRequests(params: JoinListQuery = {}) {
return http.get<JoinAdminList>('/roster/join-requests', params)
}
export interface JoinApproveReq {
/** 指定班级;不传则用学生的自述班级匹配组织名(匹配不上会要求手选) */
orgId: number
/** 修正姓名(管理员核对后可改) */
realName?: string
/** 修正证件号 */
idCardNo?: string
}
export interface JoinApproveResult {
requestId: number
status: number
rosterId: number
rosterCreated: boolean
/** ⚠️ 恒为 false:通知没发出去,需要人工告知 */
notifySent: boolean
/** true = 已绑定,学生返回重新核验就能直接进 */
canFillNow: boolean
}
export function approveJoinRequest(id: number, data: JoinApproveReq) {
return http.post<JoinApproveResult>(`/roster/join-requests/${id}/approve`, data)
}
export interface JoinRejectReq {
/** **必填** —— 会原样给学生看 */
reason: string
reasonCode?: string
}
export function rejectJoinRequest(id: number, data: JoinRejectReq) {
return http.post<{ requestId: number, status: number, notifySent: boolean }>(
`/roster/join-requests/${id}/reject`,
data
)
}
/** 申请状态。 */
export const JOIN_STATUS: Record<number, { text: string, color: string }> = {
0: { text: '待审核', color: 'orange' },
1: { text: '已通过', color: 'green' },
2: { text: '已驳回', color: 'red' }
}
/** 驳回快捷原因码(契约 §8.7.5)。 */
export const REJECT_REASON_CODES = [
{ code: 'NOT_THIS_SCHOOL', label: '不是本校学生' },
{ code: 'INFO_MISMATCH', label: '信息与报名资料不符' },
{ code: 'NOT_IN_SCOPE', label: '不在本次认定范围' },
{ code: 'OTHER', label: '其他原因(请在说明里写清)' }
]
/** 关键错误码 → 一句"接下来怎么办"。 */
export const JOIN_ERROR_HINT: Record<number, string> = {
40040: '这条申请已经被别人处理过了(刷新列表即可看到最新状态)。',
40041: '名册里已经有这个证件号了 —— 可能刚被老师手工加进去,去「名单管理」核对一下。',
40042: '已通过的申请不能驳回。要撤销请到「名单管理」里删掉那条名册项。',
40037: '该学生申请次数已达上限(每任务 2 次)。',
40038: '该学生已有一条待审申请。',
40039: '该证件号已在名册中 —— 学生只是姓名打错了,让他回去重新核验即可。'
}
+8 -2
View File
@@ -106,8 +106,14 @@ export const OPERATION_ACTIONS: Array<{ value: string, label: string }> = [
{ value: 'PROXY_UPLOAD', label: '代传材料' },
{ value: 'VIEW_IDCARD_FULL', label: '查看完整证件号' },
{ value: 'CONFIG_COMPRESS', label: '改压缩配置' },
{ value: 'JOIN_APPROVE', label: '通过加入申请' },
{ value: 'JOIN_REJECT', label: '驳回加入申请' }
// ⚠️ 2026-10 需求收敛:`JOIN_APPROVE` / `JOIN_REJECT` 两个动作码已随「加入申请」模块删除,
// 这里不再列出(库里若有历史行,`actionText` 会原样回显那个码,不会显示成空白)。
{ value: 'CREATE_ROLE', label: '新建角色' },
{ value: 'UPDATE_ROLE', label: '改角色' },
{ value: 'DELETE_ROLE', label: '删除角色' },
{ value: 'GRANT_ROLE', label: '改角色授权' },
{ value: 'UPDATE_ROLE_MENU', label: '改角色菜单' },
{ value: 'TOGGLE_ROLE', label: '停用/启用角色' }
]
export function actionText(v?: string) {
+4 -2
View File
@@ -99,8 +99,10 @@ export const BIZ_TYPES: Array<{ value: number, label: string }> = [
{ value: 3, label: '驳回通知' },
{ value: 4, label: '审核通过' },
{ value: 5, label: '催报' },
{ value: 6, label: '导出完成' },
{ value: 7, label: '加入审批' }
{ value: 6, label: '导出完成' }
// ⚠️ 2026-10 需求收敛:`7 加入审批` 已随「加入申请」模块删除。
// 后端 `CollectMessage.BIZ_JOIN_AUDIT` 也删了 —— 这里留着它会让运营
// 在下拉里选一个永远查不到记录的类型。
]
export function bizTypeText(v?: string | number) {
+5 -2
View File
@@ -34,8 +34,11 @@ export interface OrgUpsertReq {
/**
* 组织树。
* @param withCount 是否附带每节点学生数(会多一次聚合查询,列表页按需开)
* @param tenantId **仅平台运营**:代管哪个学校的组织(见 `acting-tenant.ts`)。
*
* @param params 查询条件(下面三个字段都可选;整体可省略)
* @param params.withCount 是否附带每节点学生数(会多一次聚合查询,列表页按需开)
* @param params.rootId 只取某个节点为根的子树
* @param params.tenantId **仅平台运营**:代管哪个学校的组织(见 `acting-tenant.ts`)。
* 不传 = 不代管 —— 此时服务端只会返回平台自己租户的组织(空树),
* **不会**再把所有租户的组织混在一起端出来。
*/
+183
View File
@@ -0,0 +1,183 @@
/**
* 角色与授权(二期)。
*
* ## 三条口径(界面上要按它写,不要"看起来更合理"地改)
*
* 1. **内置角色只读**:`roleType === 1` 的角色可以看权限矩阵,但改不了 ——
* 它的权限由后端代码决定(`BuiltinRole`)。一次误操作就能把管理员锁在系统外,
* 而这类错误不可逆。所以界面上的正确做法是**新建一个自定义角色**,而不是改内置的。
* 2. **看得见 ≠ 有权限**:`menus` 只决定左侧出现哪些入口;真正的访问控制是
* 后端对权限码的校验(绕过前端只会拿到 `40301`)。
* 3. **数据范围(本人/本班/本院系/全租户)本期只展示**:它目前由"拿到了哪些权限码 +
* 任务里被指派了哪些班"共同决定,做成可配要先把散在各处的判据收口(下一批)。
* 所以这里的 `dataScope` 是只读展示 —— 让界面出现一个"改了不生效"的开关更糟。
*
* ## 改完立即生效
*
* 服务端在每次写授权后会清掉该角色的缓存,所以**不需要重新登录**:
* 改完刷新页面即可看到按钮/菜单的变化。
*/
import http from '@/utils/http'
import { actingTenantConfig } from './acting-tenant'
/** 角色(内置或自定义) */
export interface RoleVO {
id: number
roleCode: string
roleName: string
/** 1 内置(只读)/ 2 自定义 */
roleType: number
/** 1 平台运营 / 2 学校管理员 / 3 班主任 / 4 学生 —— 账号的用户类型由它推导 */
userType: number
/** 1 全平台 / 2 本租户 / 3 本组织及下级 / 4 仅本人(本期只展示) */
dataScope: number
/** 0 停用 / 1 正常 */
status: number
sortNo?: number
remark?: string | null
/** 有多少账号在用(删除前的依据:大于 0 就删不掉) */
userCount: number
/** 能否编辑 / 删除 / 停用(内置角色恒 false) */
editable: boolean
/**
* 能否发给账号。
*
* ⚠️ 与 `editable` 是两件事:内置的「平台运营」角色**看得见**(列表里列出来),
* 但在学校租户里**发不出去**(服务端 40301 —— 拿到它会直接越权到平台级)。
* 所以账号页的角色选项要按它过滤,而不是让人选完再收到一个错误。
*/
assignable: boolean
permCodes: string[]
menus: string[]
}
/** 权限码(角色授权界面的勾选项) */
export interface PermVO {
code: string
label: string
/** PC / MP / BOTH */
platform: string
/** true = 平台级权限,学校租户不可授予(界面上要禁用勾选) */
platformOnly: boolean
}
/** 权限码按分组返回(30 条平铺成一张表没人看得懂) */
export interface PermGroupVO {
group: string
items: PermVO[]
}
export interface RoleCreateReq {
roleCode: string
roleName: string
userType: number
remark?: string
permCodes: string[]
menus: string[]
}
export interface RoleUpdateReq {
roleName: string
userType: number
remark?: string
}
/** 账号页用的角色选项(内置 + 自定义都在这份里) */
export interface RoleOption {
value: string
label: string
userType: number
roleType: number
status: number
}
export function getRoles(tenantId?: number | null) {
return http.get<RoleVO[]>('/roles', undefined, actingTenantConfig(tenantId))
}
export function getPermissions() {
return http.get<PermGroupVO[]>('/permissions')
}
export function createRole(data: RoleCreateReq) {
return http.post<number>('/roles', data)
}
export function updateRole(id: number, data: RoleUpdateReq) {
return http.put<void>(`/roles/${id}`, data)
}
export function deleteRole(id: number) {
return http.delete<void>(`/roles/${id}`)
}
/** 覆盖式设置权限码(改完立即生效,不必重新登录) */
export function setRolePermissions(id: number, permCodes: string[]) {
return http.put<void>(`/roles/${id}/permissions`, { permCodes })
}
/** 覆盖式设置可见菜单 */
export function setRoleMenus(id: number, menus: string[]) {
return http.put<void>(`/roles/${id}/menus`, { menus })
}
export function setRoleStatus(id: number, status: number) {
return http.put<void>(`/roles/${id}/status`, undefined, { params: { status } })
}
/** 角色列表 → 账号页的下拉/勾选项(只取**能发给账号**的启用角色) */
export async function getRoleOptions(tenantId?: number | null): Promise<RoleOption[]> {
const res = await getRoles(tenantId)
return (res ?? [])
.filter((r) => r.status === 1 && r.assignable !== false)
.map((r) => ({
value: r.roleCode,
label: r.roleName,
userType: r.userType,
roleType: r.roleType,
status: r.status
}))
}
/**
* 从所选角色推导用户类型。
*
* 用户类型与角色是**一对一绑定**的(账号的 `userType` 由它决定),所以界面上不让用户手选:
* 分别选就会产生"学生 + 学校管理员"这种自相矛盾的账号,而服务端还会因此拒掉整个提交。
*
* ⚠️ 判据来自**接口返回的角色**(`RoleVO.userType`),不是前端写死的映射表 ——
* 二期之后可选角色里还有租户自己建的那些,写死的表推不出它们的类型。
*
* @returns 同一类时返回那个类型;跨类(如「班主任 + 审核员」)或选不出时返回 null
*/
export function deriveUserType(roleCodes: string[], options: RoleOption[]): number | null {
const types = new Set<number>()
for (const code of roleCodes) {
const opt = options.find((o) => o.value === code)
if (opt) {
types.add(opt.userType)
}
}
return types.size === 1 ? [...types][0] : null
}
/** 用户类型中文名(与契约 §2.7 / 后端 BuiltinRole.UserType 一致) */
export const ROLE_USER_TYPE_NAMES: Record<number, string> = {
1: '平台运营',
2: '学校管理员',
3: '班主任',
4: '学生'
}
/** 数据范围中文名(本期只展示) */
export const DATA_SCOPE_NAMES: Record<number, string> = {
1: '全平台',
2: '本租户',
3: '本组织及下级',
4: '仅本人'
}
/** 错误码 → 人话(后端 msg 已经说清了,这里只补"我该做什么") */
export const ROLE_ERROR_HINT: Record<number, string> = {
40045: '该角色还有账号在用:请先给这些账号换一个角色,再回来删'
}
+14 -16
View File
@@ -121,6 +121,7 @@ export interface TaskListQuery {
/**
* 任务分页列表。班主任只会拿到自己带的班级的任务
*
* @param params 分页与筛选(`orgId` / `status` / `keyword` / `pageNum` / `pageSize`)
* @param tenantId **仅平台运营**:看哪所学校的任务(见 `./acting-tenant`)。
* 不传 = 平台自己租户(空列表)—— 不再把各租户的任务混在一起。
*/
@@ -254,8 +255,6 @@ export interface TaskOrgVO {
*/
headUserId: number | null
headUserName: string | null
deputyUserIds: number[]
deputyUserNames: string[]
/** 应填人数(期望值)。null = 未设置,与 0(预期 0 人)含义不同 */
expectedCount: number | null
/** 恒为 1(只返回生效行) */
@@ -266,7 +265,6 @@ export interface TaskOrgVO {
export interface TaskOrgItem {
orgId: number
headUserId?: number | null
deputyUserIds?: number[]
/** 不传或传 null 表示"未设置",**不要传 0** —— 那是"预期 0 人" */
expectedCount?: number | null
}
@@ -281,23 +279,23 @@ export function saveTaskOrgs(taskId: number, orgs: TaskOrgItem[]) {
}
/**
* 可被指定为初审人的账号。
* 可被指定为初审人的账号(只能是**班主任**)。
*
* 拉两种角色再合并:后端要求初审人持有班主任**或**副班主任角色,
* 所以两边的账号都是合法选项。只取启用状态 —— 停用的账号会被后端拒掉,
* 列在选项里只会让人白选一次。
* ⚠️ 2026-10 需求收敛:删掉副班主任角色后,初审人只剩班主任一种。
* 这里**不能**再顺手带一个 `roleCode=DEPUTY_TEACHER` 的查询 ——
* 那个角色码已经不在后端的 `BuiltinRole` 里,而老版本的后端对
* "不认识的角色码"是**静默忽略过滤条件**(等于返回全校账号,含学生)。
* 后端已改成"失败关闭"(返回空列表),前端这边也不再传它。
*
* 只取启用状态 —— 停用的账号会被后端拒掉,列在选项里只会让人白选一次。
*/
export async function getTeacherOptions(): Promise<Array<{ id: number, label: string }>> {
const [head, deputy] = await Promise.all([
getUserList({ roleCode: 'HEAD_TEACHER', status: 1, pageSize: 200 }),
getUserList({ roleCode: 'DEPUTY_TEACHER', status: 1, pageSize: 200 })
])
const merged = new Map<number, string>()
for (const u of [...(head.data?.list ?? []), ...(deputy.data?.list ?? [])]) {
const page = await getUserList({ roleCode: 'HEAD_TEACHER', status: 1, pageSize: 200 })
return (page.list ?? []).map((u) => ({
id: u.id,
// 带账号:学校里同名同姓很常见,只显示姓名选错了就是把别人的班交给了错误的人
merged.set(u.id, u.username ? `${u.realName}(${u.username})` : u.realName)
}
return Array.from(merged.entries(), ([id, label]) => ({ id, label }))
label: u.username ? `${u.realName}(${u.username})` : u.realName
}))
}
// ── 任务统计(§7.11,工作台看板用)─────────────────
+9 -57
View File
@@ -152,30 +152,17 @@ export const USER_TYPE_NAMES: Record<number, string> = {
}
/**
* 角色 → 用户类型。
* 角色选项、角色 → 用户类型、角色名的映射**都不在这里了**。
*
* 二者本来就是一对一绑定的,所以:
* · 表单里**不让用户选**用户类型,而是从角色推导出来(避免选出矛盾组合)
* · 服务端也会用同一套映射反推校验(`UserService.assertRoleMatchesUserType`)
* 二期(角色与授权)之后,可选角色不再只有 6 个内置角色 —— 租户自己建的角色也要能发出去,
* 而它们的名字与用户类型只存在于库里。所以这三件事统一走 `@/apis/xt/role`:
* · 选项:`getRoleOptions()`(`GET /roles`)
* · 用户类型:`RoleVO.userType`(`deriveUserType(roleCodes, options)`)
* · 角色名:`UserVO.roleNames`(后端已按 `sys_role.role_name` 装配)
*
* ⚠️ 留一份前端写死的映射表会**静默过期**:自定义角色推不出类型,
* 表现是"账号建不出来,但看不出为什么"(服务端 40001:用户类型与所选角色不符)。
*/
export const ROLE_TO_USER_TYPE: Record<string, number> = {
PLATFORM_ADMIN: 1,
SCHOOL_ADMIN: 2,
AUDITOR: 2,
HEAD_TEACHER: 3,
DEPUTY_TEACHER: 3,
STUDENT: 4
}
/** 从所选角色推导用户类型;角色为空或跨类时返回 `null`(调用方据此拦提交) */
export function deriveUserType(roleCodes: string[]): number | null {
const types = new Set<number>()
for (const c of roleCodes) {
const t = ROLE_TO_USER_TYPE[c]
if (t) types.add(t)
}
return types.size === 1 ? [...types][0] : null
}
/** 账号状态(对应 sys_user.status) */
export const USER_STATUS: Record<number, { text: string, color: string }> = {
@@ -184,41 +171,6 @@ export const USER_STATUS: Record<number, { text: string, color: string }> = {
2: { text: '待激活', color: 'orange' }
}
/**
* 可分配的角色,**必须与后端 `BuiltinRole` 逐字一致**。
*
* 为什么在前端也写一份:一期没有任何"自定义角色"的界面,角色集合由代码决定、
* 不由数据库决定(这是项目已定的决策 —— 权限码是前后端契约,放 DB 必然漂移)。
* 所以这里是「与后端枚举对称的镜像」,不是"业务配置"。
*
* 真实的可分配范围仍由后端 `UserService.resolveAssignableRoles` 判定:
* 传了这里的列表之外的角色会拿到 40301,前端只负责不显示没得选的项。
*
* 平台运营角色只在平台租户可分配 —— 学校管理员拿到它会直接越权到平台级。
*/
export const SCHOOL_ROLE_OPTIONS: Array<{ value: string, label: string }> = [
{ value: 'SCHOOL_ADMIN', label: '学校管理员' },
{ value: 'HEAD_TEACHER', label: '班主任' },
{ value: 'DEPUTY_TEACHER', label: '副班主任' },
{ value: 'AUDITOR', label: '审核员' },
{ value: 'STUDENT', label: '学生' }
]
/** 平台租户的可分配角色 */
export const PLATFORM_ROLE_OPTIONS: Array<{ value: string, label: string }> = [
{ value: 'PLATFORM_ADMIN', label: '平台运营' }
]
/** 导入时「角色」列允许写的角色中文名 → 角色码(与后端 BuiltinRole 对齐) */
export const ROLE_NAME_TO_CODE: Record<string, string> = {
平台运营: 'PLATFORM_ADMIN',
学校管理员: 'SCHOOL_ADMIN',
班主任: 'HEAD_TEACHER',
副班主任: 'DEPUTY_TEACHER',
审核员: 'AUDITOR',
学生: 'STUDENT'
}
/** 导入文件里被识别的列名(与后端 HEADER_ALIASES 对齐,供界面提示用) */
export const IMPORT_FIELD_NAMES: Record<string, string> = {
realName: '姓名',
+31 -21
View File
@@ -1,15 +1,29 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="64" height="64" role="img" aria-label="填报通">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="64" height="64" role="img" aria-label="深学在线">
<!--
填报通 品牌标
深学在线 品牌标 · 2026-10 定稿
================================================================
配色取自腾讯云 / TDesign 官方色板(与 src/styles/arco-ui/xt-theme.less 一致):
主色 #0052D9 主色亮阶 #2975E1 浅底 #ECF2FE
替代原先「圆角方块 + 填字」的文字标。两个几何体,都有出处:
· 实心圆角方 = 卷宗(原型设计语言「档案室 / 电子卷宗」)
· 白 环 = 在线 / 汇聚点(这件产品的入口就是扫码进来)
环画在方**之前**,只有右上四分之一露出来 —— 一个标里同时读到"在线"与"归档"。
设计说明:
· 圆角方形 + 「填」字,与产品原型(docs/prototype 的 .mark)保持同一识别符号
· 用渐变而不是纯色,是为了在 32px 的侧栏尺寸下也不显得扁平死板
· 顶部一道极淡的高光,给方形一点体积感(模仿纸质卡片的受光)
· 不画对勾等附加符号:尺寸一旦缩到 favicon,多余元素只会变成噪点
为什么是几何标而不是字形标:字形标在 16px 页签下退化成一块色斑,
换字体族还会走形。为什么后排是环而不是第二枚圆角方:两枚错位圆角方
是通用的「复制 / 多副本」图标,会被直接读成那个意思;环与方是相叠的
一体,也不会被读成放大镜。完整取舍过程见 docs/交接摘要.md §一·三十八,
五轮实测稿在 shots/logo-lab*.html。
构造(对齐 64 栅格;四周留白对称,均为 8.5;外接盒 47×49.3 居中):
· 圆角方 34×34 @ (8.5, 22.65) 圆角 10.4 —— 坐下偏左
· 白环 外径 38.5(描边 5.9 / 中线半径 16.31)@ (36.25, 26.62) —— 立上偏右
⚠️ 留白从 11.25 收到 8.5 是**有意**的:11.25 时内容只占底板 65%,
24px 侧栏下真正画出来的只有 16px,标明显偏小(见 shots/rename/logo-sizes.png)。
⚠️ 改这里要同步三处:public/favicon.svg(加粗版)、AppSider 与 login 页的
引用尺寸(24 / 34px)、docs/prototype/admin-web.html 的 .mark(内嵌同形状)。
⚠️ 注释里不能出现连续两个减号(XML 规范禁止,非浏览器宽容度问题):
写下 CSS 自定义属性的那种两减号写法会让整个 SVG not well-formed,
表现是图片裂开、控制台一句话都不报,lint / typecheck 也全绿。
-->
<defs>
<linearGradient id="xtLogoBg" x1="0" y1="0" x2="0.35" y2="1">
@@ -22,24 +36,20 @@
</linearGradient>
</defs>
<!-- 底板 -->
<!-- 底板(配色取腾讯云 / TDesign 色板,与主题主色一致) -->
<rect x="0" y="0" width="64" height="64" rx="15" fill="url(#xtLogoBg)" />
<!-- 顶部高光 -->
<!-- 顶部高光:给方形一点体积感(模仿纸质卡片的受光) -->
<path d="M0 15A15 15 0 0 1 15 0h34a15 15 0 0 1 15 15v9H0z" fill="url(#xtLogoGloss)" />
<!-- 内描边:让标在浅色底上也有轮廓,不至于"浮"着 -->
<rect x="0.75" y="0.75" width="62.5" height="62.5" rx="14.25"
fill="none" stroke="#FFFFFF" stroke-opacity="0.18" stroke-width="1.5" />
<!-- 「填」字 -->
<text
x="32" y="33.5"
fill="#FFFFFF"
font-size="37"
font-weight="600"
font-family="Songti SC, STSong, SimSun, Noto Serif SC, Source Han Serif SC, serif"
text-anchor="middle"
dominant-baseline="central"
>填</text>
<!-- 环(在线 / 汇聚点)—— 画在方之前,被方遮掉左下四分之三 -->
<circle cx="36.25" cy="26.62" r="16.31"
fill="none" stroke="#FFFFFF" stroke-width="5.9" stroke-opacity="0.76" />
<!-- 方(卷宗) -->
<rect x="8.5" y="22.65" width="34" height="34" rx="10.4" fill="#FFFFFF" />
</svg>

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

-78
View File
@@ -1,78 +0,0 @@
/* eslint-disable */
/* prettier-ignore */
// @ts-nocheck
// noinspection JSUnusedGlobalSymbols
// Generated by unplugin-auto-import
// biome-ignore lint: disable
export {}
declare global {
const EffectScope: typeof import('vue').EffectScope
const computed: typeof import('vue').computed
const createApp: typeof import('vue').createApp
const customRef: typeof import('vue').customRef
const defineAsyncComponent: typeof import('vue').defineAsyncComponent
const defineComponent: typeof import('vue').defineComponent
const effectScope: typeof import('vue').effectScope
const getCurrentInstance: typeof import('vue').getCurrentInstance
const getCurrentScope: typeof import('vue').getCurrentScope
const getCurrentWatcher: typeof import('vue').getCurrentWatcher
const h: typeof import('vue').h
const inject: typeof import('vue').inject
const isProxy: typeof import('vue').isProxy
const isReactive: typeof import('vue').isReactive
const isReadonly: typeof import('vue').isReadonly
const isRef: typeof import('vue').isRef
const isShallow: typeof import('vue').isShallow
const markRaw: typeof import('vue').markRaw
const nextTick: typeof import('vue').nextTick
const onActivated: typeof import('vue').onActivated
const onBeforeMount: typeof import('vue').onBeforeMount
const onBeforeRouteLeave: typeof import('vue-router').onBeforeRouteLeave
const onBeforeRouteUpdate: typeof import('vue-router').onBeforeRouteUpdate
const onBeforeUnmount: typeof import('vue').onBeforeUnmount
const onBeforeUpdate: typeof import('vue').onBeforeUpdate
const onDeactivated: typeof import('vue').onDeactivated
const onErrorCaptured: typeof import('vue').onErrorCaptured
const onMounted: typeof import('vue').onMounted
const onRenderTracked: typeof import('vue').onRenderTracked
const onRenderTriggered: typeof import('vue').onRenderTriggered
const onScopeDispose: typeof import('vue').onScopeDispose
const onServerPrefetch: typeof import('vue').onServerPrefetch
const onUnmounted: typeof import('vue').onUnmounted
const onUpdated: typeof import('vue').onUpdated
const onWatcherCleanup: typeof import('vue').onWatcherCleanup
const provide: typeof import('vue').provide
const reactive: typeof import('vue').reactive
const readonly: typeof import('vue').readonly
const ref: typeof import('vue').ref
const resolveComponent: typeof import('vue').resolveComponent
const shallowReactive: typeof import('vue').shallowReactive
const shallowReadonly: typeof import('vue').shallowReadonly
const shallowRef: typeof import('vue').shallowRef
const toRaw: typeof import('vue').toRaw
const toRef: typeof import('vue').toRef
const toRefs: typeof import('vue').toRefs
const toValue: typeof import('vue').toValue
const triggerRef: typeof import('vue').triggerRef
const unref: typeof import('vue').unref
const useAttrs: typeof import('vue').useAttrs
const useCssModule: typeof import('vue').useCssModule
const useCssVars: typeof import('vue').useCssVars
const useId: typeof import('vue').useId
const useLink: typeof import('vue-router').useLink
const useModel: typeof import('vue').useModel
const useRoute: typeof import('vue-router').useRoute
const useRouter: typeof import('vue-router').useRouter
const useSlots: typeof import('vue').useSlots
const useTemplateRef: typeof import('vue').useTemplateRef
const watch: typeof import('vue').watch
const watchEffect: typeof import('vue').watchEffect
const watchPostEffect: typeof import('vue').watchPostEffect
const watchSyncEffect: typeof import('vue').watchSyncEffect
}
// for type re-export
declare global {
// @ts-ignore
export type { Component, Slot, Slots, ComponentPublicInstance, ComputedRef, DirectiveBinding, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, ShallowRef, MaybeRef, MaybeRefOrGetter, VNode, WritableComputedRef } from 'vue'
import('vue')
}
-188
View File
@@ -1,188 +0,0 @@
/* eslint-disable */
// @ts-nocheck
// biome-ignore lint: disable
// oxlint-disable
// ------
// Generated by unplugin-vue-components
// Read more: https://github.com/vuejs/core/pull/3399
import { GlobalComponents } from 'vue'
export {}
/* prettier-ignore */
declare module 'vue' {
export interface GlobalComponents {
AAlert: typeof import('@arco-design/web-vue')['Alert']
AAvatar: typeof import('@arco-design/web-vue')['Avatar']
ABadge: typeof import('@arco-design/web-vue')['Badge']
ABreadcrumb: typeof import('@arco-design/web-vue')['Breadcrumb']
ABreadcrumbItem: typeof import('@arco-design/web-vue')['BreadcrumbItem']
AButton: typeof import('@arco-design/web-vue')['Button']
ACard: typeof import('@arco-design/web-vue')['Card']
ACheckbox: typeof import('@arco-design/web-vue')['Checkbox']
ACheckboxGroup: typeof import('@arco-design/web-vue')['CheckboxGroup']
ACol: typeof import('@arco-design/web-vue')['Col']
AComment: typeof import('@arco-design/web-vue')['Comment']
AConfigProvider: typeof import('@arco-design/web-vue')['ConfigProvider']
ADatePicker: typeof import('@arco-design/web-vue')['DatePicker']
ADescriptions: typeof import('@arco-design/web-vue')['Descriptions']
ADescriptionsItem: typeof import('@arco-design/web-vue')['DescriptionsItem']
ADivider: typeof import('@arco-design/web-vue')['Divider']
ADoption: typeof import('@arco-design/web-vue')['Doption']
ADrawer: typeof import('@arco-design/web-vue')['Drawer']
ADropdown: typeof import('@arco-design/web-vue')['Dropdown']
AEmpty: typeof import('@arco-design/web-vue')['Empty']
AForm: typeof import('@arco-design/web-vue')['Form']
AFormItem: typeof import('@arco-design/web-vue')['FormItem']
AGrid: typeof import('@arco-design/web-vue')['Grid']
AGridItem: typeof import('@arco-design/web-vue')['GridItem']
AInput: typeof import('@arco-design/web-vue')['Input']
AInputGroup: typeof import('@arco-design/web-vue')['InputGroup']
AInputNumber: typeof import('@arco-design/web-vue')['InputNumber']
AInputPassword: typeof import('@arco-design/web-vue')['InputPassword']
AInputSearch: typeof import('@arco-design/web-vue')['InputSearch']
AInputTag: typeof import('@arco-design/web-vue')['InputTag']
ALayout: typeof import('@arco-design/web-vue')['Layout']
ALayoutHeader: typeof import('@arco-design/web-vue')['LayoutHeader']
ALayoutSider: typeof import('@arco-design/web-vue')['LayoutSider']
ALink: typeof import('@arco-design/web-vue')['Link']
AMenu: typeof import('@arco-design/web-vue')['Menu']
AMenuItem: typeof import('@arco-design/web-vue')['MenuItem']
AModal: typeof import('@arco-design/web-vue')['Modal']
AOption: typeof import('@arco-design/web-vue')['Option']
AOverflowList: typeof import('@arco-design/web-vue')['OverflowList']
APopconfirm: typeof import('@arco-design/web-vue')['Popconfirm']
APopover: typeof import('@arco-design/web-vue')['Popover']
AProgress: typeof import('@arco-design/web-vue')['Progress']
ARadio: typeof import('@arco-design/web-vue')['Radio']
ARadioGroup: typeof import('@arco-design/web-vue')['RadioGroup']
ARow: typeof import('@arco-design/web-vue')['Row']
AScrollbar: typeof import('@arco-design/web-vue')['Scrollbar']
ASelect: typeof import('@arco-design/web-vue')['Select']
ASpace: typeof import('@arco-design/web-vue')['Space']
ASpin: typeof import('@arco-design/web-vue')['Spin']
ASplit: typeof import('@arco-design/web-vue')['Split']
ASubMenu: typeof import('@arco-design/web-vue')['SubMenu']
ASwitch: typeof import('@arco-design/web-vue')['Switch']
ATable: typeof import('@arco-design/web-vue')['Table']
ATableColumn: typeof import('@arco-design/web-vue')['TableColumn']
ATabPane: typeof import('@arco-design/web-vue')['TabPane']
ATabs: typeof import('@arco-design/web-vue')['Tabs']
ATag: typeof import('@arco-design/web-vue')['Tag']
ATextarea: typeof import('@arco-design/web-vue')['Textarea']
ATooltip: typeof import('@arco-design/web-vue')['Tooltip']
ATree: typeof import('@arco-design/web-vue')['Tree']
ATreeSelect: typeof import('@arco-design/web-vue')['TreeSelect']
AUpload: typeof import('@arco-design/web-vue')['Upload']
GiButton: typeof import('./components/GiButton/GiButton.vue')['default']
GiCellAvatar: typeof import('./components/GiCell/GiCellAvatar.vue')['default']
GiCellGender: typeof import('./components/GiCell/GiCellGender.vue')['default']
GiCellStatus: typeof import('./components/GiCell/GiCellStatus.vue')['default']
GiCellTags: typeof import('./components/GiCell/GiCellTags.vue')['default']
GiDot: typeof import('./components/GiDot/GiDot.tsx')['default']
GiEditTable: typeof import('./components/GiEditTable/GiEditTable.vue')['default']
GiFlex: typeof import('./components/GiFlex/GiFlex.vue')['default']
GiForm: typeof import('./components/GiForm/GiForm.vue')['default']
GiIconBox: typeof import('./components/GiIconBox/GiIconBox.vue')['default']
GiInputSearch: typeof import('./components/GiInputSearch/GiInputSearch.vue')['default']
GiOption: typeof import('./components/GiOption/GiOption.vue')['default']
GiOptionItem: typeof import('./components/GiOption/GiOptionItem.vue')['default']
GiPageLayout: typeof import('./components/GiPageLayout/GiPageLayout.vue')['default']
GiTable: typeof import('./components/GiTable/GiTable.vue')['default']
GiTableSetting: typeof import('./components/GiTableSetting/GiTableSetting.vue')['default']
GiTag: typeof import('./components/GiTag/GiTag.tsx')['default']
GiTenantPicker: typeof import('./components/GiTenantPicker/GiTenantPicker.vue')['default']
GiThemeBtn: typeof import('./components/GiThemeBtn/GiThemeBtn.vue')['default']
RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView']
SplitButton: typeof import('./components/GiPageLayout/SplitButton.vue')['default']
}
}
// For TSX support
declare global {
const AAlert: typeof import('@arco-design/web-vue')['Alert']
const AAvatar: typeof import('@arco-design/web-vue')['Avatar']
const ABadge: typeof import('@arco-design/web-vue')['Badge']
const ABreadcrumb: typeof import('@arco-design/web-vue')['Breadcrumb']
const ABreadcrumbItem: typeof import('@arco-design/web-vue')['BreadcrumbItem']
const AButton: typeof import('@arco-design/web-vue')['Button']
const ACard: typeof import('@arco-design/web-vue')['Card']
const ACheckbox: typeof import('@arco-design/web-vue')['Checkbox']
const ACheckboxGroup: typeof import('@arco-design/web-vue')['CheckboxGroup']
const ACol: typeof import('@arco-design/web-vue')['Col']
const AComment: typeof import('@arco-design/web-vue')['Comment']
const AConfigProvider: typeof import('@arco-design/web-vue')['ConfigProvider']
const ADatePicker: typeof import('@arco-design/web-vue')['DatePicker']
const ADescriptions: typeof import('@arco-design/web-vue')['Descriptions']
const ADescriptionsItem: typeof import('@arco-design/web-vue')['DescriptionsItem']
const ADivider: typeof import('@arco-design/web-vue')['Divider']
const ADoption: typeof import('@arco-design/web-vue')['Doption']
const ADrawer: typeof import('@arco-design/web-vue')['Drawer']
const ADropdown: typeof import('@arco-design/web-vue')['Dropdown']
const AEmpty: typeof import('@arco-design/web-vue')['Empty']
const AForm: typeof import('@arco-design/web-vue')['Form']
const AFormItem: typeof import('@arco-design/web-vue')['FormItem']
const AGrid: typeof import('@arco-design/web-vue')['Grid']
const AGridItem: typeof import('@arco-design/web-vue')['GridItem']
const AInput: typeof import('@arco-design/web-vue')['Input']
const AInputGroup: typeof import('@arco-design/web-vue')['InputGroup']
const AInputNumber: typeof import('@arco-design/web-vue')['InputNumber']
const AInputPassword: typeof import('@arco-design/web-vue')['InputPassword']
const AInputSearch: typeof import('@arco-design/web-vue')['InputSearch']
const AInputTag: typeof import('@arco-design/web-vue')['InputTag']
const ALayout: typeof import('@arco-design/web-vue')['Layout']
const ALayoutHeader: typeof import('@arco-design/web-vue')['LayoutHeader']
const ALayoutSider: typeof import('@arco-design/web-vue')['LayoutSider']
const ALink: typeof import('@arco-design/web-vue')['Link']
const AMenu: typeof import('@arco-design/web-vue')['Menu']
const AMenuItem: typeof import('@arco-design/web-vue')['MenuItem']
const AModal: typeof import('@arco-design/web-vue')['Modal']
const AOption: typeof import('@arco-design/web-vue')['Option']
const AOverflowList: typeof import('@arco-design/web-vue')['OverflowList']
const APopconfirm: typeof import('@arco-design/web-vue')['Popconfirm']
const APopover: typeof import('@arco-design/web-vue')['Popover']
const AProgress: typeof import('@arco-design/web-vue')['Progress']
const ARadio: typeof import('@arco-design/web-vue')['Radio']
const ARadioGroup: typeof import('@arco-design/web-vue')['RadioGroup']
const ARow: typeof import('@arco-design/web-vue')['Row']
const AScrollbar: typeof import('@arco-design/web-vue')['Scrollbar']
const ASelect: typeof import('@arco-design/web-vue')['Select']
const ASpace: typeof import('@arco-design/web-vue')['Space']
const ASpin: typeof import('@arco-design/web-vue')['Spin']
const ASplit: typeof import('@arco-design/web-vue')['Split']
const ASubMenu: typeof import('@arco-design/web-vue')['SubMenu']
const ASwitch: typeof import('@arco-design/web-vue')['Switch']
const ATable: typeof import('@arco-design/web-vue')['Table']
const ATableColumn: typeof import('@arco-design/web-vue')['TableColumn']
const ATabPane: typeof import('@arco-design/web-vue')['TabPane']
const ATabs: typeof import('@arco-design/web-vue')['Tabs']
const ATag: typeof import('@arco-design/web-vue')['Tag']
const ATextarea: typeof import('@arco-design/web-vue')['Textarea']
const ATooltip: typeof import('@arco-design/web-vue')['Tooltip']
const ATree: typeof import('@arco-design/web-vue')['Tree']
const ATreeSelect: typeof import('@arco-design/web-vue')['TreeSelect']
const AUpload: typeof import('@arco-design/web-vue')['Upload']
const GiButton: typeof import('./components/GiButton/GiButton.vue')['default']
const GiCellAvatar: typeof import('./components/GiCell/GiCellAvatar.vue')['default']
const GiCellGender: typeof import('./components/GiCell/GiCellGender.vue')['default']
const GiCellStatus: typeof import('./components/GiCell/GiCellStatus.vue')['default']
const GiCellTags: typeof import('./components/GiCell/GiCellTags.vue')['default']
const GiDot: typeof import('./components/GiDot/GiDot.tsx')['default']
const GiEditTable: typeof import('./components/GiEditTable/GiEditTable.vue')['default']
const GiFlex: typeof import('./components/GiFlex/GiFlex.vue')['default']
const GiForm: typeof import('./components/GiForm/GiForm.vue')['default']
const GiIconBox: typeof import('./components/GiIconBox/GiIconBox.vue')['default']
const GiInputSearch: typeof import('./components/GiInputSearch/GiInputSearch.vue')['default']
const GiOption: typeof import('./components/GiOption/GiOption.vue')['default']
const GiOptionItem: typeof import('./components/GiOption/GiOptionItem.vue')['default']
const GiPageLayout: typeof import('./components/GiPageLayout/GiPageLayout.vue')['default']
const GiTable: typeof import('./components/GiTable/GiTable.vue')['default']
const GiTableSetting: typeof import('./components/GiTableSetting/GiTableSetting.vue')['default']
const GiTag: typeof import('./components/GiTag/GiTag.tsx')['default']
const GiTenantPicker: typeof import('./components/GiTenantPicker/GiTenantPicker.vue')['default']
const GiThemeBtn: typeof import('./components/GiThemeBtn/GiThemeBtn.vue')['default']
const RouterLink: typeof import('vue-router')['RouterLink']
const RouterView: typeof import('vue-router')['RouterView']
const SplitButton: typeof import('./components/GiPageLayout/SplitButton.vue')['default']
}
@@ -1,86 +0,0 @@
<template>
<a-button v-bind="buttonProps" @click="emit('click')">
<template v-if="buttonConfig?.icon" #icon>
<component :is="buttonConfig.icon" />
</template>
<template #default>
<slot>{{ buttonConfig?.text }}</slot>
</template>
</a-button>
</template>
<script setup lang="ts">
import type { ButtonProps as AButtonProps } from '@arco-design/web-vue'
import type { Component } from 'vue'
import type { ButtonProps as Props } from './type'
import { IconDelete, IconDownload, IconEdit, IconImport, IconPlus, IconSearch, IconUpload } from '@arco-design/web-vue/es/icon'
import { computed } from 'vue'
defineOptions({
name: 'GiButton'
})
const props = withDefaults(defineProps<Props>(), {
type: ''
})
const emit = defineEmits<{
(e: 'click'): void
}>()
/** 按钮配置类型 */
interface ButtonConfig {
icon?: Component
text: string
status?: AButtonProps['status']
type?: AButtonProps['type']
}
/** 按钮类型映射表 */
const BUTTON_MAP: Record<string, ButtonConfig> = {
add: { icon: IconPlus, text: '新增' },
edit: { icon: IconEdit, text: '编辑' },
delete: { icon: IconDelete, text: '删除', status: 'danger' },
search: { icon: IconSearch, text: '搜索' },
reset: { icon: undefined, text: '重置', type: 'secondary' },
upload: { icon: IconUpload, text: '上传', type: 'secondary' },
import: { icon: IconImport, text: '导入', type: 'secondary' },
export: { icon: IconDownload, text: '导出', type: 'secondary' }
}
/** Arco 原生按钮类型 */
const ARCO_BUTTON_TYPES: AButtonProps['type'][] = ['primary', 'secondary', 'outline', 'dashed', 'text']
/** 当前按钮配置 */
const buttonConfig = computed<ButtonConfig | undefined>(() => {
if (!props.type) {
return undefined
}
return BUTTON_MAP[props.type]
})
/** 按钮属性计算 */
const buttonProps = computed(() => {
// 判断是否为 Arco 原生类型
const isArcoType = ARCO_BUTTON_TYPES.includes(props.type as AButtonProps['type'])
// 确定按钮类型
let buttonType: AButtonProps['type'] = 'primary'
if (isArcoType) {
buttonType = props.type as AButtonProps['type']
} else if (buttonConfig.value?.type) {
buttonType = buttonConfig.value.type
}
// 确定按钮状态
const buttonStatus: AButtonProps['status'] = buttonConfig.value?.status || 'normal'
return {
...props,
type: buttonType,
status: buttonStatus
}
})
</script>
<style lang='scss' scoped></style>
@@ -1,5 +0,0 @@
import Button from './GiButton.vue'
export type ButtonInstance = InstanceType<typeof Button>
export * from './type'
export { Button as GiButton }
@@ -1,5 +0,0 @@
import type { ButtonProps as ArcoButtonProps } from '@arco-design/web-vue'
export interface ButtonProps extends Omit<ArcoButtonProps, 'type'> {
type?: 'add' | 'edit' | 'delete' | 'search' | 'reset' | 'upload' | 'import' | 'export' | ''
}
@@ -1,31 +0,0 @@
<template>
<a-space fill>
<a-avatar :size="24" shape="circle">
<img :src="props.avatar" />
</a-avatar>
<a-link v-if="props.isLink" @click="emit('click')">{{ props.name }}</a-link>
<span v-else>{{ props.name }}</span>
</a-space>
</template>
<script lang="ts" setup>
defineOptions({ name: 'GiCellAvatar' })
const props = withDefaults(defineProps<Props>(), {
avatar: '',
name: '',
isLink: false // 是否可以点击
})
const emit = defineEmits<{
(e: 'click'): void
}>()
interface Props {
avatar?: string
name?: string
isLink?: boolean
}
</script>
<style lang="scss" scoped></style>
@@ -1,28 +0,0 @@
<template>
<a-tag v-if="props.gender === '1'" color="arcoblue" class="g-round">
<template #icon><icon-man /></template>
<template #default>男</template>
</a-tag>
<a-tag v-if="props.gender === '2'" color="purple" class="g-round">
<template #icon><icon-woman /></template>
<template #default>女</template>
</a-tag>
<a-tag v-if="props.gender === '3'" color="gray" class="g-round">
<template #icon><icon-lock /></template>
<template #default>保密</template>
</a-tag>
</template>
<script lang="ts" setup>
defineOptions({ name: 'GiCellGender' })
const props = withDefaults(defineProps<Props>(), {
gender: '1'
})
interface Props {
gender?: Gender
}
</script>
<style lang="scss" scoped></style>
@@ -1,24 +0,0 @@
<template>
<a-tag v-if="props.status === '1'" color="arcoblue">
<template #icon><icon-check-circle-fill /></template>
<template #default>正常</template>
</a-tag>
<a-tag v-if="props.status === '0'" color="orangered">
<template #icon><icon-minus-circle-fill /></template>
<template #default>禁用</template>
</a-tag>
</template>
<script lang="ts" setup>
defineOptions({ name: 'GiCellStatus' })
const props = withDefaults(defineProps<Props>(), {
status: '1'
})
interface Props {
status?: Status
}
</script>
<style lang="scss" scoped></style>
@@ -1,33 +0,0 @@
<template>
<a-overflow-list v-if="data.length">
<a-tag v-for="(item, index) in data" :key="index">
{{ item }}
</a-tag>
<template #overflow="{ number }">
<a-popover :content-style="{ maxWidth: '300px', padding: '8px 12px' }">
<a-tag color="arcoblue">+{{ number }}</a-tag>
<template #content>
<a-space wrap>
<a-tag v-for="tag in data.filter((i, n) => n >= data.length - number)" :key="tag">
{{ tag }}
</a-tag>
</a-space>
</template>
</a-popover>
</template>
</a-overflow-list>
</template>
<script lang="ts" setup>
defineOptions({ name: 'GiCellTags' })
withDefaults(defineProps<Props>(), {
data: () => []
})
interface Props {
data?: string[]
}
</script>
<style lang="scss" scoped></style>
@@ -1,6 +0,0 @@
import GiCellAvatar from './GiCellAvatar.vue'
import GiCellGender from './GiCellGender.vue'
import GiCellStatus from './GiCellStatus.vue'
import GiCellTags from './GiCellTags.vue'
export { GiCellAvatar, GiCellGender, GiCellStatus, GiCellTags }
@@ -1,33 +0,0 @@
/**
* @file GiDot 组件 - 用于显示带有可选动画效果的状态点
*/
import type { PropType } from 'vue'
import type { DotType, DotProps as Props } from './type'
import { defineComponent } from 'vue'
import './dot.scss'
export default defineComponent({
name: 'GiDot',
props: {
animation: {
type: Boolean as PropType<boolean>,
default: true,
required: false
},
type: {
type: String as PropType<DotType>,
default: 'primary',
required: false,
validator: (value: string): boolean => {
return ['primary', 'success', 'warning', 'danger', 'info'].includes(value)
}
}
},
setup(props: Props) {
return () => (
<span
class={['gi-dot', { 'gi-dot-processing': props.animation }, `gi-dot-${props.type}`]}
/>
)
}
})
-58
View File
@@ -1,58 +0,0 @@
.gi-dot {
display: inline-block;
width: 8px;
height: 8px;
vertical-align: middle;
background: #000;
border-radius: 50%;
}
$types: primary, success, warning, danger, info;
@each $i in $types {
.gi-dot-#{$i}
{
background-color: rgb(var(--#{$i}-6));
}
@if ($i ==info) {
.gi-dot-#{$i}
{
background-color: rgb(var(--gray-6));
}
}
}
.gi-dot-processing {
position: relative;
}
.gi-dot-processing::after {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
content: '';
background: inherit;
border-radius: 50%;
animation: gi-dot-animated 1.2s ease-in-out infinite;
}
@keyframes gi-dot-animated {
0% {
opacity: 1;
transform: scale(0.5);
}
30% {
opacity: 0.7;
}
100% {
opacity: 0;
transform: scale(2.5);
}
}
@@ -1,5 +0,0 @@
import Dot from './GiDot.tsx'
export type * from './type'
export type DotInstance = InstanceType<typeof Dot>
export { Dot as GiDot }
-10
View File
@@ -1,10 +0,0 @@
/** 点的类型 */
export type DotType = 'primary' | 'success' | 'warning' | 'danger' | 'info'
/** 组件属性定义 */
export interface DotProps {
/** 点的类型 */
type?: DotType
/** 是否启用动画效果 */
animation?: boolean
}
@@ -1,176 +0,0 @@
<template>
<div class="gi-edit-table">
<a-form ref="formRef" scroll-to-first-error :model="form">
<a-table :data="form.tableData" :bordered="{ cell: true }" :pagination="false" v-bind="attrs">
<template #columns>
<a-table-column v-for="col in props.columns" :key="col.dataIndex" :data-index="col.dataIndex"
:header-cell-class="headerCellClass(col)" v-bind="col.columnProps" :title="col.title">
<template #title>
<component :is="col?.columnProps?.title" v-if="typeof col?.columnProps?.title === 'function'"></component>
<template v-else>{{ col?.columnProps?.title || col.title }}</template>
</template>
<template #cell="{ record, rowIndex, column }">
<template v-if="!col.type && !col.slotName">{{ record[col.dataIndex] }}</template>
<a-form-item v-else :field="`tableData[${rowIndex}].${col.dataIndex}`"
:label-col-style="{ display: 'none' }" :wrapper-col-props="{ span: 24 }" v-bind="col.formItemProps"
:rules="[{ required: col.required || false, message: getRuleMessage(col) }, ...(col.rules || [])]">
<template v-if="col.slotName">
<slot :name="col.dataIndex" v-bind="{ record, rowIndex, column }"></slot>
</template>
<component :is="COMP_MAP[col.type!]" v-else-if="col.type" v-bind="getComponentBindProps(col)"
v-model="record[col.dataIndex]" :disabled="isDisabled({ row: record, rowIndex, col })">
</component>
</a-form-item>
</template>
</a-table-column>
</template>
<template #tr="{ record, rowIndex }">
<tr class="gi-edit-table-tr" @dblclick="emit('tr-dblclick', { record, rowIndex })"></tr>
</template>
<template #td="{ record, column, rowIndex }">
<td class="gi-edit-table-td" @dblclick="emit('td-dblclick', { record, column, rowIndex })"></td>
</template>
</a-table>
</a-form>
</div>
</template>
<script lang='ts' setup generic="T extends TableData">
import type { TableColumnData, TableData } from '@arco-design/web-vue'
import type { Component } from 'vue'
import type { EditTableColumnItem, EditTableProps as Props } from './type'
import * as A from '@arco-design/web-vue'
defineOptions({ name: 'GiEditTable', inheritAttrs: false })
const props = withDefaults(defineProps<Props<T>>(), {
cellDisabled: false
})
/** 事件定义 */
const emit = defineEmits<{
(e: 'tr-dblclick', value: { record: any, rowIndex: number }): void
(e: 'td-dblclick', value: { record: any, rowIndex: number, column: TableColumnData }): void
}>()
/** 插槽定义 */
defineSlots<{
[propsName: string]: (props: { record: T, rowIndex: number, column: EditTableColumnItem }) => void
}>()
const attrs = useAttrs()
const COMP_MAP: Record<string, Component> = {
'input': A.Input,
'input-number': A.InputNumber,
'input-tag': A.InputTag,
'input-search': A.InputSearch,
'textarea': A.Textarea,
'select': A.Select,
'tree-select': A.TreeSelect,
'radio': A.Radio,
'radio-group': A.RadioGroup,
'checkbox': A.Checkbox,
'checkbox-group': A.CheckboxGroup,
'date-picker': A.DatePicker,
'year-picker': A.YearPicker,
'quarter-picker': A.QuarterPicker,
'month-picker': A.MonthPicker,
'week-picker': A.WeekPicker,
'time-picker': A.TimePicker,
'range-picker': A.RangePicker,
'color-picker': A.ColorPicker,
'rate': A.Rate,
'switch': A.Switch,
'slider': A.Slider,
'cascader': A.Cascader,
'upload': A.Upload,
'auto-complete': A.AutoComplete,
'mention': A.Mention
}
/** 表单数据 */
const form = computed(() => ({ tableData: props.data }))
/** 表单实例 */
const formRef = useTemplateRef('formRef')
/** 获取表头必填星号*样式 */
const headerCellClass = (col: EditTableColumnItem) => {
return col.required ? 'g-column-require' : ''
}
/** 静态配置 */
const STATIC_PROPS = new Map<EditTableColumnItem['type'], Partial<EditTableColumnItem['props']>>([
['input', { allowClear: true, maxLength: 20 }],
['textarea', { allowClear: false, maxLength: 200 }],
['input-tag', { allowClear: true }],
['mention', { allowClear: true }],
['select', { allowClear: true }],
['tree-select', { allowClear: true }],
['cascader', { allowClear: true }],
['date-picker', { allowClear: true }],
['time-picker', { allowClear: true }]
])
/** 获取组件默认占位 */
const getPlaceholder = (item: EditTableColumnItem) => {
if (!item.type) return undefined
if (['input', 'input-tag', 'mention'].includes(item.type)) {
return `请输入${item.title}`
}
if (['textarea'].includes(item.type)) {
return `请填写${item.title}`
}
if (['select', 'tree-select', 'cascader'].includes(item.type)) {
return `请选择${item.title}`
}
if (['date-picker'].includes(item.type)) {
return '请选择日期'
}
if (['time-picker'].includes(item.type)) {
return '请选择时间'
}
return undefined
}
/** 获取组件默认配置 */
const getComponentBindProps = (col: EditTableColumnItem) => {
return {
...STATIC_PROPS.get(col.type) || {},
placeholder: getPlaceholder(col),
...col.props
}
}
/** 获取组件默认规则 */
const getRuleMessage = (col: EditTableColumnItem) => {
if (['input', 'input-number', 'input-tag', 'mention'].includes(col.type ?? '')) {
return `请输入${col.title}`
}
if (['textarea'].includes(col.type ?? '')) {
return `请填写${col.title}`
}
return `请选择${col.title}`
}
/** 判断是否禁用 */
const isDisabled: Props<T>['cellDisabled'] = (p) => {
if (typeof props?.cellDisabled === 'boolean') return props.cellDisabled
if (typeof props?.cellDisabled === 'function') return props.cellDisabled(p)
return false
}
/** 暴露表单实例 */
defineExpose({ formRef })
</script>
<style lang='scss' scoped>
:deep(.arco-form-item) {
margin-bottom: 0;
.arco-form-item-message {
display: none;
}
}
</style>
@@ -1,18 +0,0 @@
import type { FormInstance } from '@arco-design/web-vue'
import EditTable from './GiEditTable.vue'
export type * from './type'
/**
* 组件实例类型。
*
* 与 `GiTable/index.ts` 同一个原因:泛型 SFC 不能用 `InstanceType<>` 推导
* (`<script setup generic="T extends TableData">` 让组件类型成为泛型函数签名),
* 所以按 `defineExpose({ formRef })` 的真实形状手工声明。
*/
export interface EditTableInstance {
/** 内层 a-form 的实例(校验用) */
formRef: FormInstance | null
}
export { EditTable as GiEditTable }
@@ -1,81 +0,0 @@
import type * as A from '@arco-design/web-vue'
import type { VNode } from 'vue'
export type EditTableColumnItemType
= | 'input'
| 'input-number'
| 'input-tag'
| 'textarea'
| 'select'
| 'tree-select'
| 'radio'
| 'radio-group'
| 'checkbox'
| 'checkbox-group'
| 'date-picker'
| 'year-picker'
| 'quarter-picker'
| 'month-picker'
| 'week-picker'
| 'time-picker'
| 'range-picker'
| 'color-picker'
| 'rate'
| 'switch'
| 'slider'
| 'cascader'
| 'upload'
| 'auto-complete'
| 'mention'
| ''
export type EditTableComponentProps
= & A.InputInstance['$props']
& A.InputNumberInstance['$props']
& A.InputTagInstance['$props']
& A.TextareaInstance['$props']
& A.SelectInstance['$props']
& A.TreeSelectInstance['$props']
& A.RadioInstance['$props']
& A.RadioGroupInstance['$props']
& A.CheckboxInstance['$props']
& A.CheckboxGroupInstance['$props']
& A.DatePickerInstance['$props']
& A.YearPickerInstance['$props']
& A.QuarterPickerInstance['$props']
& A.MonthPickerInstance['$props']
& A.WeekPickerInstance['$props']
& A.TimePickerInstance['$props']
& A.RangePickerInstance['$props']
& A.ColorPickerInstance['$props']
& A.RateInstance['$props']
& A.SwitchInstance['$props']
& A.SliderInstance['$props']
& A.CascaderInstance['$props']
& A.UploadInstance['$props']
& A.AutoCompleteInstance['$props']
& A.MentionInstance['$props']
interface EditTableColumnItemProps extends Partial<Omit<EditTableComponentProps, 'placeholder'>> {
placeholder?: string | string[]
}
export interface EditTableColumnItem {
type?: EditTableColumnItemType
title: string
dataIndex: string
required?: boolean
rules?: A.FormItemInstance['$props']['rules'] // 表单校验规则
props?: EditTableColumnItemProps
columnProps?: Partial<Omit<A.TableColumnInstance['$props'], 'title'>> & { title?: string | (() => VNode) }
formItemProps?: A.FormItemInstance['$props']
slotName?: string
}
export type EditTableCellDisabled<T> = boolean | ((e: { row: T, rowIndex: number, col: EditTableColumnItem }) => boolean)
export interface EditTableProps<T> {
columns: EditTableColumnItem[]
data: T[]
cellDisabled?: EditTableCellDisabled<T>
}
@@ -1,65 +0,0 @@
<template>
<div class="gi-flex" :class="getClass" :style="getStyle">
<slot />
</div>
</template>
<script setup lang="ts">
import type { CSSProperties } from 'vue'
import type { FlexProps as Props } from './type'
import { computed } from 'vue'
const props = withDefaults(defineProps<Props>(), {
column: false,
justify: 'start',
align: 'start',
wrap: true,
gap: false
})
/** 计算组件的 class */
const getClass = computed(() => {
const arr: string[] = []
if (props.wrap) {
arr.push('gi-flex__wrap')
}
if (props.column) {
arr.push('gi-flex__column')
}
return arr.join(' ')
})
/** 计算组件的样式 */
const getStyle = computed((): CSSProperties => {
const style: CSSProperties = {
'justify-content': props.justify,
'align-items': props.align
}
// 联合类型中若 boolean 不在最前,裸写 `gap` 会得到 `""`;与「开启主题间距」语义一致
if (props.gap === true || props.gap === '') {
style.gap = 'var(--margin)'
} else if (props.gap === false) {
style.gap = undefined
} else if (typeof props.gap === 'number') {
style.gap = `${props.gap}px`
} else {
style.gap = props.gap
}
style.flex = props.flex
return style
})
</script>
<style lang="scss" scoped>
.gi-flex {
display: flex;
&.gi-flex__wrap {
flex-wrap: wrap;
}
&.gi-flex__column {
flex-direction: column;
}
}
</style>
@@ -1,5 +0,0 @@
import Flex from './GiFlex.vue'
export type FlexInstance = InstanceType<typeof Flex>
export * from './type'
export { Flex as GiFlex }
-29
View File
@@ -1,29 +0,0 @@
/** 组件属性定义 */
export interface FlexProps {
/** 排列方向 */
column?: boolean
/** 水平对齐方式(与 CSS justify-content 一致) */
justify?:
| 'start'
| 'center'
| 'end'
| 'flex-start'
| 'flex-end'
| 'space-between'
| 'space-around'
| 'space-evenly'
/** 垂直对齐方式(与 CSS align-items 一致) */
align?:
| 'start'
| 'center'
| 'end'
| 'flex-start'
| 'flex-end'
| 'baseline'
| 'stretch'
/** 是否自动换行 */
wrap?: boolean
/** `boolean` 须写在联合类型最前,否则模板里单独写 `gap` 会被解析成 `""` 而不是 `true` */
gap?: boolean | number | string
flex?: number | string
}
@@ -1,273 +0,0 @@
<!--
@file GiForm 组件
@description 动态表单组件,支持多种表单项类型、栅格布局、搜索模式等功能
-->
<template>
<a-form ref="formRef" v-bind="formProps" :model="modelValue">
<a-grid class="w-full" :col-gap="8" v-bind="props.gridProps" :collapsed="collapsed && search">
<!-- 表单项列表 -->
<template v-for="item in columns" :key="item.field">
<a-grid-item v-if="!isHide(item)" v-bind="item.gridItemProps || props.gridItemProps"
:span="item.span || item.gridItemProps?.span || props.gridItemProps?.span">
<a-form-item v-bind="item.formItemProps" :field="item.field" :rules="getFormItemRules(item)"
:disabled="isDisabled(item)">
<!-- 表单项标签 -->
<template #label>
<component :is="item.labelRender" v-if="item.labelRender"></component>
<template v-else>{{ item.label }}</template>
</template>
<!-- 表单项内容 -->
<slot v-if="getStringType(item.type) === 'slot'" :name="item.field"></slot>
<slot v-else-if="getStringType(item.type) !== 'group-title'" :name="item.field"
v-bind="{ disabled: isDisabled(item) }">
<component :is="(COMP_MAP[getStringType(item.type)] || item.type)" v-bind="getComponentBindProps(item)"
:model-value="modelValue[getModelField(item)]"
@update:model-value="updateValue($event, getModelField(item))">
<!-- 组件插槽 -->
<template v-for="(slotValue, slotKey) in item?.slots" :key="slotKey" #[slotKey]="scope">
<template v-if="typeof slotValue === 'string'">{{ slotValue }}</template>
<template v-else-if="slotValue">
<component :is="slotValue(scope)"></component>
</template>
</template>
</component>
</slot>
<!-- 分组标题 -->
<slot v-else :name="item.field">
<a-alert>{{ item.label }}</a-alert>
</slot>
<!-- 表单项插槽 -->
<template v-for="(slotValue, slotKey) in item?.formItemSlots" :key="slotKey" #[slotKey]>
<template v-if="typeof slotValue === 'string'">{{ slotValue }}</template>
<component :is="slotValue" v-else></component>
</template>
</a-form-item>
</a-grid-item>
</template>
<!-- 搜索按钮组 -->
<a-grid-item v-if="props.search" :key="!props.suffix ? String(collapsed) : undefined" v-bind="props.gridItemProps"
:span="props.gridItemProps?.span" :suffix="props.search && (props.suffix || (!props.suffix && collapsed))">
<a-space wrap style="margin-bottom: 8px">
<slot name="suffix">
<a-button type="primary" @click="emit('search')">
<template #icon><icon-search /></template>
<template #default>{{ props.searchBtnText }}</template>
</a-button>
<a-button @click="emit('reset')">重置</a-button>
<a-button v-if="!props.hideFoldBtn" class="gi-form__fold-btn" type="text" size="mini"
@click="collapsed = !collapsed">
<template #icon>
<icon-up v-if="!collapsed" />
<icon-down v-else />
</template>
<template #default>{{ collapsed ? '展开' : '收起' }}</template>
</a-button>
</slot>
</a-space>
</a-grid-item>
</a-grid>
</a-form>
</template>
<script setup lang="ts">
import type { FormInstance } from '@arco-design/web-vue'
import type { Component } from 'vue'
import type { FormColumnItem, FormProps as Props } from './type'
import * as A from '@arco-design/web-vue'
import { omit } from 'lodash-es'
// FormProps 默认值
const props = withDefaults(defineProps<Props>(), {
autoLabelWidth: true,
scrollToFirstError: true,
defaultCollapsed: true,
search: false,
gridItemProps: () => ({ span: { xs: 24, sm: 12 } }),
searchBtnText: '搜索',
hideFoldBtn: false,
suffix: true,
fc: () => ({})
})
/** Emits 类型定义 */
const emit = defineEmits<{
(e: 'update:modelValue', value: Record<string, any>): void
(e: 'search'): void
(e: 'reset'): void
}>()
const COMP_MAP: Record<string, Component> = {
'input': A.Input,
'input-number': A.InputNumber,
'input-tag': A.InputTag,
'input-search': A.InputSearch,
'textarea': A.Textarea,
'select': A.Select,
'tree-select': A.TreeSelect,
'radio-group': A.RadioGroup,
'checkbox-group': A.CheckboxGroup,
'date-picker': A.DatePicker,
'year-picker': A.YearPicker,
'quarter-picker': A.QuarterPicker,
'month-picker': A.MonthPicker,
'week-picker': A.WeekPicker,
'time-picker': A.TimePicker,
'range-picker': A.RangePicker,
'color-picker': A.ColorPicker,
'rate': A.Rate,
'switch': A.Switch,
'slider': A.Slider,
'cascader': A.Cascader,
'upload': A.Upload,
'auto-complete': A.AutoComplete,
'mention': A.Mention
}
/** 表单属性计算 */
const formProps = computed(() => {
const baseProps = omit(props, [
'columns',
'gridProps',
'gridItemProps',
'search',
'defaultCollapsed',
'searchBtnText',
'hideFoldBtn',
'suffix',
'layout',
'fc'
])
return {
layout: ((props.search ? 'inline' : 'horizontal') as FormInstance['layout']),
...baseProps
}
})
/** 组件状态 */
const formRef = useTemplateRef('formRef')
/** 是否折叠 */
const collapsed = ref(props.defaultCollapsed)
/** 数据字典(预留功能:用于动态加载选项数据,可通过 request 和 format 配置项加载) */
const dicData: Record<string, unknown> = reactive({})
/** 静态配置 */
const STATIC_PROPS = new Map<FormColumnItem['type'], Partial<FormColumnItem['props']>>([
['input', { allowClear: true, maxLength: 20 }],
['textarea', { allowClear: false, maxLength: 200 }],
['input-tag', { allowClear: true }],
['mention', { allowClear: true }],
['select', { allowClear: true }],
['tree-select', { allowClear: true }],
['cascader', { allowClear: true }],
['date-picker', { allowClear: true }],
['time-picker', { allowClear: true }]
])
/** 占位符映射表 */
const PLACEHOLDER_MAP: Record<string, (label?: string) => string | undefined> = {
'input': (label) => `请输入${label}`,
'input-tag': (label) => `请输入${label}`,
'mention': (label) => `请输入${label}`,
'textarea': (label) => `请填写${label}`,
'select': (label) => `请选择${label}`,
'input-search': (label) => `请选择${label}`,
'tree-select': (label) => `请选择${label}`,
'cascader': (label) => `请选择${label}`,
'date-picker': () => '请选择日期',
'time-picker': () => '请选择时间'
}
/** 获取字符串类型的表单项类型 */
const getStringType = (type: FormColumnItem['type']): string => {
return typeof type === 'string' ? type : ''
}
/** 获取模型字段名 */
const getModelField = (item: FormColumnItem) => item?.fieldName || item.field
/** 获取组件默认占位 */
const getPlaceholder = (item: FormColumnItem) => {
if (!item.type || typeof item.type !== 'string') return undefined
const placeholderFn = PLACEHOLDER_MAP[item.type]
return placeholderFn ? placeholderFn(item.label) : undefined
}
/** 获取选项数据 */
const getOptions = (item: FormColumnItem) => {
if (!item.type) return undefined
/** 需要选项数据的组件类型 */
const arr = ['select', 'tree-select', 'cascader', 'radio-group', 'checkbox-group']
if (typeof item.type === 'string' && arr.includes(item.type)) {
return dicData[item.field] || []
}
return undefined
}
/** 获取组件绑定属性 */
const getComponentBindProps = (item: FormColumnItem) => {
return {
...STATIC_PROPS.get(item.type) || {},
placeholder: getPlaceholder(item),
options: getOptions(item),
...item.props
}
}
/** 表单数据更新处理 */
const updateValue = (value: unknown, field: string) => {
const newValue = { ...props.modelValue, [field]: value }
emit('update:modelValue', newValue)
}
/** 获取表单项校验规则 */
const getFormItemRules = (item: FormColumnItem) => {
if (item.required) {
return [
{ required: true, message: `${item.label}为必填项` },
...(Array.isArray(item.rules) ? item.rules : [])
]
}
if (props.fc?.[item.field]?.required) {
return [
{
required: props.fc?.[item.field]?.required,
message: `${item.label}为必填项`
},
...(Array.isArray(item.rules) ? item.rules : [])
]
}
return item.rules
}
/** 判断表单项是否隐藏 */
const isHide = (item: FormColumnItem) => {
if (typeof item.hide === 'boolean') return item.hide
if (typeof item.hide === 'function') {
return item.hide(props.modelValue)
}
if (props.fc?.[item.field]?.hidden) return true
return false
}
/** 判断表单项是否禁用 */
const isDisabled = (item: FormColumnItem) => {
if (typeof item.disabled === 'boolean') return item.disabled
if (typeof item.disabled === 'function') {
return item.disabled(props.modelValue)
}
if (props.fc?.[item.field]?.disabled === true) return true
if (item.disabled === undefined) return (item?.props?.disabled as boolean) ?? false
}
defineExpose({ formRef })
</script>
<style lang="scss" scoped>
.gi-form__fold-btn {
padding: 0 5px;
}
</style>
@@ -1,5 +0,0 @@
import Form from './GiForm.vue'
export type * from './type'
export type FormInstance = InstanceType<typeof Form>
export { Form as GiForm }
-299
View File
@@ -1,299 +0,0 @@
/**
* @file GiForm 组件类型定义
* @description 包含表单组件所需的所有类型定义,用于构建动态表单
*/
import type * as A from '@arco-design/web-vue'
import type { GridItemProps } from '@arco-design/web-vue'
import type { Component, VNode } from 'vue'
import type { MergeMultiple } from '@/types/tool'
type FormItemProps = A.FormItemInstance['$props']
/** 支持的表单项类型 */
export type FormColumnItemType
= | 'input' // 输入框
| 'input-number' // 数字输入框
| 'input-tag' // 标签输入框
| 'input-search' // 搜索框
| 'textarea' // 文本域
| 'select' // 选择器
| 'tree-select' // 树选择器
| 'radio' // 单选框
| 'radio-group' // 单选框组
| 'checkbox' // 复选框
| 'checkbox-group' // 复选框组
| 'date-picker' // 日期选择器
| 'year-picker' // 年份选择器
| 'quarter-picker' // 季度选择器
| 'month-picker' // 月份选择器
| 'week-picker' // 周选择器
| 'time-picker' // 时间选择器
| 'range-picker' // 范围选择器
| 'color-picker' // 颜色选择器
| 'rate' // 评分
| 'switch' // 开关
| 'slider' // 滑块
| 'cascader' // 级联选择器
| 'upload' // 上传
| 'auto-complete' // 自动完成
| 'mention' // 提及
| 'group-title' // 分组标题
| 'slot' // 插槽,由父组件通过具名插槽渲染内容
| Component
/** 组件属性合并类型 */
export type FormComponentProps = MergeMultiple<[
Partial<A.InputInstance['$props']>,
Partial<A.InputNumberInstance['$props']>,
Partial<A.InputTagInstance['$props']>,
Partial<A.InputSearchInstance['$props']>,
Partial<A.TextareaInstance['$props']>,
Partial<A.SelectInstance['$props']>,
Partial<A.TreeSelectInstance['$props']>,
Partial<A.RadioInstance['$props']>,
Partial<A.RadioGroupInstance['$props']>,
Partial<A.CheckboxInstance['$props']>,
Partial<A.CheckboxGroupInstance['$props']>,
Partial<A.DatePickerInstance['$props']>,
Partial<A.YearPickerInstance['$props']>,
Partial<A.QuarterPickerInstance['$props']>,
Partial<A.MonthPickerInstance['$props']>,
Partial<A.WeekPickerInstance['$props']>,
Partial<A.TimePickerInstance['$props']>,
Partial<A.RangePickerInstance['$props']>,
Partial<A.ColorPickerInstance['$props']>,
Partial<A.RateInstance['$props']>,
Partial<A.SwitchInstance['$props']>,
Partial<A.SliderInstance['$props']>,
Partial<A.CascaderInstance['$props']>,
Partial<A.UploadInstance['$props']>,
Partial<A.AutoCompleteInstance['$props']>,
Partial<A.MentionInstance['$props']>,
Partial<A.AlertInstance['$props']>
]>
/** 选项类型定义 */
export type FormColumnItemOptions
= MergeMultiple<[A.SelectInstance['$props']['options'], A.RadioGroupInstance['$props']['options'], A.CheckboxGroupInstance['$props']['options'], A.CascaderInstance['$props']['options']]>
/** 数据源类型定义 */
export type FormColumnItemData
= MergeMultiple<[A.TreeSelectInstance['$props']['data'], A.AutoCompleteInstance['$props']['data'], A.MentionInstance['$props']['data']]>
/** 自动完成组件插槽 */
type AutoCompleteSlots = {
option: (e: { data: (string | number | A.SelectOptionData | A.SelectOptionGroup)[] }) => VNode
footer: () => VNode
}
/** 级联选择器插槽 */
type CascaderSlots = {
'label': (e: { data: A.CascaderOption }) => VNode
'prefix': () => VNode
'arrow-icon': () => VNode
'loading-icon': () => VNode
'search-icon': () => VNode
'empty': () => VNode
'option': (e: { data: A.CascaderOption }) => VNode
}
/** 复选框组插槽 */
type CheckboxGroupSlots = {
checkbox: (e: { checked: boolean, disabled: string }) => VNode
label: (e: { data: A.CheckboxOption }) => VNode
}
/** 单选框组插槽 */
type RadioGroupSlots = {
radio: (e: { checked: boolean, disabled: string }) => VNode
label: (e: { data: any }) => VNode
}
/** 日期选择器插槽 */
type DatePickerSlots = {
'prefix': () => VNode
'suffix-icon': () => VNode
'icon-next-double': () => VNode
'icon-prev-double': () => VNode
'icon-next': () => VNode
'icon-prev': () => VNode
'cell': (e: { data: Date }) => VNode
'extra': () => VNode
}
/** 输入框插槽 */
type InputSlots = {
append: (() => VNode) | string
prepend: (() => VNode) | string
suffix: (() => VNode) | string
prefix: (() => VNode) | string
}
/** 数字输入框插槽 */
type InputNumberSlots = {
minus: (() => VNode) | string
plus: (() => VNode) | string
append: (() => VNode) | string
prepend: (() => VNode) | string
suffix: (() => VNode) | string
}
/** 标签输入框插槽 */
type InputTagSlots = {
tag: (e: { data: A.TagData }) => VNode
prefix: (() => VNode) | string
suffix: (() => VNode) | string
}
/** 评分插槽 */
type RateSlots = {
character: (e: { index: number }) => VNode
}
/** 选择器插槽 */
type SelectSlots = {
'trigger': () => VNode
'prefix': () => VNode
'search-icon': () => VNode
'loading-icon': () => VNode
'arrow-icon': () => VNode
'footer': () => VNode
'header': () => VNode
'label': (e: { data: A.SelectOptionData }) => VNode
'option': (e: { data: A.SelectOptionData }) => VNode
'empty': () => VNode
}
/** 开关插槽 */
type SwitchSlots = {
'checked-icon': () => VNode
'unchecked-icon': () => VNode
'checked': () => VNode
'unchecked': () => VNode
}
/** 树选择器插槽 */
type TreeSelectSlots = {
'trigger': () => VNode
'prefix': () => VNode
'label': (e: { data: any }) => VNode
'header': () => VNode
'loader': () => VNode
'empty': () => VNode
'footer': () => VNode
'tree-slot-extra': () => VNode
'tree-slot-title': (e: { title: string }) => VNode
'tree-slot-icon': (e: { node: A.TreeNodeData }) => VNode
'tree-slot-switcher-icon': () => VNode
}
/** 提及插槽 */
type MentionSlots = {
option: (e: { data: any }) => VNode
}
/** 组件插槽合并类型 */
export type FormComponentSlots = MergeMultiple<[
AutoCompleteSlots,
CascaderSlots,
CheckboxGroupSlots,
RadioGroupSlots,
DatePickerSlots,
InputSlots,
InputNumberSlots,
InputTagSlots,
RateSlots,
SelectSlots,
SwitchSlots,
TreeSelectSlots,
MentionSlots
]>
/** 表单项插槽接口 */
export type FormColumnItemSlots = FormComponentSlots
/** 表单项显隐控制类型 */
export type FormColumnItemHide<F> = boolean | ((form: F) => boolean)
export type FormColumnItemDisabled<F> = boolean | ((form: F) => boolean)
/** 表单项数据请求相关类型 */
export type FormColumnItemRequest<F = any> = (form: F) => Promise<any>
export type FormColumnItemFormat<T = any> = (res: T) => FormColumnItemOptions | FormColumnItemData
/** 表单列配置项接口 */
export interface FormColumnItem<F = any> {
/** 表单项类型 */
type?: FormColumnItemType
/** 标签名 */
label?: string
/** 字段名 */
field: string
fieldName?: string
/** 自定义渲染label */
labelRender?: (() => VNode)
/** 表单项属性 */
props?: Partial<FormComponentProps>
/** 表单项校验规则 */
rules?: FormItemProps['rules']
/** 是否必填 */
required?: boolean
/** 栅格属性 */
gridItemProps?: GridItemProps
/** 表单项属性 */
formItemProps?: FormItemProps
/** 表单项插槽 */
slots?: FormColumnItemSlots
/** 表单项组件插槽 */
formItemSlots?: Record<string, string | VNode | (() => VNode)>
/** 是否隐藏(支持函数) */
hide?: boolean | ((model: F) => boolean)
/** 是否禁用(支持函数) */
disabled?: boolean | ((model: F) => boolean)
/** 栅格跨度 */
span?: number | Record<string, number>
}
/** Props 类型定义 */
export interface FormProps {
/** 表单数据对象 */
modelValue: any
/** 表单布局方式 */
layout?: A.FormInstance['layout']
/** 表单尺寸 */
size?: A.FormInstance['size']
/** 标签布局属性 */
labelColProps?: A.FormInstance['labelColProps']
/** 表单项布局属性 */
wrapperColProps?: A.FormInstance['wrapperColProps']
/** 标签对齐方式 */
labelAlign?: A.FormInstance['labelAlign']
/** 是否禁用表单 */
disabled?: A.FormInstance['disabled']
/** 表单校验规则 */
rules?: A.FormInstance['rules']
/** 自动标签宽度 */
autoLabelWidth?: A.FormInstance['autoLabelWidth']
/** 表单ID */
id?: A.FormInstance['id']
/** 是否滚动到第一个错误项 */
scrollToFirstError?: A.FormInstance['scrollToFirstError']
/** 表单列配置 */
columns: FormColumnItem[]
/** 栅格布局属性 */
gridProps?: A.GridProps
/** 栅格项属性 */
gridItemProps?: GridItemProps
/** 是否为搜索模式 */
search?: boolean
/** 默认是否折叠 */
defaultCollapsed?: boolean
/** 搜索按钮文字 */
searchBtnText?: string
/** 是否隐藏折叠按钮 */
hideFoldBtn?: boolean
/** 是否显示后缀 */
suffix?: boolean
/** 表单控制 */
fc?: Record<string, { disabled?: boolean, hidden?: boolean, required?: boolean }>
}
@@ -1,99 +0,0 @@
<!--
@file GiIconBox 组件 - 图标容器
@description 提供可自定义的图标容器,支持不同颜色、尺寸和形状
-->
<template>
<div class="gi-icon-box" :class="getClass" :style="getStyle">
<slot />
</div>
</template>
<script setup lang="ts">
import type { CSSProperties } from 'vue'
import type { IconBoxProps as Props } from './type'
import { computed } from 'vue'
const props = withDefaults(defineProps<Props>(), {
color: '#165DFF',
size: 20,
shape: 'square'
})
/** 预设状态颜色 */
const STATUS_COLORS = ['primary', 'success', 'warning', 'danger'] as const
/** 计算容器的 class */
const getClass = computed(() => {
const classes = [
STATUS_COLORS.includes(props.color as typeof STATUS_COLORS[number])
&& `gi-icon-box--${props.color}`,
props.shape && `gi-icon-box__shape--${props.shape}`
].filter(Boolean)
return classes.join(' ')
})
/** 计算容器的样式 */
const getStyle = computed((): CSSProperties => {
const style: CSSProperties = {}
// 处理自定义颜色(纯色或 linear-gradient / radial-gradient)
if (!STATUS_COLORS.includes(props.color as typeof STATUS_COLORS[number])) {
const c = String(props.color)
if (/gradient\(/i.test(c)) {
style.background = c
} else {
style.backgroundColor = c
}
}
// 处理自定义尺寸
if (props.size !== 20) {
style.width = `${props.size}px`
style.height = `${props.size}px`
}
return style
})
</script>
<style lang="scss" scoped>
.gi-icon-box {
display: flex;
flex-shrink: 0;
align-items: center;
justify-content: center;
width: 20px;
height: 20px;
color: #fff;
transition: all 0.2s ease;
// 状态颜色
&--primary {
background-color: rgb(var(--primary-6));
}
&--success {
background-color: rgb(var(--success-6));
}
&--warning {
background-color: rgb(var(--warning-6));
}
&--danger {
background-color: rgb(var(--danger-6));
}
// 形状样式
&__shape {
&--square {
border-radius: 4px;
}
&--round {
border-radius: 50%;
}
}
}
</style>
@@ -1,5 +0,0 @@
import IconBox from './GiIconBox.vue'
export * from './type'
export type IconBoxInstance = InstanceType<typeof IconBox>
export { IconBox as GiIconBox }
@@ -1,6 +0,0 @@
/** 组件属性定义 */
export interface IconBoxProps {
color?: 'primary' | 'success' | 'warning' | 'danger' | string
size?: number
shape?: 'square' | 'round'
}
@@ -1,50 +0,0 @@
<template>
<a-input-group class="gi-input-search">
<a-input v-model="model" :placeholder="props.placeholder" readonly></a-input>
<template v-if="!props.readonly">
<a-button :disabled="props.disabled" @click="emit('search', model)">
<icon-search />
</a-button>
<a-button :disabled="props.disabled" @click="emit('clear')">
<icon-close />
</a-button>
</template>
</a-input-group>
</template>
<script setup lang="ts">
import type { InputSearchProps as Props } from './type'
const model = defineModel({ type: String, default: '' })
const props = withDefaults(defineProps<Props>(), {
placeholder: '请选择',
disabled: false,
readonly: false
})
const emit = defineEmits<{
(e: 'search', value: string): void
(e: 'clear'): void
}>()
</script>
<style lang="scss" scoped>
.gi-input-search {
display: flex;
width: 100%;
> :deep(.arco-btn) {
flex-shrink: 0;
&:hover,
&:active {
z-index: 1;
}
}
> :deep(.arco-btn + .arco-btn) {
margin-left: -1px;
}
}
</style>
@@ -1,5 +0,0 @@
import InputSearch from './GiInputSearch.vue'
export type InputSearchInstance = InstanceType<typeof InputSearch>
export * from './type'
export { InputSearch as GiInputSearch }
@@ -1,5 +0,0 @@
export interface InputSearchProps {
placeholder?: string
disabled?: boolean
readonly?: boolean
}
@@ -1,16 +0,0 @@
<template>
<ul class="gi-option">
<slot></slot>
</ul>
</template>
<script setup lang="ts">
defineOptions({ name: 'GiOption' })
</script>
<style lang="scss" scoped>
.gi-option {
width: 100%;
min-width: 120px;
}
</style>
@@ -1,79 +0,0 @@
<!--
@file GiOptionItem 组件 - 选项列表项
@description 提供统一的选项列表项样式,支持图标和更多操作
-->
<template>
<li class="gi-option-item" :class="{ 'gi-option-item--more': props.more, 'gi-option-item--active': props.active }"
@click="handleClick">
<div class="gi-option-item__wrapper">
<span class="gi-option-item__icon">
<slot name="icon">
<Icon v-if="props.icon" :icon="props.icon" :width="16" :height="16" />
</slot>
</span>
<slot>
<span class="gi-option-item__label">{{ props.label }}</span>
</slot>
</div>
<IconRight v-if="props.more" />
</li>
</template>
<script setup lang="ts">
import type { OptionItemProps as Props } from './type'
import { Icon } from '@iconify/vue'
defineOptions({ name: 'GiOptionItem' })
const props = withDefaults(defineProps<Props>(), {
icon: '',
label: '',
more: false,
active: false
})
const emit = defineEmits<{
(e: 'click'): void
}>()
/** 处理点击事件 */
const handleClick = () => {
emit('click')
}
</script>
<style lang="scss" scoped>
.gi-option-item {
position: relative;
display: flex;
align-items: center;
height: 34px;
padding: 0 5px 0 10px;
font-size: 14px;
line-height: 34px;
color: var(--color-text-2);
cursor: pointer;
user-select: none;
&__wrapper {
display: flex;
align-items: center;
}
&__icon {
display: flex;
align-items: center;
margin-right: 8px;
}
&--active,
&:hover {
color: rgb(var(--primary-6));
background: var(--color-primary-light-1);
}
&--more {
justify-content: space-between;
}
}
</style>
@@ -1,7 +0,0 @@
import Option from './GiOption.vue'
import OptionItem from './GiOptionItem.vue'
export type OptionInstance = InstanceType<typeof Option>
export type OptionItemInstance = InstanceType<typeof OptionItem>
export * from './type'
export { Option as GiOption, OptionItem as GiOptionItem }
@@ -1,11 +0,0 @@
/** 组件属性定义 */
export interface OptionItemProps {
/** 图标名称 */
icon?: string
/** 选项文本 */
label?: string
/** 是否显示更多图标 */
more?: boolean
/** 是否激活状态 */
active?: boolean
}
@@ -1,192 +0,0 @@
<template>
<a-split v-model:size="size" class="gi-page-layout" :class="getClass" min="1px" max="600px" :disabled="!slots.left">
<template #first>
<div v-if="slots.left" class="gi-page-layout__left" :style="props.leftStyle">
<slot name="left"></slot>
</div>
</template>
<template #second>
<div v-if="slots.header" class="gi-page-layout__header" :style="props.headerStyle">
<slot name="header"></slot>
</div>
<div class="gi-page-layout__body" :style="props.bodyStyle">
<slot></slot>
</div>
</template>
<template v-if="props.collapsed || isMobile" #resize-trigger-icon>
<SplitButton :collapsed="parseInt(size) < 20" @click="handleClick"></SplitButton>
</template>
</a-split>
</template>
<script setup lang='ts'>
import type { PageLayoutProps as Props } from './type'
import { browse } from 'xe-utils'
import SplitButton from './SplitButton.vue'
defineOptions({ name: 'GiPageLayout' })
const props = withDefaults(defineProps<Props>(), {
size: '270px',
margin: false,
inner: false,
headerBordered: true,
leftStyle: () => ({}),
headerStyle: () => ({}),
bodyStyle: () => ({}),
collapsed: false,
bgTransparent: false
})
/** 组件插槽定义 */
defineSlots<{
header: () => void
left: () => void
default: () => void
}>()
const slots = useSlots()
const isMobile = browse().isMobile ?? false
const size = ref(isMobile ? '0px' : props.size)
const collapsing = ref(false)
const getClass = computed(() => {
return {
'gi-page-layout--disabled': !slots.left,
'gi-page-layout--margin': props.margin,
'gi-page-layout--inner': props.inner,
'gi-page-layout--has-header': slots.header,
'gi-page-layout--header-bordered': props.headerBordered,
'gi-page-layout--collapsing': collapsing.value,
'gi-page-layout--bg-transparent': props.bgTransparent
}
})
function handleClick() {
collapsing.value = true
setTimeout(() => {
collapsing.value = false
}, 300)
size.value = Number.parseInt(size.value) > 20 ? '0px' : props.size
}
</script>
<style lang='scss' scoped>
:deep(.arco-split-pane) {
display: flex;
flex-direction: column;
height: 100%;
overflow: hidden;
}
:deep(.arco-split-trigger) {
position: relative;
}
:deep(.arco-split-trigger-icon-wrapper) {
position: absolute;
top: 50%;
left: 50%;
z-index: 9;
width: 16px;
height: 100%;
user-select: none;
background-color: transparent;
transform: translate(-50%, -50%);
.arco-split-trigger-icon {
display: none;
}
&:hover,
&:active {
&::before {
width: 2px;
background-color: var(--color-primary-light-2);
}
}
&::before {
position: absolute;
top: 0;
left: 50%;
width: 1px;
height: 100%;
content: '';
background-color: var(--color-border-2);
transform: translateX(-50%);
}
}
.gi-page-layout {
box-sizing: border-box;
display: flex;
flex: 1;
width: auto;
height: 100%;
overflow: hidden;
background-color: var(--color-bg-1);
}
.gi-page-layout--bg-transparent {
background-color: transparent;
}
.gi-page-layout--margin {
margin: var(--margin);
}
.gi-page-layout--inner {
.gi-page-layout__header {
padding: 0;
}
.gi-page-layout__body {
padding-right: 0;
padding-bottom: 0;
padding-left: 0;
}
}
.gi-page-layout--header-bordered {
.gi-page-layout__header {
border-bottom: 1px solid var(--color-border);
}
}
.gi-page-layout--disabled {
:deep(> .arco-split-pane-first) {
display: none;
}
}
.gi-page-layout--collapsing {
:deep(> .arco-split-pane-first) {
transition: flex-basis 0.3s;
}
}
.gi-page-layout__left {
box-sizing: border-box;
display: flex;
flex-direction: column;
height: 100%;
padding: var(--padding);
overflow: hidden;
}
.gi-page-layout__header {
box-sizing: border-box;
padding: var(--padding);
padding-bottom: 0;
}
.gi-page-layout__body {
box-sizing: border-box;
display: flex;
flex: 1;
flex-direction: column;
padding: var(--padding);
overflow: hidden;
}
</style>
@@ -1,100 +0,0 @@
<!--
@file GiSplitButton 组件 - 分割面板切换按钮
@description 提供可折叠面板的切换按钮,支持多种样式和交互效果
-->
<template>
<div class="gi-split-button" :class="buttonClass" @click="handleClick">
<icon-right v-if="collapsed" :size="iconSize" />
<icon-left v-else :size="iconSize" />
</div>
</template>
<script setup lang="ts">
import { computed } from 'vue'
/** 按钮类型 */
type ButtonType = 'default' | 'circle'
/** 组件属性定义 */
interface Props {
/** 是否折叠状态 */
collapsed?: boolean
/** 按钮类型 */
type?: ButtonType
/** 图标大小 */
iconSize?: number
/** 是否禁用 */
disabled?: boolean
}
/** 组件事件定义 */
interface Emits {
(e: 'click'): void
(e: 'update:collapsed', value: boolean): void
}
const props = withDefaults(defineProps<Props>(), {
collapsed: false,
type: 'circle',
iconSize: 14,
disabled: false
})
const emit = defineEmits<Emits>()
/** 计算按钮类名 */
const buttonClass = computed(() => [
`gi-split-button--${props.type}`,
{
'is-collapsed': props.collapsed,
'is-disabled': props.disabled
}
])
/** 处理点击事件 */
const handleClick = () => {
if (props.disabled) return
emit('click')
emit('update:collapsed', !props.collapsed)
}
</script>
<style lang="scss" scoped>
.gi-split-button {
position: absolute;
top: 50%;
z-index: 2;
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
background-color: var(--color-bg-1);
border: 1px solid var(--color-border-2);
transform: translateY(-50%);
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
will-change: transform, background-color, border-color;
&.is-disabled {
pointer-events: none;
cursor: not-allowed;
opacity: 0.6;
}
&--default {
left: 0;
width: 18px;
height: 40px;
box-shadow: 2px 0 6px rgb(0 0 0 / 10%);
}
&--circle {
left: -4px;
width: 24px;
height: 24px;
overflow: hidden;
border-radius: 50%;
box-shadow: 0 4px 10px rgb(0 0 0 / 10%);
}
}
</style>
@@ -1,5 +0,0 @@
import PageLayout from './GiPageLayout.vue'
export type PageLayoutInstance = InstanceType<typeof PageLayout>
export * from './type'
export { PageLayout as GiPageLayout }
@@ -1,14 +0,0 @@
import type { CSSProperties } from 'vue'
/** 组件属性定义 */
export interface PageLayoutProps {
size?: string
margin?: boolean
inner?: boolean
headerBordered?: boolean
leftStyle?: CSSProperties
headerStyle?: CSSProperties
bodyStyle?: CSSProperties
collapsed?: boolean
bgTransparent?: boolean
}
@@ -1,440 +0,0 @@
<!--
@file GiTable 组件
@description 增强型表格组件,支持全屏、列设置、斑马纹、边框等功能
-->
<template>
<div class="gi-table" :class="{ 'gi-table--fullscreen': isFullscreen }">
<!-- 表格头部区域 -->
<a-row justify="space-between" align="center" class="g-row-tool">
<!-- 左侧标题区域 -->
<a-space wrap>
<slot name="custom-title">
<div class="gi-table__title">{{ props.title }}</div>
</slot>
</a-space>
<!-- 表格操作按钮组 -->
<a-space wrap>
<slot name="custom-extra"></slot>
<!-- 斑马纹开关 -->
<a-tooltip content="斑马纹">
<a-switch v-model="stripe" size="small" type="round" />
</a-tooltip>
<!-- 刷新按钮 -->
<a-tooltip content="刷新">
<a-button size="mini" class="g-hover-btn" @click="handleRefresh">
<template #icon><icon-refresh :size="18" /></template>
</a-button>
</a-tooltip>
<!-- 全屏按钮 -->
<a-tooltip content="全屏">
<a-button size="mini" class="g-hover-btn" @click="toggleFullscreen">
<template #icon>
<icon-fullscreen v-if="!isFullscreen" :size="18" />
<icon-fullscreen-exit v-else :size="18" />
</template>
</a-button>
</a-tooltip>
<!-- 边框显示按钮 -->
<a-tooltip content="显示边框">
<a-button size="mini" class="g-hover-btn" @click="toggleBorder">
<template #icon>
<Icon icon="custom:borders" :width="18" :height="18" />
</template>
</a-button>
</a-tooltip>
<!-- 表格尺寸设置 -->
<a-dropdown @select="handleSizeChange">
<a-tooltip content="表格尺寸">
<a-button size="mini" class="g-hover-btn">
<template #icon>
<Icon icon="custom:table-size" :width="17" :height="17" />
</template>
</a-button>
</a-tooltip>
<template #content>
<a-doption v-for="item in TABLE_SIZE_OPTIONS" :key="item.value" :value="item.value"
:active="item.value === size">
{{ item.label }}
</a-doption>
</template>
</a-dropdown>
<!-- 列设置按钮 -->
<a-popover v-if="showSettingColumnBtn" trigger="click" position="br"
:content-style="{ minWidth: '160px', padding: '6px 8px 10px' }">
<a-button type="primary" size="mini">
<template #icon><icon-settings /></template>
</a-button>
<template #content>
<!-- 列拖拽排序区域 -->
<div class="gi-table__draggable">
<VueDraggable :model-value="currentSettingColumns" :animation="150"
@update:model-value="(val) => { settingColumnList = val as TableSettingColumnItem[] }">
<div v-for="item in currentSettingColumns" :key="item.key" class="gi-table__draggable-item">
<div class="gi-table__draggable-item-move">
<icon-drag-dot-vertical />
</div>
<a-checkbox v-model:model-value="item.show" :disabled="item.disabled">
{{ item.title }}
</a-checkbox>
<div class="gi-table__draggable-item-fixed">
<span class="gi-table__pin-btn" :class="{ 'is-active': item.fixedLeft }"
@click.stop="toggleFixedLeft(item.key)">
<icon-pushpin />
</span>
<span class="gi-table__pin-btn gi-table__pin-btn--right" :class="{ 'is-active': item.fixedRight }"
@click.stop="toggleFixedRight(item.key)">
<icon-pushpin />
</span>
</div>
</div>
</VueDraggable>
</div>
<a-divider :margin="6" />
<a-row justify="center">
<a-button type="primary" size="mini" long @click="resetSettingColumns">
<template #icon><icon-refresh /></template>
<template #default>重置</template>
</a-button>
</a-row>
</template>
</a-popover>
</a-space>
</a-row>
<!-- 表格主体区域 -->
<div class="gi-table__container">
<a-table ref="tableRef" v-bind="tableProps" :stripe="stripe" :size="size" :bordered="{ cell: isBordered }"
:columns="visibleColumns" :data="data">
<template v-for="key in slotKeys" :key="key" #[key]="scope">
<slot :key="key" :name="key" v-bind="scope" />
</template>
</a-table>
</div>
</div>
</template>
<script setup lang="ts" generic="T extends TableData">
import type { DropdownInstance, TableColumnData, TableData, TableInstance } from '@arco-design/web-vue'
import type { TableProps, TableSettingColumnItem } from './type'
import { Icon } from '@iconify/vue'
import { omit } from 'lodash-es'
import { computed, ref, watch } from 'vue'
import { VueDraggable } from 'vue-draggable-plus'
defineOptions({ name: 'GiTable' })
// Props 默认值
const props = withDefaults(defineProps<Props>(), {
title: '',
disabledColumnKeys: () => [],
data: () => []
})
/** Emits 类型定义 */
const emit = defineEmits<{
(e: 'refresh'): void
}>()
/** Slots 类型定义 */
defineSlots<{
'th': (props: { column: TableColumnData }) => void
'thead': () => void
'empty': (props: { column: TableColumnData }) => void
'summary-cell': (props: { column: TableColumnData, record: T, rowIndex: number }) => void
'pagination-right': () => void
'pagination-left': () => void
'td': (props: { column: TableColumnData, record: T, rowIndex: number }) => void
'tr': (props: { record: T, rowIndex: number }) => void
'tbody': () => void
'drag-handle-icon': () => void
'footer': () => void
'expand-row': (props: { record: T }) => void
'expand-icon': (props: { record: T, expanded?: boolean }) => void
'columns': () => void
'custom-title': () => void
'custom-extra': () => void
[propsName: string]: (props: { key: string, record: T, column: TableColumnData, rowIndex: number }) => void
}>()
/** Props 类型定义 */
interface Props extends TableProps {
/** 表格标题 */
title?: string
/** 禁止控制显示隐藏的列 */
disabledColumnKeys?: string[]
/** 表格数据 */
data?: T[]
}
const slots = useSlots()
const attrs = useAttrs()
/** 插槽键名列表(性能优化:避免模板中重复计算) */
const slotKeys = computed(() => Object.keys(slots))
/** 表格属性计算 */
const tableProps = computed(() => {
return { ...attrs, ...omit(props, ['title', 'disabledColumnKeys']) }
})
/** 组件状态 */
const tableRef = useTemplateRef('tableRef')
const stripe = ref(false)
const size = ref<TableInstance['size']>('medium')
const isBordered = ref(true)
const isFullscreen = ref(false)
/** 表格尺寸选项 */
const TABLE_SIZE_OPTIONS = [
{ label: '迷你', value: 'mini' },
{ label: '小型', value: 'small' },
{ label: '中等', value: 'medium' },
{ label: '大型', value: 'large' }
] as const
/** 处理表格尺寸变更 */
const handleSizeChange: DropdownInstance['onSelect'] = (value) => {
if (value) {
size.value = value as TableInstance['size']
}
}
/** 处理表格刷新 */
const handleRefresh = () => {
emit('refresh')
}
/** 切换全屏状态 */
const toggleFullscreen = () => {
isFullscreen.value = !isFullscreen.value
}
/** 切换边框显示 */
const toggleBorder = () => {
isBordered.value = !isBordered.value
}
/** 列设置相关逻辑 */
const showSettingColumnBtn = computed(() => {
const columns = Array.isArray(props.columns) ? props.columns : undefined
return Boolean(columns?.length)
})
/** 获取列的 key */
const getColumnKey = (column: TableColumnData, index?: number) => {
if (column.dataIndex) return String(column.dataIndex)
if (typeof column.title === 'string' && column.title) return column.title
// 使用索引作为后备,确保唯一性
return `__column_${index ?? Date.now()}__`
}
/** 计算初始列设置列表 */
const initialSettingColumns = computed<TableSettingColumnItem[]>(() => {
if (!props.columns) return []
const columns = Array.isArray(props.columns) ? props.columns : []
return columns.map((column, index) => {
const key = getColumnKey(column, index)
const fixed = column.fixed
return {
key,
title: typeof column.title === 'string' ? column.title : '',
show: true,
disabled: props.disabledColumnKeys.includes(key),
fixedLeft: fixed === 'left',
fixedRight: fixed === 'right'
}
})
})
/** 用户修改后的列设置列表 */
const settingColumnList = ref<TableSettingColumnItem[]>([])
/** 检查列结构是否匹配 */
const isColumnStructureMatch = (userColumns: TableSettingColumnItem[], initialColumns: TableSettingColumnItem[]): boolean => {
if (userColumns.length === 0 || userColumns.length !== initialColumns.length) return false
const initialKeys = new Set(initialColumns.map((item) => item.key))
const userKeys = new Set(userColumns.map((item) => item.key))
return initialKeys.size === userKeys.size && [...initialKeys].every((key) => userKeys.has(key))
}
/** 列映射表(性能优化:避免在 visibleColumns 中重复创建) */
const columnMap = computed(() => {
if (!props.columns) return new Map<string, TableColumnData>()
const columns = Array.isArray(props.columns) ? props.columns : []
return new Map(columns.map((col, index) => [getColumnKey(col, index), col]))
})
/** 当前使用的列设置列表(自动处理列结构变化) */
const currentSettingColumns = computed(() => {
const isValid = isColumnStructureMatch(settingColumnList.value, initialSettingColumns.value)
return isValid ? settingColumnList.value : initialSettingColumns.value
})
/** 重置列设置 */
const resetSettingColumns = () => {
settingColumnList.value = [...initialSettingColumns.value]
}
/** 确保列设置列表已初始化(首次点击或拖拽前可能为空) */
const ensureSettingColumnList = () => {
if (settingColumnList.value.length === 0 && initialSettingColumns.value.length > 0) {
settingColumnList.value = initialSettingColumns.value.map((item) => ({ ...item }))
}
}
/** 切换列固定左侧:图标高亮且当前列固定到左侧 */
const toggleFixedLeft = (key: string) => {
ensureSettingColumnList()
settingColumnList.value = settingColumnList.value.map((item) =>
item.key === key
? { ...item, fixedLeft: !item.fixedLeft, fixedRight: false }
: item
)
}
/** 切换列固定右侧:图标高亮且当前列固定到右侧 */
const toggleFixedRight = (key: string) => {
ensureSettingColumnList()
settingColumnList.value = settingColumnList.value.map((item) =>
item.key === key
? { ...item, fixedRight: !item.fixedRight, fixedLeft: false }
: item
)
}
/** 监听 columns 变化,自动重置列设置 */
watch(() => props.columns, () => {
// 列结构变化时,如果用户设置不匹配,自动重置
if (!isColumnStructureMatch(settingColumnList.value, initialSettingColumns.value)) {
resetSettingColumns()
}
}, { deep: true })
/** 计算显示的列(含固定列设置):固定左 → 不固定 → 固定右 */
const visibleColumns = computed(() => {
if (!props.columns) return []
const shown = currentSettingColumns.value.filter((item) => item.show)
const leftFixed: typeof shown = []
const noFixed: typeof shown = []
const rightFixed: typeof shown = []
for (const item of shown) {
if (item.fixedLeft) leftFixed.push(item)
else if (item.fixedRight) rightFixed.push(item)
else noFixed.push(item)
}
const ordered = [...leftFixed, ...noFixed, ...rightFixed]
return ordered
.map((item) => {
const col = columnMap.value.get(item.key)
if (!col) return null
// 以列配置为准:未勾选固定时不再回退到 props 的 fixed,以便用户能取消固定
const fixed = item.fixedRight ? 'right' : item.fixedLeft ? 'left' : undefined
return { ...col, fixed }
})
.filter(Boolean) as TableColumnData[]
})
defineExpose({ tableRef })
</script>
<style lang="scss" scoped>
.gi-table {
display: flex;
flex: 1;
flex-direction: column;
overflow: hidden;
background: var(--color-bg-1);
&--fullscreen {
position: fixed;
inset: 0;
z-index: 1001;
padding: var(--padding);
}
&__container {
max-height: 100%;
overflow: hidden;
}
&__title {
font-size: 18px;
font-weight: 500;
line-height: 1.5;
color: var(--color-text-1);
}
&__draggable {
box-sizing: border-box;
max-height: 250px;
padding: 1px 0;
overflow: hidden auto;
}
&__draggable-item {
display: flex;
align-items: center;
cursor: pointer;
&:hover {
background-color: var(--color-fill-2);
}
&-move {
padding: 0 2px;
cursor: move;
}
&-fixed {
display: flex;
flex-shrink: 0;
gap: 4px;
align-items: center;
margin-left: auto;
}
:deep(.arco-checkbox) {
flex: 1;
min-width: 0;
font-size: 12px;
.arco-checkbox-icon {
width: 14px;
height: 14px;
}
}
}
&__pin-btn {
display: inline-flex;
align-items: center;
justify-content: center;
padding: 2px;
font-size: 14px;
color: var(--color-text-3);
cursor: pointer;
transition: color 0.2s;
&:hover {
color: var(--color-text-2);
}
&.is-active {
color: rgb(var(--primary-6));
}
&--right {
transform: scaleX(-1);
}
}
}
</style>
@@ -1,24 +0,0 @@
import type { TableInstance as ArcoTableInstance } from '@arco-design/web-vue'
import Table from './GiTable.vue'
export type * from './type'
/**
* 组件实例类型。
*
* ⚠️ 这里**不能**写 `InstanceType<typeof Table>`。
* `GiTable.vue` 是泛型 SFC(`<script setup generic="T extends TableData">`),
* 它的类型是一个泛型函数签名而不是构造函数,`InstanceType<>` 对它不成立,
* vue-tsc 会报 `TS2344: ... does not satisfy the constraint
* 'abstract new (...args: any) => any'`。
*
* 所以按 `defineExpose({ tableRef })` 的**真实形状**手工声明:
* 暴露出来的就是那一个内层 a-table 的实例(模板 ref 在暴露时会被解包)。
* 这比 `InstanceType` 推导出来的"全部 props + slots"更准确 —— 后者本来也是假的。
*/
export interface TableInstance {
/** 内层 a-table 的实例 */
tableRef: ArcoTableInstance | null
}
export { Table as GiTable }
@@ -1,53 +0,0 @@
import type { TableInstance } from '@arco-design/web-vue'
export type TableProps = {
columns?: TableInstance['$props']['columns']
data?: TableInstance['$props']['data']
bordered?: TableInstance['$props']['bordered']
hoverable?: TableInstance['$props']['hoverable']
stripe?: TableInstance['$props']['stripe']
size?: TableInstance['$props']['size']
tableLayoutFixed?: TableInstance['$props']['tableLayoutFixed']
loading?: TableInstance['$props']['loading']
rowSelection?: TableInstance['$props']['rowSelection']
expandable?: TableInstance['$props']['expandable']
scroll?: TableInstance['$props']['scroll']
pagination?: TableInstance['$props']['pagination']
pagePosition?: TableInstance['$props']['pagePosition']
indentSize?: TableInstance['$props']['indentSize']
rowKey?: TableInstance['$props']['rowKey']
showHeader?: TableInstance['$props']['showHeader']
virtualListProps?: TableInstance['$props']['virtualListProps']
spanMethod?: TableInstance['$props']['spanMethod']
spanAll?: TableInstance['$props']['spanAll']
loadMore?: TableInstance['$props']['loadMore']
filterIconAlignLeft?: TableInstance['$props']['filterIconAlignLeft']
hideExpandButtonOnEmpty?: TableInstance['$props']['hideExpandButtonOnEmpty']
rowClass?: TableInstance['$props']['rowClass']
draggable?: TableInstance['$props']['draggable']
rowNumber?: TableInstance['$props']['rowNumber']
columnResizable?: TableInstance['$props']['columnResizable']
summary?: TableInstance['$props']['summary']
summaryText?: TableInstance['$props']['summaryText']
summarySpanMethod?: TableInstance['$props']['summarySpanMethod']
selectedKeys?: TableInstance['$props']['selectedKeys']
defaultSelectedKeys?: TableInstance['$props']['defaultSelectedKeys']
expandedKeys?: TableInstance['$props']['expandedKeys']
defaultExpandedKeys?: TableInstance['$props']['defaultExpandedKeys']
defaultExpandAllRows?: TableInstance['$props']['defaultExpandAllRows']
stickyHeader?: TableInstance['$props']['stickyHeader']
scrollbar?: TableInstance['$props']['scrollbar']
showEmptyTree?: TableInstance['$props']['showEmptyTree']
}
/** 列设置项类型 */
export interface TableSettingColumnItem {
title: string
key: string
show: boolean
disabled: boolean
/** 固定左侧 */
fixedLeft?: boolean
/** 固定右侧 */
fixedRight?: boolean
}
@@ -1,291 +0,0 @@
<template>
<div class="gi-table-setting" :class="{ 'gi-table-setting--fullscreen': isFullscreen }">
<a-row justify="space-between" align="center" class="g-row-tool">
<a-space wrap>
<slot name="custom-title">
<div class="gi-table-setting__title">{{ title }}</div>
</slot>
</a-space>
<a-space wrap>
<slot name="custom-extra" />
<a-tooltip content="导出">
<a-button class="gi-table-setting__btn" type="text" size="mini" @click="emit('export')">
<template #icon><icon-download :size="18" /></template>
</a-button>
</a-tooltip>
<a-tooltip content="斑马纹">
<a-button class="gi-table-setting__btn" type="text" size="mini" @click="stripe = !stripe">
<template #icon><icon-brush :size="18" /></template>
</a-button>
</a-tooltip>
<a-tooltip content="刷新">
<a-button class="gi-table-setting__btn" type="text" size="mini" @click="emit('refresh')">
<template #icon><icon-refresh :size="18" /></template>
</a-button>
</a-tooltip>
<a-tooltip :content="isFullscreen ? '退出全屏' : '全屏'">
<a-button class="gi-table-setting__btn" type="text" size="mini" @click="toggleFullscreen">
<template #icon>
<icon-fullscreen v-if="!isFullscreen" :size="18" />
<icon-fullscreen-exit v-else :size="18" />
</template>
</a-button>
</a-tooltip>
<a-tooltip content="显示边框">
<a-button class="gi-table-setting__btn" type="text" size="mini" @click="toggleBorder">
<template #icon><icon-apps :size="18" /></template>
</a-button>
</a-tooltip>
<a-dropdown @select="handleSizeChange">
<a-tooltip content="表格尺寸">
<a-button class="gi-table-setting__btn" type="text" size="mini">
<template #icon>
<icon-font-colors :size="18" />
</template>
</a-button>
</a-tooltip>
<template #content>
<a-doption v-for="item in TABLE_SIZE_OPTIONS" :key="item.value" :value="item.value"
:active="item.value === size">
{{ item.label }}
</a-doption>
</template>
</a-dropdown>
<a-popover v-if="showSettingColumnBtn" trigger="click" position="br"
:content-style="{ minWidth: '160px', padding: '6px 8px 10px' }">
<a-button class="gi-table-setting__btn" type="text" size="mini">
<template #icon><icon-settings :size="18" /></template>
</a-button>
<template #content>
<div class="gi-table-setting__draggable">
<VueDraggable :model-value="currentSettingColumns" :animation="150"
@update:model-value="onSettingColumnsUpdate">
<div v-for="item in currentSettingColumns" :key="item.key" class="gi-table-setting__draggable-item">
<div class="gi-table-setting__draggable-item-move">
<icon-drag-dot-vertical />
</div>
<a-checkbox v-model:model-value="item.show" :disabled="item.disabled">
{{ item.title }}
</a-checkbox>
<div class="gi-table-setting__draggable-item-fixed">
<span class="gi-table-setting__pin-btn" :class="{ 'is-active': item.fixedLeft }"
@click.stop="toggleFixedLeft(item.key)">
<icon-pushpin />
</span>
<span class="gi-table-setting__pin-btn gi-table-setting__pin-btn--right"
:class="{ 'is-active': item.fixedRight }" @click.stop="toggleFixedRight(item.key)">
<icon-pushpin />
</span>
</div>
</div>
</VueDraggable>
</div>
<a-divider :margin="6" />
<a-row justify="center">
<a-button type="primary" size="mini" long @click="resetSettingColumns">
<template #icon><icon-refresh /></template>
<template #default>重置</template>
</a-button>
</a-row>
</template>
</a-popover>
</a-space>
</a-row>
<div class="gi-table-setting__body">
<slot :setting-columns="settingColumns" :is-fullscreen="isFullscreen" :table-props="tableProps" />
</div>
</div>
</template>
<script setup lang="ts">
import type { DropdownInstance, TableColumnData, TableInstance } from '@arco-design/web-vue'
import type { GiTableSettingProps, TableSettingColumnListItem } from './type'
import { computed, ref } from 'vue'
import { VueDraggable } from 'vue-draggable-plus'
import { useTableColumnSetting } from './useTableColumnSetting'
defineOptions({ name: 'GiTableSetting' })
const props = withDefaults(defineProps<GiTableSettingProps>(), {
title: '',
columns: () => [],
disabledColumnKeys: () => []
})
const emit = defineEmits<{
refresh: []
export: []
}>()
defineSlots<{
'custom-title'?: () => unknown
'custom-extra'?: () => unknown
'default': (props: {
settingColumns: TableColumnData[]
isFullscreen: boolean
tableProps: {
stripe: boolean
bordered: { cell: boolean }
size: TableInstance['size']
}
}) => unknown
}>()
const stripe = ref(false)
const size = ref<TableInstance['size']>('medium')
const isBordered = ref(true)
const isFullscreen = ref(false)
const TABLE_SIZE_OPTIONS = [
{ label: '迷你', value: 'mini' },
{ label: '小型', value: 'small' },
{ label: '中等', value: 'medium' },
{ label: '大型', value: 'large' }
] as const
const tableProps = computed(() => ({
stripe: stripe.value,
bordered: { cell: isBordered.value },
size: size.value
}))
const {
showSettingColumnBtn,
currentSettingColumns,
settingColumnList,
settingColumns,
resetSettingColumns,
toggleFixedLeft,
toggleFixedRight
} = useTableColumnSetting({
columns: () => props.columns,
disabledColumnKeys: () => props.disabledColumnKeys
})
function onSettingColumnsUpdate(val: TableSettingColumnListItem[]) {
settingColumnList.value = val
}
const handleSizeChange: DropdownInstance['onSelect'] = (value) => {
if (value) {
size.value = value as TableInstance['size']
}
}
function toggleFullscreen() {
isFullscreen.value = !isFullscreen.value
}
function toggleBorder() {
isBordered.value = !isBordered.value
}
</script>
<style lang="scss" scoped>
.gi-table-setting {
display: flex;
flex: 1;
flex-direction: column;
min-height: 0;
overflow: hidden;
background: var(--color-bg-1);
&--fullscreen {
position: fixed;
inset: 0;
z-index: 1001;
box-sizing: border-box;
padding: var(--padding);
}
&__btn {
color: var(--color-text-1);
}
&__title {
font-size: 18px;
font-weight: 500;
line-height: 1.5;
color: var(--color-text-1);
}
&__body {
flex: 1;
min-height: 0;
overflow: hidden;
}
&__draggable {
box-sizing: border-box;
max-height: 250px;
padding: 1px 0;
overflow: hidden auto;
}
&__draggable-item {
display: flex;
align-items: center;
cursor: pointer;
&:hover {
background-color: var(--color-fill-2);
}
&-move {
padding: 0 2px;
cursor: move;
}
&-fixed {
display: flex;
flex-shrink: 0;
gap: 4px;
align-items: center;
margin-left: auto;
}
:deep(.arco-checkbox) {
flex: 1;
min-width: 0;
font-size: 12px;
.arco-checkbox-icon {
width: 14px;
height: 14px;
}
}
}
&__pin-btn {
display: inline-flex;
align-items: center;
justify-content: center;
padding: 2px;
font-size: 14px;
color: var(--color-text-3);
cursor: pointer;
transition: color 0.2s;
&:hover {
color: var(--color-text-2);
}
&.is-active {
color: rgb(var(--primary-6));
}
&--right {
transform: scaleX(-1);
}
}
}
</style>
@@ -1,5 +0,0 @@
import TableSetting from './GiTableSetting.vue'
export type * from './type'
export type TableSettingInstance = InstanceType<typeof TableSetting>
export { TableSetting as GiTableSetting }
@@ -1,22 +0,0 @@
import type { TableInstance } from '@arco-design/web-vue'
export interface GiTableSettingProps {
/** 工具栏标题 */
title?: string
/** 列配置(用于列设置) */
columns?: TableInstance['columns']
/** 禁止控制显示隐藏的列 key */
disabledColumnKeys?: string[]
}
/** 列设置项类型 */
export interface TableSettingColumnListItem {
title: string
key: string
show: boolean
disabled: boolean
/** 固定左侧 */
fixedLeft?: boolean
/** 固定右侧 */
fixedRight?: boolean
}
@@ -1,141 +0,0 @@
import type { TableColumnData, TableInstance } from '@arco-design/web-vue'
import type { MaybeRefOrGetter } from 'vue'
import type { TableSettingColumnListItem } from './type'
import { computed, ref, toValue, watch } from 'vue'
export interface UseTableColumnSettingOptions {
columns: MaybeRefOrGetter<TableInstance['columns'] | undefined>
disabledColumnKeys?: MaybeRefOrGetter<string[]>
}
/** 获取列的 key */
export function getTableColumnKey(column: TableColumnData, index?: number) {
if (column.dataIndex) return String(column.dataIndex)
if (typeof column.title === 'string' && column.title) return column.title
return `__column_${index ?? Date.now()}__`
}
/** 表格列设置:显隐、排序、固定 */
export function useTableColumnSetting(options: UseTableColumnSettingOptions) {
const showSettingColumnBtn = computed(() => {
const columns = Array.isArray(toValue(options.columns)) ? toValue(options.columns) : undefined
return Boolean(columns?.length)
})
const initialSettingColumns = computed<TableSettingColumnListItem[]>(() => {
const raw = toValue(options.columns)
if (!raw) return []
const columns = Array.isArray(raw) ? raw : []
return columns.map((column, index) => {
const key = getTableColumnKey(column, index)
const fixed = column.fixed
const disabledKeys = toValue(options.disabledColumnKeys) ?? []
return {
key,
title: typeof column.title === 'string' ? column.title : '',
show: true,
disabled: disabledKeys.includes(key),
fixedLeft: fixed === 'left',
fixedRight: fixed === 'right'
}
})
})
const settingColumnList = ref<TableSettingColumnListItem[]>([])
const isColumnStructureMatch = (
userColumns: TableSettingColumnListItem[],
initialColumns: TableSettingColumnListItem[]
): boolean => {
if (userColumns.length === 0 || userColumns.length !== initialColumns.length) return false
const initialKeys = new Set(initialColumns.map((item) => item.key))
const userKeys = new Set(userColumns.map((item) => item.key))
return initialKeys.size === userKeys.size && [...initialKeys].every((key) => userKeys.has(key))
}
const columnMap = computed(() => {
const raw = toValue(options.columns)
if (!raw) return new Map<string, TableColumnData>()
const columns = Array.isArray(raw) ? raw : []
return new Map(columns.map((col, index) => [getTableColumnKey(col, index), col]))
})
const currentSettingColumns = computed(() => {
const isValid = isColumnStructureMatch(settingColumnList.value, initialSettingColumns.value)
return isValid ? settingColumnList.value : initialSettingColumns.value
})
const resetSettingColumns = () => {
settingColumnList.value = [...initialSettingColumns.value]
}
const ensureSettingColumnList = () => {
if (settingColumnList.value.length === 0 && initialSettingColumns.value.length > 0) {
settingColumnList.value = initialSettingColumns.value.map((item) => ({ ...item }))
}
}
const toggleFixedLeft = (key: string) => {
ensureSettingColumnList()
settingColumnList.value = settingColumnList.value.map((item) =>
item.key === key
? { ...item, fixedLeft: !item.fixedLeft, fixedRight: false }
: item
)
}
const toggleFixedRight = (key: string) => {
ensureSettingColumnList()
settingColumnList.value = settingColumnList.value.map((item) =>
item.key === key
? { ...item, fixedRight: !item.fixedRight, fixedLeft: false }
: item
)
}
watch(
() => toValue(options.columns),
() => {
if (!isColumnStructureMatch(settingColumnList.value, initialSettingColumns.value)) {
resetSettingColumns()
}
},
{ deep: true }
)
const settingColumns = computed(() => {
const raw = toValue(options.columns)
if (!raw) return []
const shown = currentSettingColumns.value.filter((item) => item.show)
const leftFixed: typeof shown = []
const noFixed: typeof shown = []
const rightFixed: typeof shown = []
for (const item of shown) {
if (item.fixedLeft) leftFixed.push(item)
else if (item.fixedRight) rightFixed.push(item)
else noFixed.push(item)
}
const ordered = [...leftFixed, ...noFixed, ...rightFixed]
return ordered
.map((item) => {
const col = columnMap.value.get(item.key)
if (!col) return null
const fixed = item.fixedRight ? 'right' : item.fixedLeft ? 'left' : undefined
return { ...col, fixed }
})
.filter(Boolean) as TableColumnData[]
})
return {
showSettingColumnBtn,
currentSettingColumns,
settingColumnList,
settingColumns,
resetSettingColumns,
toggleFixedLeft,
toggleFixedRight
}
}
-135
View File
@@ -1,135 +0,0 @@
/**
* @file GiTag 组件 - 提供多样化的标签展示
* @description 支持多种样式类型、状态、颜色和大小的标签组件
*/
import type { CSSProperties, PropType } from 'vue'
import type { TagProps as Props } from './type'
import { computed, defineComponent } from 'vue'
import './tag.scss'
/** 基础颜色映射表 */
const BASE_COLORS: Record<string, string> = {
red: '#FF0000',
orangered: '#f77234',
orange: '#ff7d00',
gold: '#f7ba1e',
lime: '#9fdb1d',
green: '#00b42a',
cyan: '#14c9c9',
blue: '#3491fa',
purple: '#722ed1',
pink: '#f5319d',
gray: '#86909c'
} as const
export default defineComponent({
name: 'GiTag',
props: {
type: {
type: String as PropType<Props['type']>,
default: 'light'
},
status: {
type: String as PropType<Props['status']>,
default: 'primary'
},
color: {
type: String as PropType<Props['color'] | string>,
default: ''
},
size: {
type: String as PropType<Props['size']>,
default: 'small'
},
closable: {
type: Boolean,
default: false
}
},
emits: ['click', 'close'],
setup(props: Props, { slots, emit }) {
/**
* 将十六进制颜色转换为 RGB 对象
* @param hex - 十六进制颜色值
*/
const hexToRgb = (hex: string) => {
const cleanHex = hex.startsWith('#') ? hex.slice(1) : hex
return {
r: Number.parseInt(cleanHex.slice(0, 2), 16),
g: Number.parseInt(cleanHex.slice(2, 4), 16),
b: Number.parseInt(cleanHex.slice(4, 6), 16)
}
}
/** 计算标签的 class */
const className = computed(() => {
return [
'gi-tag',
props.type && `gi-tag__type--${props.type}`,
props.size && `gi-tag__size--${props.size}`,
props.status && `gi-tag__status--${props.status}`
].filter(Boolean)
})
/** 计算标签的样式 */
const calcStyle = computed((): CSSProperties => {
if (!props.color) return {}
const color = BASE_COLORS[props.color as string] || props.color
const { r, g, b } = hexToRgb(color)
const style: CSSProperties = {}
switch (props.type) {
case 'light':
style.color = color
style.backgroundColor = `rgba(${r}, ${g}, ${b}, 0.1)`
style['--tag-close-hover-bg-color'] = color
break
case 'dark':
style.color = '#fff'
style.backgroundColor = color
style['--tag-close-hover-color'] = color
style['--tag-close-hover-bg-color'] = 'rgba(255, 255, 255, 0.9)'
break
case 'outline':
style.color = color
style.backgroundColor = 'transparent'
style.borderColor = color
style['--tag-close-hover-bg-color'] = color
break
case 'light-outline':
style.color = color
style.backgroundColor = `rgba(${r}, ${g}, ${b}, 0.1)`
style.borderColor = `rgba(${r}, ${g}, ${b}, 0.2)`
style['--tag-close-hover-bg-color'] = color
break
}
return style
})
/** 点击标签事件处理 */
const handleClick = () => emit('click')
/** 关闭标签事件处理 */
const handleClose = (event: MouseEvent) => {
event.stopPropagation()
emit('close')
}
/** 关闭图标组件 */
const CloseIcon = props.closable && (
<span class="gi-tag-close-btn" onClick={handleClose}>
<icon-close class="close-icon" />
</span>
)
return () => (
<span class={className.value} style={calcStyle.value} onClick={handleClick}>
{slots.default?.()}
{CloseIcon}
</span>
)
}
})
@@ -1,5 +0,0 @@
import Tag from './GiTag.tsx'
export type TagInstance = InstanceType<typeof Tag>
export * from './type'
export { Tag as GiTag }
-166
View File
@@ -1,166 +0,0 @@
$status: primary, success, warning, danger;
$tag-size-mini-height: 20px;
$tag-size-small-height: 22px;
$tag-size-large-height: 24px;
$tag-size-mini-padding: 0 6px;
$tag-size-small-padding: 0 8px;
$tag-size-large-padding: 0 10px;
.gi-tag {
box-sizing: border-box;
display: inline-flex;
align-items: center;
justify-content: center;
height: $tag-size-small-height;
padding: $tag-size-small-padding;
font-size: 12px;
line-height: 1;
white-space: nowrap;
cursor: pointer;
border-radius: 3px;
}
.gi-tag-close-btn {
position: relative;
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: center;
width: 16px;
height: 16px;
margin-left: 4px;
cursor: pointer;
background-color: transparent;
border-radius: var(--border-radius-circle);
transition: background-color 0.1s cubic-bezier(0, 0, 1, 1);
.close-icon {
z-index: 9;
width: 12px;
height: 12px;
}
}
.gi-tag__size--mini {
height: $tag-size-mini-height;
padding: $tag-size-mini-padding;
.gi-tag-close-btn {
.close-icon {
width: 10px;
height: 10px;
}
&::before {
width: 14px;
height: 14px;
}
}
}
.gi-tag__size--small {
height: $tag-size-small-height;
padding: $tag-size-small-padding;
}
.gi-tag__size--large {
height: $tag-size-large-height;
padding: $tag-size-small-padding;
}
.gi-tag__type--light {
color: #fff;
@each $i in $status {
&.gi-tag__status--#{$i}
{
color: rgb(var(--#{$i}-6));
background-color: rgb(var(--#{$i}-1));
--tag-close-hover-color: #fff;
--tag-close-hover-bg-color: rgb(var(--#{$i}-6));
.gi-tag-close-btn {
&:hover {
color: var(--tag-close-hover-color);
background-color: var(--tag-close-hover-bg-color);
}
}
}
}
}
.gi-tag__type--dark {
color: #fff;
@each $i in $status {
&.gi-tag__status--#{$i}
{
background-color: rgb(var(--#{$i}-6));
--tag-close-hover-color: rgb(var(--#{$i}-6));
--tag-close-hover-bg-color: rgb(255 255 255 / 90%);
.gi-tag-close-btn {
&:hover {
color: var(--tag-close-hover-color);
background-color: var(--tag-close-hover-bg-color);
}
}
}
}
}
.gi-tag__type--outline {
background: transparent;
border-style: solid;
border-width: 1px;
@each $i in $status {
&.gi-tag__status--#{$i}
{
color: rgb(var(--#{$i}-6));
border-color: rgb(var(--#{$i}-6));
--tag-close-hover-color: #fff;
--tag-close-hover-bg-color: rgb(var(--#{$i}-6));
.gi-tag-close-btn {
&:hover {
color: var(--tag-close-hover-color);
background-color: var(--tag-close-hover-bg-color);
}
}
}
}
}
.gi-tag__type--light-outline {
border-style: solid;
border-width: 1px;
@each $i in $status {
&.gi-tag__status--#{$i}
{
color: rgb(var(--#{$i}-6));
background-color: rgb(var(--#{$i}-1));
border-color: rgb(var(--#{$i}-2));
--tag-close-hover-color: #fff;
--tag-close-hover-bg-color: rgb(var(--#{$i}-6));
.gi-tag-close-btn {
&:hover {
color: var(--tag-close-hover-color);
background-color: var(--tag-close-hover-bg-color);
}
}
}
}
}
-13
View File
@@ -1,13 +0,0 @@
/** 组件属性定义 */
export interface TagProps {
/** 标签类型 */
type?: 'dark' | 'light' | 'outline' | 'light-outline'
/** 标签状态 */
status?: 'primary' | 'success' | 'warning' | 'danger' | 'info'
/** 自定义颜色,支持预设颜色名或十六进制颜色值 */
color?: 'red' | 'orangered' | 'orange' | 'gold' | 'lime' | 'green' | 'cyan' | 'blue' | 'purple' | 'pink' | 'gray' | string
/** 标签尺寸 */
size?: 'mini' | 'small' | 'large'
/** 是否可关闭 */
closable?: boolean
}
@@ -1,74 +0,0 @@
<template>
<a-select
v-model="model"
class="gi-tenant-picker"
:placeholder="props.placeholder"
:loading="loading"
:disabled="props.disabled"
:style="{ width: props.width }"
allow-search
allow-clear
>
<a-option v-for="t in options" :key="t.id" :value="t.id" :disabled="t.status === 0">
{{ t.tenantName }}({{ t.tenantCode }}){{ t.status === 0 ? ' · 已停用' : '' }}
</a-option>
</a-select>
</template>
<script setup lang="ts">
import type { TenantVO } from '@/apis/xt/tenant'
import { getTenantList } from '@/apis/xt/tenant'
/**
* 「选择学校」——平台运营的当前租户。
*
* 为什么要有这个东西:平台运营是跨租户身份,服务端对它的租户过滤是**关掉的**,
* 所以它必须**先指明看哪所学校**,否则「组织架构」「账号管理」会拿到所有租户混在一起的数据。
* 选中的值由页面带进请求头 `X-Tenant-Id`(见 `@/apis/xt/acting-tenant`)。
*
* ⚠️ 只有平台运营的页面才渲染它 —— 学校管理员的租户由 token 决定,给他一个
* "选择学校"的下拉框是纯粹的困惑(而且服务端会忽略他传的值)。
*
* ⚠️ 租户列表接口只对平台运营开放(学校管理员调它得 40301),所以本组件
* **不要**在非平台页面里渲染。
*/
defineOptions({ name: 'GiTenantPicker' })
const model = defineModel<number | undefined>({ default: undefined })
const props = withDefaults(defineProps<{
placeholder?: string
disabled?: boolean
width?: string
}>(), {
placeholder: '选择学校',
disabled: false,
width: '100%'
})
const loading = ref(false)
const options = ref<TenantVO[]>([])
async function load() {
loading.value = true
try {
// 一期租户规模是"几十所"量级(接口上限 200),一次取完比做分页下拉简单得多。
// 已停用的也列出来但不可选 —— 服务端会拒("目标单位不存在或已停用"),
// 与其让人选完才知道,不如在选择时就说明。
const res = await getTenantList({ pageNum: 1, pageSize: 200 })
options.value = res.data?.list ?? []
} finally {
loading.value = false
}
}
onMounted(load)
defineExpose({ reload: load })
</script>
<style lang="scss" scoped>
.gi-tenant-picker {
min-width: 180px;
}
</style>
@@ -1,16 +0,0 @@
<template>
<a-button size="mini" class="g-hover-btn" @click="toggleTheme">
<template #icon>
<icon-sun-fill v-if="!isDark" :size="18" />
<icon-moon-fill v-else :size="18" />
</template>
</a-button>
</template>
<script setup lang="ts">
import { useTheme } from '@/hooks'
defineOptions({ name: 'GiThemeBtn' })
const { isDark, toggleTheme } = useTheme()
</script>
@@ -1,4 +0,0 @@
import ThemeBtn from './GiThemeBtn.vue'
export type ThemeBtnInstance = InstanceType<typeof ThemeBtn>
export { ThemeBtn as GiThemeBtn }
@@ -1,45 +0,0 @@
<template>
<a-spin :loading="loading" class="g-full-column">
<a-input-search class="g-mb" placeholder="请输入关键词" allow-clear />
<a-scrollbar style="height: 100%; overflow: auto" outer-style="flex: 1;overflow: hidden">
<a-tree ref="treeRef" show-line size="mini" :data="(treeData as unknown as TreeNodeData[])"
:field-names="{ key: 'id', title: 'name' }" @select="select">
</a-tree>
</a-scrollbar>
</a-spin>
</template>
<script lang="ts" setup>
import type { TreeNodeData } from '@arco-design/web-vue'
import { getCateTree } from '@/apis/cate'
const emit = defineEmits<{
(e: 'node-click'): void
}>()
const treeRef = useTemplateRef('treeRef')
const loading = ref(false)
const treeData = ref<any[]>([])
// 获取分类树
const getTreeData = async () => {
try {
loading.value = true
const res = await getCateTree()
treeData.value = res.data
nextTick(() => {
treeRef.value?.expandAll()
})
} finally {
loading.value = false
}
}
getTreeData()
const select = () => {
emit('node-click')
}
</script>
<style lang="scss" scoped></style>
@@ -1,93 +0,0 @@
<template>
<GiPageLayout bg-transparent>
<template #left>
<Tree @node-click="search" />
</template>
<a-row justify="end" class="g-row-tool">
<a-space wrap>
<a-input v-model="searchParams.username" placeholder="输入用户名搜索" allow-clear style="max-width: 250px">
</a-input>
<a-button type="primary" @click="search">
<template #icon><icon-search /></template>
<span>查询</span>
</a-button>
<a-button @click="reset">重置</a-button>
</a-space>
</a-row>
<a-table class="g-table" row-key="id" :loading="loading" :bordered="{ cell: true }" :columns="columns"
:data="tableData" :scroll="{ x: '100%', y: '100%' }"
:row-selection="{ type: props.multiple ? 'checkbox' : 'radio', showCheckedAll: true }" :pagination="pagination"
@select="select" @select-all="selectAll">
</a-table>
</GiPageLayout>
</template>
<script setup lang="tsx">
import type { TableColumnData } from '@arco-design/web-vue'
import { baseAPI } from '@/apis/person'
import { GiCellStatus } from '@/components/index'
import { useTable } from '@/hooks'
import Tree from './Tree.vue'
interface Props {
multiple?: boolean
queryParams?: Record<string, any>
}
const props = withDefaults(defineProps<Props>(), {
multiple: false,
queryParams: () => ({})
})
const searchParams = reactive({
username: ''
})
const columns = [
{
title: '序号',
width: 68,
align: 'center',
render: ({ rowIndex }) => (<span>{rowIndex + 1}</span>)
},
{
title: '姓名',
dataIndex: 'name',
width: 100
},
{
title: '创建时间',
dataIndex: 'createTime',
width: 180
},
{
title: '地址',
dataIndex: 'address',
ellipsis: true,
tooltip: true
},
{
title: '状态',
width: 100,
align: 'center',
render: ({ record }) => {
return <GiCellStatus status={record.status} />
}
}
] as TableColumnData[]
const { loading, tableData, pagination, search, select, selectAll, getSelectedData } = useTable({
listAPI: (page) => baseAPI.getList({ ...page, ...searchParams, ...props.queryParams }),
immediate: true
})
const reset = () => {
searchParams.username = ''
search()
}
defineExpose({ getSelectedData })
</script>
<style lang="scss" scoped></style>
@@ -1,89 +0,0 @@
<template>
<GiPageLayout bg-transparent>
<a-row justify="end" class="g-row-tool">
<a-space wrap>
<a-input v-model="searchParams.username" placeholder="输入用户名搜索" allow-clear style="max-width: 250px">
</a-input>
<a-button type="primary" @click="search">
<template #icon><icon-search /></template>
<span>查询</span>
</a-button>
<a-button @click="reset">重置</a-button>
</a-space>
</a-row>
<a-table class="g-table" row-key="id" :loading="loading" :bordered="{ cell: true }" :columns="columns"
:data="tableData" :scroll="{ x: '100%', y: '100%' }"
:row-selection="{ type: props.multiple ? 'checkbox' : 'radio', showCheckedAll: true }" :pagination="pagination"
@select="select" @select-all="selectAll">
</a-table>
</GiPageLayout>
</template>
<script setup lang="tsx">
import type { TableColumnData } from '@arco-design/web-vue'
import { baseAPI } from '@/apis/person'
import { GiCellStatus } from '@/components/index'
import { useTable } from '@/hooks'
interface Props {
multiple?: boolean
queryParams?: Record<string, any>
}
const props = withDefaults(defineProps<Props>(), {
multiple: false,
queryParams: () => ({})
})
const searchParams = reactive({
username: ''
})
const columns = [
{
title: '序号',
width: 68,
align: 'center',
render: ({ rowIndex }) => (<span>{rowIndex + 1}</span>)
},
{
title: '姓名',
dataIndex: 'name',
width: 180
},
{
title: '创建时间',
dataIndex: 'createTime',
width: 180
},
{
title: '地址',
dataIndex: 'address',
ellipsis: true,
tooltip: true
},
{
title: '状态',
width: 100,
align: 'center',
render: ({ record }) => {
return <GiCellStatus status={record.status} />
}
}
] as TableColumnData[]
const { loading, tableData, pagination, search, select, selectAll, getSelectedData } = useTable({
listAPI: (page) => baseAPI.getList({ ...page, ...searchParams, ...props.queryParams }),
immediate: true
})
const reset = () => {
searchParams.username = ''
search()
}
defineExpose({ getSelectedData })
</script>
<style lang="scss" scoped></style>
@@ -1,16 +0,0 @@
import type { ListItem as UserListItem } from '@/apis/person'
import { createSelectDialog } from '@/utils/createSelectDialog'
import TreeUserList from './TreeUserList/index.vue'
import UserList from './UserList/index.vue'
/** 选择用户列表的对话框 */
export const SelectUserListDialog = createSelectDialog<UserListItem[]>({
title: '选择用户',
component: UserList
})
/** 左树右表的对话框 */
export const SelectTreeUserListDialog = createSelectDialog<UserListItem[]>({
title: '左树右表对话框示例',
component: TreeUserList
})
@@ -1,625 +0,0 @@
<template>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 500">
<g id="freepik--Floor--inject-70">
<ellipse id="freepik--floor--inject-70" cx="250" cy="384.61" rx="209.73" ry="94.79" style="fill: #f5f5f5">
</ellipse>
</g>
<g id="freepik--Shadows--inject-70">
<ellipse id="freepik--Shadow--inject-70" cx="352.36" cy="395.73" rx="56.05" ry="32.36" style="fill: #e0e0e0">
</ellipse>
<path id="freepik--shadow--inject-70"
d="M91.71,412.52c-9.53,5.57-9.53,14.59,0,20.15s25,5.56,34.51,0,9.53-14.58,0-20.15S101.24,407,91.71,412.52Z"
style="fill: #e0e0e0"></path>
</g>
<g id="freepik--Door--inject-70">
<g id="freepik--Bricks--inject-70">
<path d="M103.87,225.91v3.46c0,1.09.77,1.53,1.71,1l3.34-1.92V221L105.58,223A3.78,3.78,0,0,0,103.87,225.91Z"
style="fill: #e0e0e0"></path>
<path d="M93.28,223v3.45c0,1.09.77,1.53,1.71,1l13.93-8V212L95,220A3.78,3.78,0,0,0,93.28,223Z"
style="fill: #e0e0e0"></path>
<path
d="M100.82,262.05,85,271.18a3.8,3.8,0,0,0-1.71,3v3.46c0,1.09.77,1.53,1.71,1l15.82-9.13a3.78,3.78,0,0,0,1.71-3V263C102.53,261.94,101.76,261.5,100.82,262.05Z"
style="fill: #e0e0e0"></path>
<path d="M108.92,302.88l-13.93,8a3.78,3.78,0,0,0-1.71,3v3.46c0,1.09.77,1.53,1.71,1l13.93-8Z"
style="fill: #e0e0e0"></path>
<path d="M93.28,186.59V190c0,1.09.77,1.53,1.71,1l13.93-8v-7.4l-13.93,8A3.78,3.78,0,0,0,93.28,186.59Z"
style="fill: #e0e0e0"></path>
<path
d="M77.44,295.91v3.46c0,1.09.76,1.53,1.71,1L95,291.23a3.77,3.77,0,0,0,1.71-3v-3.46c0-1.09-.76-1.53-1.71-1L79.15,293A3.77,3.77,0,0,0,77.44,295.91Z"
style="fill: #e0e0e0"></path>
<path d="M93.28,259.32v3.46c0,1.09.77,1.53,1.71,1l13.93-8v-7.41L95,256.37A3.78,3.78,0,0,0,93.28,259.32Z"
style="fill: #e0e0e0"></path>
<path
d="M91.94,318.09v-3.45c0-1.09-.76-1.54-1.71-1l-15.82,9.13a3.8,3.8,0,0,0-1.71,3v3.46c0,1.09.77,1.53,1.71,1l15.82-9.14A3.75,3.75,0,0,0,91.94,318.09Z"
style="fill: #e0e0e0"></path>
<path
d="M92,176.33,76.2,185.46a3.8,3.8,0,0,0-1.71,3v3.46c0,1.09.77,1.53,1.71,1L92,183.74a3.8,3.8,0,0,0,1.71-3v-3.46C93.73,176.23,93,175.79,92,176.33Z"
style="fill: #e0e0e0"></path>
<path
d="M100.82,189.31,85,198.44a3.8,3.8,0,0,0-1.71,3v3.46c0,1.09.77,1.53,1.71,1l15.82-9.14a3.78,3.78,0,0,0,1.71-3v-3.46C102.53,189.2,101.76,188.76,100.82,189.31Z"
style="fill: #e0e0e0"></path>
<path
d="M100.82,225.68,85,234.81a3.8,3.8,0,0,0-1.71,3v3.46c0,1.09.77,1.53,1.71,1l15.82-9.13a3.78,3.78,0,0,0,1.71-3v-3.46C102.53,225.57,101.76,225.13,100.82,225.68Z"
style="fill: #e0e0e0"></path>
<path
d="M85,333.14,100.82,324a3.8,3.8,0,0,0,1.71-3v-3.46c0-1.09-.77-1.53-1.71-1L85,325.73a3.8,3.8,0,0,0-1.71,3v3.46C83.29,333.24,84.06,333.68,85,333.14Z"
style="fill: #e0e0e0"></path>
<path
d="M235.65,161.92v3.46a3.77,3.77,0,0,1-1.7,3l-3.34,1.93v-7.41l3.34-1.92C234.89,160.39,235.65,160.83,235.65,161.92Z"
style="fill: #e0e0e0"></path>
<path d="M230.61,281.09l13.93-8c.94-.55,1.7-.1,1.7,1v3.45a3.77,3.77,0,0,1-1.7,3l-13.93,8Z"
style="fill: #e0e0e0"></path>
<path
d="M246.24,146.74v3.46a3.79,3.79,0,0,1-1.7,3l-13.93,8v-7.4l13.93-8C245.48,145.21,246.24,145.65,246.24,146.74Z"
style="fill: #e0e0e0"></path>
<path
d="M238.71,194.54l15.82-9.14c.94-.54,1.71-.1,1.71,1v3.46a3.8,3.8,0,0,1-1.71,3l-15.82,9.13c-1,.55-1.71.1-1.71-1V197.5A3.75,3.75,0,0,1,238.71,194.54Z"
style="fill: #e0e0e0"></path>
<path d="M230.61,244.72l13.93-8c.94-.54,1.7-.1,1.7,1v3.45a3.77,3.77,0,0,1-1.7,3l-13.93,8Z"
style="fill: #e0e0e0"></path>
<path
d="M246.24,110.37v3.46a3.77,3.77,0,0,1-1.7,3l-13.93,8v-7.4l13.93-8C245.48,108.84,246.24,109.28,246.24,110.37Z"
style="fill: #e0e0e0"></path>
<path
d="M262.09,201.4v3.46a3.77,3.77,0,0,1-1.71,3L244.56,217c-.94.55-1.7.11-1.7-1v-3.46a3.77,3.77,0,0,1,1.7-3l15.82-9.13C261.33,199.87,262.09,200.31,262.09,201.4Z"
style="fill: #e0e0e0"></path>
<path
d="M246.24,183.11v3.46a3.79,3.79,0,0,1-1.7,3l-13.93,8v-7.4l13.93-8C245.48,181.58,246.24,182,246.24,183.11Z"
style="fill: #e0e0e0"></path>
<path
d="M247.59,240.33v-3.46a3.77,3.77,0,0,1,1.71-3l15.82-9.13c.94-.55,1.71-.11,1.71,1v3.46a3.78,3.78,0,0,1-1.71,3l-15.82,9.14C248.35,241.86,247.59,241.42,247.59,240.33Z"
style="fill: #e0e0e0"></path>
<path
d="M238.71,121.8l15.82-9.14c.94-.54,1.71-.1,1.71,1v3.46a3.8,3.8,0,0,1-1.71,3l-15.82,9.13c-1,.55-1.71.1-1.71-1v-3.46A3.75,3.75,0,0,1,238.71,121.8Z"
style="fill: #e0e0e0"></path>
<path
d="M238.71,158.17,254.53,149c.94-.54,1.71-.1,1.71,1v3.46a3.8,3.8,0,0,1-1.71,3l-15.82,9.13c-1,.55-1.71.1-1.71-1v-3.45A3.75,3.75,0,0,1,238.71,158.17Z"
style="fill: #e0e0e0"></path>
<path
d="M254.53,247.36l-15.82,9.14c-1,.54-1.71.1-1.71-1v-3.46a3.77,3.77,0,0,1,1.71-3L254.53,240c.94-.55,1.71-.1,1.71,1v3.46A3.78,3.78,0,0,1,254.53,247.36Z"
style="fill: #e0e0e0"></path>
<path d="M230.61,299.27l13.93-8c.94-.54,1.7-.1,1.7,1v3.46a3.79,3.79,0,0,1-1.7,3l-13.93,8Z"
style="fill: #e0e0e0"></path>
</g>
<g id="freepik--door--inject-70">
<g id="freepik--door--inject-70">
<path
d="M108.92,413V165.44a12,12,0,0,1,5.42-9.38L221.46,94.21a3.83,3.83,0,0,1,3.83-.38L229,96a3.79,3.79,0,0,1,1.6,3.51V347.06l-7.81,4.51-6.34-3.67-96,55.42v7.33l-7.81,4.51Z"
style="fill: #37474f"></path>
<path d="M134.28,395.32l-13.85,8v7.33l-7.81,4.51-3.7-2.14V165.44a11,11,0,0,1,1.6-5.35l23.58,13.62Z"
style="fill: #263238"></path>
<path
d="M112.62,167.59V415.14l7.81-4.5v-7.32l96-55.42,6.34,3.66,7.81-4.5V99.48c0-3.47-2.43-4.85-5.4-3.13L118,158.21A12,12,0,0,0,112.62,167.59Z"
style="fill: #455a64"></path>
<polygon points="120.43 168.9 120.43 406.38 219.1 349.42 219.1 111.95 120.43 168.9"
style="fill: currentcolor"></polygon>
<polygon points="120.43 168.9 120.43 406.38 219.1 349.42 219.1 111.95 120.43 168.9"
style=" opacity: 0.7;fill: #fff"></polygon>
<g style="opacity: 0.43">
<path d="M137.25,377.26V178.61l65-37.54V339.71ZM140,180.19V372.53l59.59-34.4V145.8Z"
style="fill: currentcolor"></path>
<path d="M137.25,178.61V377.26l65-37.55V141.07Zm62.31,159.52L140,372.53V180.19l59.59-34.39Z"
style="opacity: 0.1"></path>
</g>
<polygon points="219.1 349.42 219.1 111.95 222.75 109.83 222.76 351.57 219.1 349.42" style="fill: #263238">
</polygon>
<polygon points="120.43 410.64 222.76 351.57 219.1 349.42 120.43 406.38 120.43 410.64" style="fill: #e0e0e0">
</polygon>
</g>
<g id="freepik--Latch--inject-70">
<polygon points="122.34 258.22 124.31 259.36 124.32 292.09 122.34 290.95 122.34 258.22" style="fill: #e0e0e0">
</polygon>
<polygon points="124.31 259.36 134.94 253.22 134.95 285.95 124.32 292.09 124.31 259.36" style="fill: #fafafa">
</polygon>
<path d="M135,262.23l-4.66,2.68v5.32a.64.64,0,0,0,1,.55l3.7-2.13Z" style="opacity: 0.05"></path>
<polygon points="134.94 253.22 132.97 252.08 122.34 258.22 124.31 259.36 134.94 253.22" style="fill: #ebebeb">
</polygon>
<path
d="M128.39,263.82l4.88,2.81,1.95-3.38-4.88-2.81h0a.94.94,0,0,0-1,.09,3,3,0,0,0-1.38,2.39A1,1,0,0,0,128.39,263.82Z"
style="fill: #e0e0e0"></path>
<polygon
points="130.29 264.91 132.06 265.94 132.06 263.61 133.95 262.52 132.18 261.5 130.29 262.58 130.29 264.91"
style="opacity: 0.1"></polygon>
<polygon points="132.65 263.98 132.65 269.09 152.15 257.84 152.15 252.73 132.65 263.98" style="fill: #fafafa">
</polygon>
<polygon points="132.65 263.98 130.88 262.95 130.88 268.07 132.65 269.09 132.65 263.98" style="fill: #e0e0e0">
</polygon>
<polygon points="152.15 252.73 150.38 251.7 130.88 262.95 132.65 263.98 152.15 252.73" style="fill: #ebebeb">
</polygon>
<path
d="M127.84,278.23a4,4,0,0,1,1.79-3.1c1-.57,1.79-.11,1.79,1a3.92,3.92,0,0,1-1.08,2.52V282a1.35,1.35,0,0,1-.61,1.05l-.2.12c-.34.19-.61,0-.61-.35v-3.34C128.28,279.56,127.84,279.08,127.84,278.23Z"
style="fill: #455a64"></path>
</g>
<g id="freepik--Close--inject-70">
<path
d="M155.5,200.16l30.07-17.36c1.79-1,3.25-.2,3.25,1.87v20.65a7.21,7.21,0,0,1-3.25,5.63L155.5,228.31c-1.79,1-3.25.19-3.25-1.88V205.78A7.17,7.17,0,0,1,155.5,200.16Z"
style="opacity: 0.15"></path>
<path
d="M156.65,201l30.07-17.36c1.79-1,3.25-.2,3.25,1.87v20.65a7.21,7.21,0,0,1-3.25,5.63l-30.07,17.36c-1.8,1-3.25.19-3.25-1.88V206.66A7.15,7.15,0,0,1,156.65,201Z"
style="fill: #455a64"></path>
<path
d="M165.59,198h-.08a.37.37,0,0,1-.29-.45l6.1-26.68a.36.36,0,0,1,.35-.29h0a.37.37,0,0,1,.36.26l6.1,19.65a.38.38,0,1,1-.72.22l-5.68-18.31L166,197.74A.38.38,0,0,1,165.59,198Z"
style="fill: #263238"></path>
<path
d="M157.66,220.88a.72.72,0,0,1-.09-.44V209.63a1.37,1.37,0,0,1,.09-.55.58.58,0,0,1,.29-.31l3.27-1.89c.11-.06.18,0,.23.05a1.51,1.51,0,0,1,.06.52v.45a2.41,2.41,0,0,1-.06.6.5.5,0,0,1-.23.31l-2.16,1.25v3L161,212c.1-.06.18,0,.22.05a1.3,1.3,0,0,1,.07.53V213a1.89,1.89,0,0,1-.07.6.55.55,0,0,1-.22.32L159.06,215v3.28l2.17-1.26a.15.15,0,0,1,.22,0,1.54,1.54,0,0,1,.06.53v.45a2.34,2.34,0,0,1-.06.61.54.54,0,0,1-.22.3l-3.28,1.9C157.81,220.93,157.71,220.94,157.66,220.88Z"
style="fill: #fafafa"></path>
<path
d="M162.78,217.6v-11a1.19,1.19,0,0,1,.1-.53.72.72,0,0,1,.29-.33l1.81-1q2.25-1.31,2.25,2a5.9,5.9,0,0,1-1,3.53v.07c.3.08.55.56.76,1.44l.68,2.95a.44.44,0,0,0,0,.1.34.34,0,0,1,0,.1c0,.27-.2.52-.61.75l-.32.19c-.35.2-.55.18-.58-.06l-.62-3a1.21,1.21,0,0,0-.31-.64c-.12-.08-.29-.05-.53.09l-.42.24v4.26a1,1,0,0,1-.59.85l-.31.17C163,218,162.78,217.93,162.78,217.6Zm2.28-7.69a1.4,1.4,0,0,0,.51-.76,3.86,3.86,0,0,0,.22-1.37,2,2,0,0,0-.21-1.1q-.21-.27-.57-.06l-.76.44v3.32Z"
style="fill: #fafafa"></path>
<path
d="M168.65,214.21v-11a1.38,1.38,0,0,1,.09-.54.8.8,0,0,1,.3-.33l1.81-1q2.25-1.31,2.25,2a5.94,5.94,0,0,1-1,3.53v.06c.3.09.55.57.76,1.45l.67,2.94,0,.1s0,.07,0,.11c0,.26-.2.51-.61.74l-.32.19c-.36.2-.55.18-.59-.06l-.61-3a1.19,1.19,0,0,0-.31-.63c-.12-.08-.3-.06-.54.08l-.41.24v4.27a1,1,0,0,1-.6.84l-.3.18C168.84,214.6,168.65,214.55,168.65,214.21Zm2.28-7.69a1.36,1.36,0,0,0,.51-.76,4.07,4.07,0,0,0,.21-1.37,1.92,1.92,0,0,0-.2-1.09.39.39,0,0,0-.57-.07l-.76.44V207Z"
style="fill: #fafafa"></path>
<path
d="M174.29,205.36q0-6.15,2.89-7.82t2.89,4.48q0,6.18-2.89,7.85T174.29,205.36Zm3.93,1a13.59,13.59,0,0,0,.33-3.46,9.2,9.2,0,0,0-.33-3.07q-.33-.77-1-.36a2.49,2.49,0,0,0-1,1.56,13.45,13.45,0,0,0-.33,3.45,9.36,9.36,0,0,0,.33,3.08c.23.52.57.64,1,.37A2.55,2.55,0,0,0,178.22,206.36Z"
style="fill: #fafafa"></path>
<path
d="M181.35,206.88v-11a1.38,1.38,0,0,1,.09-.54.68.68,0,0,1,.3-.33l1.8-1q2.27-1.31,2.26,2a5.94,5.94,0,0,1-1.05,3.53v.06c.29.09.55.57.76,1.45l.67,2.94a.3.3,0,0,1,0,.1.41.41,0,0,1,0,.11c0,.26-.2.51-.6.74l-.33.19c-.35.2-.54.18-.58-.06l-.62-3a1.13,1.13,0,0,0-.31-.63c-.11-.09-.29-.06-.53.08l-.41.24V206a1,1,0,0,1-.6.84l-.3.17C181.54,207.27,181.35,207.21,181.35,206.88Zm2.27-7.69a1.32,1.32,0,0,0,.52-.76,4.11,4.11,0,0,0,.21-1.37,2,2,0,0,0-.21-1.1.39.39,0,0,0-.56-.06l-.76.44v3.32Z"
style="fill: #fafafa"></path>
</g>
</g>
<g id="freepik--Tapes--inject-70">
<polygon points="112.53 369.86 108.83 367.75 108.84 380.2 112.53 382.31 112.53 369.86" style="opacity: 0.2">
</polygon>
<polygon points="112.53 366.54 108.35 364.1 108.36 376.55 112.53 378.99 112.53 366.54"
style="fill: currentcolor"></polygon>
<polygon points="112.53 366.54 108.35 364.1 108.36 376.55 112.53 378.99 112.53 366.54" style="opacity: 0.2">
</polygon>
<polygon points="230.53 215.01 112.53 369.86 112.54 382.31 230.53 227.47 230.53 215.01" style="opacity: 0.25">
</polygon>
<polygon points="230.53 211.7 112.53 366.54 112.54 378.99 230.53 224.15 230.53 211.7"
style="fill: currentcolor"></polygon>
<polygon points="230.53 224.13 230.53 218.48 224.68 219.38 219.81 225.77 230.53 224.13" style="fill: #455a64">
</polygon>
<polygon points="215.94 243.32 205.18 244.97 200.3 251.37 211.07 249.71 215.94 243.32" style="fill: #455a64">
</polygon>
<polygon points="225.69 230.52 214.93 232.17 210.05 238.57 220.82 236.92 225.69 230.52" style="fill: #455a64">
</polygon>
<polygon points="206.19 256.11 195.43 257.77 190.55 264.16 201.32 262.51 206.19 256.11" style="fill: #455a64">
</polygon>
<polygon points="196.44 268.91 185.67 270.56 180.8 276.96 191.56 275.31 196.44 268.91" style="fill: #455a64">
</polygon>
<polygon points="186.69 281.71 175.92 283.36 171.05 289.76 181.81 288.11 186.69 281.71" style="fill: #455a64">
</polygon>
<polygon points="176.94 294.5 166.17 296.16 161.29 302.55 172.06 300.9 176.94 294.5" style="fill: #455a64">
</polygon>
<polygon points="167.18 307.3 156.42 308.95 151.54 315.35 162.31 313.7 167.18 307.3" style="fill: #455a64">
</polygon>
<polygon points="157.43 320.1 146.67 321.75 141.79 328.15 152.56 326.5 157.43 320.1" style="fill: #455a64">
</polygon>
<polygon points="147.68 332.89 136.91 334.55 132.04 340.94 142.81 339.29 147.68 332.89" style="fill: #455a64">
</polygon>
<polygon points="137.93 345.69 127.16 347.34 122.29 353.74 133.05 352.09 137.93 345.69" style="fill: #455a64">
</polygon>
<polygon points="128.18 358.49 117.41 360.14 112.53 366.54 123.3 364.88 128.18 358.49" style="fill: #455a64">
</polygon>
<polygon points="118.41 371.29 112.53 372.19 112.53 378.99 113.53 377.68 118.41 371.29" style="fill: #455a64">
</polygon>
<polygon points="112.53 283.52 230.53 298.93 230.53 311.38 112.53 295.98 112.53 283.52" style="opacity: 0.25">
</polygon>
<polygon points="112.53 281.42 230.53 296.82 230.53 309.27 112.53 293.87 112.53 281.42"
style="fill: currentcolor"></polygon>
<polygon points="112.53 283.52 108.83 281.35 108.84 293.81 112.53 295.97 112.53 283.52" style="opacity: 0.2">
</polygon>
<polygon points="112.53 281.42 108.35 278.97 108.36 291.43 112.53 293.87 112.53 281.42"
style="fill: currentcolor"></polygon>
<polygon points="112.53 281.42 108.35 278.97 108.36 291.43 112.53 293.87 112.53 281.42" style="opacity: 0.2">
</polygon>
<path
d="M117.8,284.78s.06,0,.07.09a.54.54,0,0,1,0,.22l-.17,1.15a.52.52,0,0,1-.06.2c0,.06-.07.08-.1.08l-1.34-.17-.22,1.48,1.25.16s.06,0,.08.1a.74.74,0,0,1,0,.21l-.17,1.16a.66.66,0,0,1-.06.2s-.07.08-.1.07l-1.25-.16-.34,2.35a.77.77,0,0,1-.07.2c0,.06-.07.09-.1.08l-.59-.07s0,0-.07-.1a.49.49,0,0,1,0-.21l1-7a.59.59,0,0,1,.06-.2s.07-.08.1-.08Z"
style="fill: #37474f"></path>
<path
d="M118.2,287.72a7.33,7.33,0,0,1,.27-1.14,4.74,4.74,0,0,1,.41-.9,1.83,1.83,0,0,1,.53-.57A.8.8,0,0,1,120,285a.81.81,0,0,1,.55.31,1.82,1.82,0,0,1,.35.68,4.55,4.55,0,0,1,.13,1,7.67,7.67,0,0,1,0,1.16c0,.32-.09.64-.14,1s-.1.66-.15,1a7.47,7.47,0,0,1-.27,1.13,4.85,4.85,0,0,1-.41.91,2,2,0,0,1-.53.57.86.86,0,0,1-.61.16.84.84,0,0,1-.56-.31,1.88,1.88,0,0,1-.34-.68,4,4,0,0,1-.13-1,7.78,7.78,0,0,1,0-1.16c0-.3.08-.62.13-1S118.14,288,118.2,287.72Zm1.69,2.13c0-.13,0-.28.07-.43s.06-.33.08-.49,0-.33.07-.49,0-.29,0-.42a2.9,2.9,0,0,0,0-.5,1.58,1.58,0,0,0-.05-.41.71.71,0,0,0-.13-.29.34.34,0,0,0-.48-.06.74.74,0,0,0-.22.24,2.29,2.29,0,0,0-.16.38,3.33,3.33,0,0,0-.12.5,3.86,3.86,0,0,0-.07.41c0,.16,0,.32-.08.49s0,.33-.07.49,0,.3,0,.43a2.79,2.79,0,0,0,0,.93c0,.25.17.39.36.41a.47.47,0,0,0,.46-.31A2.93,2.93,0,0,0,119.89,289.85Z"
style="fill: #37474f"></path>
<path
d="M123.63,285.52a1,1,0,0,1,.5.22,1.3,1.3,0,0,1,.34.51,2.92,2.92,0,0,1,.13.81,5.59,5.59,0,0,1-.07,1.11,5.42,5.42,0,0,1-.34,1.34,1.91,1.91,0,0,1-.51.77l.18,2.66v.12a.38.38,0,0,1-.06.16s0,.07-.08.07l-.61-.08a.13.13,0,0,1-.11-.12.69.69,0,0,1,0-.2l-.16-2.39-.42-.05-.34,2.32a.52.52,0,0,1-.06.2c0,.06-.07.09-.1.08l-.59-.07s0,0-.07-.1a.49.49,0,0,1,0-.21l1-7a.59.59,0,0,1,.06-.2c0-.05.07-.08.1-.08Zm-1,3.23.51.07a.37.37,0,0,0,.33-.14,1.11,1.11,0,0,0,.22-.61,1.27,1.27,0,0,0,0-.65.35.35,0,0,0-.29-.21l-.51-.07Z"
style="fill: #37474f"></path>
<path
d="M124.75,293.42a.12.12,0,0,1-.07-.1.48.48,0,0,1,0-.21l1-7a.93.93,0,0,1,.07-.2c0-.05.07-.08.1-.07l1.44.18a.69.69,0,0,1,.48.27,1.37,1.37,0,0,1,.25.56,2.93,2.93,0,0,1,.08.75,7.35,7.35,0,0,1-.07.82,3.19,3.19,0,0,1-.11.54,4,4,0,0,1-.12.4c0,.11-.09.19-.13.26l-.09.15a2,2,0,0,1,.15.71,7.05,7.05,0,0,1-.07.94,6.25,6.25,0,0,1-.18.86,3.27,3.27,0,0,1-.29.73,1.32,1.32,0,0,1-.4.49.63.63,0,0,1-.51.14Zm1-1.6.74.1c.09,0,.17-.05.24-.17a1.24,1.24,0,0,0,.15-.46,1.26,1.26,0,0,0,0-.48c0-.14-.1-.21-.19-.22l-.74-.09Zm1.49-3.49a1.17,1.17,0,0,0,0-.46c0-.12-.09-.19-.18-.2l-.7-.09-.18,1.24.7.09c.09,0,.16,0,.23-.14A1.44,1.44,0,0,0,127.2,288.33Z"
style="fill: #37474f"></path>
<path
d="M128.27,293.87s-.05,0-.07-.1a.49.49,0,0,1,0-.21l1-7a.59.59,0,0,1,.06-.2c0-.05.07-.08.1-.07l.59.07a.12.12,0,0,1,.07.1.48.48,0,0,1,0,.21l-1,7a.86.86,0,0,1-.07.21c0,.05-.07.08-.1.07Z"
style="fill: #37474f"></path>
<path
d="M132.37,286.64a.83.83,0,0,1,.53.29,1.72,1.72,0,0,1,.35.69,3.94,3.94,0,0,1,.16,1,8.93,8.93,0,0,1-.06,1.24q0,.24-.06.42c0,.13,0,.25,0,.37s0,.23-.06.36a3.55,3.55,0,0,1-.06.4,7.41,7.41,0,0,1-.29,1.21,4.66,4.66,0,0,1-.43.92,1.94,1.94,0,0,1-.52.57.81.81,0,0,1-.59.15l-1.22-.15s0,0-.07-.1a.7.7,0,0,1,0-.21l1-7a.59.59,0,0,1,.06-.2c0-.05.07-.08.1-.07Zm.15,3.06c.11-.83,0-1.28-.42-1.32l-.46-.06-.6,4.13.48.06c.37.05.63-.34.77-1.18l.06-.42.06-.4.06-.38C132.49,290,132.5,289.86,132.52,289.7Z"
style="fill: #37474f"></path>
<path
d="M136,287.1a.79.79,0,0,1,.53.29,1.75,1.75,0,0,1,.35.68,4.1,4.1,0,0,1,.16,1,8.93,8.93,0,0,1-.06,1.24c0,.16,0,.29-.06.42s0,.25,0,.37,0,.23-.05.35,0,.26-.07.41a7.67,7.67,0,0,1-.29,1.21,4.66,4.66,0,0,1-.43.92,1.94,1.94,0,0,1-.52.57.81.81,0,0,1-.59.15l-1.22-.15s0,0-.07-.1a.49.49,0,0,1,0-.21l1-7a.59.59,0,0,1,.06-.2s.07-.08.1-.07Zm.15,3.06c.11-.83,0-1.28-.42-1.33l-.46-.05-.6,4.13.48.06c.37,0,.63-.34.77-1.18l.06-.43L136,291l.06-.38C136.08,290.46,136.09,290.32,136.11,290.16Z"
style="fill: #37474f"></path>
<path
d="M139.62,293.55s0,0,.07.09a.49.49,0,0,1,0,.21l-.16,1.16a.93.93,0,0,1-.07.2.14.14,0,0,1-.1.08l-2.13-.28s0,0-.07-.1a.67.67,0,0,1,0-.2l1-7a.52.52,0,0,1,.06-.2c0-.06.07-.08.1-.08l2.09.27s.06,0,.08.1a.74.74,0,0,1,0,.21l-.17,1.15a.52.52,0,0,1-.06.2c0,.06-.07.08-.1.08l-1.38-.18-.17,1.18,1.28.16a.12.12,0,0,1,.07.1.48.48,0,0,1,0,.21l-.17,1.15a.65.65,0,0,1-.06.21c0,.05-.07.08-.1.07l-1.28-.16-.18,1.21Z"
style="fill: #37474f"></path>
<path
d="M142.39,295.67s-.08,0-.1-.11a.41.41,0,0,1,0-.16l-.49-3.85-.53,3.67a.77.77,0,0,1-.07.2c0,.06-.07.09-.1.08l-.59-.07s-.05,0-.07-.1a.7.7,0,0,1,0-.21l1-7a.59.59,0,0,1,.06-.2c0-.05.07-.08.1-.07l.47.06s.09,0,.11.11,0,.12,0,.16l.48,3.85.54-3.68a.59.59,0,0,1,.06-.2c0-.05.07-.08.1-.07l.59.07s.06,0,.07.1a.48.48,0,0,1,0,.21l-1,7a.65.65,0,0,1-.06.21s-.07.08-.1.07Z"
style="fill: #37474f"></path>
<path
d="M146.72,296.22s-.06,0-.08-.09a.74.74,0,0,1,0-.21l.16-1.11-1.41-.18s-.06,0-.08-.1a.74.74,0,0,1,0-.21l.17-1.15a1.4,1.4,0,0,1,.12-.47l1.94-3.92a.42.42,0,0,1,.1-.15.14.14,0,0,1,.09,0l.68.09s.06,0,.07.1a.48.48,0,0,1,0,.21l-.61,4.17.39.05a.12.12,0,0,1,.07.1.48.48,0,0,1,0,.21l-.17,1.15a.48.48,0,0,1-.07.21c0,.05-.06.08-.09.07l-.39,0-.16,1.11a.52.52,0,0,1-.07.2c0,.06-.06.08-.1.08Zm.35-3.15.3-2-1,1.92Z"
style="fill: #37474f"></path>
<path
d="M151.09,288.92a.79.79,0,0,1,.54.31,1.88,1.88,0,0,1,.31.7,4.59,4.59,0,0,1,.1,1A11.23,11.23,0,0,1,152,292c0,.32-.09.64-.14,1s-.1.66-.14,1a11.3,11.3,0,0,1-.26,1.11,4.09,4.09,0,0,1-.38.91,1.84,1.84,0,0,1-.49.59.81.81,0,0,1-.61.17.79.79,0,0,1-.55-.31,1.81,1.81,0,0,1-.31-.7,4.59,4.59,0,0,1-.1-1,11.23,11.23,0,0,1,.07-1.13c0-.3.08-.62.13-1s.1-.67.16-1a9,9,0,0,1,.25-1.11,4.09,4.09,0,0,1,.38-.91,1.84,1.84,0,0,1,.49-.59A.82.82,0,0,1,151.09,288.92Zm-.23,4.89c.1-.62.19-1.22.27-1.83,0-.18,0-.35,0-.5a2.55,2.55,0,0,0,0-.41.71.71,0,0,0-.11-.28.27.27,0,0,0-.21-.13.3.3,0,0,0-.24.07.7.7,0,0,0-.18.25,2.35,2.35,0,0,0-.14.38c0,.15-.07.32-.1.5q-.15.9-.27,1.83a4.77,4.77,0,0,0,0,.5,1.76,1.76,0,0,0,0,.41.66.66,0,0,0,.11.28.27.27,0,0,0,.21.13.3.3,0,0,0,.24-.07.7.7,0,0,0,.18-.25,1.68,1.68,0,0,0,.14-.38C150.8,294.16,150.83,294,150.86,293.81Z"
style="fill: #37474f"></path>
<path
d="M155.51,289.6s.06,0,.07.09a.49.49,0,0,1,0,.21l-.17,1.16a.65.65,0,0,1-.06.21l-.09.16-.73,1.25a1.59,1.59,0,0,1,.46.81,3.34,3.34,0,0,1,0,1.39,3.93,3.93,0,0,1-.62,1.81,1.09,1.09,0,0,1-1.06.49.92.92,0,0,1-.55-.26,1.49,1.49,0,0,1-.35-.54,2.71,2.71,0,0,1-.16-.72,3.56,3.56,0,0,1,0-.8.69.69,0,0,1,0-.17s.05-.06.08-.06l.57.07a.17.17,0,0,1,.13.12,2.17,2.17,0,0,0,.07.24.7.7,0,0,0,.13.24.32.32,0,0,0,.26.14.43.43,0,0,0,.38-.13.84.84,0,0,0,.22-.53.86.86,0,0,0-.06-.58.47.47,0,0,0-.33-.22l-.37,0a.12.12,0,0,1-.07-.1.48.48,0,0,1,0-.21l.14-.94a.65.65,0,0,1,.06-.21l.09-.17.64-1.1-1.17-.15s-.06,0-.07-.1a.48.48,0,0,1,0-.21l.17-1.15a.4.4,0,0,1,.07-.2c0-.06.06-.08.09-.08Z"
style="fill: #37474f"></path>
<path
d="M160.1,290.18s.06,0,.08.1a.74.74,0,0,1,0,.21l-.17,1.15a.58.58,0,0,1-.06.21s-.07.08-.1.07l-1.34-.17-.22,1.49,1.25.16s.06,0,.08.1a.74.74,0,0,1,0,.21l-.17,1.15a.65.65,0,0,1-.06.21c0,.05-.07.08-.1.07L158,295l-.34,2.35a.52.52,0,0,1-.07.2c0,.06-.06.08-.1.08l-.59-.08s-.05,0-.07-.09a.54.54,0,0,1,0-.22l1-7a.52.52,0,0,1,.06-.2c0-.06.07-.08.1-.08Z"
style="fill: #37474f"></path>
<path
d="M160.47,293.12a8.91,8.91,0,0,1,.27-1.13,4.74,4.74,0,0,1,.41-.9,2.15,2.15,0,0,1,.53-.58.91.91,0,0,1,.62-.16.86.86,0,0,1,.55.31,2,2,0,0,1,.34.69,3.93,3.93,0,0,1,.13,1,6.63,6.63,0,0,1,0,1.16c0,.31-.09.64-.14,1s-.1.66-.14,1a8.64,8.64,0,0,1-.28,1.14,4.19,4.19,0,0,1-.41.9,1.88,1.88,0,0,1-.53.58.84.84,0,0,1-.61.15.89.89,0,0,1-.56-.3,1.93,1.93,0,0,1-.33-.69,3.9,3.9,0,0,1-.14-1,7.71,7.71,0,0,1,.06-1.16c0-.3.08-.62.13-1S160.42,293.43,160.47,293.12Zm1.69,2.13c0-.13.05-.27.08-.43s0-.32.07-.49.05-.33.07-.48,0-.3.05-.42a4.77,4.77,0,0,0,0-.51,2.42,2.42,0,0,0-.05-.41.78.78,0,0,0-.14-.29.34.34,0,0,0-.23-.13.32.32,0,0,0-.25.07.83.83,0,0,0-.21.24,1.76,1.76,0,0,0-.17.39,3.19,3.19,0,0,0-.12.49c0,.12,0,.26-.07.42s-.05.31-.08.48l-.06.49c0,.16,0,.31-.06.44a2.73,2.73,0,0,0,0,.92c0,.25.17.39.36.41s.34-.08.47-.3A3,3,0,0,0,162.16,295.25Z"
style="fill: #37474f"></path>
<path
d="M165.89,290.92a1,1,0,0,1,.51.22,1.19,1.19,0,0,1,.33.51,2.64,2.64,0,0,1,.13.81,5.59,5.59,0,0,1-.07,1.11,6,6,0,0,1-.33,1.34,2,2,0,0,1-.52.77l.18,2.66a.48.48,0,0,1,0,.12.43.43,0,0,1-.06.17.1.1,0,0,1-.07.06l-.62-.08a.14.14,0,0,1-.11-.11.76.76,0,0,1,0-.21l-.16-2.39-.41,0-.34,2.33a.59.59,0,0,1-.07.2c0,.05-.06.08-.1.07l-.58-.07s-.06,0-.08-.1a.74.74,0,0,1,0-.21l1-7a.48.48,0,0,1,.07-.21s.06-.08.09-.07Zm-1,3.23.51.07a.39.39,0,0,0,.34-.14,1.12,1.12,0,0,0,.21-.61,1.08,1.08,0,0,0,0-.65.35.35,0,0,0-.29-.21l-.5-.07Z"
style="fill: #37474f"></path>
<path
d="M167,298.82s-.06,0-.07-.1a.48.48,0,0,1,0-.21l1-7a.65.65,0,0,1,.07-.21s.06-.08.1-.07l1.44.18a.73.73,0,0,1,.48.27,1.37,1.37,0,0,1,.25.56,3,3,0,0,1,.07.75,5.55,5.55,0,0,1-.06.82,5.33,5.33,0,0,1-.11.55,2.54,2.54,0,0,1-.13.39,1.29,1.29,0,0,1-.12.26l-.09.15a1.8,1.8,0,0,1,.14.71,5.5,5.5,0,0,1-.06.94c-.05.3-.11.58-.18.86a3.83,3.83,0,0,1-.29.73,1.47,1.47,0,0,1-.4.5.67.67,0,0,1-.51.14Zm.95-1.6.74.1c.09,0,.17,0,.25-.16a1.37,1.37,0,0,0,.15-.47,1.25,1.25,0,0,0,0-.48c0-.13-.09-.21-.18-.22l-.74-.09Zm1.5-3.49a1.4,1.4,0,0,0,0-.46c0-.12-.09-.19-.18-.2l-.7-.09-.18,1.24.7.09a.22.22,0,0,0,.22-.14A1.14,1.14,0,0,0,169.47,293.73Z"
style="fill: #37474f"></path>
<path
d="M170.55,299.27s-.06,0-.07-.1a.48.48,0,0,1,0-.21l1-7a.52.52,0,0,1,.07-.2c0-.06.06-.08.1-.08l.58.08s.06,0,.08.09a.74.74,0,0,1,0,.21l-1,7a.4.4,0,0,1-.07.2c0,.06-.06.08-.09.08Z"
style="fill: #37474f"></path>
<path
d="M174.66,292a.82.82,0,0,1,.53.3,1.75,1.75,0,0,1,.35.68,4.1,4.1,0,0,1,.16,1,9,9,0,0,1-.06,1.24q0,.23-.06.42c0,.13,0,.25-.05.36s0,.24-.05.36,0,.26-.07.4a7.54,7.54,0,0,1-.29,1.22,4.94,4.94,0,0,1-.43.92,1.94,1.94,0,0,1-.52.57.86.86,0,0,1-.59.15l-1.22-.16s-.05,0-.07-.09a.5.5,0,0,1,0-.21l1-7a.52.52,0,0,1,.06-.2c0-.06.07-.08.1-.08Zm.15,3.07c.11-.84,0-1.28-.42-1.33l-.46-.06-.6,4.13.48.07c.37,0,.63-.35.77-1.18l.06-.43.06-.39.06-.39C174.78,295.4,174.79,295.26,174.81,295.11Z"
style="fill: #37474f"></path>
<path
d="M178.25,292.5a.87.87,0,0,1,.53.3,1.75,1.75,0,0,1,.35.68,3.63,3.63,0,0,1,.15,1,6.71,6.71,0,0,1-.06,1.24c0,.15,0,.29-.05.42s0,.25,0,.36l-.06.36c0,.12,0,.26-.06.4a6.81,6.81,0,0,1-.3,1.22,4.38,4.38,0,0,1-.42.92,1.94,1.94,0,0,1-.52.57.93.93,0,0,1-.6.15L176,300s-.06,0-.07-.1a.48.48,0,0,1,0-.21l1-7a.77.77,0,0,1,.07-.2c0-.06.07-.08.1-.08Zm.15,3.07c.1-.84,0-1.28-.43-1.33l-.46-.06-.6,4.13.48.06c.38.05.64-.34.77-1.17,0-.15.05-.3.07-.43l.06-.39c0-.13,0-.26.05-.39S178.38,295.72,178.4,295.57Z"
style="fill: #37474f"></path>
<path
d="M181.91,299s.05,0,.07.1a.49.49,0,0,1,0,.21l-.16,1.15a.77.77,0,0,1-.07.2c0,.06-.07.09-.1.08l-2.12-.27s-.06,0-.08-.1a.74.74,0,0,1,0-.21l1-7a.48.48,0,0,1,.07-.21c0-.05.06-.08.09-.07l2.09.27s.06,0,.08.09a.8.8,0,0,1,0,.22l-.17,1.15a.59.59,0,0,1-.06.2.14.14,0,0,1-.1.08l-1.38-.18-.17,1.17,1.28.17s.06,0,.07.1a.48.48,0,0,1,0,.21l-.17,1.15a.52.52,0,0,1-.06.2c0,.06-.07.08-.1.08l-1.29-.17-.17,1.22Z"
style="fill: #37474f"></path>
<path
d="M184.67,301.08a.15.15,0,0,1-.11-.12.73.73,0,0,1,0-.16L184,297l-.53,3.68a.4.4,0,0,1-.07.2c0,.06-.06.08-.09.08l-.59-.08s-.06,0-.07-.1a.48.48,0,0,1,0-.21l1-7a.52.52,0,0,1,.07-.2c0-.06.06-.08.1-.08l.46.06a.14.14,0,0,1,.11.11.9.9,0,0,1,0,.16l.49,3.85.53-3.67a.4.4,0,0,1,.07-.2c0-.06.06-.08.09-.08l.59.07s.06,0,.08.1a.74.74,0,0,1,0,.21l-1,7a.4.4,0,0,1-.07.2c0,.06-.06.08-.09.08Z"
style="fill: #37474f"></path>
<path
d="M189,301.63a.12.12,0,0,1-.07-.1.48.48,0,0,1,0-.21l.16-1.11-1.41-.18s-.06,0-.07-.1a.48.48,0,0,1,0-.21l.17-1.15a1.61,1.61,0,0,1,.12-.46l1.94-3.93a.42.42,0,0,1,.1-.15.11.11,0,0,1,.1,0l.67.08s.06,0,.08.1a.74.74,0,0,1,0,.21l-.6,4.18.38.05s.06,0,.07.09a.53.53,0,0,1,0,.22l-.17,1.15a.52.52,0,0,1-.06.2s-.07.08-.1.08l-.39-.05-.16,1.11a.43.43,0,0,1-.07.2c0,.05-.06.08-.09.07Zm.36-3.16.29-2-.95,1.92Z"
style="fill: #37474f"></path>
<path
d="M193.37,294.33a.76.76,0,0,1,.54.31,1.83,1.83,0,0,1,.31.69,4.07,4.07,0,0,1,.1,1,8.94,8.94,0,0,1-.07,1.14c0,.31-.08.64-.13,1s-.1.66-.15.95a8.77,8.77,0,0,1-.26,1.12,4.53,4.53,0,0,1-.37.91,2,2,0,0,1-.5.59.79.79,0,0,1-.61.16.76.76,0,0,1-.55-.31,1.83,1.83,0,0,1-.3-.69,4.63,4.63,0,0,1-.11-1,9,9,0,0,1,.08-1.14c0-.3.08-.62.13-1s.1-.66.15-1a9,9,0,0,1,.25-1.11,4.53,4.53,0,0,1,.38-.91,2,2,0,0,1,.49-.59A.82.82,0,0,1,193.37,294.33Zm-.23,4.88c.11-.61.19-1.22.27-1.82,0-.18,0-.35,0-.51a1.67,1.67,0,0,0,0-.4.7.7,0,0,0-.11-.29.28.28,0,0,0-.21-.12.26.26,0,0,0-.23.06.86.86,0,0,0-.19.25,2.49,2.49,0,0,0-.14.39,4.9,4.9,0,0,0-.1.5c-.1.59-.19,1.2-.27,1.82,0,.18,0,.35,0,.5a1.73,1.73,0,0,0,0,.41.7.7,0,0,0,.11.29.28.28,0,0,0,.21.12.29.29,0,0,0,.24-.06.7.7,0,0,0,.18-.25,1.77,1.77,0,0,0,.14-.39A3.15,3.15,0,0,0,193.14,299.21Z"
style="fill: #37474f"></path>
<path
d="M197.78,295s.05,0,.07.1a.7.7,0,0,1,0,.21l-.17,1.15a.65.65,0,0,1-.07.21.79.79,0,0,1-.08.16l-.73,1.26a1.52,1.52,0,0,1,.46.8,3.57,3.57,0,0,1,0,1.4,3.84,3.84,0,0,1-.62,1.8,1.13,1.13,0,0,1-1.07.5,1,1,0,0,1-.54-.26,1.48,1.48,0,0,1-.35-.55,2.54,2.54,0,0,1-.16-.72,3.07,3.07,0,0,1,0-.8.42.42,0,0,1,.05-.17s0-.06.08-.06l.57.08q.09,0,.12.12c0,.07.05.15.08.23a.85.85,0,0,0,.13.25.34.34,0,0,0,.26.13.45.45,0,0,0,.38-.12.94.94,0,0,0,.22-.54.84.84,0,0,0-.06-.57.44.44,0,0,0-.33-.22l-.37-.05s-.06,0-.08-.1a.74.74,0,0,1,0-.21l.13-.93a.81.81,0,0,1,.07-.22l.09-.16.64-1.11-1.17-.14a.12.12,0,0,1-.07-.1.48.48,0,0,1,0-.21l.17-1.16a.59.59,0,0,1,.06-.2c0-.05.07-.08.1-.07Z"
style="fill: #37474f"></path>
<path
d="M202.36,295.59s.06,0,.08.09a.81.81,0,0,1,0,.22l-.17,1.15a.59.59,0,0,1-.06.2c0,.05-.07.08-.1.08l-1.34-.18-.22,1.49,1.25.16s.06,0,.08.1a.74.74,0,0,1,0,.21l-.17,1.16a.59.59,0,0,1-.06.2s-.07.08-.1.07l-1.25-.16-.34,2.35a.77.77,0,0,1-.07.2c0,.06-.06.08-.1.08l-.59-.08s0,0-.07-.09a.49.49,0,0,1,0-.21l1-7a.59.59,0,0,1,.06-.2c0-.06.07-.08.1-.08Z"
style="fill: #37474f"></path>
<path
d="M202.76,298.53a7.18,7.18,0,0,1,.28-1.13,3.78,3.78,0,0,1,.41-.9,2,2,0,0,1,.52-.58.87.87,0,0,1,.62-.16.84.84,0,0,1,.55.31,1.89,1.89,0,0,1,.34.68,4.06,4.06,0,0,1,.14,1,7.85,7.85,0,0,1-.06,1.16c0,.31-.08.63-.13,1s-.1.66-.15.95A7.6,7.6,0,0,1,205,302a3.94,3.94,0,0,1-.41.9,1.85,1.85,0,0,1-.52.58.88.88,0,0,1-1.17-.15,1.86,1.86,0,0,1-.34-.69,4.52,4.52,0,0,1-.14-1,7.91,7.91,0,0,1,.06-1.17c0-.29.08-.61.13-.95S202.71,298.84,202.76,298.53Zm1.7,2.13c0-.13,0-.27.07-.43s.05-.32.08-.49l.06-.49c0-.15,0-.29.05-.42a3,3,0,0,0,0-.5,1.64,1.64,0,0,0-.05-.41.71.71,0,0,0-.13-.29.32.32,0,0,0-.23-.13.36.36,0,0,0-.26.07.63.63,0,0,0-.21.24,2.7,2.7,0,0,0-.17.38c0,.15-.08.32-.11.5s-.05.26-.08.42,0,.31-.07.48-.05.33-.07.49,0,.3-.05.44a3,3,0,0,0,0,.92c.06.25.18.39.37.41a.47.47,0,0,0,.46-.31A2.83,2.83,0,0,0,204.46,300.66Z"
style="fill: #37474f"></path>
<path
d="M208.17,296.33a.91.91,0,0,1,.5.22,1.13,1.13,0,0,1,.33.5,2.62,2.62,0,0,1,.14.81,6.52,6.52,0,0,1-.07,1.12,5.54,5.54,0,0,1-.34,1.34,2,2,0,0,1-.51.77l.18,2.65v.12a.43.43,0,0,1-.06.17c0,.05-.05.06-.08.06l-.61-.08c-.06,0-.1,0-.11-.11a.75.75,0,0,1,0-.2l-.16-2.39-.42-.06-.34,2.33a.52.52,0,0,1-.06.2c0,.06-.07.08-.1.08l-.59-.08s-.05,0-.07-.09a.79.79,0,0,1,0-.22l1-7a.52.52,0,0,1,.06-.2c0-.06.07-.08.1-.08Zm-1,3.23.51.06a.37.37,0,0,0,.33-.13,1.68,1.68,0,0,0,.19-1.26.38.38,0,0,0-.29-.22l-.51-.06Z"
style="fill: #37474f"></path>
<path
d="M209.29,304.22s-.06,0-.07-.09a.48.48,0,0,1,0-.21l1-7a.77.77,0,0,1,.07-.2c0-.06.06-.08.1-.08l1.44.19a.68.68,0,0,1,.48.26,1.41,1.41,0,0,1,.25.57,2.52,2.52,0,0,1,.07.75,5.55,5.55,0,0,1-.06.82,4.63,4.63,0,0,1-.11.54,2.35,2.35,0,0,1-.13.4,2.17,2.17,0,0,1-.12.26l-.09.14a1.85,1.85,0,0,1,.14.72,5.39,5.39,0,0,1-.06.93,6.09,6.09,0,0,1-.18.87,3.27,3.27,0,0,1-.29.73,1.53,1.53,0,0,1-.4.49.67.67,0,0,1-.51.14Zm1-1.59.75.09c.08,0,.16,0,.24-.16a1.31,1.31,0,0,0,.15-.46,1.5,1.5,0,0,0,0-.48c0-.14-.1-.21-.19-.22l-.74-.1Zm1.5-3.5a1.17,1.17,0,0,0,0-.46c0-.12-.09-.18-.18-.19l-.7-.09-.18,1.24.7.09c.09,0,.16,0,.23-.14A1.43,1.43,0,0,0,211.74,299.13Z"
style="fill: #37474f"></path>
<path
d="M212.83,304.68s-.06,0-.08-.1a.74.74,0,0,1,0-.21l1-7a.43.43,0,0,1,.07-.2c0-.05.06-.08.09-.07l.59.07s.06,0,.07.1a.48.48,0,0,1,0,.21l-1,7a.52.52,0,0,1-.07.2c0,.06-.06.09-.1.08Z"
style="fill: #37474f"></path>
<path
d="M216.92,297.45a.81.81,0,0,1,.53.29,1.89,1.89,0,0,1,.35.68,4.13,4.13,0,0,1,.15,1,6.68,6.68,0,0,1-.06,1.24c0,.15,0,.29,0,.42l-.06.37c0,.11,0,.23-.05.35s0,.26-.06.41a7.64,7.64,0,0,1-.3,1.21,4.15,4.15,0,0,1-.42.92,2,2,0,0,1-.53.57.8.8,0,0,1-.59.15l-1.21-.15a.12.12,0,0,1-.07-.1.48.48,0,0,1,0-.21l1-7a.59.59,0,0,1,.07-.2c0-.05.06-.08.1-.07Zm.15,3.06c.1-.83,0-1.28-.43-1.33l-.46-.06-.6,4.14.48.06c.38.05.64-.35.77-1.18,0-.15,0-.29.07-.43l.06-.39c0-.12,0-.25,0-.38S217.05,300.66,217.07,300.51Z"
style="fill: #37474f"></path>
<path
d="M220.51,297.91a.81.81,0,0,1,.54.29,2.06,2.06,0,0,1,.35.68,4.69,4.69,0,0,1,.15,1,6.68,6.68,0,0,1-.06,1.24l-.06.42c0,.13,0,.25-.05.36s0,.24,0,.36l-.06.4a8.71,8.71,0,0,1-.3,1.22,4.15,4.15,0,0,1-.42.92,2,2,0,0,1-.53.57.81.81,0,0,1-.59.15l-1.21-.16s-.06,0-.08-.09a.74.74,0,0,1,0-.21l1-7a.4.4,0,0,1,.07-.2c0-.06.06-.08.1-.08Zm.16,3.06c.1-.83,0-1.28-.43-1.33l-.46-.06-.6,4.14.48.06c.38,0,.63-.35.77-1.18,0-.15,0-.29.07-.43s0-.26.05-.39l.06-.38C220.63,301.27,220.65,301.12,220.67,301Z"
style="fill: #37474f"></path>
<path
d="M224.18,304.36s0,0,.07.09a.49.49,0,0,1,0,.21l-.16,1.16a.93.93,0,0,1-.07.2c0,.05-.06.08-.1.07l-2.13-.27s0,0-.07-.09a.74.74,0,0,1,0-.21l1-7a.4.4,0,0,1,.07-.2c0-.06.06-.08.09-.08l2.09.27s.06,0,.08.1a.74.74,0,0,1,0,.21l-.17,1.15a.52.52,0,0,1-.06.2c0,.06-.07.08-.1.08l-1.38-.18-.17,1.18,1.28.16a.12.12,0,0,1,.07.1.48.48,0,0,1,0,.21l-.17,1.15a.52.52,0,0,1-.06.2c0,.06-.07.08-.1.08l-1.29-.16-.17,1.21Z"
style="fill: #37474f"></path>
<path
d="M226.94,306.48c-.05,0-.08,0-.11-.11a.69.69,0,0,1,0-.16l-.49-3.85-.54,3.67a.52.52,0,0,1-.06.2c0,.06-.07.08-.1.08l-.59-.08s-.06,0-.07-.09a.48.48,0,0,1,0-.21l1-7a.52.52,0,0,1,.06-.2c0-.06.07-.08.1-.08l.47.06c.05,0,.08.05.1.12a.41.41,0,0,1,0,.16l.49,3.85.53-3.68a.77.77,0,0,1,.07-.2.14.14,0,0,1,.1-.08l.59.08s0,0,.07.1a.48.48,0,0,1,0,.21l-1,7a.52.52,0,0,1-.06.2c0,.06-.07.08-.1.08Z"
style="fill: #37474f"></path>
</g>
</g>
<g id="freepik--error-403--inject-70">
<g id="freepik--404--inject-70">
<path
d="M142.21,105.27a1.09,1.09,0,0,0-.17-.13l-5.26-3V77.19a1.71,1.71,0,0,0-.41-1.27.64.64,0,0,0-.17-.13l-5.62-3.24a.75.75,0,0,0-.82,0L122,77.11a3.55,3.55,0,0,0-1.07.89,7.56,7.56,0,0,0-.85,1.65L104.56,118.6a10.66,10.66,0,0,0-.67,3.81v8.45a1.67,1.67,0,0,0,.42,1.27.7.7,0,0,0,.17.13l5.62,3.25a.75.75,0,0,0,.81-.06l10.67-6.16v1.63a1.69,1.69,0,0,0,.42,1.27l.16.13,5.63,3.25a.79.79,0,0,0,.82-.06l6.77-3.91a2.64,2.64,0,0,0,1-1.21,4.14,4.14,0,0,0,.41-1.75v-8.12l4.45-2.57a2.63,2.63,0,0,0,1-1.21,4,4,0,0,0,.41-1.75v-8.44A1.7,1.7,0,0,0,142.21,105.27Z"
style="fill: currentcolor"></path>
<path
d="M126.47,81.24l0,.1a7.51,7.51,0,0,0-.79,1.55l-15.47,39a9.49,9.49,0,0,0-.46,1.6l-5.66-3.27a10.25,10.25,0,0,1,.45-1.58L120,79.65a7.74,7.74,0,0,1,.86-1.65,0,0,0,0,1,0,0Z"
style="opacity: 0.15"></path>
<path
d="M110,135.47c-.63-.37-5.32-3.08-5.55-3.2l-.17-.14a1.7,1.7,0,0,1-.42-1.28v-8.43a11.37,11.37,0,0,1,.22-2.22l5.62,3.25a11.3,11.3,0,0,0-.21,2.22v8.44a1.73,1.73,0,0,0,.41,1.27Z"
style="opacity: 0.3"></path>
<polygon points="127.47 98.5 127.47 113.15 122.73 110.42 127.47 98.5" style="opacity: 0.3"></polygon>
<polygon points="127.47 113.15 119.92 117.51 122.73 110.42 127.47 113.15" style="opacity: 0.4"></polygon>
<path
d="M127.62,135.44l.1.08-5.55-3.2a.43.43,0,0,1-.17-.13,1.67,1.67,0,0,1-.42-1.27v-1.63l5.63-3.25v8.12A1.74,1.74,0,0,0,127.62,135.44Z"
style="opacity: 0.3"></path>
<path d="M142,105.11a.78.78,0,0,0-.74.09l-4.45,2.57v-5.66Z" style="opacity: 0.15"></path>
<path
d="M136.16,75.77a.79.79,0,0,0-.78.07l-7.81,4.51a3.76,3.76,0,0,0-1,.89L120.89,78a3.72,3.72,0,0,1,1-.88l7.82-4.51a.75.75,0,0,1,.82,0Z"
style=" opacity: 0.4;fill: #fff"></path>
<path
d="M128.61,135.51a.77.77,0,0,1-1-.07,1.74,1.74,0,0,1-.41-1.28V126l-16.3,9.41a.74.74,0,0,1-1-.07,1.74,1.74,0,0,1-.41-1.28v-8.44a10.45,10.45,0,0,1,.67-3.81l15.47-39a7.24,7.24,0,0,1,.85-1.64,3.51,3.51,0,0,1,1.06-.89l7.81-4.51a.75.75,0,0,1,1,.07,1.71,1.71,0,0,1,.41,1.27v30.58l4.45-2.57a.76.76,0,0,1,1,.07,1.7,1.7,0,0,1,.41,1.28V115a4,4,0,0,1-.41,1.75,2.63,2.63,0,0,1-1,1.21l-4.45,2.57v8.12a4.14,4.14,0,0,1-.41,1.75,2.64,2.64,0,0,1-1,1.21Zm-1.14-22.36V98.5l-7.55,19Z"
style="fill: currentcolor"></path>
<path
d="M181.49,70a34.85,34.85,0,0,0-1.06-7.63,11.8,11.8,0,0,0-2.74-5.31A6.76,6.76,0,0,0,176.28,56l-5.64-3.25a6.94,6.94,0,0,0-3.21-.91,12.68,12.68,0,0,0-6.67,2.1,24.42,24.42,0,0,0-6.67,5.6,32.84,32.84,0,0,0-4.63,7.38,38.69,38.69,0,0,0-2.75,8.47,55.19,55.19,0,0,0-1.06,8.85q-.1,3.5-.1,7.23c0,2.5,0,4.81.1,7a35.47,35.47,0,0,0,1.06,7.63,11.81,11.81,0,0,0,2.75,5.31,6.12,6.12,0,0,0,1.4,1.1c.94.56,5.18,3,5.72,3.31a7.11,7.11,0,0,0,3.13.86,12.68,12.68,0,0,0,6.67-2.1,24.46,24.46,0,0,0,6.68-5.6,33.57,33.57,0,0,0,4.63-7.38,38.67,38.67,0,0,0,2.74-8.47,54.08,54.08,0,0,0,1.06-8.85q.1-3.33.1-7.07T181.49,70Zm-20.44,28.3a22.2,22.2,0,0,1-.2-2.6q-.25-6.63,0-13.38a26.75,26.75,0,0,1,.36-3.88,17.86,17.86,0,0,1,.93-3.44,11.62,11.62,0,0,1,1.66-2.91,8.47,8.47,0,0,1,2.25-2q.16,1.17.24,2.58.21,6.48,0,13.38a29.35,29.35,0,0,1-.33,3.85,15.61,15.61,0,0,1-.93,3.45,11.91,11.91,0,0,1-1.69,2.92A8.75,8.75,0,0,1,161.05,98.32Z"
style="fill: currentcolor"></path>
<path
d="M156.43,115.65c-.93-.53-4.7-2.7-5.57-3.22a6.65,6.65,0,0,1-1.4-1.1,11.81,11.81,0,0,1-2.75-5.31,35.47,35.47,0,0,1-1.06-7.63c-.06-2.14-.1-4.45-.1-7s0-4.91.1-7.23a55.06,55.06,0,0,1,1.06-8.85,38.81,38.81,0,0,1,1.75-6.06l5.62,3.25a39,39,0,0,0-1.74,6,53.12,53.12,0,0,0-1.06,8.86q-.1,3.48-.11,7.23c0,2.5,0,4.81.11,7a34.34,34.34,0,0,0,1.06,7.63,11.71,11.71,0,0,0,2.74,5.3A6.54,6.54,0,0,0,156.43,115.65Z"
style="opacity: 0.15"></path>
<path
d="M176.06,55.85a7.13,7.13,0,0,0-3-.79q-2.79-.14-6.68,2.1a24.57,24.57,0,0,0-6.67,5.61,33.21,33.21,0,0,0-4.63,7.36c-.19.41-.36.81-.53,1.23l-.47,1.19h0l-5.62-3.25c.13-.36.27-.71.41-1.06s.38-.9.59-1.35a33.3,33.3,0,0,1,4.62-7.38,24.76,24.76,0,0,1,6.68-5.6,12.59,12.59,0,0,1,6.67-2.1,6.9,6.9,0,0,1,3.21.91Z"
style=" opacity: 0.4;fill: #fff"></path>
<path
d="M171.92,89.32a29.32,29.32,0,0,1-.34,3.86,15.52,15.52,0,0,1-.92,3.44A12,12,0,0,1,170,98l-5.62-3.25a12.61,12.61,0,0,0,.63-1.34,15.77,15.77,0,0,0,.94-3.45,29.35,29.35,0,0,0,.33-3.85q.21-6.89,0-13.38c0-.94-.13-1.8-.24-2.59l.33-.21a4.35,4.35,0,0,1,2.59-.78,2.34,2.34,0,0,1,1.66,1,6.11,6.11,0,0,1,.9,2.38,26.61,26.61,0,0,1,.39,3.45Q172.12,82.43,171.92,89.32Z"
style="opacity: 0.3"></path>
<path
d="M170,98a10.51,10.51,0,0,1-1,1.58,8.86,8.86,0,0,1-2.59,2.21,4.38,4.38,0,0,1-2.58.77,2.33,2.33,0,0,1-1.68-1,5.76,5.76,0,0,1-.93-2.37c-.06-.28-.1-.57-.14-.87a8.6,8.6,0,0,0,2.29-2,11.4,11.4,0,0,0,1-1.58Z"
style="opacity: 0.4"></path>
<path
d="M166.38,57.16q3.88-2.25,6.68-2.1a6.71,6.71,0,0,1,4.63,2,11.8,11.8,0,0,1,2.74,5.31A34.85,34.85,0,0,1,181.49,70q.1,3.36.1,7.11t-.1,7.07a54.08,54.08,0,0,1-1.06,8.85,38.67,38.67,0,0,1-2.74,8.47,33.57,33.57,0,0,1-4.63,7.38,24.46,24.46,0,0,1-6.68,5.6,12.68,12.68,0,0,1-6.67,2.1,6.68,6.68,0,0,1-4.63-2,11.71,11.71,0,0,1-2.74-5.3,34.94,34.94,0,0,1-1.06-7.63c-.07-2.14-.1-4.45-.1-7s0-4.9.1-7.23a54,54,0,0,1,1.06-8.85,38.93,38.93,0,0,1,2.74-8.48,33.5,33.5,0,0,1,4.63-7.37A24.57,24.57,0,0,1,166.38,57.16Zm5.54,32.16q.21-6.88,0-13.38a26.64,26.64,0,0,0-.39-3.44,6.17,6.17,0,0,0-.9-2.38,2.31,2.31,0,0,0-1.66-1,4.44,4.44,0,0,0-2.59.78,9,9,0,0,0-2.58,2.21A11.62,11.62,0,0,0,162.14,75a17.86,17.86,0,0,0-.93,3.44,26.75,26.75,0,0,0-.36,3.88q-.25,6.75,0,13.38a21.32,21.32,0,0,0,.34,3.46,5.52,5.52,0,0,0,.93,2.37,2.31,2.31,0,0,0,1.68,1,4.38,4.38,0,0,0,2.58-.77A9,9,0,0,0,169,99.55a11.88,11.88,0,0,0,1.68-2.92,15.76,15.76,0,0,0,.93-3.45A31.14,31.14,0,0,0,171.92,89.32Z"
style="fill: currentcolor"></path>
<path
d="M219.68,56a6.27,6.27,0,0,0-1.16-.85,6.56,6.56,0,0,0-.76-.35,6,6,0,0,1,.58.25l-4.27-2.48h0l5.3-11.28c.21-.44.43-1,.66-1.57a4.82,4.82,0,0,0,.36-1.77V29.59a1.68,1.68,0,0,0-.41-1.26.91.91,0,0,0-.24-.16h0L214.25,25a.81.81,0,0,0-.79.07L189,39.14a2.31,2.31,0,0,0-.83,1,1.49,1.49,0,0,0-.14.24,4.17,4.17,0,0,0-.41,1.74V50.4a1.66,1.66,0,0,0,.41,1.25,1.46,1.46,0,0,0,.21.16c.19.09,4.54,2.62,5.41,3.12,0,0-.05,0-.06-.06h0a.75.75,0,0,0,1,.07l3.61-2.09L197,55.57a17.85,17.85,0,0,0-.71,1.67,3.17,3.17,0,0,0-.14.4c0,.13-.08.26-.11.4a.11.11,0,0,1,0,.05,1.9,1.9,0,0,0,0,.25s0,0,0,.08a3.1,3.1,0,0,0-.05.6v6.76a1.73,1.73,0,0,0,.4,1.26,1.43,1.43,0,0,0,.22.15L202,70.34l-.08-.06a.75.75,0,0,0,.94,0l4.23-2.45h0a7.94,7.94,0,0,1-1.52,3.72,12.92,12.92,0,0,1-4.06,3.6,5.83,5.83,0,0,1-3.13,1.07,5.76,5.76,0,0,1-.66-.1h0l-2.44-1.41a1,1,0,0,0-.34-.11,2,2,0,0,0-1.23.36l-6.44,3.72a2.18,2.18,0,0,0-.79,1,.49.49,0,0,0,0,.11h0a4.15,4.15,0,0,0-.22.65,2.88,2.88,0,0,0-.07.65,12.08,12.08,0,0,0,1.09,5.06,7.11,7.11,0,0,0,3,3.28c.82.46,4.08,2.38,5.34,3.09-.18-.11-.34-.24-.5-.36a6,6,0,0,0,.72.48,7.9,7.9,0,0,0,4.77.78A17.12,17.12,0,0,0,207.06,91a29.39,29.39,0,0,0,15.12-26.58C222.18,60.32,221.35,57.52,219.68,56Z"
style="fill: currentcolor"></path>
<path
d="M188.18,40.22a.64.64,0,0,0,0-.07l-.13.25a4,4,0,0,0-.41,1.74v8.32a1.63,1.63,0,0,0,.41,1.26.7.7,0,0,0,.2.15L193.68,55a.12.12,0,0,0-.06-.06h0a1.65,1.65,0,0,1-.41-1.26V45.34a3.87,3.87,0,0,1,.41-1.72,3,3,0,0,1,.28-.46c-.06.09-.13.17-.19.28Z"
style="opacity: 0.15"></path>
<path
d="M201.46,62.06l-5.56-3.21c0,.06,0,.11,0,.17v6.76a1.73,1.73,0,0,0,.4,1.26,1.43,1.43,0,0,0,.22.15c.21.11,4.83,2.78,5.46,3.15l-.07-.07,0,0a1.65,1.65,0,0,1-.41-1.24V62.23S201.46,62.12,201.46,62.06Z"
style="opacity: 0.15"></path>
<path
d="M201.8,60.45c.24-.61.48-1.16.72-1.67l5.41-11.54-9.72,5.62L197,55.57c-.24.5-.48,1-.71,1.67a3,3,0,0,0-.14.39c0,.14-.08.26-.11.4v.06a2,2,0,0,1,0,.24.19.19,0,0,1,0,.08,2.25,2.25,0,0,0,0,.44l5.56,3.21A5.05,5.05,0,0,1,201.8,60.45Z"
style="opacity: 0.3"></path>
<path
d="M186.45,79.66s0,.07,0,.11h0a3.41,3.41,0,0,0-.22.66,3,3,0,0,0-.08.64,12.13,12.13,0,0,0,1.1,5.07,7,7,0,0,0,3,3.27l5.33,3.1a.45.45,0,0,1-.1-.09,7.07,7.07,0,0,1-2.66-3.06,12,12,0,0,1-1.1-5.07,3.33,3.33,0,0,1,.33-1.41,3,3,0,0,1,.27-.44l-5.57-3.2A2.77,2.77,0,0,0,186.45,79.66Z"
style="opacity: 0.15"></path>
<path
d="M197.71,76.16h0l-2.44-1.42a1.13,1.13,0,0,0-.34-.1,2.08,2.08,0,0,0-1.23.35l-6.44,3.73a1.76,1.76,0,0,0-.52.53l5.57,3.2a1.9,1.9,0,0,1,.53-.53l6.43-3.71c.71-.41,1.26-.48,1.63-.19l-3.17-1.85Z"
style="opacity: 0.3"></path>
<path
d="M203.92,79.47a5.75,5.75,0,0,0,3.15-1.07,12.88,12.88,0,0,0,4.05-3.6,8.13,8.13,0,0,0,1.62-4.94c0-1.82-.55-2.86-1.62-3.08a6,6,0,0,0-4.05,1.1,7.85,7.85,0,0,1-1.52,3.71,12.88,12.88,0,0,1-4.05,3.6,5.71,5.71,0,0,1-3.14,1.06,4.25,4.25,0,0,1-.65-.09L200.88,78l1.26.89A3.75,3.75,0,0,0,203.92,79.47Z"
style="opacity: 0.4"></path>
<path d="M214.07,52.55s3.08,1.8,4.27,2.48a.46.46,0,0,0-.14-.05.34.34,0,0,0-.15-.07,7.72,7.72,0,0,0-4.86-.48Z"
style=" opacity: 0.4;fill: #fff"></path>
<path
d="M216.76,26.52l-2.52-1.47a.81.81,0,0,0-.79.07L189,39.21a2.36,2.36,0,0,0-.84.94.64.64,0,0,1,0,.07l5.55,3.22c.06-.11.13-.19.19-.28a3,3,0,0,1,.19-.3,1.79,1.79,0,0,1,.49-.43L219,28.34a.82.82,0,0,1,.71-.11Z"
style=" opacity: 0.4;fill: #fff"></path>
<path
d="M219,28.26a.75.75,0,0,1,1,.07,1.68,1.68,0,0,1,.41,1.26v8.34A4.82,4.82,0,0,1,220,39.7c-.23.61-.45,1.13-.66,1.57l-5.3,11.28-.88,1.88a7.58,7.58,0,0,1,5.33.71,6.63,6.63,0,0,1,1.16.85c1.67,1.53,2.5,4.33,2.5,8.42A29.39,29.39,0,0,1,207.06,91a17.12,17.12,0,0,1-6.51,2.42,7.9,7.9,0,0,1-4.77-.78,7.12,7.12,0,0,1-3-3.27,12.2,12.2,0,0,1-1.1-5.07,3.3,3.3,0,0,1,.33-1.41,2.07,2.07,0,0,1,.8-1l6.43-3.72c.72-.41,1.26-.48,1.64-.2s.79.58,1.25.89a3.68,3.68,0,0,0,1.78.58,5.86,5.86,0,0,0,3.14-1.06,13.09,13.09,0,0,0,4.06-3.61,8,8,0,0,0,1.61-4.93c0-1.84-.53-2.86-1.61-3.08a6.09,6.09,0,0,0-4.06,1.08l-4.23,2.45a.75.75,0,0,1-1-.07,1.69,1.69,0,0,1-.4-1.26V62.23a5,5,0,0,1,.35-1.78c.24-.61.48-1.16.72-1.67l5.41-11.54-13.33,7.7a.75.75,0,0,1-1-.07,1.69,1.69,0,0,1-.41-1.26V45.28a4.06,4.06,0,0,1,.41-1.73,2.61,2.61,0,0,1,1-1.19Z"
style="fill: currentcolor"></path>
</g>
</g>
<g id="freepik--Character--inject-70">
<g id="freepik--character--inject-70">
<path d="M414.41,218.19l7.08-.31,4.58,8.68s-2.85,1.48-13.05,1.6Z" style="fill: #f28f8f"></path>
<path
d="M369.6,197.3c2.7,1.27,4.17,2.74,7.07,5.1,3.58,2.92,15.93,11.31,18.58,12a170.44,170.44,0,0,0,21.36,3.44s-1.15,7,.34,10.45c-6.34.28-22.5.82-28.14-.51-6-1.42-12.66-4.8-17.78-7.77S367.05,199.82,369.6,197.3Z"
style="fill: currentcolor"></path>
<g style="opacity: 0.7">
<path
d="M369.6,197.3c2.7,1.27,4.17,2.74,7.07,5.1,3.58,2.92,15.93,11.31,18.58,12a170.44,170.44,0,0,0,21.36,3.44s-1.15,7,.34,10.45c-6.34.28-22.5.82-28.14-.51-6-1.42-12.66-4.8-17.78-7.77S367.05,199.82,369.6,197.3Z"
style="fill: #fff"></path>
</g>
<path
d="M371,220.06c5.12,3,11.74,6.35,17.78,7.77,4.08,1,13.68.95,21.08.76a118.81,118.81,0,0,1-19-3.06,73.51,73.51,0,0,1-11.77-6.2c-3.33-2.37-3.53-6.62-5.23-12.77-2.26-8.16-4.25-9.26-4.25-9.26C367.05,199.82,365.92,217.09,371,220.06Z"
style="opacity: 0.1"></path>
<path d="M409.89,228.59a14.48,14.48,0,0,1,.31-8.69s-2.06,2-1.62,8.72Z" style="fill: currentcolor"></path>
<path d="M409.89,228.59a14.48,14.48,0,0,1,.31-8.69s-2.06,2-1.62,8.72Z" style="opacity: 0.1"></path>
<path
d="M424.39,226.71c6-.21,8.23-3.25,9.07-8.52s.69-12.16.76-14-.47-2.46-1.2-2.56c-.27,0-1.43.25-1.56,2.2-.24,3.56-.33,5.75-1,5.72s-.57-2.66-.51-6.25c0-2.42,0-4.46-1.4-4.46s-1.79,1.44-1.86,4.71,0,5.7-.86,5.77c-.7,0-.56-3.43-.72-5.67s-.15-3.58-1.55-3.55-1.61,1.83-1.56,4a86.09,86.09,0,0,1-.23,9c-.39,1.29-1.73-1.89-2.71-3.2-1.61-2.15-3.58-1.17-2.78.79a38.83,38.83,0,0,1,2.18,7.4C418.88,220.58,419.89,226.73,424.39,226.71Z"
style="fill: #ffa8a7"></path>
<path d="M424.36,215.82s3.62,3.77,2.32,7.8a5.35,5.35,0,0,0,.65-5.4A4.09,4.09,0,0,0,424.36,215.82Z"
style="fill: #f28f8f"></path>
<path
d="M345.39,404.83c-.13,1.14-.28,4.34-6.07,5.13s-9.44-1.12-11-3.9-1.19-5.06-1.44-7.64-2.37-3.95-3-5.28c-.9-1.95.42-5,.42-5Z"
style="fill: #263238"></path>
<path
d="M387.63,395.77a3.49,3.49,0,0,1-.38,2.8,12.16,12.16,0,0,1-9.28,2.48,22.39,22.39,0,0,1-9.81-3.85,12.92,12.92,0,0,0-7.58-2.18c-2.79-.1-4.82-.72-5-1.45-.37-1.28-.37-2.1.23-2.06Z"
style="fill: #263238"></path>
<path
d="M345,402.2a31.89,31.89,0,0,0-2.66-3.17,28.64,28.64,0,0,1-6-15.36c0-.31-.06-.91-.37-1.1s-.63.08-1,.22h0v0a6,6,0,0,1-1.79.47,33.38,33.38,0,0,1-4.83-.19c-.4.05-.52,1.29-.49,2.62-.73-.46-1-1.38-1.62-1.91-.36-.29-.51-.3-.51-.77,0-.31,0-.59,0-.9-.52-.15-1,1.87-1.4,3.41-.5,1.78-1.12,3.79-.42,5.6a15.72,15.72,0,0,0,1.63,2.8,11.62,11.62,0,0,1,2.1,5.12c.08.81,0,1.64.13,2.45a7.16,7.16,0,0,0,5.06,5.87c3.52,1.11,8.82.93,11.93-1.53C345.85,405,345.48,403.15,345,402.2Z"
style="fill: #455a64"></path>
<path
d="M385.29,392c-.77-.24-1.53-.52-2.28-.82a41.85,41.85,0,0,1-6.07-3c-.85-.52-1.69-1.06-2.51-1.63s-1.65-1.27-2.47-1.93a8.81,8.81,0,0,1-1.18-1.26,13,13,0,0,1-1.74-2.82,1,1,0,0,0-.43-.57.84.84,0,0,0-.82.17,4,4,0,0,1-.64.43l-.68.28a7.85,7.85,0,0,1-2.28.56c-2.94.26-3-.33-3.16.62a7.93,7.93,0,0,0,0,1.06c-1.55-.25-2.77-.76-2.84-1.34l-.18-1.88c-2.31-.32-2.08,2.38-2.36,5.34-.23,2.54-.82,4.73-.12,6.58,2.33,2,6.46,1.54,8.81,1.93,3.32.55,4.88,3,9.5,4.61,7.44,2.58,12.15-.4,13.54-1.69C388.28,395,388.46,393.05,385.29,392Z"
style="fill: #455a64"></path>
<path
d="M329.2,250.14c-.93,9-1.91,22.55-2.29,33.12-.7,19.86-.43,44.69-.43,44.69a68.59,68.59,0,0,0-2.14,12.73c-.47,12.69-.38,44.1-.38,44.1s5.26,5.3,13.13,1.14c0,0,7-42.87,8.92-55.38,1.87-11.93,5.5-38,5.5-38l1.64,36.05a52.37,52.37,0,0,0-1.23,16.26c.42,5.81,3.74,37.44,3.74,37.44,3,2.84,11.84,1.3,13.77-1,0,0,3.09-45.34,3.43-51.47.74-13.26,1-63.83,0-71.5S329.2,250.14,329.2,250.14Z"
style="fill: #263238"></path>
<path d="M351.51,292.56l2.31-15.29a30.68,30.68,0,0,0,11-4.64s-1.8,4.08-8.82,7l-2.28,14.23-.55,34.75Z"></path>
<path
d="M340,155.33s-.21,0-.54.11a2.48,2.48,0,0,0-1.33-2.8,2.67,2.67,0,0,0-3.45,1.41l3.76,1.73a5.24,5.24,0,0,0-2.86,2.44c-1,2.12.33,6.64,1.7,12.22a79,79,0,0,0,3,10.34c.63,1.63,1.77,1.68,1.77,1.68v-5.57l-.24-4.61s3-4.05,3.29-7.37c.41-4.26-.48-6-.48-6Z"
style="fill: #263238"></path>
<path
d="M342,171.54c-1.11,1-2-1.53-2.95-2.51s-4-2.3-5.5.91,1.39,7.71,3.68,8.77c3.34,1.55,4.84-1.82,4.84-1.82v13.93c3.52,6.35,11.29,6.14,14.89,7a12.33,12.33,0,0,0-.14-6.25l0-4.54a16.7,16.7,0,0,0,4.6.25c3-.48,4.67-3,5.58-6.28,1.47-5.29,1.77-14.18-.27-24.45-3.4-2.63-14.92-2.21-22.06,2.32C345.19,168,343.14,170.57,342,171.54Z"
style="fill: #ffa8a7"></path>
<path
d="M356.82,187.06s-6.79-1.34-9.17-2.6a7.88,7.88,0,0,1-3.29-3.23,10.64,10.64,0,0,0,1.88,3.82c1.74,2.21,10.59,3.82,10.59,3.82Z"
style="fill: #f28f8f"></path>
<path d="M353.73,169.64a1.45,1.45,0,1,1-1.45-1.45A1.45,1.45,0,0,1,353.73,169.64Z" style="fill: #263238"></path>
<path d="M365.24,168.58a1.45,1.45,0,1,1-1.45-1.45A1.45,1.45,0,0,1,365.24,168.58Z" style="fill: #263238"></path>
<path d="M351.77,165.78l-3,1.59a1.79,1.79,0,0,1,.75-2.37A1.67,1.67,0,0,1,351.77,165.78Z" style="fill: #263238">
</path>
<path d="M354.48,178.6l5.09,1.32a2.57,2.57,0,0,1-3.15,2A2.75,2.75,0,0,1,354.48,178.6Z" style="fill: #b16668">
</path>
<path
d="M355,179.67a3.05,3.05,0,0,0-.52.05,2.73,2.73,0,0,0,2,2.17,2.41,2.41,0,0,0,1.28,0A2.77,2.77,0,0,0,355,179.67Z"
style="fill: #f28f8f"></path>
<path d="M366.44,166.06l-3.12-1.48a1.66,1.66,0,0,1,2.25-.86A1.82,1.82,0,0,1,366.44,166.06Z"
style="fill: #263238"></path>
<polygon points="358.23 167.93 359.14 177.24 363.79 175.15 358.23 167.93" style="fill: #f28f8f"></polygon>
<path
d="M336.08,190.82c-6.18,2.21-10.77,4.37-15.06,8.05,0,0,4.44,19.27,7.22,29.88,2.52,9.67.16,29.37.16,29.37s3.89,5.88,26,5.24C366.9,263,373,259,373,259s1.06-21.73.58-39.9c-.38-14.62-1.44-18.15-3.93-21.81-1.8-1.22-11.75-4.9-11.75-4.9a26.09,26.09,0,0,0-.86,5.45C353.36,192.18,336.08,190.82,336.08,190.82Z"
style="fill: currentcolor"></path>
<path
d="M336.08,190.82c-6.18,2.21-10.77,4.37-15.06,8.05,0,0,4.44,19.27,7.22,29.88,2.52,9.67.16,29.37.16,29.37s3.89,5.88,26,5.24C366.9,263,373,259,373,259s1.06-21.73.58-39.9c-.38-14.62-1.44-18.15-3.93-21.81-1.8-1.22-11.75-4.9-11.75-4.9a26.09,26.09,0,0,0-.86,5.45C353.36,192.18,336.08,190.82,336.08,190.82Z"
style=" opacity: 0.3;fill: #fff"></path>
<path
d="M333.15,240.67c-.26-6.51-1.67-18.85-1.57-28.2l-4.41-6.69-2.57,8.31c1.23,5.1,2.56,10.54,3.64,14.66,2.52,9.67.16,29.37.16,29.37s3.89,5.88,26,5.24l.4,0A37.07,37.07,0,0,1,342.93,260C336.06,256.6,333.41,247.19,333.15,240.67Z"
style="opacity: 0.1"></path>
<path
d="M342.1,184.93V186c.2,1,2.25,3.45,7.41,5.77a17.37,17.37,0,0,1,7.48,6.06s-1.76-2.71-3.93-1.28-4.37,5-5.49,5-4.86-3.57-7.79-6.63c-2.45-2.58-3.7-4.13-3.7-4.13S340.09,185,342.1,184.93Z"
style="fill: currentcolor"></path>
<path d="M357,197.85c1.57-3.76,4.4-.55,4.58-.53.82.05-1.79-6.86-4.73-8.76v3Z" style="fill: currentcolor"></path>
<path
d="M342.1,184.93V186c.2,1,2.25,3.45,7.41,5.77a17.37,17.37,0,0,1,7.48,6.06s-1.76-2.71-3.93-1.28-4.37,5-5.49,5-4.86-3.57-7.79-6.63c-2.45-2.58-3.7-4.13-3.7-4.13S340.09,185,342.1,184.93Z"
style=" opacity: 0.65;fill: #fff"></path>
<path d="M357,197.85c1.57-3.76,4.4-.55,4.58-.53.82.05-1.79-6.86-4.73-8.76v3Z" style=" opacity: 0.65;fill: #fff">
</path>
<path d="M361.11,262.77c.26-13.86.62-49.46-4.12-64.92,0,0,4.47,32.91,2.05,65.19Q360.12,262.92,361.11,262.77Z"
style="fill: currentcolor"></path>
<path d="M361.11,262.77c.26-13.86.62-49.46-4.12-64.92,0,0,4.47,32.91,2.05,65.19Q360.12,262.92,361.11,262.77Z"
style="opacity: 0.1"></path>
<path d="M338.56,214.48a38.54,38.54,0,0,0,14.09-1.7l.22,2.72a35,35,0,0,1-14,1.46Z" style="fill: currentcolor">
</path>
<path d="M338.56,214.48a38.54,38.54,0,0,0,14.09-1.7l.22,2.72a35,35,0,0,1-14,1.46Z" style="opacity: 0.1"></path>
<g id="freepik--Shield--inject-70">
<path
d="M373.17,208.11a.2.2,0,0,0-.07-.2h0c-.05,0-.38-.23-.43-.26h0c-.05,0-.12,0-.22.06a3.15,3.15,0,0,1-3.12.34,2.24,2.24,0,0,1-.35-.34v0h0a.32.32,0,0,0-.09-.08l-.44-.27h0c-.1-.05-.2,0-.27.14-.93,2.11-2.84,4.22-4.08,4.72a.7.7,0,0,0-.25.17.53.53,0,0,0-.15.35c-.09,2.75,1.27,7.19,4.07,8.76a5.58,5.58,0,0,0,.52.32C372.32,217.85,373.06,211.37,373.17,208.11Z"
style="fill: #ebebeb"></path>
<path
d="M367.74,221.45c-2.8-1.57-4.16-6-4.07-8.76a.55.55,0,0,1,.06-.22l.43.28a.46.46,0,0,0-.05.21C364,215.56,365.23,219.68,367.74,221.45Z"
style="fill: #e0e0e0"></path>
<path
d="M373.17,208.11c-.11,3.26-.85,9.74-4.91,13.66-2.86-1.53-4.24-6-4.15-8.81a.53.53,0,0,1,.15-.35.74.74,0,0,1,.25-.17c1.24-.5,3.15-2.61,4.08-4.72.07-.15.16-.19.26-.14h0a.32.32,0,0,1,.09.08h0v0a3,3,0,0,0,3.91.28.25.25,0,0,1,.22-.07h0A.2.2,0,0,1,373.17,208.11Z"
style="fill: #fafafa"></path>
<path
d="M368.85,207.58c-.1-.05-.19,0-.26.14-.93,2.11-2.84,4.22-4.08,4.72a.74.74,0,0,0-.25.17.53.53,0,0,0-.15.35c-.09,2.77,1.29,7.28,4.15,8.81A30.26,30.26,0,0,0,368.85,207.58Z"
style="fill: #f0f0f0"></path>
</g>
<path d="M346.57,160.89s9.32,4.54,19.32.61c10.27-4.05,1.27-6.92,1.27-6.92Z" style="fill: #263238"></path>
<path
d="M367.42,141c-7.75-1.72-16.22-2.63-26.39,1.54s-12.73,10.4-12.73,10.4,9.86,3.38,18.19,1.55S367.42,141,367.42,141Z"
style="fill: #455a64"></path>
<path
d="M334.13,158.62s-5.45-4.43-5.83-5.73a34.25,34.25,0,0,0,11.82-1.45c6.68-2,13.93-8.7,21.41-10.25s10.4,2,10.4,2a35.42,35.42,0,0,1-4.74,8.65s-2.61,5.09-11.41,6.75S334.13,158.62,334.13,158.62Z"
style="fill: #37474f"></path>
<path
d="M334.13,158.62a14.94,14.94,0,0,0,.42,1.74,8.37,8.37,0,0,0,.81,1.47c3.12.61,10.62,1.1,20.51-1.26,6.2-1.49,9.06-3.21,10.24-4.45a3.36,3.36,0,0,0,1.2-2.9l-.12-1.37s-2.06,2.73-12.2,5.26A70.36,70.36,0,0,1,334.13,158.62Z"
style="fill: currentcolor"></path>
<path
d="M334.13,158.62a14.94,14.94,0,0,0,.42,1.74,8.37,8.37,0,0,0,.81,1.47c3.12.61,10.62,1.1,20.51-1.26,6.2-1.49,9.06-3.21,10.24-4.45a3.36,3.36,0,0,0,1.2-2.9l-.12-1.37s-2.06,2.73-12.2,5.26A70.36,70.36,0,0,1,334.13,158.62Z"
style="opacity: 0.05"></path>
<path
d="M339.53,295.16c-1-1.46-3.31-2.78-4.17-3.64-1.52-1.54-3.74-4.79-3.41-5.39s1.26.18,3.2.17c3,0,3.82-1.18,3.79-2.28,0-.86-1.83-.7-4-1.18-1.91-.61-4.2-2.76-5.45-4.45s-2.26-6.1-2.26-6.1-6.49.09-11,3.16c0,0,1.29,6.7,2.77,11.45,1.65,5.33,5.39,11.21,11.08,12.53a13.83,13.83,0,0,0,7.16-.36,5.29,5.29,0,0,0,1.9-.94A2,2,0,0,0,339.53,295.16Z"
style="fill: #ffa8a7"></path>
<path
d="M321,198.87s-1-.2-2.68,3.66a61.94,61.94,0,0,0-3.27,11.53c-.67,3.22-3.87,20.13-3.87,27.4s2.17,21.88,5,34.33c3.48.35,9.46-.55,11.46-2.83-1.31-12.42-2.41-18.81-2.11-28.58,2-14.5,7.87-29.69,8.12-31.38C334.18,209.29,328.32,197.63,321,198.87Z"
style="fill: currentcolor"></path>
<path
d="M321,198.87s-1-.2-2.68,3.66a61.94,61.94,0,0,0-3.27,11.53c-.67,3.22-3.87,20.13-3.87,27.4s2.17,21.88,5,34.33c3.48.35,9.46-.55,11.46-2.83-1.31-12.42-2.41-18.81-2.11-28.58,2-14.5,7.87-29.69,8.12-31.38C334.18,209.29,328.32,197.63,321,198.87Z"
style=" opacity: 0.65;fill: #fff"></path>
<path
d="M316.27,260c-1.74-8.5-4.59-25.14-2.64-38.23-1.12,6.43-2.43,15-2.43,19.69,0,7.27,2.17,21.88,5,34.33a20.33,20.33,0,0,0,4.16-.08C319.11,271.6,317.34,265.24,316.27,260Z"
style="opacity: 0.1"></path>
<path d="M314.94,269.69c2.84.18,7.89-.62,10-2,0,0-3.68,1.63-10.19.7Z" style="fill: currentcolor"></path>
<path d="M314.94,269.69c2.84.18,7.89-.62,10-2,0,0-3.68,1.63-10.19.7Z" style="opacity: 0.1"></path>
<g id="freepik--shield--inject-70">
<path
d="M364.79,145.63c0-.08,0-.13,0-.15h0l-.32-.2h0s-.1,0-.17,0a2.37,2.37,0,0,1-2.33.25,1.6,1.6,0,0,1-.26-.26h0a.19.19,0,0,0-.07-.06l-.32-.2h0c-.07,0-.14,0-.19.11a7.61,7.61,0,0,1-3.05,3.52.5.5,0,0,0-.19.13.41.41,0,0,0-.11.26c-.07,2,.95,5.37,3,6.54a3,3,0,0,0,.38.24C364.16,152.9,364.71,148.07,364.79,145.63Z"
style="fill: #ebebeb"></path>
<path
d="M360.74,155.59c-2.1-1.17-3.11-4.49-3-6.54a.42.42,0,0,1,0-.16l.33.2a.29.29,0,0,0,0,.16C358,151.19,358.86,154.27,360.74,155.59Z"
style="fill: #e0e0e0"></path>
<path
d="M364.79,145.63c-.08,2.44-.63,7.27-3.67,10.2-2.13-1.14-3.16-4.51-3.09-6.58a.36.36,0,0,1,.11-.26.59.59,0,0,1,.18-.13,7.5,7.5,0,0,0,3.05-3.52c.05-.11.13-.15.2-.11h0a.19.19,0,0,1,.07.06h0a2.19,2.19,0,0,0,2.92.21c.07-.05.12-.06.16,0h0S364.8,145.55,364.79,145.63Z"
style="fill: #fafafa"></path>
<path
d="M361.57,145.23c-.07,0-.15,0-.2.11a7.5,7.5,0,0,1-3.05,3.52.59.59,0,0,0-.18.13.36.36,0,0,0-.11.26c-.07,2.07,1,5.44,3.09,6.58A22.54,22.54,0,0,0,361.57,145.23Z"
style="fill: #f0f0f0"></path>
</g>
</g>
</g>
<g id="freepik--speech-bubble--inject-70">
<g id="freepik--speech-bubble--inject-70">
<g id="freepik--speech-bubble--inject-70">
<path d="M349.86,130l-5.46-12.44,4.39-12.67V97.08l-13.44,7.76v7.76l5.78,12.18a.87.87,0,0,0,.39.35h0Z"
style="fill: currentcolor"></path>
<path d="M349.86,130l-5.46-12.44,4.39-12.67V97.08l-13.44,7.76v7.76l5.78,12.18a.87.87,0,0,0,.39.35h0Z"
style="opacity: 0.2"></path>
<path
d="M390.07,55.14a8.93,8.93,0,0,0-4-7l-3.28-1.89a8.88,8.88,0,0,0-8.06,0L297.61,90.86a8.9,8.9,0,0,0-4,7V128.6a8.93,8.93,0,0,0,4,7l3.28,1.89a8.88,8.88,0,0,0,8.06,0l34.84-20,5.77,12.17a.86.86,0,0,0,1.55-.15l6.1-19.77L386,92.88a8.91,8.91,0,0,0,4-7Z"
style="fill: currentcolor"></path>
<path
d="M293.58,128.6a8.93,8.93,0,0,0,4,7l3.28,1.89a9,9,0,0,0,7.37.33c-1.89.71-3.34-.36-3.34-2.65V104.38a8.2,8.2,0,0,1,1.18-4l-11.34-6.55a8.26,8.26,0,0,0-1.18,4Z"
style="opacity: 0.2"></path>
<path
d="M389.94,54c-.47-1.71-2-2.25-3.89-1.18L309,97.41a7.84,7.84,0,0,0-2.84,3l-11.33-6.54a8,8,0,0,1,2.83-3l77.08-44.6a9,9,0,0,1,8.07,0l3.29,1.9A8.93,8.93,0,0,1,389.94,54Z"
style=" opacity: 0.5;fill: #fff"></path>
</g>
<path
d="M310.48,123.13V106.88a2.14,2.14,0,0,1,.15-.88,1.11,1.11,0,0,1,.47-.51l4.61-2.67c.17-.09.29-.06.37.1a2.33,2.33,0,0,1,.12.91v.8a3.6,3.6,0,0,1-.12,1.05.84.84,0,0,1-.37.52l-2.61,1.51v3.77l2.46-1.42c.17-.1.29-.07.37.09a2.44,2.44,0,0,1,.11.92v.8a3.74,3.74,0,0,1-.11,1,.87.87,0,0,1-.37.52l-2.46,1.42v6.76a1.64,1.64,0,0,1-1,1.39l-.67.38C310.81,123.77,310.48,123.68,310.48,123.13Z"
style="fill: #455a64"></path>
<path
d="M317.25,111q0-9.22,4.39-11.77,2.14-1.23,3.26.37c.74,1.06,1.12,3.18,1.12,6.34a21.71,21.71,0,0,1-1.12,7.64,7.75,7.75,0,0,1-3.26,4.13Q317.26,120.21,317.25,111Zm5.38,2.24a6.69,6.69,0,0,0,.55-2.11,27.55,27.55,0,0,0,.19-3.66,22.45,22.45,0,0,0-.19-3.41,2.52,2.52,0,0,0-.55-1.48c-.25-.2-.57-.18-1,0a2.53,2.53,0,0,0-1,1.08,7,7,0,0,0-.57,2.12,27.42,27.42,0,0,0-.19,3.64,22.69,22.69,0,0,0,.19,3.42,2.51,2.51,0,0,0,.57,1.48.83.83,0,0,0,1,0A2.63,2.63,0,0,0,322.63,113.2Z"
style="fill: #455a64"></path>
<path
d="M327.56,113.27V97a2,2,0,0,1,.16-.88,1.11,1.11,0,0,1,.51-.54L331,94a2.29,2.29,0,0,1,2.48-.26c.63.43.94,1.55.94,3.37a9,9,0,0,1-1.59,5.28v.11a1.13,1.13,0,0,1,.67.64,4.44,4.44,0,0,1,.45,1.29l1,4.38.05.28c0,.46-.34.89-1,1.29l-.58.34c-.59.34-.93.31-1-.11l-.89-4.39a1.08,1.08,0,0,0-.34-.6c-.13-.08-.33,0-.61.12l-.4.23v5.83a1.67,1.67,0,0,1-1,1.41l-.57.33C327.89,113.9,327.56,113.82,327.56,113.27Zm3.52-11.63a1.69,1.69,0,0,0,.62-.93,5.19,5.19,0,0,0,.26-1.8,2.64,2.64,0,0,0-.26-1.44.47.47,0,0,0-.68-.11l-.88.51v4.31Z"
style="fill: #455a64"></path>
<path
d="M336.35,108.72a1.09,1.09,0,0,1-.15-.7V92a2.09,2.09,0,0,1,.15-.85,1.11,1.11,0,0,1,.47-.51l3-1.73c2.35-1.36,3.52-.58,3.52,2.32a8.92,8.92,0,0,1-1.51,5.13l0,.09a1.28,1.28,0,0,1,1.34.73,5,5,0,0,1,.49,2.48,9.46,9.46,0,0,1-1,4.24,7,7,0,0,1-2.84,3l-3.05,1.77C336.61,108.82,336.45,108.82,336.35,108.72Zm3.49-12.47a1.85,1.85,0,0,0,.79-1,5.05,5.05,0,0,0,.26-1.82,2.79,2.79,0,0,0-.24-1.44q-.24-.34-.78,0l-1.19.69v4.25Zm.12,7.51a2.12,2.12,0,0,0,.91-1.06,5.23,5.23,0,0,0,.29-2,2.65,2.65,0,0,0-.28-1.52c-.19-.23-.5-.22-.92,0l-1.28.73v4.52Z"
style="fill: #455a64"></path>
<path
d="M345.15,103.11V86.6a1.62,1.62,0,0,1,1-1.41l.71-.41c.63-.37.95-.26.95.3v16.51a1.63,1.63,0,0,1-.95,1.41l-.71.4C345.47,103.78,345.15,103.68,345.15,103.11Z"
style="fill: #455a64"></path>
<path
d="M349.78,101a1,1,0,0,1-.16-.7v-16a2,2,0,0,1,.16-.88,1,1,0,0,1,.46-.51l3.19-1.84q2.18-1.26,3.21.39c.68,1.1,1,3.17,1,6.19a22.19,22.19,0,0,1-1,7.38,7.47,7.47,0,0,1-3.21,4.1l-3.19,1.83C350,101.07,349.87,101.08,349.78,101Zm3.56-5.19a3.08,3.08,0,0,0,1.28-2,20.41,20.41,0,0,0,.38-4.59,14.66,14.66,0,0,0-.38-4.15c-.26-.7-.68-.89-1.28-.54l-1.07.61V96.4Z"
style="fill: #455a64"></path>
<path
d="M359.44,95.39a1.11,1.11,0,0,1-.15-.7v-16a2.14,2.14,0,0,1,.15-.88,1.11,1.11,0,0,1,.47-.51l3.19-1.84q2.17-1.26,3.2.39t1,6.19a22,22,0,0,1-1,7.38,7.41,7.41,0,0,1-3.2,4.1l-3.19,1.83C359.7,95.48,359.54,95.49,359.44,95.39Zm3.57-5.2a3.07,3.07,0,0,0,1.28-2,20.48,20.48,0,0,0,.38-4.59,14.66,14.66,0,0,0-.38-4.15c-.26-.71-.69-.89-1.28-.55l-1.07.62v11.3Z"
style="fill: #455a64"></path>
<path
d="M369.11,89.81a1.11,1.11,0,0,1-.15-.7v-16a2.12,2.12,0,0,1,.15-.87,1.18,1.18,0,0,1,.47-.52l4.94-2.85a.23.23,0,0,1,.37.09,2.39,2.39,0,0,1,.12.92v.8a3.64,3.64,0,0,1-.12,1,.87.87,0,0,1-.37.52L371.57,74v3.74l2.62-1.51c.17-.09.29-.06.37.1a2.3,2.3,0,0,1,.12.91V78a3.6,3.6,0,0,1-.12,1.05.84.84,0,0,1-.37.52l-2.62,1.51v4.18l3-1.71c.17-.1.29-.07.36.1a2.63,2.63,0,0,1,.11.92v.8a4,4,0,0,1-.11,1,.82.82,0,0,1-.36.52l-5,2.86C369.37,89.9,369.21,89.91,369.11,89.81Z"
style="fill: #455a64"></path>
<path
d="M376.53,85V68.48a1.61,1.61,0,0,1,1-1.38l.43-.26a1,1,0,0,1,.54-.16c.13,0,.24.14.33.38l3,6.67a13.89,13.89,0,0,1,.57,1.69l.07-.1c-.09-.84-.14-1.49-.14-2V65.13a1.62,1.62,0,0,1,1-1.38l.41-.23c.64-.38,1-.29,1,.26V80.29a1.64,1.64,0,0,1-1,1.39l-.32.18a1.06,1.06,0,0,1-.56.18c-.14,0-.26-.14-.35-.38l-3.2-6.92a10.16,10.16,0,0,1-.45-1.39l-.08.12a14.88,14.88,0,0,1,.13,1.68v8.49a1.62,1.62,0,0,1-1,1.39l-.4.23C376.86,85.63,376.53,85.54,376.53,85Z"
style="fill: #455a64"></path>
</g>
</g>
<g id="freepik--Plant--inject-70">
<g id="freepik--Pot--inject-70">
<g id="freepik--pot--inject-70">
<path
d="M124.7,425.24c8.41-8.69,13.36-44,5.15-50.91H88.08c-8.2,6.88-3.27,42.21,5.15,50.9l.23.24.29.28a8.57,8.57,0,0,0,.76.69l.2.16.63.48a10,10,0,0,0,1.09.7c6.92,4.05,18.15,4.05,25.07,0h0a10,10,0,0,0,1.09-.7c.21-.15.4-.3.6-.46l.24-.19c.27-.22.51-.44.74-.66l.33-.33Z"
style="fill: #455a64"></path>
<path
d="M91.71,371.55c-9.53,5.57-9.53,14.59,0,20.15s25,5.56,34.51,0,9.53-14.58,0-20.15S101.24,366,91.71,371.55Z"
style="fill: #455a64"></path>
<g style="opacity: 0.1">
<path
d="M91.71,371.55c-9.53,5.57-9.53,14.59,0,20.15s25,5.56,34.51,0,9.53-14.58,0-20.15S101.24,366,91.71,371.55Z"
style="fill: #fff"></path>
</g>
<path d="M96.29,374.23c-7,4.08-7,10.71,0,14.79s18.35,4.09,25.35,0,7-10.71,0-14.79S103.29,370.14,96.29,374.23Z"
style="fill: #263238"></path>
<path
d="M121.63,381.25c-7-4.09-18.34-4.09-25.34,0a11.69,11.69,0,0,0-4.19,3.89A11.76,11.76,0,0,0,96.29,389c7,4.09,18.35,4.09,25.34,0a11.72,11.72,0,0,0,4.2-3.88A11.65,11.65,0,0,0,121.63,381.25Z"
style="fill: #f5f5f5"></path>
</g>
<g id="freepik--Plants--inject-70">
<path
d="M85.81,305.77l16.7,11.42-15.79-6a28.78,28.78,0,0,0,3.12,12.14s10.43,5.06,16.1,10.4l-13.89-4.37a15.32,15.32,0,0,0,.43,7.26c.09.32.19.65.29,1,.74,2.22,1.79,6.43,3.56,11.4h0a73.25,73.25,0,0,0,5.74,12.56,51.3,51.3,0,0,0,3.82,5.64l.26.34q3.87-2.58,8-5.05c1.6-4.1,3.37-14.06,3.69-22.14,1.21-30.93-23.23-46.89-42.31-51.47C75.59,288.91,82.57,296.5,85.81,305.77Z"
style="fill: currentcolor"></path>
<path
d="M85.81,305.77l16.7,11.42-15.79-6a28.78,28.78,0,0,0,3.12,12.14s10.43,5.06,16.1,10.4l-13.89-4.37a15.32,15.32,0,0,0,.43,7.26c.09.32.19.65.29,1,.74,2.22,1.79,6.43,3.56,11.4h0a73.25,73.25,0,0,0,5.74,12.56,51.3,51.3,0,0,0,3.82,5.64l.26.34q3.87-2.58,8-5.05c1.6-4.1,3.37-14.06,3.69-22.14,1.21-30.93-23.23-46.89-42.31-51.47C75.59,288.91,82.57,296.5,85.81,305.77Z"
style="opacity: 0.3"></path>
<path
d="M99.13,306.12a22.94,22.94,0,0,1,4.34,5.23,48.28,48.28,0,0,1,3.06,6.1,62.65,62.65,0,0,1,3.74,13.08,57.68,57.68,0,0,1-1.47,26.89h0a.44.44,0,0,0,.85.26h0a58.35,58.35,0,0,0,1.06-27.23,62.82,62.82,0,0,0-4-13.09,47.87,47.87,0,0,0-3.16-6.07A23.37,23.37,0,0,0,99.13,306.12Z"
style="fill: #fafafa"></path>
<path
d="M157.52,321.57l0,0c-.38.49-6.29,5.64-15.36,21.07l-18.39,4.62,15,1.35-6.88,12-15.7,3.88,12.44,1.54s-3,12.18-11.61,17.55c-4.78,3-7.15,3.48-8.67,2.15-1.06-.94-1.52-6.71-2.58-11.84s-1.45-13.52,3-23.83a31.46,31.46,0,0,1,4.78-7.64C124.72,329,146.58,321.83,157.52,321.57Z"
style="fill: currentcolor"></path>
<path
d="M157.52,321.57l0,0c-.38.49-6.29,5.64-15.36,21.07l-18.39,4.62,15,1.35-6.88,12-15.7,3.88,12.44,1.54s-3,12.18-11.61,17.55c-4.78,3-7.15,3.48-8.67,2.15-1.06-.94-1.52-6.71-2.58-11.84s-1.45-13.52,3-23.83a31.46,31.46,0,0,1,4.78-7.64C124.72,329,146.58,321.83,157.52,321.57Z"
style="opacity: 0.15"></path>
<path
d="M112.17,355.34a0,0,0,0,0,0,0v0A48.67,48.67,0,0,0,109,368.81h0a145.8,145.8,0,0,0,.22,17.45,2.92,2.92,0,0,1-.91-.51c-1.06-.94-1.52-6.71-2.58-11.84s-1.45-13.52,3-23.83a31.46,31.46,0,0,1,4.78-7.64c11.2-13.49,33.06-20.63,44-20.89-16.68,3.39-34.29,15.26-42.7,28.59A34.19,34.19,0,0,0,112.17,355.34Z"
style="opacity: 0.1"></path>
<path
d="M140.91,327.48c-8.17,4-15.85,9.28-21.77,16.31a43.5,43.5,0,0,0-7.21,11.67,41.81,41.81,0,0,0-3,13.34,0,0,0,0,0,.09,0,53.43,53.43,0,0,1,3.72-13,50.07,50.07,0,0,1,6.94-11.55,57.58,57.58,0,0,1,9.76-9.41,75.9,75.9,0,0,1,11.5-7.28,0,0,0,1,0,0-.08Z"
style="fill: #fafafa"></path>
<path
d="M60.05,333.25h0a33.68,33.68,0,0,1,4,0,64.21,64.21,0,0,1,15.67,2.9c1.89.59,3.78,1.26,5.66,2,.93.39,1.86.8,2.78,1.23a45,45,0,0,1,12.34,8.3,28.44,28.44,0,0,1,4.39,5.5c.16.26.33.52.48.78h0c.39.68.73,1.36,1.07,2A38.81,38.81,0,0,1,111,374.83c.09,4.62-1.19,10-2,10.89a2.23,2.23,0,0,1-.38.32c-1.27.91-3.39.54-7.42-1.43-8.07-3.94-11.76-14.86-11.76-14.86l10.78-2.45-14.12-2-6.17-8.54,10.34-2.47L76,352.87a209.33,209.33,0,0,0-15.88-19.6l0,0Z"
style="fill: currentcolor"></path>
<path
d="M64.1,333.22a64.21,64.21,0,0,1,15.67,2.9c1.89.59,3.78,1.26,5.66,2,.93.39,1.86.8,2.78,1.23a45,45,0,0,1,12.34,8.3,28.44,28.44,0,0,1,4.39,5.5c.16.26.33.52.48.78h0c.39.68.73,1.36,1.07,2A38.81,38.81,0,0,1,111,374.83c.09,4.62-1.19,10-2,10.89a2.23,2.23,0,0,1-.38.32,2.42,2.42,0,0,1-.85.37c.57-7.2-4-25.13-9.68-32.29-6-7.45-19.73-18-38-20.85l0,0A33,33,0,0,1,64.1,333.22Z"
style="opacity: 0.05"></path>
<path
d="M107.81,386.41a61.14,61.14,0,0,0-1.91-15.75A50.94,50.94,0,0,0,99.83,356a36,36,0,0,0-5.13-6.15,52.73,52.73,0,0,0-6.14-5.12,59.51,59.51,0,0,0-14.07-7.4,0,0,0,0,0-.06,0,.06.06,0,0,0,0,.06,78.8,78.8,0,0,1,13.58,8,66.22,66.22,0,0,1,6,5,35.22,35.22,0,0,1,5.15,5.9,50.3,50.3,0,0,1,6.23,14.42,61.24,61.24,0,0,1,2.25,15.64,0,0,0,0,0,0,0A0,0,0,0,0,107.81,386.41Z"
style="fill: #fafafa"></path>
</g>
</g>
</g>
</svg>
</template>
<script lang="ts" setup></script>
<style lang="scss" scoped></style>
@@ -1,363 +0,0 @@
<template>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 500">
<g id="freepik--Floor--inject-37">
<ellipse id="freepik--floor--inject-37" cx="249.03" cy="368.25" rx="228.44" ry="118.95" style="fill: #f5f5f5">
</ellipse>
</g>
<g id="freepik--Shadows--inject-37">
<ellipse id="freepik--Shadow--inject-37" cx="395.38" cy="348.61" rx="60.93" ry="35.18" style="fill: #e6e6e6">
</ellipse>
<g id="freepik--shadow--inject-37">
<path id="freepik--shadow--inject-37"
d="M150,327.73c23.31,13.46,24.26,35.68.94,49.14s-62.05,13.06-85.37-.4-23.31-35.28,0-48.74S126.67,314.27,150,327.73Z"
style="fill: #e6e6e6"></path>
<path id="freepik--shadow--inject-37"
d="M340.14,400.26l-76.52-44.18a9.57,9.57,0,0,0-8.66,0l-76.52,44.18c-2.39,1.38-2.39,3.62,0,5l34.85,20.12-32.55,18.79c-6.61,3.81-17.37,3.81-24,0l-51.2-29.56c-2.82-1.63-4.38-3.68-4.38-5.76s1.56-4.14,4.38-5.77l45.37-26.2a2,2,0,1,0-2-3.46L103.56,399.6c-4.11,2.38-6.38,5.66-6.38,9.24s2.27,6.85,6.38,9.23l51.2,29.56a30.56,30.56,0,0,0,28,0l34.55-19.94L255,449.44a9.57,9.57,0,0,0,8.66,0l76.52-44.18C342.53,403.88,342.53,401.64,340.14,400.26Z"
style="fill: #e6e6e6"></path>
</g>
</g>
<g id="freepik--character-2--inject-37">
<g id="freepik--Character--inject-37">
<g id="freepik--Bottom--inject-37">
<path
d="M427.58,332.09s2.78-41.18,2-56.36c-.65-12-2.28-17-2.62-19.71,0,0-2.95-28-3.19-51.89-.12-11.48-1.18-19.64-7.47-33.28l-40.43,9.67c-.82,6.06-3.6,46.36-4.26,82.19-.57,31.37.32,58.83.32,58.83l0,1.65c0,1.84-.4,3.12-1.58,6.06a35.32,35.32,0,0,1-6.26,10.36c-.83.9-6.6,5.94-7.36,7-2.48,2.89,2.66,4.52,6.47,4,4-.54,10.26-2.07,12-4.51,1.18-1.64,2.07-7.35,3.28-9,4.09-5.58,5.77-8,5.8-9.76.06-3.22-1.05-4.49-1.45-6.31.33-3.8,8.54-35.05,8.68-46.12.07-5.27-.29-12.53-.29-12.53l6.36-36.52c2.46,9.12,6.78,31.76,8.24,40.45,1.77,10.62,6.4,37.88,9.14,54.14,1.05,6.27,1.54,9.44,2,12.35l.11,1.24c.09,1.58,1.24,18.48,1.86,22,1.3,7.39,7.87,6.46,8.92.48.9-5.08-.22-20.84-.25-22.77Z"
style="fill: #ffa8a7"></path>
<path
d="M427.58,332.09c1.86,0,.64,7.21,1.12,11.82.51,4.95,2.13,8.57,2.6,12.62a16.48,16.48,0,0,1-1.55,10.39c-1.29,3-7.79,7-10.26,2.79s-3-9.08-2.71-13.7,0-7.72.09-11.35c.09-3.2-2.26-11.37.15-11.83l.11,1.24c.87,1.73,9.65,2.07,10.53-.27Z"
style="fill: #37474f"></path>
<path d="M384.7,331.27c.57,2.31,0,8.65,0,8.65s-1,2.19-4.57,3.64l-1.6-8.82Z" style="fill: #263238"></path>
<polygon points="380.11 343.56 372.25 340.98 370.35 334 379.19 338.47 380.11 343.56"></polygon>
<path
d="M371.93,323.19l0-1.65c-1.07.52-3.42,9.13-6.6,15-2.9,5.39-8.65,8.39-10.52,10.74-2.5,3.13,2.36,7.18,10.15,5.51,3.87-.83,9.73-3.3,11.32-5.91s2.12-7.41,3.42-9.33,4.39-4.13,5-6.31a12,12,0,0,0,0-6c-.61-2-1.15-4.39-1.83-4.17l0,1.51c-.52,1.06-2.41,2.3-6.34,2.52C374.61,325.19,372.79,324.9,371.93,323.19Z"
style="fill: #37474f"></path>
<path
d="M375.05,180s-2.67,29.67-3.53,55.94-.09,60.17-.09,60.17,2.71,1.94,8.68,2.21,8-1.72,8-1.72,3.65-11.91,4.22-20.29a85.71,85.71,0,0,0,0-13.63l5.33-35.06s6.76,34.52,7.53,38.69,7.24,41.06,7.24,41.06,2.54,2.34,9.06,2.22c5.77-.11,7.44-2.18,7.44-2.18s1.39-22.62,1.07-32.28c-.27-8.52-2.22-15.3-2.61-20.83s-.61-37-1-49S425,183,414.73,168.56Z"
style="fill: #455a64"></path>
<path d="M397.7,227.65l-4.44-22s-7.73-2-11.34-6.74c0,0,1,5.24,9,8.59l4.72,21.88L394,252Z"
style="fill: #37474f"></path>
</g>
<g id="freepik--Top--inject-37">
<path
d="M318.56,174.53a19.1,19.1,0,0,0,8.51-.63,16.74,16.74,0,0,1-3.37-2.23,2.33,2.33,0,0,1-.4-3.22c.37-.4,1.29.53,3.37,1.12,2.66.75,4.59.91,7.15,2.39a4.69,4.69,0,0,0,3.2.56c6.24-1.17,20.79-8,27.46-11.56,1.36-5.55,3.72-13.71,6.63-23.89,2.69-9.38,7-13.48,13.88-13.33L384,144.11s-3.28,14.07-7.34,25.56c-.71,2-3.56,4.33-8.78,6.27-6.76,2.51-14.92,4.88-24.89,7.61A77.29,77.29,0,0,1,330.65,186c-10.54.9-14.58-2-16-4.08C310.61,176.18,313,173.42,318.56,174.53Z"
style="fill: #ffa8a7"></path>
<path
d="M402.72,123.59l9.62.74a22.36,22.36,0,0,0,7.24,21.54l-4.29,17.28c.14,2.14,3.68,9.34,7.11,17.08-6.45,8.64-38.09,11.59-48.41,4,1.59-8.14,2.78-14.32,3.1-17.41l-.52-11.17c-12.94-10.61,2.67-26.78,8.42-31.92l7.22-.32Z"
style="fill: currentcolor"></path>
<path
d="M443.23,209.68a5.39,5.39,0,0,1-2.06-4.64c.17-1.61.54-3.63,1.21-4.41s4.87-6.49,6.73-3.17c2,3.62,1.59,5.09,1.59,5.09Z"
style="fill: #f28f8f"></path>
<path
d="M430.27,286a25.84,25.84,0,0,1-12.75-3.86L367.59,253.3c-7.71-4.45-14-15.32-14-24.23V187.18a8,8,0,0,0-12-6.9L324.11,190.4a2,2,0,1,1-2-3.46l17.53-10.13a12,12,0,0,1,18,10.37v41.89c0,7.5,5.5,17,12,20.77l49.93,28.82c6.39,3.69,12.32,4.33,16.68,1.82s6.77-8,6.77-15.35V211.65c0-9.06,5.79-19.5,13.18-23.77l12.19-7a2,2,0,1,1,2,3.46l-12.19,7c-6.06,3.5-11.18,12.79-11.18,20.3v53.48c0,8.86-3.12,15.54-8.77,18.81A15.68,15.68,0,0,1,430.27,286Z"
style="fill: #37474f"></path>
<g id="freepik--Plug--inject-37">
<path
d="M344,193.29v3.27c0,5.23-3.67,11.6-8.21,14.21l-30.28,17.49-30.79-17.78V183.82L304.58,170c4.75-2.19,12.27-1.85,16.81.76l14.38,8.31C340.3,181.69,344,188.06,344,193.29Z"
style="fill: #37474f"></path>
<path
d="M304.58,170c4.75-2.19,12.27-1.85,16.81.76l14.38,8.31c4.53,2.61,4.35,6.51-.4,8.71l-29.89,13.8-30.8-17.77Z"
style="fill: #455a64"></path>
<path d="M308.39,195.18a9.07,9.07,0,0,1,4.1,7.1v21.93l-7,4-30.79-17.78V183.82l7.8-3.6Z"
style="opacity: 0.15"></path>
<path
d="M272.07,179.23a2.85,2.85,0,0,1,2.88.28L305.23,197a9.06,9.06,0,0,1,4.1,7.11v26.08a2.85,2.85,0,0,1-1.2,2.64c-.7.39-3.17,1.82-3.86,2.23a2.87,2.87,0,0,1-2.89-.28l-30.29-17.49a9.07,9.07,0,0,1-4.1-7.1V184.11a2.89,2.89,0,0,1,1.19-2.65Z"
style="fill: #37474f"></path>
<path
d="M301.38,199.22l-30.29-17.48c-2.26-1.31-4.1-.25-4.1,2.37v26.08a9.07,9.07,0,0,0,4.1,7.1l30.29,17.49c2.26,1.31,4.1.25,4.1-2.37V206.33A9.09,9.09,0,0,0,301.38,199.22Z"
style="fill: #455a64"></path>
<path
d="M265.51,229.58v4.51c0,1.83.63,3.1,1.67,3.7l2.72,1.57A4,4,0,0,0,274,239l25-14.46V206.74l-2.72-1.57-25.05,14.46A12.69,12.69,0,0,0,265.51,229.58ZM276.84,224A4,4,0,0,1,277,225a8.5,8.5,0,0,1-3.85,6.67,3.62,3.62,0,0,1-1,.4,4.11,4.11,0,0,1-.14-1,8.51,8.51,0,0,1,3.85-6.67A4.74,4.74,0,0,1,276.84,224Z"
style="fill: currentcolor"></path>
<path
d="M269.76,239.26a1,1,0,0,0,.17.12h0l-.1-.06-2.63-1.53c-1.05-.58-1.67-1.85-1.67-3.69v-4.51a11.64,11.64,0,0,1,1.69-5.67l2.72,1.57a11.8,11.8,0,0,0-1.68,5.67v4.51a4.59,4.59,0,0,0,1.05,3.22A2.45,2.45,0,0,0,269.76,239.26Z"
style="opacity: 0.2"></path>
<path
d="M299,206.74,274,221.2a11.72,11.72,0,0,0-4.06,4.28l-2.72-1.57a11.78,11.78,0,0,1,4.05-4.28l25.05-14.46Z"
style=" opacity: 0.5;fill: #fff"></path>
<path d="M270,239.45l-.07,0,0,0S270,239.45,270,239.45Z" style=" opacity: 0.5;fill: #fff"></path>
<path d="M270,239.43l0,0,0,0Z" style="opacity: 0.2"></path>
<path
d="M277,225a4.27,4.27,0,0,0-.14-1.07h0c1.65-.45,2.86.58,2.86,2.64a8.52,8.52,0,0,1-3.84,6.67c-1.78,1-3.3.49-3.72-1.17a3.27,3.27,0,0,0,1-.4A8.53,8.53,0,0,0,277,225Z"
style="opacity: 0.2"></path>
<path
d="M242.42,216.24v4.52c0,1.82.63,3.1,1.67,3.69l2.72,1.58a4,4,0,0,0,4.08-.38l25-14.47V193.41l-2.72-1.58-25,14.46A12.72,12.72,0,0,0,242.42,216.24Zm11.33-5.61a4.33,4.33,0,0,1,.14,1.07,8.51,8.51,0,0,1-3.85,6.67,4.6,4.6,0,0,1-1,.4,3.81,3.81,0,0,1-.14-1.05,8.52,8.52,0,0,1,3.84-6.67A3.91,3.91,0,0,1,253.75,210.63Z"
style="fill: currentcolor"></path>
<path
d="M246.93,226.1l-.05,0-.07,0-2.72-1.59c-1.05-.59-1.67-1.86-1.67-3.7v-4.51a9.88,9.88,0,0,1,.45-2.84,13.48,13.48,0,0,1,1.23-2.82h0l2.72,1.56h0a12.69,12.69,0,0,0-.69,1.38,10.89,10.89,0,0,0-1,4.28v4.51a4.61,4.61,0,0,0,1,3.22A2.8,2.8,0,0,0,246.93,226.1Z"
style="opacity: 0.2"></path>
<path d="M275.92,193.41l-25,14.46a11.64,11.64,0,0,0-4.06,4.28l-2.72-1.56a11.77,11.77,0,0,1,4-4.3l25-14.46Z"
style=" opacity: 0.5;fill: #fff"></path>
<path d="M247,226.12l-.07,0,.05,0Z" style=" opacity: 0.5;fill: #fff"></path>
<path
d="M253.88,211.69a4.21,4.21,0,0,0-.13-1.06h0c1.64-.46,2.86.58,2.86,2.64a8.52,8.52,0,0,1-3.84,6.67c-1.79,1-3.3.49-3.72-1.18a3.12,3.12,0,0,0,1-.4A8.5,8.5,0,0,0,253.88,211.69Z"
style="opacity: 0.2"></path>
</g>
<path
d="M250,199.55a1.49,1.49,0,0,1-1.45-1.13l-4-15.68a1.5,1.5,0,0,1,2.91-.75l4,15.69a1.48,1.48,0,0,1-1.08,1.82A1.57,1.57,0,0,1,250,199.55Z"
style="fill: #e0e0e0"></path>
<path
d="M238.74,206.09a1.5,1.5,0,0,1-.93-.32L222.92,194a1.5,1.5,0,1,1,1.86-2.35l14.89,11.76a1.51,1.51,0,0,1,.25,2.11A1.48,1.48,0,0,1,238.74,206.09Z"
style="fill: #e0e0e0"></path>
<path
d="M218.22,220.45a1.5,1.5,0,0,1-.11-3l17.41-1.35a1.49,1.49,0,0,1,1.61,1.38,1.51,1.51,0,0,1-1.38,1.61l-17.41,1.35Z"
style="fill: #e0e0e0"></path>
<path
d="M456.84,193.36a98.58,98.58,0,0,0-1.64-11,148.11,148.11,0,0,0-9.06-24.81c-1.67-3.19-5.44-7.84-8.11-11.77-3.78-5.55-6.44-8.66-9.31-12.43-6.32-8.27-9-8.75-16.38-9-1,2.63-3.28,13.41,4.11,22.12l15.84,16.7c.9,1.45,10.58,18,12.19,24.11a4.52,4.52,0,0,1-.38,3.23,39,39,0,0,0-2.77,8.76c-.47,2.12-1.73,3.8-1.3,4.13a2.84,2.84,0,0,0,3.51-.28,15.05,15.05,0,0,0,2.73-4.12,2.15,2.15,0,0,1,2.29,2.19c.09,1.23-.47,2.94-.9,5.07-.08.42-.18.9-.37,2.06a13.42,13.42,0,0,0-.28,2.38c2,.37,4.09-.85,7.45-4C457.49,203.76,457.69,199.9,456.84,193.36Z"
style="fill: #ffa8a7"></path>
<path
d="M404.44,118.73c.06-2,6.56-6.68,9.85-11.66,3-4.62,7.31-17.32-2.79-21.38,0,0,2.18-6.09-1.78-9.68s-9.29-1.37-10.13.13a9,9,0,0,0-8.46-6.64,7.87,7.87,0,0,0-8.28,6.17,7.59,7.59,0,0,0-9.21,2.58c-3.71,5.11,1.21,9.79,1.21,9.79A4.25,4.25,0,0,0,373,92c.29,2.16,2.36,2.69,2.6,3.77a1.06,1.06,0,0,1-1.81.94,2.18,2.18,0,0,0,2.56,1.73c2.33-.13,4.41-3.3,4.41-3.3Z"
style="fill: #263238"></path>
<path
d="M383.24,85.05c-3,1.3-5.83,5.87-5.79,18.65,0,10.83,3.36,13.57,5,14.38s4.95.39,8.14-.1v6.23s-5.77,7.16-.6,10.72c13.32-2.33,14.34-11.07,14.34-11.07l.24-13.58s1.83,1.92,5-.9c2.66-2.33,3.62-6.32,1.62-8.52s-4.56-2.37-6.88.08c0,0-4.25.28-10.64-3.73S385,89.13,383.24,85.05Z"
style="fill: #ffa8a7"></path>
<path d="M390.91,110.48a1.56,1.56,0,0,1-1.48,1.66,1.61,1.61,0,1,1,1.48-1.66Z" style="fill: #b16668"></path>
<path d="M382.68,100a1.44,1.44,0,1,1-1.5-1.45A1.47,1.47,0,0,1,382.68,100Z" style="fill: #263238"></path>
<path d="M393.75,100.66a1.56,1.56,0,0,1-1.48,1.66,1.59,1.59,0,0,1-1.6-1.56,1.54,1.54,0,1,1,3.08-.1Z"
style="fill: #263238"></path>
<path d="M381.68,94.27l-3.05,1.79a1.7,1.7,0,0,0,2.4.65A1.83,1.83,0,0,0,381.68,94.27Z" style="fill: #263238">
</path>
<path d="M404.37,99.18l0,6a2.82,2.82,0,0,1-2.89-2.92A3.1,3.1,0,0,1,404.37,99.18Z" style="fill: #263238">
</path>
<polygon points="386.62 98.57 386.01 107.21 381.45 106.14 386.62 98.57" style="fill: #f28f8f"></polygon>
<path d="M390.63,118c3.35-.39,10.27-2.31,11.4-5.13a7.35,7.35,0,0,1-2.48,3.57c-2.09,1.8-8.93,3.66-8.93,3.66Z"
style="fill: #f28f8f"></path>
</g>
<g id="freepik--question-marks--inject-37">
<path
d="M430.9,51.18a13.78,13.78,0,0,1,3.55,2,10.75,10.75,0,0,1,2.65,2.79,8.68,8.68,0,0,1,1.3,3.44,7.65,7.65,0,0,1-.47,3.87,7.9,7.9,0,0,1-1.59,2.66,9.5,9.5,0,0,1-2.13,1.68,14.81,14.81,0,0,1-2.4,1.1l-2.36.85a11.94,11.94,0,0,0-2,.94A3.57,3.57,0,0,0,426,71.85a1.76,1.76,0,0,1-.66.64,1,1,0,0,1-.86.05l-3.12-1.17a1.18,1.18,0,0,1-.67-.63,1,1,0,0,1,0-.89,7.71,7.71,0,0,1,1.74-2.56,10.91,10.91,0,0,1,2.25-1.63,15.6,15.6,0,0,1,2.46-1.06c.84-.28,1.62-.55,2.35-.83a10.4,10.4,0,0,0,1.89-.92,2.79,2.79,0,0,0,1.12-1.38,3.29,3.29,0,0,0-.34-3.06,6,6,0,0,0-3.11-2.31,5.73,5.73,0,0,0-6.43,1.55,2.59,2.59,0,0,1-.69.52,1.15,1.15,0,0,1-.84-.06l-3.32-1.25a.93.93,0,0,1-.54-.49.85.85,0,0,1,0-.75,6.67,6.67,0,0,1,2-2.6,10.71,10.71,0,0,1,3.27-1.86,13,13,0,0,1,4.07-.74A11.48,11.48,0,0,1,430.9,51.18Zm-7.12,23.9a1.1,1.1,0,0,1,.65.62,1.13,1.13,0,0,1,0,.9l-1.36,3.61a1.1,1.1,0,0,1-.62.65,1.13,1.13,0,0,1-.9,0l-3.53-1.33a1.1,1.1,0,0,1-.65-.62,1.13,1.13,0,0,1,0-.9l1.36-3.61a1.15,1.15,0,0,1,.62-.66,1.17,1.17,0,0,1,.9,0Z"
style="fill: currentcolor"></path>
<path
d="M432.63,94.28a1.1,1.1,0,0,1,0,1.57l-2.5,2.64a1.08,1.08,0,0,1-.78.34,1.11,1.11,0,0,1-.8-.3L426,96.08a1.08,1.08,0,0,1-.34-.78,1.07,1.07,0,0,1,.3-.8l2.51-2.63a1.12,1.12,0,0,1,1.57,0Zm15-18.13a13.34,13.34,0,0,1,2.37,3,10.44,10.44,0,0,1,1.27,3.4A8.25,8.25,0,0,1,451.1,86a8,8,0,0,1-4.19,4.91,8.77,8.77,0,0,1-2.46.68,14.86,14.86,0,0,1-2.49.07l-2.36-.13a12.13,12.13,0,0,0-2.11.07,3.4,3.4,0,0,0-1.72.7,1.56,1.56,0,0,1-.81.31.94.94,0,0,1-.77-.27l-2.27-2.16a1.15,1.15,0,0,1-.36-.79.92.92,0,0,1,.32-.79A7.27,7.27,0,0,1,434.32,87a10.23,10.23,0,0,1,2.55-.59,15.29,15.29,0,0,1,2.53,0q1.25.11,2.34.15a9.53,9.53,0,0,0,2-.11,2.61,2.61,0,0,0,1.49-.78,3.13,3.13,0,0,0,.82-2.78,5.62,5.62,0,0,0-1.85-3.15,5.42,5.42,0,0,0-6.16-1,2.3,2.3,0,0,1-.78.19,1,1,0,0,1-.71-.36l-2.42-2.31a.92.92,0,0,1-.3-.61.88.88,0,0,1,.26-.67,6.45,6.45,0,0,1,2.68-1.53,10.2,10.2,0,0,1,3.52-.41,12.17,12.17,0,0,1,3.81.86A10.6,10.6,0,0,1,447.59,76.15Z"
style="fill: currentcolor"></path>
<g style="opacity: 0.6">
<path
d="M432.63,94.28a1.1,1.1,0,0,1,0,1.57l-2.5,2.64a1.08,1.08,0,0,1-.78.34,1.11,1.11,0,0,1-.8-.3L426,96.08a1.08,1.08,0,0,1-.34-.78,1.07,1.07,0,0,1,.3-.8l2.51-2.63a1.12,1.12,0,0,1,1.57,0Zm15-18.13a13.34,13.34,0,0,1,2.37,3,10.44,10.44,0,0,1,1.27,3.4A8.25,8.25,0,0,1,451.1,86a8,8,0,0,1-4.19,4.91,8.77,8.77,0,0,1-2.46.68,14.86,14.86,0,0,1-2.49.07l-2.36-.13a12.13,12.13,0,0,0-2.11.07,3.4,3.4,0,0,0-1.72.7,1.56,1.56,0,0,1-.81.31.94.94,0,0,1-.77-.27l-2.27-2.16a1.15,1.15,0,0,1-.36-.79.92.92,0,0,1,.32-.79A7.27,7.27,0,0,1,434.32,87a10.23,10.23,0,0,1,2.55-.59,15.29,15.29,0,0,1,2.53,0q1.25.11,2.34.15a9.53,9.53,0,0,0,2-.11,2.61,2.61,0,0,0,1.49-.78,3.13,3.13,0,0,0,.82-2.78,5.62,5.62,0,0,0-1.85-3.15,5.42,5.42,0,0,0-6.16-1,2.3,2.3,0,0,1-.78.19,1,1,0,0,1-.71-.36l-2.42-2.31a.92.92,0,0,1-.3-.61.88.88,0,0,1,.26-.67,6.45,6.45,0,0,1,2.68-1.53,10.2,10.2,0,0,1,3.52-.41,12.17,12.17,0,0,1,3.81.86A10.6,10.6,0,0,1,447.59,76.15Z"
style="fill: #fff"></path>
</g>
</g>
</g>
</g>
<g id="freepik--character-1--inject-37">
<g id="freepik--character--inject-37">
<g id="freepik--bottom--inject-37">
<path d="M76.81,345.71c3.17,1.93,7.38,2,11.35.61l3-21-14-3.58Z" style="fill: #ffa8a7"></path>
<path
d="M99.4,365.81c.35.36.14,3-.29,3.59s-2.84,2.59-7.28,2.67c-4.23.07-8-.7-10.36-2.41s-3.49-3.5-3.6-5.92.29-4.71-.75-6.62-2.29-3.51-2.61-4.45a12,12,0,0,1,0-5.17Z"
style="fill: #263238"></path>
<path
d="M89.13,345.44a11.56,11.56,0,0,0,.38,2.7,24.77,24.77,0,0,0,2.29,5.42,22.77,22.77,0,0,0,1.63,2.57c1.19,1.59,2.71,2.92,4,4.45a8.61,8.61,0,0,1,2.33,5.32c0,3.32-3.65,4.25-6.44,4.59a20.33,20.33,0,0,1-9-.93,8.26,8.26,0,0,1-5.69-6.92c-.11-.93,0-1.86-.06-2.79a12.93,12.93,0,0,0-2.26-5.93,17,17,0,0,1-1.8-3.26c-.76-2.09.06-4.36.72-6.37.57-1.73,1-3.82,1.64-3.62,0,.35,0,1.13,0,1.13.18.39.62.67.73,1.13a8.59,8.59,0,0,0,.43,1.39,3.6,3.6,0,0,0,1.38,1.7c.11-1.25.22-2.5.32-3.74a1.31,1.31,0,0,1,1.43-1.49,23.59,23.59,0,0,1,7.11-.21,1.36,1.36,0,0,1,.93.47,1.44,1.44,0,0,1,.11.85A32.79,32.79,0,0,0,89.13,345.44Z"
style="fill: currentcolor"></path>
<path
d="M89.13,345.44a11.56,11.56,0,0,0,.38,2.7,24.77,24.77,0,0,0,2.29,5.42,22.77,22.77,0,0,0,1.63,2.57c1.19,1.59,2.71,2.92,4,4.45a8.61,8.61,0,0,1,2.33,5.32c0,3.32-3.65,4.25-6.44,4.59a20.33,20.33,0,0,1-9-.93,8.26,8.26,0,0,1-5.69-6.92c-.11-.93,0-1.86-.06-2.79a12.93,12.93,0,0,0-2.26-5.93,17,17,0,0,1-1.8-3.26c-.76-2.09.06-4.36.72-6.37.57-1.73,1-3.82,1.64-3.62,0,.35,0,1.13,0,1.13.18.39.62.67.73,1.13a8.59,8.59,0,0,0,.43,1.39,3.6,3.6,0,0,0,1.38,1.7c.11-1.25.22-2.5.32-3.74a1.31,1.31,0,0,1,1.43-1.49,23.59,23.59,0,0,1,7.11-.21,1.36,1.36,0,0,1,.93.47,1.44,1.44,0,0,1,.11.85A32.79,32.79,0,0,0,89.13,345.44Z"
style="opacity: 0.2"></path>
<path
d="M92.21,354.28c-1.18-1-3.94-1.15-5.46-1.07a9.22,9.22,0,0,0-4.37,1.27,1,1,0,0,1-1.25-.17h0a.92.92,0,0,1,.16-1.4,9.45,9.45,0,0,1,4.93-1.53C90,351.32,91,352,91,352S92.64,353.2,92.21,354.28Z"
style="fill: #455a64"></path>
<path
d="M94.86,357.82c-1.5-1-4.54-1-6.06-.95a8.6,8.6,0,0,0-4.25,1.36,1,1,0,0,1-1.26-.17h0a.91.91,0,0,1,.17-1.4,9.55,9.55,0,0,1,5-1.66c3.73-.07,4.66.75,4.66.75A3.07,3.07,0,0,1,94.86,357.82Z"
style="fill: #455a64"></path>
<path
d="M84.93,347.75a9.27,9.27,0,0,1,4.65.64c.63.41,1,1.46.57,1.7A8.66,8.66,0,0,0,86,349.3a12.24,12.24,0,0,0-4.07.89c-.33.12-.71.3-1,.46a.87.87,0,0,1-1.2-.44h0a.84.84,0,0,1,.38-1A11.93,11.93,0,0,1,84.93,347.75Z"
style="fill: #455a64"></path>
<path d="M116.27,337.82c2.44,6.11,6.26,4.23,12.08.71l.88-20.86-14.81-1.37Z" style="fill: #ffa8a7"></path>
<path
d="M150.69,352.53a4,4,0,0,1-.32,2.93c-.46.84-5.09,3.14-11.14,2.4a25.22,25.22,0,0,1-12.32-5.06c-2.23-1.66-4.62-2.07-7.62-2.41s-5.25-1.38-5.84-2.82.31-3.82.31-3.82Z"
style="fill: #263238"></path>
<path
d="M127.13,333.3a11.94,11.94,0,0,0,1.61-.46,1.31,1.31,0,0,1,.91,0c.38.17.5.63.59,1a13.86,13.86,0,0,0,.52,2.67,6.54,6.54,0,0,0,1.6,1.88,27.83,27.83,0,0,0,4.69,3.39c1.93,1.18,3.83,2.11,5.82,3.14s4.78,1.77,6.36,3c2.29,1.74,2.38,5.79-.42,7.23-2.41,1.25-8.65,2.41-15,.23-3.47-1.19-7.17-5.16-11.77-5.77-2.93-.38-6.83-.84-8.6-3.17-.64-1-.08-3.9.44-7.29.47-3,.9-7.8,1.87-7.48l.07.92L117,334a10.07,10.07,0,0,0,.82.78,14.84,14.84,0,0,0,1,1.06,3,3,0,0,0,1.69.71,1.56,1.56,0,0,0,.85-.19c.5-.28.57-.94,1-1.35A4.88,4.88,0,0,1,124,333.9a9.61,9.61,0,0,1,2.66-.54A3.65,3.65,0,0,0,127.13,333.3Z"
style="fill: currentcolor"></path>
<path
d="M127.13,333.3a11.94,11.94,0,0,0,1.61-.46,1.31,1.31,0,0,1,.91,0c.38.17.5.63.59,1a13.86,13.86,0,0,0,.52,2.67,6.54,6.54,0,0,0,1.6,1.88,27.83,27.83,0,0,0,4.69,3.39c1.93,1.18,3.83,2.11,5.82,3.14s4.78,1.77,6.36,3c2.29,1.74,2.38,5.79-.42,7.23-2.41,1.25-8.65,2.41-15,.23-3.47-1.19-7.17-5.16-11.77-5.77-2.93-.38-6.83-.84-8.6-3.17-.64-1-.08-3.9.44-7.29.47-3,.9-7.8,1.87-7.48l.07.92L117,334a10.07,10.07,0,0,0,.82.78,14.84,14.84,0,0,0,1,1.06,3,3,0,0,0,1.69.71,1.56,1.56,0,0,0,.85-.19c.5-.28.57-.94,1-1.35A4.88,4.88,0,0,1,124,333.9a9.61,9.61,0,0,1,2.66-.54A3.65,3.65,0,0,0,127.13,333.3Z"
style="opacity: 0.2"></path>
<path
d="M134.4,340a2.76,2.76,0,0,0-2.1-1.57c-1.32-.32-3.73.54-5.26,1.67a1.1,1.1,0,0,0,.06,1.82h0a1.12,1.12,0,0,0,1.26-.07A8.32,8.32,0,0,1,134.4,340Z"
style="fill: #455a64"></path>
<path
d="M138.41,342.57a3.15,3.15,0,0,0-2.5-1.46,9.76,9.76,0,0,0-5.76,1.81,1.07,1.07,0,0,0,0,1.76h0a1.07,1.07,0,0,0,1.22-.08A8.42,8.42,0,0,1,138.41,342.57Z"
style="fill: #455a64"></path>
<path
d="M142.87,344.91a3.51,3.51,0,0,0-2.6-1.34,9.46,9.46,0,0,0-5.53,1.84,1.07,1.07,0,0,0,.06,1.76h0a1,1,0,0,0,1.21-.07A8,8,0,0,1,142.87,344.91Z"
style="fill: #455a64"></path>
<path
d="M76.42,289.41c.45-10.07,2.59-15.31,2.89-18.1,0,0,.82-55.4,2.17-72.21l49.6-2.11c.73,18,1.39,66.36,1,72.76-.37,6.13-2.86,59.3-2.86,59.3-7,2.19-14.47-1-14.47-1s-4.16-30.25-4.84-36.92a85.23,85.23,0,0,1,.46-18l-3.17-43.07s-3.83,33.4-5.72,46C99.32,290.47,90,335.14,90,335.14c-6.7,1.67-13.22-1.22-13.22-1.22S75.76,304,76.42,289.41Z"
style="fill: #455a64"></path>
<path d="M107.21,230.1l.94-5.94c2.89-.43,10.21-5,14.54-9a34.5,34.5,0,0,1-12.16,11.21l-.15,46.78Z"
style="fill: #37474f"></path>
</g>
<g id="freepik--top--inject-37">
<path
d="M127.55,167.81c-3.37-7.69-9.17-20.64-9.17-20.64l-1.47-21a56.64,56.64,0,0,1,6.41.57c3.12.49,8.07,3.47,10.33,9.09,1.69,4.17,10.47,29.61,10.47,29.61l15.3-8.06c3.92-2.49,5.31-6.62,7.81-9s5-2.74,7.77-4.65,3.86-3.44,4.56-1.53-2.4,4.84-3,5.57-3.61,2.29.23,2.49,11.61-3.54,13.47-4.18,1.7,1.57.73,2.94-1.07,5.39-2.69,7.64c-1.72,2.4-2.65,3.43-6.34,4.86-3.43,1.32-10.54,1.66-14.2,3.77s-12.52,10.12-18.43,14.23c-7.93,5.52-12.39,5.88-15.5,1.48S128.74,170.52,127.55,167.81Z"
style="fill: #ffa8a7"></path>
<path
d="M114.84,125.72c5.2-.4,11.33-.08,14.72,3,2.71,2.47,3.73,4,6.75,12.54,2,5.73,6.28,18.93,6.28,18.93a27.32,27.32,0,0,0-15,9.19l-9.75-21.91Z"
style="fill: #e0e0e0"></path>
<path d="M144.12,165.39a13.09,13.09,0,0,0-6.47,5s.37-4,6-6.39Z" style="fill: #f28f8f"></path>
<path
d="M102.39,124.78a24.57,24.57,0,0,0-7.31.8c-4.57,1.21-12.76,3.51-12.76,3.51-2.6,1.35-3.61,5.85-4.2,8.44-1.88,8.29,3,27,3.75,34.29S81,201.44,81,201.44c5.59,6.48,35.88,10.78,50.63,0,0,0,.64-51.27-.81-58.63-2.2-11.14-5.47-16.43-17-17.1Z"
style="fill: #f5f5f5"></path>
<path d="M108.86,97.28l-3.29,1.81a2,2,0,0,1,.77-2.62A1.83,1.83,0,0,1,108.86,97.28Z" style="fill: #263238">
</path>
<path d="M123.17,98.6l-3-2.31a1.82,1.82,0,0,1,2.61-.4A2,2,0,0,1,123.17,98.6Z" style="fill: #263238"></path>
<path
d="M93.74,86.81S90.2,87.3,88.9,90c-1.12,2.32-.72,7.92.79,14a56.45,56.45,0,0,0,3.8,11.46,4.7,4.7,0,0,0,2.7,2.17L96,110.37l-.26-5s3.23-4.42,3.59-8c.46-4.66-.52-6.57-.52-6.57Z"
style="fill: #263238"></path>
<path
d="M99.45,93.81A13.53,13.53,0,0,0,113,107.29c7.46,0,13.06-6.15,13-13.62s-5.66-13.45-13.13-13.42A13.52,13.52,0,0,0,99.45,93.81Z"
style="fill: #263238"></path>
<path
d="M96,104.52c-1.22,1.06-2.21-1.67-3.23-2.74s-4.37-2.51-6,1,1.46,8.6,4,9.58A3.65,3.65,0,0,0,95.08,111v16c3.85,6.94,10.64,6.72,14.27,6.33s4.42-4.16,1.77-7.2l0-5a28.29,28.29,0,0,0,6.1.29c3.32-.52,5-3,6-6.63,1.6-5.79,2.25-15.51,0-26.74-3.72-2.88-16.62-2.4-24.43,2.55C99.4,100.67,97.16,103.47,96,104.52Z"
style="fill: #ffa8a7"></path>
<path
d="M123.88,82.49a24.39,24.39,0,0,0,.67-6.37c0-.84-.21-1.86-1-2.18s-1.57.26-2.25.72c-2.88,1.94-6.46,2.49-9.93,2.68-6,.33-15.17-.06-18.22,6.51-.85,1.82-1,3.74.68,5a11.5,11.5,0,0,0,5,1.86c3,.53,6,1.19,9.08,1.6s6.74.81,9.79-.13c2.57-.79,5.18-1.47,7.09-3.51a9.78,9.78,0,0,0,2.62-6.54c0-.34-.07-.77-.41-.86a.78.78,0,0,0-.49.1Z"
style="fill: #263238"></path>
<path
d="M111.09,121.24s-7.42-1.47-10-2.84a8.57,8.57,0,0,1-3.6-3.54,11.65,11.65,0,0,0,2,4.18c1.91,2.42,11.58,4.17,11.58,4.17Z"
style="fill: #f28f8f"></path>
<path d="M109.6,102.19a1.67,1.67,0,1,1-1.67-1.72A1.7,1.7,0,0,1,109.6,102.19Z" style="fill: #263238"></path>
<path
d="M112,113.74a1.6,1.6,0,0,1-1.56,1.63,1.61,1.61,0,0,1-1.58-1.63,1.59,1.59,0,0,1,1.56-1.62A1.61,1.61,0,0,1,112,113.74Z"
style="fill: #b16668"></path>
<path d="M107.5,96.94l-3.44,2.17a2.13,2.13,0,0,1,.66-2.88A2,2,0,0,1,107.5,96.94Z" style="fill: #263238">
</path>
<path d="M119.64,94.82l3.62,1.62a1.9,1.9,0,0,1-2.56,1A2.09,2.09,0,0,1,119.64,94.82Z" style="fill: #263238">
</path>
<path d="M121.55,101.69a1.61,1.61,0,1,1-1.62-1.67A1.65,1.65,0,0,1,121.55,101.69Z" style="fill: #263238">
</path>
<polygon points="113.37 98.87 113.97 109.99 119.24 108.59 113.37 98.87" style="fill: #f28f8f"></polygon>
<path
d="M20,144.67c1.73.93,8.78,5.89,12.61,6.32,1.62.18,2.06-.08,2-.5-.08-.58-1.11-1.45-1.36-1.92-.43-.82-3-4.22-2-6s1.87-.08,4.25,2.25,4.82,3.14,6.91,5.85,2.79,7,6.25,10.11l13.78,9.41s6.42-29.79,9.24-33.3c3-3.69,15.87,4.35,13.17,16.08S76,185.06,71.72,189.05c-2.76,2.59-8.57.15-15.82-6.3C50.17,177.65,42.32,170,39,167.29s-10.22-4.17-13.39-6c-3.41-2-4.16-3.17-5.47-5.82-1.23-2.49-.68-6.48-1.41-8S18.24,143.74,20,144.67Z"
style="fill: #ffa8a7"></path>
<path
d="M82.32,129.09c4.42,2.76,4.64,6.78,4.86,11.38a47.57,47.57,0,0,1-2.52,15.84c-1.87,5.79-4.84,16.36-4.84,16.36s-11.54.27-17.48-4.86c0,0,2.71-11.4,4.62-20S71.19,130.06,82.32,129.09Z"
style="fill: #e0e0e0"></path>
<path d="M62.39,170.21c3.15,1.75,5,5.51,5.57,7a11,11,0,0,0-5.24-8.53Z" style="fill: #f28f8f"></path>
</g>
<g id="freepik--Outlet--inject-37">
<polygon points="182.11 386.34 259.29 430.9 259.29 447.32 182.11 402.76 182.11 386.34"
style="fill: currentcolor"></polygon>
<polygon points="182.11 386.34 259.29 430.9 259.29 447.32 182.11 402.76 182.11 386.34" style="opacity: 0.35">
</polygon>
<polygon points="336.47 386.34 259.29 430.9 259.29 447.32 336.47 402.76 336.47 386.34"
style="fill: currentcolor"></polygon>
<polygon points="336.47 386.34 259.29 430.9 259.29 447.32 336.47 402.76 336.47 386.34" style="opacity: 0.2">
</polygon>
<polygon points="336.47 386.34 259.29 341.79 182.11 386.34 259.29 430.9 336.47 386.34"
style="fill: currentcolor"></polygon>
<polygon points="336.47 386.34 259.29 341.79 182.11 386.34 259.29 430.9 336.47 386.34" style="opacity: 0.15">
</polygon>
<polygon points="259.29 430.9 259.29 426.21 190.23 386.34 182.11 386.34 259.29 430.9" style="opacity: 0.1">
</polygon>
<polygon points="259.29 341.79 259.29 346.48 328.35 386.34 336.47 386.34 259.29 341.79" style="opacity: 0.1">
</polygon>
<polygon points="336.47 386.34 328.35 386.34 259.29 426.21 259.29 430.9 336.47 386.34"
style="fill: currentcolor"></polygon>
<polygon points="259.29 341.79 259.29 346.48 190.23 386.34 182.11 386.34 259.29 341.79"
style="fill: currentcolor"></polygon>
<path
d="M259.57,367l33.16,19.14c2.48,1.44,2.48,3.76,0,5.19L268,405.65a9.89,9.89,0,0,1-9,0l-33.16-19.14c-2.48-1.44-2.48-3.76,0-5.19L250.58,367A9.89,9.89,0,0,1,259.57,367Z"
style="fill: #37474f"></path>
<path
d="M268,405.65l23.91-13.81-32.34-18.67a10,10,0,0,0-9,0L226.66,387,259,405.65A9.89,9.89,0,0,0,268,405.65Z"
style="fill: #455a64"></path>
<path
d="M239.54,386.37,254.05,378a1.94,1.94,0,0,1,1.74,0l1.78,1c.48.27.48.72,0,1l-14.51,8.37a1.92,1.92,0,0,1-1.73,0l-1.78-1A.53.53,0,0,1,239.54,386.37Z"
style="fill: #263238"></path>
<path
d="M261.21,398.9l14.51-8.37a1.92,1.92,0,0,1,1.73,0l1.79,1c.48.27.48.72,0,1l-14.51,8.37a1.92,1.92,0,0,1-1.73,0l-1.78-1A.53.53,0,0,1,261.21,398.9Z"
style="fill: #263238"></path>
<path
d="M225.76,418.77a9.64,9.64,0,0,0-4.38-7.57,3.05,3.05,0,0,0-3.09-.3L216.4,412a3.06,3.06,0,0,0-1.28,2.82,9.69,9.69,0,0,0,4.37,7.58,3.07,3.07,0,0,0,3.1.3l1.88-1.13A3.08,3.08,0,0,0,225.76,418.77Z"
style="fill: currentcolor"></path>
<path
d="M219.49,412.33a9.64,9.64,0,0,1,4.38,7.57c0,2.79-2,3.92-4.38,2.53a9.69,9.69,0,0,1-4.37-7.58C215.12,412.07,217.08,410.94,219.49,412.33Z"
style="opacity: 0.1"></path>
</g>
<g id="freepik--Cable--inject-37">
<path
d="M168.76,444.27a28.55,28.55,0,0,1-14-3.39l-51.2-29.56c-4.11-2.38-6.38-5.66-6.38-9.24s2.27-6.85,6.38-9.23l59.32-34.25c6.5-3.75,12-13.26,12-20.77V150.1a2,2,0,0,1,4,0V337.83c0,9.06-6.14,19.71-14,24.24l-59.32,34.25c-2.82,1.63-4.38,3.67-4.38,5.76s1.56,4.14,4.38,5.77l51.2,29.56c6.61,3.82,17.37,3.82,24,0l37.75-21.78a2,2,0,1,1,2,3.46l-37.75,21.79A28.5,28.5,0,0,1,168.76,444.27Z"
style="fill: #37474f"></path>
</g>
<g id="freepik--exclamation-marks--inject-37">
<path
d="M78.92,78.31a1,1,0,0,1,.16-.79,1,1,0,0,1,.68-.45l4.86-.94a1,1,0,0,1,.8.16,1.09,1.09,0,0,1,.45.68l.75,3.9a1,1,0,0,1-.17.79,1,1,0,0,1-.67.46l-4.87.93a1,1,0,0,1-.79-.16,1,1,0,0,1-.45-.68ZM74.86,57.25A1.06,1.06,0,0,1,75.7,56l4.87-.94a1,1,0,0,1,.79.17,1,1,0,0,1,.45.67L85,72.57a1,1,0,0,1-.17.79,1,1,0,0,1-.67.45l-4.87.94a1,1,0,0,1-.79-.17,1,1,0,0,1-.45-.67Z"
style="fill: currentcolor"></path>
<path
d="M70.8,94.63a1.06,1.06,0,0,1,.08-1.5l3.69-3.31a1,1,0,0,1,.77-.26,1,1,0,0,1,.73.34l2.65,3a1.06,1.06,0,0,1-.08,1.5L75,97.67a1,1,0,0,1-.77.26,1,1,0,0,1-.73-.34Zm-14.31-16a1.07,1.07,0,0,1-.27-.77,1,1,0,0,1,.35-.73l3.69-3.31a1,1,0,0,1,.77-.27,1,1,0,0,1,.73.35L73.08,86.56a1,1,0,0,1,.26.77,1,1,0,0,1-.34.73l-3.7,3.31a1,1,0,0,1-.76.26,1,1,0,0,1-.74-.34Z"
style="fill: currentcolor"></path>
<g style="opacity: 0.6">
<path
d="M70.8,94.63a1.06,1.06,0,0,1,.08-1.5l3.69-3.31a1,1,0,0,1,.77-.26,1,1,0,0,1,.73.34l2.65,3a1.06,1.06,0,0,1-.08,1.5L75,97.67a1,1,0,0,1-.77.26,1,1,0,0,1-.73-.34Zm-14.31-16a1.07,1.07,0,0,1-.27-.77,1,1,0,0,1,.35-.73l3.69-3.31a1,1,0,0,1,.77-.27,1,1,0,0,1,.73.35L73.08,86.56a1,1,0,0,1,.26.77,1,1,0,0,1-.34.73l-3.7,3.31a1,1,0,0,1-.76.26,1,1,0,0,1-.74-.34Z"
style="fill: #fff"></path>
</g>
</g>
</g>
</g>
<g id="freepik--error-404--inject-37">
<g id="freepik--Text--inject-37">
<path
d="M166,48a7.12,7.12,0,0,1,4.77,1.45,5.24,5.24,0,0,1,1.7,4.23,5.34,5.34,0,0,1-1.7,4.26A7.07,7.07,0,0,1,166,59.44H162v5.65a.66.66,0,0,1-.2.49.67.67,0,0,1-.48.2h-2.05a.68.68,0,0,1-.69-.69V48.71a.68.68,0,0,1,.69-.68ZM162,56.27h3.93a4.11,4.11,0,0,0,2.31-.57,2.19,2.19,0,0,0,.86-2,2.14,2.14,0,0,0-.86-2,4.29,4.29,0,0,0-2.31-.54H162Z"
style="fill: #455a64"></path>
<path
d="M174.76,55.84a3.58,3.58,0,0,1,.47-1.14,4.24,4.24,0,0,1,1-1.14,5.61,5.61,0,0,1,1.65-.88,6.82,6.82,0,0,1,2.27-.34,7.36,7.36,0,0,1,2.33.34,5.13,5.13,0,0,1,1.79,1,4.38,4.38,0,0,1,1.15,1.66,6.13,6.13,0,0,1,.41,2.3v7.45a.67.67,0,0,1-.21.49.66.66,0,0,1-.48.2h-1.92a.68.68,0,0,1-.69-.69v-.83A4.13,4.13,0,0,1,181,65.51a5.48,5.48,0,0,1-2.55.52,6.15,6.15,0,0,1-2-.29,4,4,0,0,1-1.45-.82,3.74,3.74,0,0,1-.9-1.26,3.91,3.91,0,0,1-.31-1.58,3.3,3.3,0,0,1,1.24-2.74A7.21,7.21,0,0,1,178.44,58l4.13-.71a1.62,1.62,0,0,0-.68-1.47,3.22,3.22,0,0,0-1.7-.43,2.24,2.24,0,0,0-1,.18,2.81,2.81,0,0,0-.68.48,1.6,1.6,0,0,1-.42.28,1.16,1.16,0,0,1-.42.08h-2.36a.6.6,0,0,1-.43-.16A.39.39,0,0,1,174.76,55.84ZM179,63a4.55,4.55,0,0,0,1.53-.24,3.46,3.46,0,0,0,1.13-.65,2.68,2.68,0,0,0,.68-.91,2.42,2.42,0,0,0,.23-1V59.9l-3.45.6a3.67,3.67,0,0,0-1.49.52,1.09,1.09,0,0,0-.46.93.83.83,0,0,0,.55.79A3.14,3.14,0,0,0,179,63Z"
style="fill: #455a64"></path>
<path
d="M195,68.31a3.89,3.89,0,0,0,1.09-.16,2.94,2.94,0,0,0,1-.52,3,3,0,0,0,.75-.9,2.75,2.75,0,0,0,.29-1.28v-.94a4.37,4.37,0,0,1-.53.49,4.06,4.06,0,0,1-.8.5,5.54,5.54,0,0,1-1.09.38,6.1,6.1,0,0,1-1.41.15,5.2,5.2,0,0,1-2.29-.49,5.36,5.36,0,0,1-1.75-1.32,6.17,6.17,0,0,1-1.14-1.9,6.9,6.9,0,0,1-.47-2.25c0-.25,0-.55,0-.88s0-.64,0-.89a6.9,6.9,0,0,1,.47-2.25,6.29,6.29,0,0,1,1.14-1.9A5.36,5.36,0,0,1,192,52.83a5.2,5.2,0,0,1,2.29-.49,6.1,6.1,0,0,1,1.41.15,5.54,5.54,0,0,1,1.09.38,4.06,4.06,0,0,1,.8.5,4.37,4.37,0,0,1,.53.49v-.58a.7.7,0,0,1,.68-.69h1.93a.72.72,0,0,1,.69.69V65.17a6,6,0,0,1-1.72,4.63A6.74,6.74,0,0,1,195,71.36a8,8,0,0,1-2.4-.35,6.51,6.51,0,0,1-1.91-.91,4.84,4.84,0,0,1-1.3-1.29,3,3,0,0,1-.53-1.49.57.57,0,0,1,.19-.48.71.71,0,0,1,.49-.2h1.73a.85.85,0,0,1,.61.24c.17.16.31.31.43.44a2.39,2.39,0,0,0,.9.71A4.21,4.21,0,0,0,195,68.31ZM192,58.48a6.74,6.74,0,0,0,0,1.42,3.37,3.37,0,0,0,1,2.37,3.15,3.15,0,0,0,2.1.72,3.07,3.07,0,0,0,2.09-.74,3,3,0,0,0,1-2.1,8.31,8.31,0,0,0,.05-1,8.5,8.5,0,0,0-.05-1,3,3,0,0,0-3.07-2.84,3.15,3.15,0,0,0-2.1.72A3.37,3.37,0,0,0,192,58.48Z"
style="fill: #455a64"></path>
<path
d="M204.27,59.19a8.14,8.14,0,0,1,.44-2.68A6.32,6.32,0,0,1,206,54.33a5.82,5.82,0,0,1,2-1.46,6.58,6.58,0,0,1,5.15,0,6.06,6.06,0,0,1,2,1.39,6.35,6.35,0,0,1,1.26,2.06,7.06,7.06,0,0,1,.44,2.47v1.14a.62.62,0,0,1-.2.48.64.64,0,0,1-.48.21h-8.47a2.11,2.11,0,0,0,.24,1,2.24,2.24,0,0,0,.65.75,2.84,2.84,0,0,0,.94.46,3.93,3.93,0,0,0,1.09.15,4.25,4.25,0,0,0,1.31-.17,3,3,0,0,0,.84-.41,2.34,2.34,0,0,1,.46-.28,1.26,1.26,0,0,1,.48-.08h2a.71.71,0,0,1,.49.2.55.55,0,0,1,.19.49,2.19,2.19,0,0,1-.39.91,4.55,4.55,0,0,1-1.1,1.09,7.19,7.19,0,0,1-1.82.91,7.53,7.53,0,0,1-2.49.38,6.49,6.49,0,0,1-2.58-.49,5.44,5.44,0,0,1-2-1.41A6.19,6.19,0,0,1,204.71,62,8.38,8.38,0,0,1,204.27,59.19Zm6.22-3.81a3.19,3.19,0,0,0-1.26.22,2.56,2.56,0,0,0-.87.56,2.38,2.38,0,0,0-.55.76,2.59,2.59,0,0,0-.24.8h5.73a4.2,4.2,0,0,0-.19-.8,2,2,0,0,0-.46-.76,2.29,2.29,0,0,0-.83-.56A3.39,3.39,0,0,0,210.49,55.38Z"
style="fill: #455a64"></path>
<path
d="M237.64,65.09a.68.68,0,0,1-.68.69H235a.66.66,0,0,1-.48-.2.67.67,0,0,1-.21-.49V58.65a3.82,3.82,0,0,0-.71-2.43,2.58,2.58,0,0,0-2.18-.91,2.61,2.61,0,0,0-2.11.91,3.62,3.62,0,0,0-.78,2.43v6.44a.66.66,0,0,1-.2.49.67.67,0,0,1-.48.2H226a.67.67,0,0,1-.48-.2.66.66,0,0,1-.2-.49V53.28a.62.62,0,0,1,.2-.48.64.64,0,0,1,.48-.21h1.93a.64.64,0,0,1,.48.21.62.62,0,0,1,.2.48v.58a5.77,5.77,0,0,1,1.55-1.09,4.71,4.71,0,0,1,2.1-.43,6.14,6.14,0,0,1,2.59.48,4.44,4.44,0,0,1,1.67,1.29,4.87,4.87,0,0,1,.9,1.89,9.35,9.35,0,0,1,.27,2.27Z"
style="fill: #455a64"></path>
<path
d="M246.82,52.34a6.94,6.94,0,0,1,2.52.43A6.19,6.19,0,0,1,251.29,54a5.94,5.94,0,0,1,1.32,1.78,5.72,5.72,0,0,1,.57,2.18,4.51,4.51,0,0,1,0,.58v1.41a4.45,4.45,0,0,1,0,.57,6.4,6.4,0,0,1-.58,2.18,5.55,5.55,0,0,1-1.31,1.76,6.16,6.16,0,0,1-1.95,1.18,7.6,7.6,0,0,1-5,0,6.1,6.1,0,0,1-2-1.18,5.52,5.52,0,0,1-1.3-1.76,6.41,6.41,0,0,1-.59-2.18q0-.23,0-.57c0-.23,0-.46,0-.7s0-.47,0-.71,0-.43,0-.58a6.11,6.11,0,0,1,.57-2.18A5.94,5.94,0,0,1,242.34,54a6.13,6.13,0,0,1,2-1.19A6.94,6.94,0,0,1,246.82,52.34Zm3.07,5.7a3.38,3.38,0,0,0-.37-1.3,2.52,2.52,0,0,0-.72-.82,2.41,2.41,0,0,0-.94-.42,4.55,4.55,0,0,0-1-.12,4.48,4.48,0,0,0-1,.12,2.41,2.41,0,0,0-.94.42,2.31,2.31,0,0,0-.72.82,3.21,3.21,0,0,0-.37,1.3c0,.14,0,.31,0,.51s0,.42,0,.64,0,.43,0,.64a4.81,4.81,0,0,0,0,.5,3.17,3.17,0,0,0,.37,1.3,2.44,2.44,0,0,0,.72.83,2.74,2.74,0,0,0,.94.42,5.1,5.1,0,0,0,1,.11,5.17,5.17,0,0,0,1-.11,2.74,2.74,0,0,0,.94-.42,2.67,2.67,0,0,0,.72-.83,3.33,3.33,0,0,0,.37-1.3c0-.12,0-.29,0-.5V58.55C249.91,58.35,249.9,58.18,249.89,58Z"
style="fill: #455a64"></path>
<path
d="M260.38,61a1.83,1.83,0,0,0,.42,1.26,2.06,2.06,0,0,0,1.56.47h1.55a.65.65,0,0,1,.48.2.66.66,0,0,1,.2.48v1.67a.68.68,0,0,1-.68.69H262a5.27,5.27,0,0,1-3.66-1.16,4.47,4.47,0,0,1-1.28-3.53V55.64h-1.68a.7.7,0,0,1-.68-.69V53.28a.7.7,0,0,1,.68-.69h1.68V48.46a.68.68,0,0,1,.68-.68h1.93a.65.65,0,0,1,.48.2.66.66,0,0,1,.2.48v4.13h3.27a.72.72,0,0,1,.69.69V55a.72.72,0,0,1-.69.69h-3.27Z"
style="fill: #455a64"></path>
<path
d="M277,52.59h3.52a.67.67,0,0,1,.49.21.66.66,0,0,1,.2.48V55a.66.66,0,0,1-.2.48.67.67,0,0,1-.49.21H277v9.45a.68.68,0,0,1-.68.69h-1.93a.66.66,0,0,1-.48-.2.67.67,0,0,1-.21-.49V55.64H272a.63.63,0,0,1-.48-.21.62.62,0,0,1-.2-.48V53.28a.62.62,0,0,1,.2-.48.63.63,0,0,1,.48-.21h1.67V51.45a5.24,5.24,0,0,1,.36-2.06,3.41,3.41,0,0,1,1-1.39,4.2,4.2,0,0,1,1.59-.76,8.68,8.68,0,0,1,2.06-.22h2.06a.65.65,0,0,1,.48.2.66.66,0,0,1,.2.48v1.67a.68.68,0,0,1-.68.69H279a2.58,2.58,0,0,0-1.47.34,1.47,1.47,0,0,0-.51,1.31Z"
style="fill: #455a64"></path>
<path
d="M289,52.34a6.94,6.94,0,0,1,2.52.43A6.19,6.19,0,0,1,293.43,54a5.94,5.94,0,0,1,1.32,1.78,5.72,5.72,0,0,1,.57,2.18,4.51,4.51,0,0,1,0,.58v1.41a4.45,4.45,0,0,1,0,.57,6.4,6.4,0,0,1-.58,2.18,5.55,5.55,0,0,1-1.31,1.76,6.16,6.16,0,0,1-1.95,1.18A6.94,6.94,0,0,1,289,66a7,7,0,0,1-2.53-.43,6.16,6.16,0,0,1-1.95-1.18,5.52,5.52,0,0,1-1.3-1.76,6.19,6.19,0,0,1-.59-2.18c0-.15,0-.34,0-.57s0-.46,0-.7,0-.47,0-.71,0-.43,0-.58a5.72,5.72,0,0,1,.57-2.18A5.94,5.94,0,0,1,284.48,54a6.19,6.19,0,0,1,1.95-1.19A7,7,0,0,1,289,52.34ZM292,58a3.38,3.38,0,0,0-.36-1.3,2.43,2.43,0,0,0-.73-.82,2.37,2.37,0,0,0-.93-.42,4.55,4.55,0,0,0-1-.12,4.42,4.42,0,0,0-1,.12,2.41,2.41,0,0,0-.94.42,2.31,2.31,0,0,0-.72.82,3.21,3.21,0,0,0-.37,1.3c0,.14,0,.31,0,.51s0,.42,0,.64,0,.43,0,.64a4.81,4.81,0,0,0,0,.5,3.17,3.17,0,0,0,.37,1.3,2.44,2.44,0,0,0,.72.83,2.74,2.74,0,0,0,.94.42,5,5,0,0,0,1,.11,5.17,5.17,0,0,0,1-.11,2.7,2.7,0,0,0,.93-.42,2.57,2.57,0,0,0,.73-.83,3.33,3.33,0,0,0,.36-1.3,3.25,3.25,0,0,0,0-.5V58.55A3.68,3.68,0,0,0,292,58Z"
style="fill: #455a64"></path>
<path
d="M298.11,53.28a.7.7,0,0,1,.68-.69h1.93a.72.72,0,0,1,.69.69v6.44a4.14,4.14,0,0,0,.64,2.43,2.42,2.42,0,0,0,2.12.92,2.44,2.44,0,0,0,2.05-.92,3.82,3.82,0,0,0,.71-2.43V53.28a.72.72,0,0,1,.69-.69h1.92a.67.67,0,0,1,.49.21.66.66,0,0,1,.2.48V65.09a.68.68,0,0,1-.69.69h-1.92a.66.66,0,0,1-.48-.2.67.67,0,0,1-.21-.49v-.58a6.22,6.22,0,0,1-1.44,1,4.23,4.23,0,0,1-2.08.47,6,6,0,0,1-2.56-.48,4.19,4.19,0,0,1-1.62-1.29,5,5,0,0,1-.87-1.89,9.87,9.87,0,0,1-.25-2.27Z"
style="fill: #455a64"></path>
<path
d="M326.1,65.09a.68.68,0,0,1-.68.69h-1.93a.66.66,0,0,1-.48-.2.67.67,0,0,1-.21-.49V58.65a3.82,3.82,0,0,0-.71-2.43,2.58,2.58,0,0,0-2.18-.91,2.61,2.61,0,0,0-2.11.91,3.62,3.62,0,0,0-.78,2.43v6.44a.66.66,0,0,1-.2.49.67.67,0,0,1-.48.2h-1.93a.67.67,0,0,1-.48-.2.66.66,0,0,1-.2-.49V53.28a.62.62,0,0,1,.2-.48.64.64,0,0,1,.48-.21h1.93a.64.64,0,0,1,.48.21.62.62,0,0,1,.2.48v.58a5.77,5.77,0,0,1,1.55-1.09,4.71,4.71,0,0,1,2.1-.43,6.14,6.14,0,0,1,2.59.48,4.44,4.44,0,0,1,1.67,1.29,4.87,4.87,0,0,1,.9,1.89,9.35,9.35,0,0,1,.27,2.27Z"
style="fill: #455a64"></path>
<path
d="M334.54,52.34a6,6,0,0,1,1.41.15,5.54,5.54,0,0,1,1.09.38,4.06,4.06,0,0,1,.8.5,3.73,3.73,0,0,1,.53.49v-5.4a.68.68,0,0,1,.69-.68H341a.62.62,0,0,1,.48.2.63.63,0,0,1,.21.48V65.09a.67.67,0,0,1-.21.49.66.66,0,0,1-.48.2h-1.92a.68.68,0,0,1-.69-.69v-.58a3.73,3.73,0,0,1-.53.49,4.06,4.06,0,0,1-.8.5,5.54,5.54,0,0,1-1.09.38,6,6,0,0,1-1.41.15,5.2,5.2,0,0,1-2.29-.49,5.36,5.36,0,0,1-1.75-1.32,6.37,6.37,0,0,1-1.14-1.9,6.9,6.9,0,0,1-.47-2.25c0-.25,0-.55,0-.88s0-.64,0-.89a6.9,6.9,0,0,1,.47-2.25,6.49,6.49,0,0,1,1.14-1.9,5.36,5.36,0,0,1,1.75-1.32A5.2,5.2,0,0,1,334.54,52.34Zm-2.36,6.14a6.74,6.74,0,0,0,0,1.42,3.41,3.41,0,0,0,1,2.37,3.17,3.17,0,0,0,2.1.72,3.11,3.11,0,0,0,2.1-.74,3,3,0,0,0,1-2.1,8.31,8.31,0,0,0,.05-1,8.5,8.5,0,0,0-.05-1,3,3,0,0,0-3.07-2.84,3.17,3.17,0,0,0-2.1.72A3.41,3.41,0,0,0,332.18,58.48Z"
style="fill: #455a64"></path>
<path
d="M196.44,90.76a.59.59,0,0,1,.44.19.6.6,0,0,1,.18.44v2.46a.6.6,0,0,1-.18.44.59.59,0,0,1-.44.19h-11a.58.58,0,0,1-.44-.19.61.61,0,0,1-.19-.44v-15a.61.61,0,0,1,.19-.44.58.58,0,0,1,.44-.19h10.83a.65.65,0,0,1,.63.63V81.3a.61.61,0,0,1-.19.45.6.6,0,0,1-.44.18h-7.16v2.51h6.65a.58.58,0,0,1,.44.19.61.61,0,0,1,.19.44v2.46a.61.61,0,0,1-.19.44.58.58,0,0,1-.44.19h-6.65v2.6Z"
style="fill: currentcolor"></path>
<path
d="M206.66,78.21a10.39,10.39,0,0,1,2.74.33,6,6,0,0,1,2.06,1,4.3,4.3,0,0,1,1.3,1.67,5.73,5.73,0,0,1,.45,2.35,5.37,5.37,0,0,1-.72,2.9,4.61,4.61,0,0,1-2,1.75l2.88,5.53a.56.56,0,0,1,.07.26.51.51,0,0,1-.51.51h-3.16a.87.87,0,0,1-.66-.21,2,2,0,0,1-.32-.42l-2.58-5H204v5a.6.6,0,0,1-.18.44.59.59,0,0,1-.44.19h-3a.59.59,0,0,1-.44-.19.6.6,0,0,1-.18-.44v-15a.6.6,0,0,1,.18-.44.59.59,0,0,1,.44-.19Zm-2.63,7h2.63a3.18,3.18,0,0,0,1.62-.37,1.43,1.43,0,0,0,.63-1.35,1.41,1.41,0,0,0-.63-1.34,3.18,3.18,0,0,0-1.62-.37H204Z"
style="fill: currentcolor"></path>
<path
d="M222.81,78.21a10.39,10.39,0,0,1,2.74.33,6,6,0,0,1,2.06,1,4.21,4.21,0,0,1,1.3,1.67,5.73,5.73,0,0,1,.45,2.35,5.37,5.37,0,0,1-.72,2.9,4.61,4.61,0,0,1-2,1.75l2.88,5.53a.56.56,0,0,1,.07.26.51.51,0,0,1-.51.51h-3.16a.87.87,0,0,1-.66-.21,2,2,0,0,1-.32-.42l-2.58-5h-2.13v5a.61.61,0,0,1-.19.44.59.59,0,0,1-.44.19h-3.05a.59.59,0,0,1-.44-.19.6.6,0,0,1-.18-.44v-15a.6.6,0,0,1,.18-.44.59.59,0,0,1,.44-.19Zm-2.62,7h2.62a3.18,3.18,0,0,0,1.62-.37,1.43,1.43,0,0,0,.63-1.35,1.41,1.41,0,0,0-.63-1.34,3.18,3.18,0,0,0-1.62-.37h-2.62Z"
style="fill: currentcolor"></path>
<path
d="M231.5,84.28a7.14,7.14,0,0,1,.57-2.45,5.8,5.8,0,0,1,1.42-2,6.62,6.62,0,0,1,2.23-1.35,9.4,9.4,0,0,1,6.05,0A6.72,6.72,0,0,1,244,79.83a5.77,5.77,0,0,1,1.41,2,6.71,6.71,0,0,1,.57,2.45c0,.66.05,1.36.05,2.09s0,1.41-.05,2a6.81,6.81,0,0,1-.57,2.46,6.1,6.1,0,0,1-1.41,2,6.54,6.54,0,0,1-2.25,1.34,9.58,9.58,0,0,1-6.05,0,6.45,6.45,0,0,1-2.23-1.34,6.13,6.13,0,0,1-1.42-2,7.25,7.25,0,0,1-.57-2.46c0-.63,0-1.31,0-2S231.47,84.94,231.5,84.28Zm10.2,4c0-.28,0-.59.05-.93s0-.69,0-1.05,0-.7,0-1,0-.63-.05-.9a3.57,3.57,0,0,0-.24-1.06,2.47,2.47,0,0,0-.56-.85,2.62,2.62,0,0,0-.89-.57,3.47,3.47,0,0,0-1.26-.21,3.37,3.37,0,0,0-1.25.21,2.57,2.57,0,0,0-.9.57,2.62,2.62,0,0,0-.56.85,3.57,3.57,0,0,0-.24,1.06q0,.4-.06.9c0,.33,0,.68,0,1s0,.71,0,1.05,0,.65.06.93a3.13,3.13,0,0,0,.8,1.93,2.79,2.79,0,0,0,2.15.76,2.75,2.75,0,0,0,2.14-.76A3.26,3.26,0,0,0,241.7,88.3Z"
style="fill: currentcolor"></path>
<path
d="M255.65,78.21a10.45,10.45,0,0,1,2.74.33,5.91,5.91,0,0,1,2.05,1,4.32,4.32,0,0,1,1.31,1.67,5.73,5.73,0,0,1,.45,2.35,5.37,5.37,0,0,1-.72,2.9,4.58,4.58,0,0,1-2.05,1.75l2.88,5.53a.59.59,0,0,1,.08.26.5.5,0,0,1-.16.36.49.49,0,0,1-.36.15h-3.16a.87.87,0,0,1-.66-.21,1.89,1.89,0,0,1-.31-.42l-2.58-5H253v5a.65.65,0,0,1-.63.63h-3a.65.65,0,0,1-.63-.63v-15a.65.65,0,0,1,.63-.63Zm-2.63,7h2.63a3.14,3.14,0,0,0,1.61-.37,1.41,1.41,0,0,0,.64-1.35,1.4,1.4,0,0,0-.64-1.34,3.14,3.14,0,0,0-1.61-.37H253Z"
style="fill: currentcolor"></path>
<path
d="M277.47,94.48a.61.61,0,0,1-.45-.19.6.6,0,0,1-.18-.44V91.48h-7.32a.6.6,0,0,1-.44-.18.61.61,0,0,1-.19-.45V88.39a1.63,1.63,0,0,1,.3-1l6.95-8.76a1.38,1.38,0,0,1,.38-.34,1.26,1.26,0,0,1,.48-.08h3.51a.58.58,0,0,1,.44.19.61.61,0,0,1,.19.44v8.92h2a.63.63,0,0,1,.44.19.6.6,0,0,1,.18.44v2.46a.64.64,0,0,1-.18.45.62.62,0,0,1-.44.18h-2v2.37a.61.61,0,0,1-.19.44.58.58,0,0,1-.44.19ZM277,87.76V83.49l-3.39,4.27Z"
style="fill: currentcolor"></path>
<path
d="M292.5,78a8,8,0,0,1,3,.51,6,6,0,0,1,2.08,1.37,5.62,5.62,0,0,1,1.23,2,8.82,8.82,0,0,1,.48,2.41c0,.66,0,1.36,0,2.09s0,1.41,0,2a8.82,8.82,0,0,1-.48,2.41,5.46,5.46,0,0,1-1.23,2,6,6,0,0,1-2.08,1.37,9.08,9.08,0,0,1-6,0,6,6,0,0,1-2.08-1.37,5.46,5.46,0,0,1-1.23-2,8.82,8.82,0,0,1-.48-2.41c0-.63,0-1.31,0-2s0-1.43,0-2.09a8.82,8.82,0,0,1,.48-2.41,5.62,5.62,0,0,1,1.23-2,6,6,0,0,1,2.08-1.37A8,8,0,0,1,292.5,78ZM295,88.3c.06-1.32.06-2.62,0-3.91a5.58,5.58,0,0,0-.18-1.06,2.31,2.31,0,0,0-.4-.85,2,2,0,0,0-.75-.57,2.8,2.8,0,0,0-1.16-.21,2.83,2.83,0,0,0-1.16.21,2,2,0,0,0-.75.57,2.49,2.49,0,0,0-.41.85,4.35,4.35,0,0,0-.17,1.06,36.43,36.43,0,0,0,0,3.91,5.75,5.75,0,0,0,.15,1.07,2.42,2.42,0,0,0,.42.85,2,2,0,0,0,.76.56,2.83,2.83,0,0,0,1.16.21,2.8,2.8,0,0,0,1.16-.21,2,2,0,0,0,.76-.56,2.42,2.42,0,0,0,.42-.85A5.75,5.75,0,0,0,295,88.3Z"
style="fill: currentcolor"></path>
<path
d="M309.79,94.48a.65.65,0,0,1-.63-.63V91.48h-7.32a.6.6,0,0,1-.44-.18.65.65,0,0,1-.19-.45V88.39a1.57,1.57,0,0,1,.31-1l6.94-8.76a1.27,1.27,0,0,1,.39-.34,1.17,1.17,0,0,1,.47-.08h3.51a.65.65,0,0,1,.63.63v8.92h2a.65.65,0,0,1,.63.63v2.46a.65.65,0,0,1-.19.45.6.6,0,0,1-.44.18h-2v2.37a.65.65,0,0,1-.63.63Zm-.51-6.72V83.49l-3.39,4.27Z"
style="fill: currentcolor"></path>
</g>
</g>
</svg>
</template>
<script lang="ts" setup></script>
<style lang="scss" scoped></style>
@@ -1,967 +0,0 @@
<template>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 500">
<g id="freepik--Floor--inject-87">
<ellipse id="freepik--floor--inject-87" cx="250" cy="378.78" rx="230.68" ry="112.11" style="fill: #f5f5f5">
</ellipse>
</g>
<g id="freepik--Shadows--inject-87">
<path id="freepik--Shadow--inject-87"
d="M152.14,433.48a2,2,0,0,1-2-1.63l-.45-2.42a24.58,24.58,0,0,1-3.07-.75h-.07l-4.26,2a2.47,2.47,0,0,1-1,.21,2.42,2.42,0,0,1-1.21-.31l-4.24-2.45a1.68,1.68,0,0,1-.15-2.88l2.57-1.84a9.54,9.54,0,0,1-.64-1l-5.41-.34a1.94,1.94,0,0,1-1.81-1.93V417a1.94,1.94,0,0,1,1.82-1.93l5.4-.34a9.54,9.54,0,0,1,.64-1l-2.57-1.84a1.74,1.74,0,0,1-.74-1.48,1.71,1.71,0,0,1,.89-1.4l4.24-2.45a2.42,2.42,0,0,1,1.21-.31,2.31,2.31,0,0,1,1,.21l4.26,2h.05s0,0,0,0a26.67,26.67,0,0,1,3.11-.77l.45-2.41a2.05,2.05,0,0,1,2-1.64h6.24a2,2,0,0,1,2,1.64l.46,2.41a26.48,26.48,0,0,1,3.07.76H164l4.26-2a2.31,2.31,0,0,1,1-.21,2.42,2.42,0,0,1,1.21.31l4.24,2.45a1.71,1.71,0,0,1,.89,1.4,1.76,1.76,0,0,1-.74,1.48l-2.57,1.84a9.54,9.54,0,0,1,.64,1l5.4.34a1.94,1.94,0,0,1,1.82,1.93v3.16a1.94,1.94,0,0,1-1.82,1.93l-5.4.34a9.54,9.54,0,0,1-.64,1l2.57,1.84a1.76,1.76,0,0,1,.74,1.48,1.72,1.72,0,0,1-.89,1.4l-4.24,2.45a2.42,2.42,0,0,1-1.21.31h0a2.47,2.47,0,0,1-1-.21l-4.26-2h0s0,0,0,0a26,26,0,0,1-3.1.76l-.46,2.42a2,2,0,0,1-2,1.63Zm3.12-19.39a13.16,13.16,0,0,0-6.48,1.53c-1.45.84-2.28,1.91-2.28,2.95s.83,2.11,2.28,2.95a14.49,14.49,0,0,0,13,0c1.45-.84,2.28-1.91,2.28-2.95s-.83-2.11-2.28-2.95A13.16,13.16,0,0,0,155.26,414.09Z"
style="fill: #e6e6e6"></path>
<path id="freepik--shadow--inject-87"
d="M200.64,405.59a2.25,2.25,0,0,1-1.6-.7l-1.69-1.77-1.25,0c-.42,0-.83,0-1.24,0l-1.8,1.89a2,2,0,0,1-1.46.58,2.5,2.5,0,0,1-.54-.07l-4.2-1a1.84,1.84,0,0,1-1.24-1,1.6,1.6,0,0,1,0-1.37l.67-1.32c-.36-.2-.7-.41-1-.63l-4,.66a1.39,1.39,0,0,1-.3,0,2.14,2.14,0,0,1-1.69-.89l-1.59-2.21a1.84,1.84,0,0,1-.35-1,1.62,1.62,0,0,1,1.14-1.57l3.06-1a.66.66,0,0,1,0-.14l-2.95-.94a1.71,1.71,0,0,1-1.26-1.5v-.11a1.53,1.53,0,0,1,.3-.92l1.73-2.42a2,2,0,0,1,1.63-.77,2,2,0,0,1,.35,0l3.91.66c.28-.19.59-.38.91-.56l.12-.07-.62-1.23a1.62,1.62,0,0,1-.19-.69l0-.21,0-.11a1.65,1.65,0,0,1,1.25-1.41l4.39-1a1.49,1.49,0,0,1,.43-.05,2.22,2.22,0,0,1,1.59.7l1.7,1.77c.42,0,.85,0,1.27,0s.81,0,1.21,0l1.8-1.89a2,2,0,0,1,1.46-.58,1.88,1.88,0,0,1,.53.07l4.21,1a1.71,1.71,0,0,1,1.38,1.63,1.41,1.41,0,0,1-.15.69l-.68,1.35.14.08a10.26,10.26,0,0,1,.88.55l4-.66a1.36,1.36,0,0,1,.29,0,2.17,2.17,0,0,1,1.7.88l1.59,2.22a1.73,1.73,0,0,1,.35,1v.18l0,.12a1.62,1.62,0,0,1-1.1,1.3l-3.08,1v.14l3,.93a1.72,1.72,0,0,1,1,2.53c-.51.79-1.1,1.53-1.64,2.29l-.09.13a2,2,0,0,1-1.63.77l-.36,0-3.9-.65c-.33.22-.67.43-1,.63l.62,1.23a1.67,1.67,0,0,1,0,1.51,1.63,1.63,0,0,1-1.13.91l-4.36,1.05A2.06,2.06,0,0,1,200.64,405.59ZM190,395a3.29,3.29,0,0,0,.83.84,4.32,4.32,0,0,0,.5.33,7.8,7.8,0,0,0,2.12.81,11.25,11.25,0,0,0,2.62.3,9.87,9.87,0,0,0,4.73-1.1,5.65,5.65,0,0,0,.51-.33,3.16,3.16,0,0,0,.76-.74,1.35,1.35,0,0,0,.13-1.6l-.08-.12-.1-.15-.11-.13,0,0,0,0,0,0a6.51,6.51,0,0,0-3.11-1.56,11.32,11.32,0,0,0-2.62-.3c-2.62,0-5.09.89-6,2.17a1.37,1.37,0,0,0-.23,1.38l0,.11.11.19Z"
style="fill: #e6e6e6"></path>
<path id="freepik--shadow--inject-87"
d="M257.82,424.33l35.88-20.72a1.17,1.17,0,0,0,0-2.22l-8.8-5.08a4.28,4.28,0,0,0-3.85,0L245.18,417a1.17,1.17,0,0,0,0,2.22l4.39,2.54-45,26c-1.06.61-.61.82-.12,1.11s.87.54,1.93-.07l45-26,2.59,1.5A4.28,4.28,0,0,0,257.82,424.33Z"
style="fill: #e6e6e6"></path>
<path id="freepik--shadow--inject-87"
d="M244.29,384.57a16.13,16.13,0,0,1-8-1.95c-.25-.15-.49-.3-.72-.46l-1.32-.93,11.29-1.66,1-2.13-3.05-1.79-10.76,1.58.35-1a7,7,0,0,1,3.31-3.56,16.27,16.27,0,0,1,7.9-1.88,18.75,18.75,0,0,1,3.62.35l36.81-21.25a4.43,4.43,0,0,1-.31-3,6.67,6.67,0,0,1,3.42-4,16.34,16.34,0,0,1,7.91-1.88,16.14,16.14,0,0,1,8,2c.26.15.49.3.72.46l1.33.93-11.29,1.65-1,2.14,3.05,1.78,10.76-1.57-.35,1a7,7,0,0,1-3.31,3.55,16.27,16.27,0,0,1-7.9,1.88,18.83,18.83,0,0,1-3.62-.34l-36.81,21.25a4.35,4.35,0,0,1,.31,3,6.64,6.64,0,0,1-3.42,3.95A16.17,16.17,0,0,1,244.29,384.57Z"
style="fill: #e6e6e6"></path>
<ellipse id="freepik--shadow--inject-87" cx="387.02" cy="400.95" rx="57.04" ry="32.93" style="fill: #e6e6e6">
</ellipse>
<polygon id="freepik--shadow--inject-87"
points="143.07 320.2 205.13 356.03 263.01 322.5 200.95 286.68 143.07 320.2" style="fill: #e6e6e6"></polygon>
<polygon id="freepik--shadow--inject-87" points="119.51 407 203.19 358.69 129.97 316.42 46.3 364.73 119.51 407"
style="fill: #e6e6e6"></polygon>
</g>
<g id="freepik--Gate--inject-87">
<g id="freepik--gate--inject-87">
<polygon
points="205.12 353.37 146.37 319.44 146.37 316.88 200.37 285.7 259.12 319.62 259.12 322.19 205.12 353.37"
style="fill: currentcolor"></polygon>
<polygon points="146.37 316.88 205.12 350.8 259.12 319.62 200.37 285.7 146.37 316.88"
style="fill: currentcolor"></polygon>
<polygon points="146.37 316.88 205.12 350.8 259.12 319.62 200.37 285.7 146.37 316.88" style="opacity: 0.15">
</polygon>
<path
d="M219.68,331a4.34,4.34,0,0,0,3.94,0,1.2,1.2,0,0,0,0-2.27,4.34,4.34,0,0,0-3.94,0A1.2,1.2,0,0,0,219.68,331Z"
style="fill: #37474f"></path>
<polygon points="205.12 350.8 205.12 353.37 146.37 319.44 146.37 316.88 205.12 350.8" style="opacity: 0.3">
</polygon>
</g>
</g>
<g id="freepik--Server--inject-87">
<g id="freepik--server--inject-87">
<path
d="M128.34,115.9l65.46,37.79a4.85,4.85,0,0,1,2.19,3.79V356.29a4.85,4.85,0,0,1-2.19,3.8L123,401a4.83,4.83,0,0,1-4.38,0L53.16,363.17A4.83,4.83,0,0,1,51,359.38V160.57a4.85,4.85,0,0,1,2.19-3.8L124,115.9A4.83,4.83,0,0,1,128.34,115.9Z"
style="fill: currentcolor"></path>
<path
d="M51,160.56V359.38a4.87,4.87,0,0,0,2.19,3.79L118.62,401a4.36,4.36,0,0,0,2.19.53V197.62a4.49,4.49,0,0,1-2.19-.53L53.16,159.3l-.6-.5-.78-.64A4.57,4.57,0,0,0,51,160.56Z"
style="fill: currentcolor"></path>
<path
d="M51,160.56V359.38a4.87,4.87,0,0,0,2.19,3.79L118.62,401a4.36,4.36,0,0,0,2.19.53V197.62a4.49,4.49,0,0,1-2.19-.53L53.16,159.3l-.6-.5-.78-.64A4.57,4.57,0,0,0,51,160.56Z"
style="opacity: 0.3"></path>
<path
d="M53.16,156.77,124,115.9a4.81,4.81,0,0,1,4.37,0l65.46,37.79a1.34,1.34,0,0,1,0,2.53L123,197.1a4.89,4.89,0,0,1-4.38,0L53.16,159.3A1.34,1.34,0,0,1,53.16,156.77Z"
style="fill: currentcolor"></path>
<path
d="M53.16,156.77,124,115.9a4.81,4.81,0,0,1,4.37,0l65.46,37.79a1.34,1.34,0,0,1,0,2.53L123,197.1a4.89,4.89,0,0,1-4.38,0L53.16,159.3A1.34,1.34,0,0,1,53.16,156.77Z"
style="opacity: 0.15"></path>
<polygon points="188.13 291.62 129.38 325.54 129.38 387.89 188.13 353.97 188.13 291.62" style="fill: #455a64">
</polygon>
<path
d="M159.26,336.16a.62.62,0,0,0-.61.06L134.75,350a1.79,1.79,0,0,0-.61.64l-1.6-.93a1.77,1.77,0,0,1,.6-.64l23.4-13.45a1.85,1.85,0,0,1,1.71,0Z"
style="fill: #263238"></path>
<path
d="M133.89,351.46v26.77c0,.55.39.77.86.5L158.65,365a1.9,1.9,0,0,0,.86-1.48V336.72c0-.55-.39-.77-.86-.5L134.75,350A1.89,1.89,0,0,0,133.89,351.46Z"
style="fill: #37474f"></path>
<path
d="M134.12,378.78l-1-.57a1.89,1.89,0,0,1-.85-1.48v-26.2a1.7,1.7,0,0,1,.25-.85l1.6.93a1.81,1.81,0,0,0-.25.85v26.77A.65.65,0,0,0,134.12,378.78Z"
style="fill: #263238"></path>
<path
d="M135.8,376.32a.46.46,0,0,1-.2-.05.51.51,0,0,1-.22-.46V352a1.34,1.34,0,0,1,.61-1l21.31-12.25a.5.5,0,0,1,.51,0,.51.51,0,0,1,.22.46v23.79a1.32,1.32,0,0,1-.6,1.05l-21.31,12.25A.64.64,0,0,1,135.8,376.32Zm21.8-37.44a.41.41,0,0,0-.18.05L136.1,351.19a1.08,1.08,0,0,0-.48.83v23.79c0,.12,0,.21.09.24a.26.26,0,0,0,.26,0h0l21.31-12.25a1.08,1.08,0,0,0,.48-.83V339.14c0-.12,0-.21-.09-.24A.12.12,0,0,0,157.6,338.88Z"
style="fill: currentcolor"></path>
<path
d="M137.48,373.19a.21.21,0,0,1-.12,0,.26.26,0,0,1-.13-.25V352.72a.72.72,0,0,1,.29-.5l18.21-10.49a.28.28,0,0,1,.29,0,.29.29,0,0,1,.13.26l0,20.22a.64.64,0,0,1-.29.51l-18.19,10.45A.32.32,0,0,1,137.48,373.19Zm0-.24Zm18.4-31h0l-18.22,10.5a.5.5,0,0,0-.16.28V373l0,0,18.18-10.45a.39.39,0,0,0,.17-.29h0l0-20.22A.06.06,0,0,0,155.89,341.93Z"
style="fill: currentcolor"></path>
<path d="M138.71,346.89a.25.25,0,0,1-.24-.25v-5.7a.24.24,0,1,1,.48,0v5.7A.25.25,0,0,1,138.71,346.89Z"
style="fill: currentcolor"></path>
<path
d="M142.7,344.6a.24.24,0,0,1-.24-.24v-5.71a.24.24,0,0,1,.24-.24.24.24,0,0,1,.24.24v5.71A.24.24,0,0,1,142.7,344.6Z"
style="fill: currentcolor"></path>
<path d="M146.69,342.31a.24.24,0,0,1-.25-.24v-5.7a.25.25,0,0,1,.49,0v5.7A.24.24,0,0,1,146.69,342.31Z"
style="fill: currentcolor"></path>
<path d="M150.67,340a.24.24,0,0,1-.24-.24v-5.71a.25.25,0,0,1,.49,0v5.71A.25.25,0,0,1,150.67,340Z"
style="fill: currentcolor"></path>
<path
d="M154.66,337.74a.24.24,0,0,1-.24-.24v-5.7a.24.24,0,0,1,.24-.24.23.23,0,0,1,.24.24v5.7A.23.23,0,0,1,154.66,337.74Z"
style="fill: currentcolor"></path>
<path
d="M159.26,315.1a.6.6,0,0,0-.61.06l-23.9,13.75a1.84,1.84,0,0,0-.61.63l-1.6-.92a1.69,1.69,0,0,1,.6-.64l23.4-13.46a1.91,1.91,0,0,1,1.71,0Z"
style="fill: #263238"></path>
<path
d="M133.89,330.39v13.5c0,.55.39.77.86.5l23.9-13.75a1.9,1.9,0,0,0,.86-1.48V315.65c0-.54-.39-.76-.86-.49l-23.9,13.75A1.88,1.88,0,0,0,133.89,330.39Z"
style="fill: #37474f"></path>
<path
d="M134.12,344.44l-1-.57a1.89,1.89,0,0,1-.85-1.48V329.46a1.7,1.7,0,0,1,.25-.84l1.6.92a1.84,1.84,0,0,0-.25.85V343.9A.64.64,0,0,0,134.12,344.44Z"
style="fill: #263238"></path>
<path
d="M135.8,342a.46.46,0,0,1-.2-.05.51.51,0,0,1-.22-.46V331a1.34,1.34,0,0,1,.61-1l21.31-12.26a.46.46,0,0,1,.73.43v10.51a1.32,1.32,0,0,1-.6,1.05l-21.31,12.25A.64.64,0,0,1,135.8,342Zm21.8-24.17a.32.32,0,0,0-.18.06L136.1,330.13a1.08,1.08,0,0,0-.48.83v10.51c0,.12,0,.21.09.24a.26.26,0,0,0,.26,0h0l21.31-12.25a1.08,1.08,0,0,0,.48-.83V318.08a.29.29,0,0,0-.09-.25Z"
style="fill: currentcolor"></path>
<path
d="M137.48,338.86a.21.21,0,0,1-.12,0,.26.26,0,0,1-.13-.25v-6.91a.76.76,0,0,1,.29-.51l18.21-10.49a.3.3,0,0,1,.29,0,.27.27,0,0,1,.13.25l0,7a.64.64,0,0,1-.29.51l-18.19,10.45A.33.33,0,0,1,137.48,338.86Zm0-.25Zm18.4-17.75,0,0-18.22,10.49a.56.56,0,0,0-.16.29v6.95l0,0,18.18-10.45a.39.39,0,0,0,.17-.29h0l0-7S155.89,320.87,155.89,320.86Z"
style="fill: currentcolor"></path>
<path
d="M164.09,312.35a3.14,3.14,0,0,0-1.42,2.45c0,.9.64,1.26,1.42.81a3.14,3.14,0,0,0,1.41-2.44C165.5,312.27,164.86,311.9,164.09,312.35Z"
style="fill: currentcolor"></path>
<path
d="M164.09,336.35a3.14,3.14,0,0,0-1.42,2.45c0,.9.64,1.26,1.42.81a3.14,3.14,0,0,0,1.41-2.44C165.5,336.27,164.86,335.9,164.09,336.35Z"
style="fill: currentcolor"></path>
<path
d="M164.09,342.81a3.12,3.12,0,0,0-1.42,2.44c0,.9.64,1.26,1.42.81a3.12,3.12,0,0,0,1.41-2.44C165.5,342.72,164.86,342.36,164.09,342.81Z"
style="fill: currentcolor"></path>
<path
d="M164.09,349.26a3.14,3.14,0,0,0-1.42,2.45c0,.89.64,1.26,1.42.81a3.14,3.14,0,0,0,1.41-2.44C165.5,349.18,164.86,348.81,164.09,349.26Z"
style="fill: currentcolor"></path>
<path
d="M164.09,355.72a3.12,3.12,0,0,0-1.42,2.44c0,.9.64,1.26,1.42.81a3.14,3.14,0,0,0,1.41-2.44C165.5,355.63,164.86,355.27,164.09,355.72Z"
style="fill: currentcolor"></path>
<path
d="M164.09,318.18a3.14,3.14,0,0,0-1.42,2.45c0,.9.64,1.26,1.42.81A3.14,3.14,0,0,0,165.5,319C165.5,318.1,164.86,317.73,164.09,318.18Z"
style="fill: currentcolor"></path>
<path
d="M164.09,324a3.14,3.14,0,0,0-1.42,2.45c0,.9.64,1.26,1.42.81a3.14,3.14,0,0,0,1.41-2.44C165.5,323.93,164.86,323.56,164.09,324Z"
style="fill: currentcolor"></path>
<path
d="M179.52,315.4l-.14-1.31a.14.14,0,0,0-.18-.13,2.94,2.94,0,0,1-.65.07.3.3,0,0,0-.26.13l-.29.43,1.54.88A.14.14,0,0,1,179.52,315.4Zm1.11-9.18a3,3,0,0,1,0,.31,5,5,0,0,1-2.28,4l-.28.15c.14,1.22,1.1,1.67,2.26,1a5,5,0,0,0,2.28-3.95C182.63,306.33,181.76,305.73,180.63,306.22Zm4.94-1.16-1.55-.9-.23.47a.33.33,0,0,0,0,.29,3,3,0,0,1,.27.6.14.14,0,0,0,.2.09l1.2-.53a.12.12,0,0,1,.1,0Zm-3-3.42-.87-.51h-.13l0,0s0,0,0,0l0,0-.71,1.07-.9-.52h0l-.65-.38h0l-.07,0-.93.54-.42.24-.05,0,0,.06,0,0,0,0h0a.41.41,0,0,0,0,.08l-.13,1.51a.17.17,0,0,1,0,.05.11.11,0,0,1,0,.05.61.61,0,0,1-.11.18,8.13,8.13,0,0,0-.76.79.14.14,0,0,1-.11.07.26.26,0,0,1-.15,0l-.87-.3h-.15l-.05,0,0,0-.41.71-.43.75-.15.26a.21.21,0,0,0,0,.13.23.23,0,0,0,.07.13l.7.6.05.07a.23.23,0,0,1,0,.11.19.19,0,0,1,0,.08,8.41,8.41,0,0,0-.32,1.05.51.51,0,0,1-.08.17l-.09.1-1.23.86s-.06.06-.09.1a.34.34,0,0,0,0,.17v1.56a.12.12,0,0,0,0,.1l1.57.9-.57,1.15a.18.18,0,0,0,.07.23l1.9,1.1.08,0a.46.46,0,0,1-.07-.07.2.2,0,0,1,0-.17l.8-1.61a.14.14,0,0,0,0-.07.29.29,0,0,0,0-.22,3.29,3.29,0,0,1-.26-.6.14.14,0,0,0-.2-.09l-.61.27-.6.27a.09.09,0,0,1-.1,0,.1.1,0,0,1-.05-.1v-1.56a.33.33,0,0,1,.05-.16s0-.08.09-.1l1.23-.87a.32.32,0,0,0,.1-.1.37.37,0,0,0,.07-.16,8.41,8.41,0,0,1,.32-1.05.25.25,0,0,0,0-.09.27.27,0,0,0-.08-.18l-.7-.6a.16.16,0,0,1-.06-.12.2.2,0,0,1,0-.13l.29-.49.34-.61.36-.62a.25.25,0,0,1,.16-.1h.09l.86.3a.22.22,0,0,0,.16,0,.26.26,0,0,0,.11-.07,8.22,8.22,0,0,1,.75-.8.42.42,0,0,0,.11-.17.23.23,0,0,0,0-.11l.14-1.5a.24.24,0,0,1,0-.08.34.34,0,0,1,.14-.17l.25-.15.54-.31.56-.32a.1.1,0,0,1,.09,0h0s.05.05.06.09l.07.69.06.62a.14.14,0,0,0,.18.13,3,3,0,0,1,.65-.07.24.24,0,0,0,.19-.06.16.16,0,0,0,.07-.07l1-1.5a.17.17,0,0,1,.23-.05Z"
style="fill: #263238"></path>
<path
d="M179.54,303.46a.24.24,0,0,0,0,.08l-.14,1.5a.23.23,0,0,1,0,.11l-2-1.15h0l0-.05a.17.17,0,0,0,0-.05l.13-1.51a.41.41,0,0,1,0-.08Z"
style="opacity: 0.1"></path>
<path d="M178.38,306.19a.22.22,0,0,1-.16,0l-.86-.3h-.09l-2-1.13h.06l.87.3a.26.26,0,0,0,.15,0Z"
style="opacity: 0.15"></path>
<path
d="M176.94,308.73l-2-1.14h0s0-.06,0-.1l-.05-.07-.7-.6a.23.23,0,0,1-.07-.13l2,1.15a.16.16,0,0,0,.06.12l.7.6A.27.27,0,0,1,176.94,308.73Z"
style="opacity: 0.15"></path>
<path
d="M176.93,313.29a.14.14,0,0,1,0,.07l-.8,1.61a.2.2,0,0,0,0,.17v0h0l-1.89-1.1a.18.18,0,0,1-.07-.23l.57-1.15.42.24h0a.09.09,0,0,0,.1,0l.6-.27Z"
style="opacity: 0.15"></path>
<path
d="M179.52,315.4a.14.14,0,0,0,0,.07l-1.54-.88.29-.43a.3.3,0,0,1,.26-.13,2.94,2.94,0,0,0,.65-.07.14.14,0,0,1,.18.13Z"
style="opacity: 0.15"></path>
<path
d="M183.64,302.28a.17.17,0,0,0-.23.05l-1,1.5a.16.16,0,0,1-.07.07l-.56-.32-.52-.3-.07-.69s0-.08-.06-.09h0l-.4-.24.71-1.07,0,0s0,0,0,0l0,0h0a.22.22,0,0,1,.11,0l.87.51Z"
style="opacity: 0.1"></path>
<path d="M176.54,310a.32.32,0,0,1-.1.1l-1.23.87s-.06.06-.09.1l-2-1.15s.05-.08.09-.1l1.23-.86.09-.1Z"
style="opacity: 0.15"></path>
<path
d="M185.48,305.07l-1.2.54a.14.14,0,0,1-.2-.09,3,3,0,0,0-.27-.6.33.33,0,0,1,0-.29l.8-1.61a.19.19,0,0,0-.07-.24l-.87-.5a.18.18,0,0,0-.24.05l-1,1.5a.3.3,0,0,1-.26.13,3,3,0,0,0-.65.07.14.14,0,0,1-.18-.13l-.13-1.31a.1.1,0,0,0-.16-.08l-1.35.78a.33.33,0,0,0-.16.25l-.14,1.5a.47.47,0,0,1-.14.28,8.22,8.22,0,0,0-.75.8.27.27,0,0,1-.27.07l-.86-.3a.22.22,0,0,0-.25.09l-1,1.72a.21.21,0,0,0,0,.25l.7.6a.27.27,0,0,1,.07.27,8.41,8.41,0,0,0-.32,1.05.41.41,0,0,1-.17.26l-1.23.87a.34.34,0,0,0-.14.26v1.56a.1.1,0,0,0,.15.1l1.21-.54a.14.14,0,0,1,.2.09,3.29,3.29,0,0,0,.26.6.3.3,0,0,1,0,.29l-.8,1.61a.19.19,0,0,0,.07.24l.87.5a.18.18,0,0,0,.24,0l1-1.5a.3.3,0,0,1,.26-.13,2.94,2.94,0,0,0,.65-.07.14.14,0,0,1,.18.13l.14,1.31c0,.09.07.13.16.08l1.35-.78a.38.38,0,0,0,.16-.25l.13-1.5a.47.47,0,0,1,.14-.28,7.16,7.16,0,0,0,.75-.8.27.27,0,0,1,.27-.07l.87.3a.21.21,0,0,0,.24-.09l1-1.72a.2.2,0,0,0,0-.25l-.7-.6a.27.27,0,0,1-.07-.27,8.41,8.41,0,0,0,.32-1.05.46.46,0,0,1,.17-.26l1.23-.87a.34.34,0,0,0,.14-.26v-1.56A.1.1,0,0,0,185.48,305.07Zm-5.13,6.56c-1.26.73-2.28.14-2.28-1.32a5,5,0,0,1,2.28-3.95c1.26-.73,2.28-.14,2.28,1.32A5,5,0,0,1,180.35,311.63Z"
style="fill: #37474f"></path>
<path
d="M176.19,318.62l-.06,0,0,0h0l-.32-.18-.91-.53,0,0-.08,0h-.12l-.85.08h-.08l0,0,0,0,0,0s0,0,0,0l-.46,1.23a.23.23,0,0,1-.07.1l-.11.08-.28.14-.88-.51h0a.16.16,0,0,0-.09,0l-.66.7-.27.28a.13.13,0,0,0,0,.06l0,.06a.11.11,0,0,0,0,.05v0l.26.88s0,.07,0,.11a.42.42,0,0,1,0,.1,6.17,6.17,0,0,0-.43.74.24.24,0,0,1-.1.1.24.24,0,0,1-.1.05l-.8.2-.06,0a.1.1,0,0,0-.05,0l0,0a.07.07,0,0,0,0,.06l-.3,1-.1.36c0,.05,0,.08,0,.1h0l.53.31.07,0,.29.16h0c0,.12,0,.24,0,.36a.28.28,0,0,1-.07.21l-.81,1a.34.34,0,0,0,0,.11h0a.12.12,0,0,0,0,.1l.38.84,0,0h0l1.61.94.08,0v0l0-.08-.19-.41-.16-.36a.2.2,0,0,1,0-.11.14.14,0,0,1,.05-.09l.81-1a.31.31,0,0,0,0-.1.3.3,0,0,0,0-.12,4.09,4.09,0,0,1,0-.7.12.12,0,0,0-.12-.12l-.73,0-.06,0h0a.09.09,0,0,1,0-.09l.18-.61,0,0,.2-.7,0-.06a.26.26,0,0,1,.15-.09l.8-.2a.16.16,0,0,0,.1-.05.19.19,0,0,0,.1-.1,7.89,7.89,0,0,1,.43-.74.3.3,0,0,0,0-.1.22.22,0,0,0,0-.11l-.26-.88a.17.17,0,0,1,0-.1h0a.17.17,0,0,1,.06-.1l.63-.67.3-.32s.1-.06.13,0h0l0,0,.43.66s.11,0,.18,0a4.26,4.26,0,0,1,.53-.31.27.27,0,0,0,.1-.06.26.26,0,0,0,.08-.11l.46-1.24,0-.06.31-.08.68-.07h.07Zm-3.6,9a.13.13,0,0,0-.08-.15,1.51,1.51,0,0,1-.37-.22.18.18,0,0,0-.2,0l-.86.79a.21.21,0,0,1-.1,0l.85.49.53.31a.09.09,0,0,1,0-.08Zm3.8-8.92a.1.1,0,0,1,0,.09l-.27,1.21a.14.14,0,0,0,.09.15,2,2,0,0,1,.37.22s.12,0,.19,0l.86-.8c.05,0,.1-.05.13,0Zm-1.13,9-.43-.66c0-.05-.11-.05-.18,0l-.26.16.89.52Zm.69-5.51a.85.85,0,0,0-.67-.53h-.1a1.39,1.39,0,0,0-.6.13,1.69,1.69,0,0,1,0,.23,3.74,3.74,0,0,1-1.71,2.95l-.19.11a1.24,1.24,0,0,0,.11.44.84.84,0,0,0,.8.54h.33a2.42,2.42,0,0,0,1.1-.72A3.23,3.23,0,0,0,176,322.19Zm1.34,0c0,.12,0,.23,0,.34a.12.12,0,0,0,.13.12l.72,0,.06,0Z"
style="fill: #263238"></path>
<path d="M175.26,327.7l0,0-.89-.52.26-.16c.07-.05.15-.05.18,0Z" style="opacity: 0.15"></path>
<path
d="M172.32,328.88a.09.09,0,0,0,0,.08l-.53-.31-.85-.49a.21.21,0,0,0,.1,0l.86-.79a.18.18,0,0,1,.2,0,1.51,1.51,0,0,0,.37.22.13.13,0,0,1,.08.15Z"
style="opacity: 0.1"></path>
<path
d="M171.46,326a.28.28,0,0,1-.06.09l-.82,1a.18.18,0,0,0,0,.1l-1.71-1a.51.51,0,0,1,0-.12l.81-1s0-.06.05-.08Z"
style="opacity: 0.1"></path>
<path
d="M171.47,325.17c0,.24,0,.47,0,.7a.26.26,0,0,1,0,.12l-1.72-1a.21.21,0,0,0,0-.13c0-.12,0-.24,0-.36l.8.47h0l.06,0,.73,0A.12.12,0,0,1,171.47,325.17Z"
style="opacity: 0.05"></path>
<path
d="M172,323.15a.19.19,0,0,1-.11,0l-.8.2a.23.23,0,0,0-.15.1l-1.71-1,0,0s0,0,.05,0l.06,0,.8-.19a.27.27,0,0,0,.1-.06Z"
style="opacity: 0.1"></path>
<path
d="M172.59,322.09a.22.22,0,0,1,0,.11l-1.71-1a.24.24,0,0,0,0-.12l-.26-.88a0,0,0,0,1,0,0s0,0,0-.05l1.72,1a.38.38,0,0,0,0,.1Z"
style="opacity: 0.1"></path>
<path d="M175.32,318.88l0,.06-.45,1.23a.31.31,0,0,1-.09.12l-1.72-1,0,0,.07-.09.47-1.24,0,0s0,0,0,0Z"
style="opacity: 0.1"></path>
<path d="M175.32,318.88a.27.27,0,0,1,.14-.07h.17" style="fill: none"></path>
<path
d="M178.18,322.71l-.06,0-.72,0a.12.12,0,0,1-.13-.12c0-.11,0-.22,0-.34s0-.24,0-.36a.34.34,0,0,1,.08-.21l.82-1a.22.22,0,0,0,0-.2l-.38-.85,0,0s-.08,0-.13,0l-.86.8c-.07.05-.15.07-.19,0a2,2,0,0,0-.37-.22.14.14,0,0,1-.09-.15l.27-1.21a.1.1,0,0,0,0-.09.11.11,0,0,0-.08,0l-.68.07h-.17a.27.27,0,0,0-.14.07l0,.06-.46,1.24a.26.26,0,0,1-.08.11.27.27,0,0,1-.1.06,4.26,4.26,0,0,0-.53.31c-.07,0-.15,0-.18,0l-.43-.66,0,0s-.08,0-.13,0l-.3.32-.63.67a.26.26,0,0,0-.07.1.17.17,0,0,0,0,.1l.26.88a.22.22,0,0,1,0,.11.3.3,0,0,1,0,.1,7.89,7.89,0,0,0-.43.74.19.19,0,0,1-.1.1.16.16,0,0,1-.1.05l-.8.2a.26.26,0,0,0-.15.09l0,.06-.2.7,0,0-.18.61a.09.09,0,0,0,0,.09h0l.06,0,.73,0a.12.12,0,0,1,.12.12,4.09,4.09,0,0,0,0,.7.3.3,0,0,1,0,.12.31.31,0,0,1,0,.1l-.81,1a.23.23,0,0,0-.05.2l.16.36,0,.05.05.11.07.14,0,.13,0,.06v0s0,0,0,0a.21.21,0,0,0,.1,0l.86-.79a.18.18,0,0,1,.2,0,1.51,1.51,0,0,0,.37.22.13.13,0,0,1,.08.15l-.27,1.22a.09.09,0,0,0,0,.08.11.11,0,0,0,.08,0l.85-.08a.27.27,0,0,0,.19-.13l.46-1.23a.32.32,0,0,1,.18-.18l.27-.15.26-.16c.07-.05.15-.05.18,0l.43.66,0,0a.12.12,0,0,0,.14,0l.93-1a.21.21,0,0,0,.07-.2l-.26-.88a.34.34,0,0,1,.05-.21,7.89,7.89,0,0,0,.43-.74.28.28,0,0,1,.2-.15l.8-.19a.31.31,0,0,0,.18-.15l.4-1.36A.08.08,0,0,0,178.18,322.71Zm-4.25,3.3h-.33a.84.84,0,0,1-.8-.54,1.24,1.24,0,0,1-.11-.44,2.11,2.11,0,0,1,0-.25,3.83,3.83,0,0,1,1.05-2.41,2.75,2.75,0,0,1,.65-.52l.21-.11a1.39,1.39,0,0,1,.6-.13h.1a.85.85,0,0,1,.67.53,3.23,3.23,0,0,1-.92,3.1A2.42,2.42,0,0,1,173.93,326Z"
style="fill: #37474f"></path>
<path
d="M175.34,341.7a6.41,6.41,0,0,0-3.62,3,5.94,5.94,0,0,0,.19,5.64,6.5,6.5,0,0,0-1,3.49,7.74,7.74,0,0,0,5.1,6.89l.29.1.87-.5a8.29,8.29,0,0,1-4.68-4.3,5.85,5.85,0,0,1,.15-4.59A7.35,7.35,0,0,0,174.3,353c1.74,1.14,5.13,2,6.72.17a2.84,2.84,0,0,0-.13-3.71,5.56,5.56,0,0,0-4-1.87,5.62,5.62,0,0,0-4.16,1.75,5.46,5.46,0,0,1-.41-2.58,4.92,4.92,0,0,1,3.52-4.13c1.44,2.24,4.62,4.28,7.07,2.37s-1.46-3.64-3.1-3.79a10.71,10.71,0,0,0-3.39.19,3.68,3.68,0,0,1-.22-2,4.39,4.39,0,0,1,1.67-2.6,5.6,5.6,0,0,1,6.6-.4.36.36,0,1,0,.46-.56C181,332.24,173.28,336.65,175.34,341.7Zm-.62,7.42a4.17,4.17,0,0,1,3.69-.17c1,.45,2.2,1.4,2,2.66-.28,2.19-3.23,1.58-4.61,1a5.79,5.79,0,0,1-2.59-2.24A4.77,4.77,0,0,1,174.72,349.12Zm3-6.91a7.28,7.28,0,0,1,3.08.22c.47.15,1.81.6,1.74,1.28,0,.42-.65.74-1,.88a2.54,2.54,0,0,1-1.61.08,5.49,5.49,0,0,1-2.78-2l-.23-.33A6.84,6.84,0,0,1,177.69,342.21Z"
style="fill: currentcolor"></path>
<path
d="M175.34,341.7a6.41,6.41,0,0,0-3.62,3,5.94,5.94,0,0,0,.19,5.64,6.5,6.5,0,0,0-1,3.49,7.74,7.74,0,0,0,5.1,6.89l.29.1.87-.5a8.29,8.29,0,0,1-4.68-4.3,5.85,5.85,0,0,1,.15-4.59A7.35,7.35,0,0,0,174.3,353c1.74,1.14,5.13,2,6.72.17a2.84,2.84,0,0,0-.13-3.71,5.56,5.56,0,0,0-4-1.87,5.62,5.62,0,0,0-4.16,1.75,5.46,5.46,0,0,1-.41-2.58,4.92,4.92,0,0,1,3.52-4.13c1.44,2.24,4.62,4.28,7.07,2.37s-1.46-3.64-3.1-3.79a10.71,10.71,0,0,0-3.39.19,3.68,3.68,0,0,1-.22-2,4.39,4.39,0,0,1,1.67-2.6,5.6,5.6,0,0,1,6.6-.4.36.36,0,1,0,.46-.56C181,332.24,173.28,336.65,175.34,341.7Zm-.62,7.42a4.17,4.17,0,0,1,3.69-.17c1,.45,2.2,1.4,2,2.66-.28,2.19-3.23,1.58-4.61,1a5.79,5.79,0,0,1-2.59-2.24A4.77,4.77,0,0,1,174.72,349.12Zm3-6.91a7.28,7.28,0,0,1,3.08.22c.47.15,1.81.6,1.74,1.28,0,.42-.65.74-1,.88a2.54,2.54,0,0,1-1.61.08,5.49,5.49,0,0,1-2.78-2l-.23-.33A6.84,6.84,0,0,1,177.69,342.21Z"
style=" opacity: 0.7;fill: #fff"></path>
<path
d="M172.27,352.4a5.43,5.43,0,0,1,.35-1,3.86,3.86,0,0,1-.71-1.09,7,7,0,0,0-.54,1.06A8.6,8.6,0,0,0,172.27,352.4Z"
style="fill: currentcolor"></path>
<path
d="M174.6,343.21a7.24,7.24,0,0,1,1.22-.59,5.7,5.7,0,0,1-.48-.92,7.31,7.31,0,0,0-1.36.63A6.94,6.94,0,0,0,174.6,343.21Z"
style="fill: currentcolor"></path>
<path d="M176.28,360.81l.87-.5a10.72,10.72,0,0,1-1.08-.52l-.93.53a7.2,7.2,0,0,0,.85.39Z"
style="fill: currentcolor"></path>
<path
d="M199.46,344.67a6.45,6.45,0,0,0-4.52-1.29,6,6,0,0,0-4.54,3.36,6.44,6.44,0,0,0-2.28.5,7.83,7.83,0,0,0-1.17.64,7.58,7.58,0,0,0-2.93,7.2c0,.31.09.61.15.91l.06.22.77-.44,0-.24a7.81,7.81,0,0,1,1.08-5.11,5.7,5.7,0,0,1,2.07-1.86,6,6,0,0,1,1.79-.62,6.89,6.89,0,0,0-.33,2.28c0,2.08,1.26,5.36,3.67,5.63a2.84,2.84,0,0,0,3-2.22,5.47,5.47,0,0,0-.74-4.36,5.63,5.63,0,0,0-3.79-2.44,5.4,5.4,0,0,1,1.88-1.8,4.92,4.92,0,0,1,5.4.56c-1,2.46-.9,6.22,2.06,7.15s2.16-3.26,1.37-4.69a11.14,11.14,0,0,0-2.08-2.69,3.64,3.64,0,0,1,1.54-1.33,4.36,4.36,0,0,1,3.08-.1,5.62,5.62,0,0,1,4.08,5.21.36.36,0,1,0,.72.06C210.47,344,202.45,340.11,199.46,344.67Zm-6.46,3.7a4.16,4.16,0,0,1,2.23,2.94c.21,1.1.1,2.61-1,3.19-2,1-3.14-1.77-3.45-3.24a5.87,5.87,0,0,1,.38-3.4A4.84,4.84,0,0,1,193,348.37Zm7.37-1.48a7.41,7.41,0,0,1,1.57,2.66c.14.47.54,1.84-.08,2.16-.36.2-1-.11-1.28-.31a2.47,2.47,0,0,1-1-1.28,5.44,5.44,0,0,1,.08-3.43,3,3,0,0,1,.13-.39C200,346.5,200.2,346.69,200.37,346.89Z"
style="fill: currentcolor"></path>
<path
d="M199.46,344.67a6.45,6.45,0,0,0-4.52-1.29,6,6,0,0,0-4.54,3.36,6.44,6.44,0,0,0-2.28.5,7.83,7.83,0,0,0-1.17.64,7.58,7.58,0,0,0-2.93,7.2c0,.31.09.61.15.91l.06.22.77-.44,0-.24a7.81,7.81,0,0,1,1.08-5.11,5.7,5.7,0,0,1,2.07-1.86,6,6,0,0,1,1.79-.62,6.89,6.89,0,0,0-.33,2.28c0,2.08,1.26,5.36,3.67,5.63a2.84,2.84,0,0,0,3-2.22,5.47,5.47,0,0,0-.74-4.36,5.63,5.63,0,0,0-3.79-2.44,5.4,5.4,0,0,1,1.88-1.8,4.92,4.92,0,0,1,5.4.56c-1,2.46-.9,6.22,2.06,7.15s2.16-3.26,1.37-4.69a11.14,11.14,0,0,0-2.08-2.69,3.64,3.64,0,0,1,1.54-1.33,4.36,4.36,0,0,1,3.08-.1,5.62,5.62,0,0,1,4.08,5.21.36.36,0,1,0,.72.06C210.47,344,202.45,340.11,199.46,344.67Zm-6.46,3.7a4.16,4.16,0,0,1,2.23,2.94c.21,1.1.1,2.61-1,3.19-2,1-3.14-1.77-3.45-3.24a5.87,5.87,0,0,1,.38-3.4A4.84,4.84,0,0,1,193,348.37Zm7.37-1.48a7.41,7.41,0,0,1,1.57,2.66c.14.47.54,1.84-.08,2.16-.36.2-1-.11-1.28-.31a2.47,2.47,0,0,1-1-1.28,5.44,5.44,0,0,1,.08-3.43,3,3,0,0,1,.13-.39C200,346.5,200.2,346.69,200.37,346.89Z"
style=" opacity: 0.7;fill: #fff"></path>
<path
d="M188.91,348.21a5.68,5.68,0,0,1,1-.27,4.22,4.22,0,0,1,.49-1.2,6.85,6.85,0,0,0-1.18.17A8.27,8.27,0,0,0,188.91,348.21Z"
style="fill: currentcolor"></path>
<path
d="M197.79,344.92a6,6,0,0,1,1.18.67,6.92,6.92,0,0,1,.49-.93,7.66,7.66,0,0,0-1.31-.73A5.86,5.86,0,0,0,197.79,344.92Z"
style="fill: currentcolor"></path>
<path d="M184.23,356.21l-.06-.22c-.06-.3-.11-.6-.15-.91l.95.45,0,.24Z" style="fill: currentcolor"></path>
<path
d="M185.94,245,131.56,276.4a4.84,4.84,0,0,0-2.18,3.79v18.66c0,1.4,1,2,2.19,1.27l54.37-31.39a4.87,4.87,0,0,0,2.19-3.79V246.27C188.13,244.88,187.15,244.31,185.94,245Z"
style="fill: #455a64"></path>
<path
d="M184,253.23a4.7,4.7,0,0,1-2.19,3.64l-46.16,26.65c-1.21.69-2.19.2-2.19-1.11a4.7,4.7,0,0,1,2.19-3.64l46.16-26.65C183,251.43,184,251.92,184,253.23Z"
style="fill: currentcolor"></path>
<path
d="M184,262.72a4.7,4.7,0,0,1-2.19,3.64L135.67,293c-1.21.7-2.19.21-2.19-1.1a4.7,4.7,0,0,1,2.19-3.64l46.16-26.65C183,260.91,184,261.41,184,262.72Z"
style="fill: #263238"></path>
<path
d="M181.83,261.61l-19.59,11.31v4.74l19.59-11.3a4.7,4.7,0,0,0,2.19-3.64C184,261.41,183,260.91,181.83,261.61Z"
style="fill: currentcolor"></path>
<path
d="M110.54,201.07c-2.27-1.31-4.11-.12-4.11,2.68V304.13a9.4,9.4,0,0,0,4.11,7.44c2.27,1.32,4.11.12,4.11-2.67V208.51A9.43,9.43,0,0,0,110.54,201.07Z"
style="fill: currentcolor"></path>
<path
d="M110.54,201.07c-2.27-1.31-4.11-.12-4.11,2.68V304.13a9.4,9.4,0,0,0,4.11,7.44c2.27,1.32,4.11.12,4.11-2.67V208.51A9.43,9.43,0,0,0,110.54,201.07Z"
style="opacity: 0.5"></path>
<path
d="M110.54,309.17a4.7,4.7,0,0,1-2.05-3.71V204.77c0-1.4.92-2,2.05-1.35a4.69,4.69,0,0,1,2,3.72V307.83C112.59,309.23,111.67,309.83,110.54,309.17Z"
style="fill: #37474f"></path>
<path d="M110.54,309.17a4.7,4.7,0,0,1-2.05-3.71v-49.2l4.1,2.37v49.2C112.59,309.23,111.67,309.83,110.54,309.17Z"
style="fill: currentcolor"></path>
<path
d="M98.22,194c-2.27-1.32-4.11-.12-4.11,2.67V297a9.43,9.43,0,0,0,4.11,7.44c2.26,1.31,4.1.11,4.1-2.68V201.39A9.41,9.41,0,0,0,98.22,194Z"
style="fill: currentcolor"></path>
<path
d="M98.22,194c-2.27-1.32-4.11-.12-4.11,2.67V297a9.43,9.43,0,0,0,4.11,7.44c2.26,1.31,4.1.11,4.1-2.68V201.39A9.41,9.41,0,0,0,98.22,194Z"
style="opacity: 0.5"></path>
<path
d="M98.22,302.06a4.7,4.7,0,0,1-2.06-3.72V197.65c0-1.4.92-2,2.06-1.34a4.7,4.7,0,0,1,2,3.71V300.71C100.27,302.11,99.35,302.71,98.22,302.06Z"
style="fill: currentcolor"></path>
<path
d="M85.89,186.84c-2.27-1.31-4.11-.12-4.11,2.68V289.9a9.4,9.4,0,0,0,4.11,7.44c2.27,1.32,4.11.12,4.11-2.67V194.28A9.43,9.43,0,0,0,85.89,186.84Z"
style="fill: currentcolor"></path>
<path
d="M85.89,186.84c-2.27-1.31-4.11-.12-4.11,2.68V289.9a9.4,9.4,0,0,0,4.11,7.44c2.27,1.32,4.11.12,4.11-2.67V194.28A9.43,9.43,0,0,0,85.89,186.84Z"
style="opacity: 0.5"></path>
<path
d="M85.89,294.94a4.7,4.7,0,0,1-2-3.71V190.54c0-1.4.92-2,2-1.35A4.7,4.7,0,0,1,88,192.91V293.6C87.94,295,87,295.6,85.89,294.94Z"
style="fill: #37474f"></path>
<path d="M85.89,294.94a4.7,4.7,0,0,1-2-3.71V218.11L88,220.49V293.6C87.94,295,87,295.6,85.89,294.94Z"
style="fill: currentcolor"></path>
<path
d="M73.57,179.73c-2.27-1.32-4.11-.12-4.11,2.67V282.79a9.43,9.43,0,0,0,4.11,7.44c2.26,1.31,4.1.11,4.1-2.68V187.16A9.39,9.39,0,0,0,73.57,179.73Z"
style="fill: currentcolor"></path>
<path
d="M73.57,179.73c-2.27-1.32-4.11-.12-4.11,2.67V282.79a9.43,9.43,0,0,0,4.11,7.44c2.26,1.31,4.1.11,4.1-2.68V187.16A9.39,9.39,0,0,0,73.57,179.73Z"
style="opacity: 0.5"></path>
<path
d="M73.57,287.83a4.7,4.7,0,0,1-2.06-3.72V183.42c0-1.4.92-2,2.06-1.34a4.7,4.7,0,0,1,2.05,3.71V286.48C75.62,287.88,74.7,288.48,73.57,287.83Z"
style="fill: #37474f"></path>
<path d="M73.57,287.83a4.7,4.7,0,0,1-2.06-3.72V265.75l4.11,2.37v18.36C75.62,287.88,74.7,288.48,73.57,287.83Z"
style="fill: currentcolor"></path>
<path
d="M61.24,172.61c-2.27-1.32-4.11-.12-4.11,2.68V275.67a9.4,9.4,0,0,0,4.11,7.44c2.27,1.32,4.11.12,4.11-2.67V180.05A9.43,9.43,0,0,0,61.24,172.61Z"
style="fill: currentcolor"></path>
<path
d="M61.24,172.61c-2.27-1.32-4.11-.12-4.11,2.68V275.67a9.4,9.4,0,0,0,4.11,7.44c2.27,1.32,4.11.12,4.11-2.67V180.05A9.43,9.43,0,0,0,61.24,172.61Z"
style="opacity: 0.5"></path>
<path
d="M61.24,280.71A4.7,4.7,0,0,1,59.19,277V176.3c0-1.39.92-2,2.05-1.34a4.7,4.7,0,0,1,2.06,3.72V279.37C63.3,280.76,62.38,281.37,61.24,280.71Z"
style="fill: #37474f"></path>
<path d="M61.24,280.71A4.7,4.7,0,0,1,59.19,277V223.05l4.11,2.38v53.94C63.3,280.76,62.38,281.37,61.24,280.71Z"
style="fill: currentcolor"></path>
<path
d="M185.94,169.32l-54.38,31.39a4.82,4.82,0,0,0-2.18,3.79V267c0,1.39,1,2,2.19,1.26l54.37-31.39a4.87,4.87,0,0,0,2.19-3.79V170.58C188.13,169.18,187.15,168.62,185.94,169.32Z"
style="fill: #37474f"></path>
<path d="M130,202.43a4.29,4.29,0,0,0-.59,2.07V267c0,1.39,1,2,2.19,1.26l54.37-31.39a4.58,4.58,0,0,0,1.59-1.72Z"
style="fill: #263238"></path>
<path d="M131.56,200.71a4.82,4.82,0,0,0-2.18,3.79V267l54.37-31.39a4.87,4.87,0,0,0,2.18-3.8V169.32Z"
style="fill: #455a64"></path>
<g id="freepik--dead-emoji--inject-87">
<path
d="M149.47,217.14a1.1,1.1,0,0,1-.78-.31l-7.23-7a1.12,1.12,0,1,1,1.56-1.62l7.23,6.95a1.13,1.13,0,0,1-.78,1.94Z"
style="fill: currentcolor"></path>
<path
d="M142.24,221.31a1.05,1.05,0,0,1-.48-.11,1.13,1.13,0,0,1-.54-1.5l7.23-15.3a1.12,1.12,0,0,1,1.5-.53,1.13,1.13,0,0,1,.54,1.5l-7.23,15.3A1.13,1.13,0,0,1,142.24,221.31Z"
style="fill: currentcolor"></path>
<path
d="M173.07,203.51a1.12,1.12,0,0,1-.78-.31l-7.23-6.95a1.13,1.13,0,0,1,1.57-1.63l7.22,6.95a1.14,1.14,0,0,1,0,1.6A1.1,1.1,0,0,1,173.07,203.51Z"
style="fill: currentcolor"></path>
<path
d="M165.84,207.69a1.2,1.2,0,0,1-.48-.11,1.14,1.14,0,0,1-.54-1.5l7.23-15.3a1.13,1.13,0,0,1,2,1L166.86,207A1.13,1.13,0,0,1,165.84,207.69Z"
style="fill: currentcolor"></path>
<path
d="M141.92,238.65a1.14,1.14,0,0,1-1-.57,1.13,1.13,0,0,1,.42-1.54l31.47-18.17a1.13,1.13,0,0,1,1.54.41,1.14,1.14,0,0,1-.42,1.55l-31.47,18.16A1,1,0,0,1,141.92,238.65Z"
style="fill: currentcolor"></path>
<path
d="M163.85,239.16a3.11,3.11,0,0,1-1.58-.42,4.17,4.17,0,0,1-1.81-3.79v-8.79a1.14,1.14,0,0,1,1.13-1.13h0a1.14,1.14,0,0,1,1.13,1.13V235a2.07,2.07,0,0,0,.68,1.83,1.65,1.65,0,0,0,1.56-.24,7.85,7.85,0,0,0,3.37-6.14v-8.78a1.13,1.13,0,1,1,2.25,0v8.78a10.09,10.09,0,0,1-4.49,8.09A4.46,4.46,0,0,1,163.85,239.16Z"
style="fill: currentcolor"></path>
<path
d="M165.52,233.5a1.13,1.13,0,0,1-1.13-1.13v-8.48a1.13,1.13,0,0,1,2.26,0v8.48A1.12,1.12,0,0,1,165.52,233.5Z"
style="fill: currentcolor"></path>
</g>
<g id="freepik--server--inject-87">
<path
d="M66.16,363.4a2.11,2.11,0,0,1,1,1.67c0,.62-.43.87-1,.56a2.16,2.16,0,0,1-1-1.67C65.19,363.34,65.63,363.09,66.16,363.4Z"
style="fill: #37474f"></path>
<path
d="M74.24,368.07a2.11,2.11,0,0,1,1,1.67c0,.61-.43.86-1,.56a2.13,2.13,0,0,1-1-1.68C73.27,368,73.7,367.76,74.24,368.07Z"
style="fill: #37474f"></path>
<path
d="M82.17,372.65a2.1,2.1,0,0,1,1,1.66c0,.62-.43.87-1,.56a2.13,2.13,0,0,1-1-1.67C81.21,372.59,81.64,372.34,82.17,372.65Z"
style="fill: #37474f"></path>
<path
d="M90.18,377.27a2.13,2.13,0,0,1,1,1.66c0,.61-.43.86-1,.56a2.13,2.13,0,0,1-1-1.66C89.22,377.21,89.65,377,90.18,377.27Z"
style="fill: #37474f"></path>
<path
d="M56.74,315.92,65,320.63a5.17,5.17,0,0,1,2.32,4v4.71c0,1.48-1,2.09-2.32,1.34L56.74,326a5.16,5.16,0,0,1-2.33-4v-4.71C54.41,315.78,55.46,315.18,56.74,315.92Z"
style="fill: #37474f"></path>
<path
d="M59,321.23l1.07-.62h0a1.41,1.41,0,0,1,1.42.14,4.48,4.48,0,0,1,2,3.51,1.4,1.4,0,0,1-.59,1.3h0l-1,.57-.18-.3a1.81,1.81,0,0,1-.58-.22,4.46,4.46,0,0,1-2-3.5,2.06,2.06,0,0,1,.06-.52Z"
style="fill: currentcolor"></path>
<path
d="M59,321.23l1.07-.62h0a1.41,1.41,0,0,1,1.42.14,4.48,4.48,0,0,1,2,3.51,1.4,1.4,0,0,1-.59,1.3h0l-1,.57-.18-.3a1.81,1.81,0,0,1-.58-.22,4.46,4.46,0,0,1-2-3.5,2.06,2.06,0,0,1,.06-.52Z"
style="opacity: 0.2"></path>
<path
d="M60.42,321.34a4.49,4.49,0,0,1,2,3.51c0,1.28-.91,1.81-2,1.16a4.47,4.47,0,0,1-2-3.5C58.4,321.22,59.31,320.7,60.42,321.34Z"
style="fill: currentcolor"></path>
<path
d="M56.74,293.25,65,298a5.14,5.14,0,0,1,2.32,4v4.7c0,1.49-1,2.09-2.32,1.35l-8.21-4.72a5.15,5.15,0,0,1-2.33-4v-4.71C54.41,293.11,55.46,292.51,56.74,293.25Z"
style="fill: #455a64"></path>
<path
d="M59,298.56l1.07-.62h0a1.42,1.42,0,0,1,1.42.15,4.45,4.45,0,0,1,2,3.5,1.43,1.43,0,0,1-.59,1.31h0l-1,.57-.18-.3a2.12,2.12,0,0,1-.58-.23,4.45,4.45,0,0,1-2-3.5,2.12,2.12,0,0,1,.06-.52Z"
style="fill: currentcolor"></path>
<path
d="M59,298.56l1.07-.62h0a1.42,1.42,0,0,1,1.42.15,4.45,4.45,0,0,1,2,3.5,1.43,1.43,0,0,1-.59,1.31h0l-1,.57-.18-.3a2.12,2.12,0,0,1-.58-.23,4.45,4.45,0,0,1-2-3.5,2.12,2.12,0,0,1,.06-.52Z"
style="opacity: 0.2"></path>
<path
d="M60.42,298.68a4.46,4.46,0,0,1,2,3.5c0,1.29-.91,1.81-2,1.17a4.51,4.51,0,0,1-2-3.51C58.4,298.55,59.31,298,60.42,298.68Z"
style="fill: currentcolor"></path>
<path
d="M185.57,276.07l-38,21.95a5.66,5.66,0,0,0-2.55,4.43v5.17c0,1.62,1.14,2.28,2.55,1.47l38-21.95a5.67,5.67,0,0,0,2.56-4.43v-5.16C188.13,275.92,187,275.26,185.57,276.07Z"
style="fill: #455a64"></path>
<path
d="M185.43,280.45V283a1.13,1.13,0,0,1-.51.89l-.57.33c-.29.16-.52,0-.52-.29v-2.51a1.13,1.13,0,0,1,.52-.89l.57-.33C185.2,280,185.43,280.12,185.43,280.45Z"
style="fill: currentcolor"></path>
<path
d="M182.85,281.94v2.5a1.13,1.13,0,0,1-.51.89l-.58.33c-.28.16-.51,0-.51-.29v-2.51a1.15,1.15,0,0,1,.51-.89l.58-.33C182.62,281.48,182.85,281.61,182.85,281.94Z"
style="fill: currentcolor"></path>
<path
d="M180.27,283.42v2.51a1.15,1.15,0,0,1-.51.89l-.58.33c-.28.16-.51,0-.51-.3v-2.5a1.13,1.13,0,0,1,.51-.89l.58-.33C180,283,180.27,283.1,180.27,283.42Z"
style="fill: currentcolor"></path>
<path
d="M177.69,284.91v2.51a1.11,1.11,0,0,1-.51.88l-.58.34c-.28.16-.51,0-.51-.3v-2.51a1.13,1.13,0,0,1,.51-.88l.58-.33C177.46,284.45,177.69,284.59,177.69,284.91Z"
style="fill: currentcolor"></path>
<path
d="M175.1,286.4v2.51a1.1,1.1,0,0,1-.51.88l-.57.33c-.28.17-.51,0-.51-.29v-2.51a1.13,1.13,0,0,1,.51-.88l.57-.33C174.88,285.94,175.1,286.08,175.1,286.4Z"
style="fill: #37474f"></path>
<path
d="M172.52,287.89v2.51a1.13,1.13,0,0,1-.51.88l-.57.33c-.29.17-.51,0-.51-.29v-2.51a1.1,1.1,0,0,1,.51-.88l.57-.34C172.29,287.43,172.52,287.56,172.52,287.89Z"
style="fill: #37474f"></path>
<path
d="M169.94,289.38v2.5a1.13,1.13,0,0,1-.51.89l-.58.33c-.28.16-.51,0-.51-.29V290.3a1.15,1.15,0,0,1,.51-.89l.58-.33C169.71,288.92,169.94,289.05,169.94,289.38Z"
style="fill: currentcolor"></path>
<path
d="M167.36,290.87v2.5a1.13,1.13,0,0,1-.51.89l-.58.33c-.28.16-.51,0-.51-.3v-2.5a1.15,1.15,0,0,1,.51-.89l.58-.33C167.13,290.41,167.36,290.54,167.36,290.87Z"
style="fill: currentcolor"></path>
<path
d="M164.78,292.35v2.51a1.15,1.15,0,0,1-.51.89l-.58.33c-.28.16-.51,0-.51-.3v-2.5a1.13,1.13,0,0,1,.51-.89l.58-.33C164.55,291.9,164.78,292,164.78,292.35Z"
style="fill: currentcolor"></path>
<path
d="M162.2,293.84v2.51a1.1,1.1,0,0,1-.52.88l-.57.34c-.28.16-.51,0-.51-.3v-2.51a1.13,1.13,0,0,1,.51-.88l.57-.33C162,293.38,162.2,293.52,162.2,293.84Z"
style="fill: #37474f"></path>
<path
d="M159.61,295.33v2.51a1.13,1.13,0,0,1-.51.88l-.57.33c-.28.17-.51,0-.51-.29v-2.51a1.13,1.13,0,0,1,.51-.88l.57-.33C159.38,294.87,159.61,295,159.61,295.33Z"
style="fill: currentcolor"></path>
<path
d="M157,296.82v2.51a1.13,1.13,0,0,1-.51.88l-.57.33c-.29.17-.51,0-.51-.29v-2.51a1.1,1.1,0,0,1,.51-.88l.57-.34C156.8,296.36,157,296.49,157,296.82Z"
style="fill: currentcolor"></path>
<path
d="M154.45,298.31v2.5a1.13,1.13,0,0,1-.51.89l-.58.33c-.28.16-.51,0-.51-.29v-2.51a1.15,1.15,0,0,1,.51-.89l.58-.33C154.22,297.85,154.45,298,154.45,298.31Z"
style="fill: #37474f"></path>
<path
d="M151.87,299.8v2.5a1.13,1.13,0,0,1-.51.89l-.58.33c-.28.16-.51,0-.51-.3v-2.5a1.15,1.15,0,0,1,.51-.89l.58-.33C151.64,299.34,151.87,299.47,151.87,299.8Z"
style="fill: currentcolor"></path>
<path
d="M149.29,301.28v2.51a1.15,1.15,0,0,1-.51.89l-.58.33c-.28.16-.51,0-.51-.3v-2.5a1.13,1.13,0,0,1,.51-.89l.58-.33C149.06,300.83,149.29,301,149.29,301.28Z"
style="fill: #37474f"></path>
<path
d="M141.15,306.31l-1.06-.62h0a1.41,1.41,0,0,0-1.42.14,4.49,4.49,0,0,0-2,3.51,1.42,1.42,0,0,0,.59,1.3h0l1,.56.18-.3a2,2,0,0,0,.58-.22,4.49,4.49,0,0,0,2-3.5,2.66,2.66,0,0,0-.06-.52Z"
style="fill: #455a64"></path>
<path
d="M139.68,306.42a4.51,4.51,0,0,0-2,3.51c0,1.29.91,1.81,2,1.16a4.45,4.45,0,0,0,2-3.5C141.7,306.3,140.8,305.78,139.68,306.42Z"
style="fill: currentcolor"></path>
<path
d="M139.68,306.42a4.51,4.51,0,0,0-2,3.51c0,1.29.91,1.81,2,1.16a4.45,4.45,0,0,0,2-3.5C141.7,306.3,140.8,305.78,139.68,306.42Z"
style=" opacity: 0.8;fill: #fff"></path>
<path
d="M132.38,311.37l-1.07-.61h0a1.44,1.44,0,0,0-1.42.15,4.45,4.45,0,0,0-2,3.5,1.41,1.41,0,0,0,.59,1.31h0l1,.57.18-.3a1.94,1.94,0,0,0,.58-.23,4.45,4.45,0,0,0,2-3.5,2,2,0,0,0-.06-.51Z"
style="fill: #455a64"></path>
<path
d="M130.9,311.49a4.47,4.47,0,0,0-2,3.5c0,1.29.91,1.81,2,1.17a4.47,4.47,0,0,0,2-3.5C132.93,311.37,132,310.84,130.9,311.49Z"
style="fill: currentcolor"></path>
<path
d="M130.9,311.49a4.47,4.47,0,0,0-2,3.5c0,1.29.91,1.81,2,1.17a4.47,4.47,0,0,0,2-3.5C132.93,311.37,132,310.84,130.9,311.49Z"
style=" opacity: 0.8;fill: #fff"></path>
<path
d="M73.87,301.3l39.79,23a2.85,2.85,0,0,1,1.29,2.23v11c0,.82-.58,1.15-1.29.74l-39.79-23A2.83,2.83,0,0,1,72.58,313v-11C72.58,301.22,73.15,300.89,73.87,301.3Z"
style="fill: #455a64"></path>
<path
d="M75,306.14a2.74,2.74,0,0,0,1.29,2.14l34.95,20.17c.71.41,1.29.11,1.29-.66a2.77,2.77,0,0,0-1.29-2.14L76.29,305.49C75.57,305.08,75,305.37,75,306.14Z"
style="fill: currentcolor"></path>
<path
d="M75,311.73a2.74,2.74,0,0,0,1.29,2.14L111.24,334c.71.41,1.29.12,1.29-.65a2.77,2.77,0,0,0-1.29-2.14L76.29,311.08C75.57,310.67,75,311,75,311.73Z"
style="fill: #263238"></path>
<path
d="M76.29,311.08,95.6,322.21V325L76.29,313.87A2.74,2.74,0,0,1,75,311.73C75,311,75.57,310.67,76.29,311.08Z"
style="fill: currentcolor"></path>
<path
d="M56.74,293.25,65,298a5.14,5.14,0,0,1,2.32,4v4.7c0,1.49-1,2.09-2.32,1.35l-8.21-4.72a5.15,5.15,0,0,1-2.33-4v-4.71C54.41,293.11,55.46,292.51,56.74,293.25Z"
style="fill: #37474f"></path>
<path
d="M59,298.56l1.07-.62h0a1.42,1.42,0,0,1,1.42.15,4.45,4.45,0,0,1,2,3.5,1.43,1.43,0,0,1-.59,1.31h0l-1,.57-.18-.3a2.12,2.12,0,0,1-.58-.23,4.45,4.45,0,0,1-2-3.5,2.12,2.12,0,0,1,.06-.52Z"
style="fill: currentcolor"></path>
<path
d="M59,298.56l1.07-.62h0a1.42,1.42,0,0,1,1.42.15,4.45,4.45,0,0,1,2,3.5,1.43,1.43,0,0,1-.59,1.31h0l-1,.57-.18-.3a2.12,2.12,0,0,1-.58-.23,4.45,4.45,0,0,1-2-3.5,2.12,2.12,0,0,1,.06-.52Z"
style="opacity: 0.2"></path>
<path
d="M60.42,298.68a4.46,4.46,0,0,1,2,3.5c0,1.29-.91,1.81-2,1.17a4.51,4.51,0,0,1-2-3.51C58.4,298.55,59.31,298,60.42,298.68Z"
style="fill: currentcolor"></path>
<path
d="M73.87,301.3l39.79,23a2.85,2.85,0,0,1,1.29,2.23v11c0,.82-.58,1.15-1.29.74l-39.79-23A2.83,2.83,0,0,1,72.58,313v-11C72.58,301.22,73.15,300.89,73.87,301.3Z"
style="fill: #37474f"></path>
<path
d="M75,306.14a2.74,2.74,0,0,0,1.29,2.14l34.95,20.17c.71.41,1.29.11,1.29-.66a2.77,2.77,0,0,0-1.29-2.14L76.29,305.49C75.57,305.08,75,305.37,75,306.14Z"
style="fill: currentcolor"></path>
<path
d="M75,311.73a2.74,2.74,0,0,0,1.29,2.14L111.24,334c.71.41,1.29.12,1.29-.65a2.77,2.77,0,0,0-1.29-2.14L76.29,311.08C75.57,310.67,75,311,75,311.73Z"
style="fill: #263238"></path>
<path
d="M76.29,311.08,95.6,322.21V325L76.29,313.87A2.74,2.74,0,0,1,75,311.73C75,311,75.57,310.67,76.29,311.08Z"
style="fill: currentcolor"></path>
<path
d="M73.87,324l39.79,23a2.89,2.89,0,0,1,1.29,2.24v11c0,.82-.58,1.15-1.29.74L73.87,338a2.84,2.84,0,0,1-1.29-2.24v-11C72.58,324,73.15,323.62,73.87,324Z"
style="fill: #37474f"></path>
<path
d="M75,328.87A2.74,2.74,0,0,0,76.29,331l34.95,20.16c.71.42,1.29.12,1.29-.65a2.77,2.77,0,0,0-1.29-2.14L76.29,328.22C75.57,327.81,75,328.1,75,328.87Z"
style="fill: currentcolor"></path>
<path
d="M75,334.46a2.74,2.74,0,0,0,1.29,2.14l34.95,20.16c.71.41,1.29.12,1.29-.65a2.77,2.77,0,0,0-1.29-2.14L76.29,333.81C75.57,333.4,75,333.69,75,334.46Z"
style="fill: #263238"></path>
<path
d="M76.29,333.81l24.15,13.92v2.79L76.29,336.6A2.74,2.74,0,0,1,75,334.46C75,333.69,75.57,333.4,76.29,333.81Z"
style="fill: currentcolor"></path>
</g>
<path
d="M56.74,338.72,65,343.43a5.15,5.15,0,0,1,2.32,4v4.71c0,1.48-1,2.08-2.32,1.34l-8.21-4.71a5.18,5.18,0,0,1-2.33-4v-4.71C54.41,338.58,55.46,338,56.74,338.72Z"
style="fill: #455a64"></path>
<path
d="M59,344l1.07-.62h0a1.41,1.41,0,0,1,1.42.14,4.46,4.46,0,0,1,2,3.5,1.41,1.41,0,0,1-.59,1.31h0l-1,.57-.18-.3a2.08,2.08,0,0,1-.58-.22,4.48,4.48,0,0,1-2-3.51,2,2,0,0,1,.06-.51Z"
style="fill: currentcolor"></path>
<path
d="M59,344l1.07-.62h0a1.41,1.41,0,0,1,1.42.14,4.46,4.46,0,0,1,2,3.5,1.41,1.41,0,0,1-.59,1.31h0l-1,.57-.18-.3a2.08,2.08,0,0,1-.58-.22,4.48,4.48,0,0,1-2-3.51,2,2,0,0,1,.06-.51Z"
style="opacity: 0.2"></path>
<path
d="M60.42,344.14a4.46,4.46,0,0,1,2,3.5c0,1.29-.91,1.81-2,1.17a4.47,4.47,0,0,1-2-3.5C58.4,344,59.31,343.5,60.42,344.14Z"
style="fill: currentcolor"></path>
<path
d="M56.74,338.72,65,343.43a5.15,5.15,0,0,1,2.32,4v4.71c0,1.48-1,2.08-2.32,1.34l-8.21-4.71a5.18,5.18,0,0,1-2.33-4v-4.71C54.41,338.58,55.46,338,56.74,338.72Z"
style="fill: #37474f"></path>
<path
d="M59,344l1.07-.62h0a1.41,1.41,0,0,1,1.42.14,4.46,4.46,0,0,1,2,3.5,1.41,1.41,0,0,1-.59,1.31h0l-1,.57-.18-.3a2.08,2.08,0,0,1-.58-.22,4.48,4.48,0,0,1-2-3.51,2,2,0,0,1,.06-.51Z"
style="fill: currentcolor"></path>
<path
d="M59,344l1.07-.62h0a1.41,1.41,0,0,1,1.42.14,4.46,4.46,0,0,1,2,3.5,1.41,1.41,0,0,1-.59,1.31h0l-1,.57-.18-.3a2.08,2.08,0,0,1-.58-.22,4.48,4.48,0,0,1-2-3.51,2,2,0,0,1,.06-.51Z"
style="opacity: 0.2"></path>
<path
d="M60.42,344.14a4.46,4.46,0,0,1,2,3.5c0,1.29-.91,1.81-2,1.17a4.47,4.47,0,0,1-2-3.5C58.4,344,59.31,343.5,60.42,344.14Z"
style="fill: currentcolor"></path>
<path
d="M73.87,346.77l39.79,23A2.85,2.85,0,0,1,115,372v11c0,.83-.58,1.16-1.29.75l-39.79-23a2.83,2.83,0,0,1-1.29-2.23v-11C72.58,346.69,73.15,346.35,73.87,346.77Z"
style="fill: #37474f"></path>
<path
d="M75,351.61a2.74,2.74,0,0,0,1.29,2.14l34.95,20.16c.71.41,1.29.12,1.29-.65a2.77,2.77,0,0,0-1.29-2.14L76.29,351C75.57,350.54,75,350.84,75,351.61Z"
style="fill: currentcolor"></path>
<path
d="M75,357.19a2.76,2.76,0,0,0,1.29,2.15l34.95,20.16c.71.41,1.29.12,1.29-.65a2.79,2.79,0,0,0-1.29-2.15L76.29,356.54C75.57,356.13,75,356.42,75,357.19Z"
style="fill: #263238"></path>
<path
d="M76.29,356.54,95.6,367.67v2.8L76.29,359.34A2.76,2.76,0,0,1,75,357.19C75,356.42,75.57,356.13,76.29,356.54Z"
style="fill: currentcolor"></path>
<path
d="M177.29,158.41l-53.07,30.64a3.07,3.07,0,0,1-2.74,0L68.41,158.41a.84.84,0,0,1,0-1.59l53.07-29.58a3.07,3.07,0,0,1,2.74,0l53.07,29.58A.84.84,0,0,1,177.29,158.41Z"
style="opacity: 0.1"></path>
<path
d="M124.16,187.37l50.78-29.32a2.9,2.9,0,0,0,1.32-2.27v-1.71a2.91,2.91,0,0,0-1.32-2.28l-50.78-29.32a2.88,2.88,0,0,0-2.62,0L70.76,151.79a2.91,2.91,0,0,0-1.32,2.28v1.71a2.9,2.9,0,0,0,1.32,2.27l50.78,29.32A2.88,2.88,0,0,0,124.16,187.37Z"
style="fill: currentcolor"></path>
<path
d="M124.16,187.37l50.78-29.32a2.9,2.9,0,0,0,1.32-2.27v-1.71a2.91,2.91,0,0,0-1.32-2.28l-50.78-29.32a2.88,2.88,0,0,0-2.62,0L70.76,151.79a2.91,2.91,0,0,0-1.32,2.28v1.71a2.9,2.9,0,0,0,1.32,2.27l50.78,29.32A2.88,2.88,0,0,0,124.16,187.37Z"
style=" opacity: 0.5;fill: #fff"></path>
<path
d="M124.16,187.37l50.78-29.32a2.9,2.9,0,0,0,1.32-2.27v-1.71a2.91,2.91,0,0,0-1.32-2.28l-50.78-29.32a2.88,2.88,0,0,0-2.62,0L70.76,151.79a2.91,2.91,0,0,0-1.32,2.28v1.71a2.9,2.9,0,0,0,1.32,2.27l50.78,29.32A2.88,2.88,0,0,0,124.16,187.37Z"
style="opacity: 0.05"></path>
<path
d="M174.94,153.31l-50.78,29.31a2.88,2.88,0,0,1-2.62,0L70.76,153.31a.8.8,0,0,1,0-1.52l50.78-28.3a2.88,2.88,0,0,1,2.62,0l50.78,28.3A.8.8,0,0,1,174.94,153.31Z"
style="fill: currentcolor"></path>
<path
d="M174.94,153.31l-50.78,29.31a2.88,2.88,0,0,1-2.62,0L70.76,153.31a.8.8,0,0,1,0-1.52l50.78-28.3a2.88,2.88,0,0,1,2.62,0l50.78,28.3A.8.8,0,0,1,174.94,153.31Z"
style=" opacity: 0.7;fill: #fff"></path>
<path
d="M122.85,182.94v4.74a2.67,2.67,0,0,0,1.31-.31l50.78-29.32a2.91,2.91,0,0,0,1.32-2.28v-1.71a2.92,2.92,0,0,0-1.07-2.1c.47.41.39,1-.25,1.34l-50.78,29.32A2.57,2.57,0,0,1,122.85,182.94Z"
style="fill: currentcolor"></path>
<path
d="M122.85,182.94v4.74a2.67,2.67,0,0,0,1.31-.31l50.78-29.32a2.91,2.91,0,0,0,1.32-2.28v-1.71a2.92,2.92,0,0,0-1.07-2.1c.47.41.39,1-.25,1.34l-50.78,29.32A2.57,2.57,0,0,1,122.85,182.94Z"
style=" opacity: 0.6;fill: #fff"></path>
<path
d="M124.16,173.14l34.35-19.83a2.89,2.89,0,0,0,1.31-2.28v-1.71a2.88,2.88,0,0,0-1.31-2.27l-22-12.72a8.71,8.71,0,0,1-2.22-2l-10.52-14.17a1.74,1.74,0,0,0-2.21-.46L87.19,137.56a2.89,2.89,0,0,0-1.31,2.27V151a2.92,2.92,0,0,0,1.31,2.28l34.35,19.83A2.88,2.88,0,0,0,124.16,173.14Z"
style="fill: #263238"></path>
<path
d="M121.54,168.39l-22-12.71a7.19,7.19,0,0,1-1.15-.85,7.87,7.87,0,0,1-1.07-1.13L86.78,139.53a1.31,1.31,0,0,1,.41-2l34.35-19.83a1.74,1.74,0,0,1,2.21.46l10.52,14.17a8.28,8.28,0,0,0,2,2l22.2,12.64a.79.79,0,0,1,0,1.51l-34.35,19.83A2.88,2.88,0,0,1,121.54,168.39Z"
style="fill: #455a64"></path>
<path
d="M87.19,137.56l34.35-19.83a1.74,1.74,0,0,1,2.21.46l10.52,14.17a8,8,0,0,0,1.08,1.12s-37,21.35-37,21.34a7.84,7.84,0,0,1-1.07-1.12L86.78,139.53A1.31,1.31,0,0,1,87.19,137.56Z"
style="fill: #37474f"></path>
<path
d="M150.18,147.39a3.41,3.41,0,0,0-3.08,0c-.86.5-.86,1.29,0,1.78a3.41,3.41,0,0,0,3.08,0A.94.94,0,0,0,150.18,147.39Z"
style="fill: currentcolor"></path>
<path d="M144,151a3.41,3.41,0,0,0-3.08,0,.94.94,0,0,0,0,1.78,3.41,3.41,0,0,0,3.08,0A.94.94,0,0,0,144,151Z"
style="fill: currentcolor"></path>
<path
d="M137.85,154.51a3.41,3.41,0,0,0-3.08,0,.94.94,0,0,0,0,1.78,3.41,3.41,0,0,0,3.08,0A.94.94,0,0,0,137.85,154.51Z"
style="fill: #263238"></path>
<path
d="M131.69,158.07a3.41,3.41,0,0,0-3.08,0,.94.94,0,0,0,0,1.78,3.41,3.41,0,0,0,3.08,0A.94.94,0,0,0,131.69,158.07Z"
style="fill: #263238"></path>
<path
d="M145.56,144.73a3.37,3.37,0,0,0-3.09,0,.93.93,0,0,0,0,1.77,3.37,3.37,0,0,0,3.09,0A.93.93,0,0,0,145.56,144.73Z"
style="fill: currentcolor"></path>
<path
d="M139.39,148.28a3.41,3.41,0,0,0-3.08,0,.94.94,0,0,0,0,1.78,3.41,3.41,0,0,0,3.08,0A.94.94,0,0,0,139.39,148.28Z"
style="fill: #263238"></path>
<ellipse cx="131.69" cy="152.73" rx="2.18" ry="1.26" style="fill: currentcolor"></ellipse>
<path
d="M127.07,155.4a3.41,3.41,0,0,0-3.08,0,.94.94,0,0,0,0,1.78,3.41,3.41,0,0,0,3.08,0A.94.94,0,0,0,127.07,155.4Z"
style="fill: #263238"></path>
<path
d="M140.93,142.06a3.41,3.41,0,0,0-3.08,0,.94.94,0,0,0,0,1.78,3.41,3.41,0,0,0,3.08,0A.94.94,0,0,0,140.93,142.06Z"
style="fill: #263238"></path>
<path
d="M134.77,145.62a3.35,3.35,0,0,0-3.08,0,.93.93,0,0,0,0,1.77,3.35,3.35,0,0,0,3.08,0A.93.93,0,0,0,134.77,145.62Z"
style="fill: currentcolor"></path>
<path
d="M128.61,149.17a3.41,3.41,0,0,0-3.08,0,.94.94,0,0,0,0,1.78,3.41,3.41,0,0,0,3.08,0A.94.94,0,0,0,128.61,149.17Z"
style="fill: #263238"></path>
<path
d="M125.49,161.55a3.41,3.41,0,0,0-3.08,0,.94.94,0,0,0,0,1.78,3.41,3.41,0,0,0,3.08,0A.94.94,0,0,0,125.49,161.55Z"
style="fill: currentcolor"></path>
<ellipse cx="119.33" cy="159.77" rx="2.18" ry="1.26" style="fill: #263238"></ellipse>
<path
d="M122.45,152.73a3.41,3.41,0,0,0-3.08,0,.94.94,0,0,0,0,1.78,3.41,3.41,0,0,0,3.08,0A.94.94,0,0,0,122.45,152.73Z"
style="fill: #263238"></path>
<path
d="M136.31,139.39a3.41,3.41,0,0,0-3.08,0,.94.94,0,0,0,0,1.78,3.41,3.41,0,0,0,3.08,0A.94.94,0,0,0,136.31,139.39Z"
style="fill: currentcolor"></path>
<path d="M130.15,143a3.41,3.41,0,0,0-3.08,0,.94.94,0,0,0,0,1.78,3.41,3.41,0,0,0,3.08,0A.94.94,0,0,0,130.15,143Z"
style="fill: #263238"></path>
<path d="M124,146.51a3.41,3.41,0,0,0-3.08,0,.94.94,0,0,0,0,1.78,3.41,3.41,0,0,0,3.08,0A.94.94,0,0,0,124,146.51Z"
style="fill: currentcolor"></path>
<path
d="M117.83,150.06a3.41,3.41,0,0,0-3.08,0c-.86.5-.86,1.29,0,1.78a3.41,3.41,0,0,0,3.08,0A.94.94,0,0,0,117.83,150.06Z"
style="fill: #263238"></path>
<path
d="M116.25,156.22a3.41,3.41,0,0,0-3.08,0,.94.94,0,0,0,0,1.78,3.41,3.41,0,0,0,3.08,0A.94.94,0,0,0,116.25,156.22Z"
style="fill: currentcolor"></path>
<path
d="M111.63,153.55a3.41,3.41,0,0,0-3.08,0,.94.94,0,0,0,0,1.78,3.41,3.41,0,0,0,3.08,0A.94.94,0,0,0,111.63,153.55Z"
style="fill: #263238"></path>
<path
d="M122.78,168.71v4.73a2.72,2.72,0,0,0,1.38-.3l34.35-19.84a2.86,2.86,0,0,0,1.31-2.27v-1.71a2.89,2.89,0,0,0-1.07-2.1c.48.41.4,1-.24,1.34l-34.35,19.83A2.63,2.63,0,0,1,122.78,168.71Z"
style="fill: #37474f"></path>
<path
d="M129.73,131.76l0,0a1.17,1.17,0,0,0-1.48-.31L98.33,148.67a.89.89,0,0,0-.27,1.32l0,0a1.18,1.18,0,0,0,1.48.31l29.88-17.26A.88.88,0,0,0,129.73,131.76Z"
style="fill: #263238"></path>
<path
d="M129.73,131.76l0,0a1.17,1.17,0,0,0-1.48-.31L106,144.24l1.24,1.67,22.21-12.83A.88.88,0,0,0,129.73,131.76Z"
style="fill: currentcolor"></path>
<path
d="M127.26,128.45l0,0a1.16,1.16,0,0,0-1.48-.31L95.86,145.36a.87.87,0,0,0-.27,1.31l0,0a1.16,1.16,0,0,0,1.48.31L127,129.77A.88.88,0,0,0,127.26,128.45Z"
style="fill: #263238"></path>
<path d="M127.26,128.45l0,0a1.16,1.16,0,0,0-1.48-.31l-7.43,4.29,1.24,1.66,7.42-4.28A.88.88,0,0,0,127.26,128.45Z"
style="fill: currentcolor"></path>
<path
d="M124.79,125.13l0,0a1.16,1.16,0,0,0-1.48-.31L93.39,142a.89.89,0,0,0-.27,1.32l0,0a1.16,1.16,0,0,0,1.48.3l29.88-17.25A.88.88,0,0,0,124.79,125.13Z"
style="fill: #263238"></path>
<path d="M124.79,125.13l0,0a1.16,1.16,0,0,0-1.48-.31l-15.57,9L109,135.4l15.56-9A.88.88,0,0,0,124.79,125.13Z"
style="fill: currentcolor"></path>
<path
d="M122.32,121.81l0,0a1.16,1.16,0,0,0-1.48-.3L90.92,138.72a.88.88,0,0,0-.27,1.32l0,0a1.16,1.16,0,0,0,1.48.31L122,123.13A.88.88,0,0,0,122.32,121.81Z"
style="fill: #263238"></path>
<path
d="M122.32,121.81l0,0a1.16,1.16,0,0,0-1.48-.3L93.68,137.13l1.24,1.66L122,123.13A.88.88,0,0,0,122.32,121.81Z"
style="fill: currentcolor"></path>
</g>
</g>
<g id="freepik--Gears--inject-87">
<g id="freepik--gears--inject-87">
<path
d="M132.4,412.71v7.54a.56.56,0,0,0,.51.55l3.93.24v5.54h0a.33.33,0,0,0,.19.28l4.15,2.39a1,1,0,0,0,.52.11h0a.83.83,0,0,0,.39-.08l4.2-1.94a1.58,1.58,0,0,1,1-.06,24.6,24.6,0,0,0,3.26.78.78.78,0,0,1,.61.59l.52,2.76a.69.69,0,0,0,.23.37h0a.62.62,0,0,0,.39.14h6.09a.55.55,0,0,0,.34-.13.19.19,0,0,0,.08-.07.73.73,0,0,0,.09-.08v-.06c0-.06.09-.1.1-.17l.53-2.76a.77.77,0,0,1,.6-.59,24.23,24.23,0,0,0,3.26-.78,1.58,1.58,0,0,1,1,.06l4.2,1.94a.71.71,0,0,0,.26,0v0H169a1,1,0,0,0,.4-.1h0l4.14-2.39a.41.41,0,0,0,.15-.14h0a.35.35,0,0,0,0-.11h0v-2.36h0v-3.18h0l3.86-.25h.07a.93.93,0,0,0,.1-.05.53.53,0,0,0,.26-.13.41.41,0,0,0,.08-.19c0-.06.08-.11.08-.18h0v-3.08h0v-3.95h0v-3.08a.56.56,0,0,0-.52-.55l-3.93-.25v-5.53h0a.34.34,0,0,0-.19-.3l-4.14-2.39a1.14,1.14,0,0,0-.92,0l-4.2,1.94a1.5,1.5,0,0,1-1,.06,24.21,24.21,0,0,0-3.26-.77.79.79,0,0,1-.6-.59L159,399a.65.65,0,0,0-.61-.51h-6.09a.66.66,0,0,0-.62.51l-.52,2.77a.8.8,0,0,1-.61.59,24.58,24.58,0,0,0-3.26.77,1.51,1.51,0,0,1-1-.06l-4.2-1.94a1.11,1.11,0,0,0-.91,0l-4.14,2.39a.35.35,0,0,0-.2.3h0v5.52l-3.93.25a.56.56,0,0,0-.51.55v2.46A.41.41,0,0,0,132.4,412.71Zm15.91,2a15.48,15.48,0,0,1,14,0q.44.25.81.51a8.14,8.14,0,0,1-.81.54,15.46,15.46,0,0,1-14,0,7.58,7.58,0,0,1-.81-.53A8.52,8.52,0,0,1,148.31,414.67Z"
style="fill: currentcolor"></path>
<path
d="M132.39,412.71l0,7.54a.55.55,0,0,0,.51.54l3.93.25v5.54a.33.33,0,0,0,.19.28l4.15,2.39a1,1,0,0,0,.52.11h0a.83.83,0,0,0,.39-.08l4.2-1.94a1.46,1.46,0,0,1,.4-.1h0a1.47,1.47,0,0,1,.56,0,24.6,24.6,0,0,0,3.26.78.64.64,0,0,1,.26.1v0a.79.79,0,0,1,.35.46l.52,2.76a.63.63,0,0,0,.23.36h0a.62.62,0,0,0,.39.14h6.2a.69.69,0,0,0,.4-.27v-.06c0-.06.09-.1.1-.17l.53-2.76a.7.7,0,0,1,.24-.4h0a.77.77,0,0,1,.36-.18,24.23,24.23,0,0,0,3.26-.78,1.69,1.69,0,0,1,.64,0v0a1.27,1.27,0,0,1,.32.07l4.2,1.94a.71.71,0,0,0,.26,0v0h0a1.07,1.07,0,0,0,.65-.1h0l4.14-2.39.09-.06.07-.09a.27.27,0,0,0,0-.12h0v-5.54l.72-.05,3.14-.2h.07a.55.55,0,0,0,.52-.54v-7a.55.55,0,0,1-.52.54l-5.52.35a1,1,0,0,0-.74.5,8.28,8.28,0,0,1-1.18,1.63.43.43,0,0,0,.07.67l3.28,2.36a.31.31,0,0,1,0,.56l-4.14,2.39a1.1,1.1,0,0,1-.92,0l-4.2-1.94a1.57,1.57,0,0,0-1-.06,23.87,23.87,0,0,1-3.26.78.79.79,0,0,0-.6.59l-.53,2.76a.65.65,0,0,1-.61.51h-6.09a.66.66,0,0,1-.62-.51l-.52-2.76a.81.81,0,0,0-.61-.59,24.6,24.6,0,0,1-3.26-.78,1.58,1.58,0,0,0-1,.06l-4.2,1.94a1.07,1.07,0,0,1-.91,0L137,419.83a.31.31,0,0,1,0-.56l3.28-2.36a.45.45,0,0,0,.06-.68,7.89,7.89,0,0,1-1.17-1.62,1,1,0,0,0-.75-.5l-5.52-.34a.56.56,0,0,1-.51-.55v-.62A.43.43,0,0,0,132.39,412.71Z"
style="opacity: 0.3"></path>
<path
d="M136.85,403.82v5.52l1.59-.1a1,1,0,0,0,.75-.5,8.17,8.17,0,0,1,1.17-1.62.45.45,0,0,0-.06-.68L137,404.08a.37.37,0,0,1-.17-.26Z"
style="opacity: 0.3"></path>
<path
d="M147.51,415.19l.35-.25,0,0,.41-.25a15.48,15.48,0,0,1,14,0l.37.22c.15.1.3.19.44.3,3-2.25,2.76-5.49-.81-7.55a15.4,15.4,0,0,0-14,0C144.74,409.7,144.47,413,147.51,415.19Z"
style="opacity: 0.4"></path>
<path
d="M170.26,407.12a8.23,8.23,0,0,1,1.18,1.62,1,1,0,0,0,.74.5l1.59.1v-5.53a.39.39,0,0,1-.17.27l-3.28,2.36A.44.44,0,0,0,170.26,407.12Z"
style="opacity: 0.3"></path>
<path
d="M168.52,401.09l-4.2,1.94a1.5,1.5,0,0,1-1,.06,24.21,24.21,0,0,0-3.26-.77.79.79,0,0,1-.6-.59L159,399a.65.65,0,0,0-.61-.51h-6.09a.66.66,0,0,0-.62.51l-.52,2.77a.8.8,0,0,1-.61.59,24.58,24.58,0,0,0-3.26.77,1.51,1.51,0,0,1-1-.06l-4.2-1.94a1.11,1.11,0,0,0-.91,0l-4.14,2.39a.31.31,0,0,0,0,.56l3.28,2.36a.45.45,0,0,1,.06.68,8.17,8.17,0,0,0-1.17,1.62,1,1,0,0,1-.75.5l-5.52.35a.56.56,0,0,0-.51.55v3.08a.56.56,0,0,0,.51.55l5.52.34a1,1,0,0,1,.75.5,8.22,8.22,0,0,0,1.17,1.63.44.44,0,0,1-.06.67L137,419.27a.31.31,0,0,0,0,.56l4.14,2.39a1.07,1.07,0,0,0,.91,0l4.2-1.94a1.58,1.58,0,0,1,1-.06,24.6,24.6,0,0,0,3.26.78.78.78,0,0,1,.61.59l.52,2.76a.66.66,0,0,0,.62.51h6.09a.65.65,0,0,0,.61-.51l.53-2.76a.77.77,0,0,1,.6-.59,24.23,24.23,0,0,0,3.26-.78,1.57,1.57,0,0,1,1,.06l4.2,1.94a1.1,1.1,0,0,0,.92,0l4.14-2.39a.31.31,0,0,0,0-.56l-3.28-2.36a.42.42,0,0,1-.06-.67,8.22,8.22,0,0,0,1.17-1.63,1,1,0,0,1,.74-.5l5.52-.34a.56.56,0,0,0,.52-.55v-3.08a.56.56,0,0,0-.52-.55l-5.52-.35a1,1,0,0,1-.74-.5,8.17,8.17,0,0,0-1.17-1.62.43.43,0,0,1,.06-.68l3.28-2.36a.31.31,0,0,0,0-.56l-4.14-2.39A1.14,1.14,0,0,0,168.52,401.09Zm-6.21,6.55c3.87,2.23,3.87,5.85,0,8.08a15.46,15.46,0,0,1-14,0c-3.87-2.23-3.87-5.85,0-8.08A15.46,15.46,0,0,1,162.31,407.64Z"
style="fill: currentcolor"></path>
<path
d="M173.77,419.55a.35.35,0,0,0-.16-.28L172,418.08v-3.91a.9.9,0,0,1,.22-.06l5.52-.35a.55.55,0,0,0,.52-.54v7a.55.55,0,0,1-.52.54h-.07l-3.14.2-.72.05S173.78,419.65,173.77,419.55Z"
style="fill: currentcolor"></path>
<path
d="M173.77,419.55a.35.35,0,0,0-.16-.28L172,418.08v-3.91a.9.9,0,0,1,.22-.06l5.52-.35a.55.55,0,0,0,.52-.54v7a.55.55,0,0,1-.52.54h-.07l-3.14.2-.72.05S173.78,419.65,173.77,419.55Z"
style="opacity: 0.2"></path>
<path
d="M164,420.23a1.26,1.26,0,0,1,.31.09l4.2,1.94a1.06,1.06,0,0,0,.54.07v7a.88.88,0,0,1-.28,0h0v0a.71.71,0,0,1-.26,0l-4.2-1.94a1.29,1.29,0,0,0-.31-.07Z"
style="fill: currentcolor"></path>
<path
d="M164,420.23a1.26,1.26,0,0,1,.31.09l4.2,1.94a1.06,1.06,0,0,0,.54.07v7a.88.88,0,0,1-.28,0h0v0a.71.71,0,0,1-.26,0l-4.2-1.94a1.29,1.29,0,0,0-.31-.07Z"
style="opacity: 0.2"></path>
<path
d="M158.89,424.59a.5.5,0,0,0,.08-.2l.53-2.76a.49.49,0,0,1,.08-.21v7a.54.54,0,0,0-.08.21l-.53,2.76c0,.06-.05.09-.08.14Z"
style="fill: currentcolor"></path>
<path
d="M158.89,424.59a.5.5,0,0,0,.08-.2l.53-2.76a.49.49,0,0,1,.08-.21v7a.54.54,0,0,0-.08.21l-.53,2.76c0,.06-.05.09-.08.14Z"
style="opacity: 0.2"></path>
<path
d="M151.05,421.42a.66.66,0,0,1,.08.21l.52,2.76a1.19,1.19,0,0,0,.08.2v7a1.19,1.19,0,0,1-.08-.2l-.52-2.76a.64.64,0,0,0-.08-.19Z"
style="opacity: 0.15"></path>
<path
d="M141.56,422.33a1.06,1.06,0,0,0,.54-.07l4.2-1.94a1.35,1.35,0,0,1,.32-.09v7a1,1,0,0,0-.32.08l-4.2,1.94a.83.83,0,0,1-.39.08h-.15Z"
style="opacity: 0.15"></path>
<path
d="M132.92,413.77l5.52.34a1,1,0,0,1,.23.06v3.91L137,419.27a.36.36,0,0,0-.17.28V421l-3.93-.25a.55.55,0,0,1-.51-.54l0-7.54a.43.43,0,0,1,0-.11v.62A.56.56,0,0,0,132.92,413.77Z"
style="opacity: 0.15"></path>
<path
d="M213.17,391.05h0l0-.1h0v-5h0a.4.4,0,0,0-.09-.24l-1.55-2.16a.71.71,0,0,0-.63-.3l-4.06.68a1.3,1.3,0,0,1-.77-.22,9.1,9.1,0,0,0-.8-.51V380h0c0-.13-.12-.25-.32-.3l-4.12-1a.79.79,0,0,0-.66.12l-2,2.07a.88.88,0,0,1-.64.2,21.77,21.77,0,0,0-2.68,0,1.1,1.1,0,0,1-.73-.32L192.36,379a.79.79,0,0,0-.68-.25l-4.28,1a.27.27,0,0,0-.22.28v3.21a9.23,9.23,0,0,0-1,.61,1.12,1.12,0,0,1-.7.12l-3.93-.66a.69.69,0,0,0-.62.18l-1.7,2.37a.15.15,0,0,0,0,.11v0c0,.36,0,6.13,0,6.16a.29.29,0,0,0,0,.1v5a.41.41,0,0,0,.09.26l1.55,2.16a.74.74,0,0,0,.63.3l4-.69a1.26,1.26,0,0,1,.78.23c.25.17.52.34.8.5v3.21c0,.14.12.26.32.31l4.11,1a.77.77,0,0,0,.67-.13l2-2.07a.88.88,0,0,1,.64-.2,24,24,0,0,0,2.68,0,1,1,0,0,1,.72.31l1.77,1.85a.82.82,0,0,0,.68.26l4.28-1a.29.29,0,0,0,.22-.23c0-.07,0-3.26,0-3.26a11.2,11.2,0,0,0,1-.6,1,1,0,0,1,.7-.13l3.93.67a.67.67,0,0,0,.62-.19l1.7-2.37a.17.17,0,0,0,0-.11c0-.11,0-6,0-6.17Zm-22.89.13c.19-.13.39-.26.61-.39a11.8,11.8,0,0,1,10.64,0c.21.13.41.25.59.38a5.89,5.89,0,0,1-.64.42,11.82,11.82,0,0,1-8.16.92,9.18,9.18,0,0,1-2.41-.92C190.69,391.46,190.47,391.32,190.28,391.18Z"
style="fill: currentcolor"></path>
<path
d="M213.17,391.05h0l0-.1h0v-5h0a.4.4,0,0,0-.09-.24l-1.55-2.16a.71.71,0,0,0-.63-.3l-4.06.68a1.3,1.3,0,0,1-.77-.22,9.1,9.1,0,0,0-.8-.51V380h0c0-.13-.12-.25-.32-.3l-4.12-1a.79.79,0,0,0-.66.12l-2,2.07a.88.88,0,0,1-.64.2,21.77,21.77,0,0,0-2.68,0,1.1,1.1,0,0,1-.73-.32L192.36,379a.79.79,0,0,0-.68-.25l-4.28,1a.27.27,0,0,0-.22.28v3.21a9.23,9.23,0,0,0-1,.61,1.12,1.12,0,0,1-.7.12l-3.93-.66a.69.69,0,0,0-.62.18l-1.7,2.37a.15.15,0,0,0,0,.11v0c0,.36,0,6.13,0,6.16a.29.29,0,0,0,0,.1v5a.41.41,0,0,0,.09.26l1.55,2.16a.74.74,0,0,0,.63.3l4-.69a1.26,1.26,0,0,1,.78.23c.25.17.52.34.8.5v3.21c0,.14.12.26.32.31l4.11,1a.77.77,0,0,0,.67-.13l2-2.07a.88.88,0,0,1,.64-.2,24,24,0,0,0,2.68,0,1,1,0,0,1,.72.31l1.77,1.85a.82.82,0,0,0,.68.26l4.28-1a.29.29,0,0,0,.22-.23c0-.07,0-3.26,0-3.26a11.2,11.2,0,0,0,1-.6,1,1,0,0,1,.7-.13l3.93.67a.67.67,0,0,0,.62-.19l1.7-2.37a.17.17,0,0,0,0-.11c0-.11,0-6,0-6.17Zm-22.89.13c.19-.13.39-.26.61-.39a11.8,11.8,0,0,1,10.64,0c.21.13.41.25.59.38a5.89,5.89,0,0,1-.64.42,11.82,11.82,0,0,1-8.16.92,9.18,9.18,0,0,1-2.41-.92C190.69,391.46,190.47,391.32,190.28,391.18Z"
style="opacity: 0.3"></path>
<path d="M179.23,386h0v0s0,0,0,0A.09.09,0,0,0,179.23,386Z" style="fill: currentcolor"></path>
<path d="M188.12,382.74c-.33.15-.64.31-.94.48V380a.28.28,0,0,0,0,.17l1,2A.38.38,0,0,1,188.12,382.74Z"
style="opacity: 0.3"></path>
<path
d="M183.41,387.81a4,4,0,0,0,0,1.34.42.42,0,0,1-.27.47l-3.7,1.17a.26.26,0,0,0-.18.24c0,.07,0,1.2,0,1.2l0-.09c0-2.1,0-5.61,0-5.92V386c0,.12.12.23.3.28l3.49,1.11A.49.49,0,0,1,183.41,387.81Z"
style="opacity: 0.15"></path>
<path d="M185.72,393v6.18h-.15l-4,.68a.47.47,0,0,1-.2,0v-6.18a.5.5,0,0,0,.21,0l4.05-.68Z" style="opacity: 0.15">
</path>
<path
d="M187.15,400c-.28-.16-.55-.33-.8-.5a1.51,1.51,0,0,0-.63-.23V393a1.42,1.42,0,0,1,.64.23,12.15,12.15,0,0,0,1.64.94c.24.12.37.33.29.49l-1.11,2.2a.3.3,0,0,0,0,.1C187.16,397.12,187.15,400,187.15,400Z"
style="opacity: 0.25"></path>
<path
d="M194.47,395.94v6.18a.55.55,0,0,0-.25.14l-2,2.07a.54.54,0,0,1-.36.14v-6.18a.55.55,0,0,0,.37-.14l2-2.07A.76.76,0,0,1,194.47,395.94Z"
style="opacity: 0.15"></path>
<path
d="M197.8,395.92v6.18a.61.61,0,0,0-.26,0,24,24,0,0,1-2.68,0,1,1,0,0,0-.39.06v-6.18a1.08,1.08,0,0,1,.4-.06,21.78,21.78,0,0,0,2.68,0A.59.59,0,0,1,197.8,395.92Z"
style="opacity: 0.25"></path>
<path
d="M200.42,398.27v6.18a.86.86,0,0,1-.39-.23l-1.76-1.85a1.06,1.06,0,0,0-.47-.27v-6.18a1.16,1.16,0,0,1,.47.27L200,398A.83.83,0,0,0,200.42,398.27Z"
style="opacity: 0.15"></path>
<path
d="M205.21,397.05V400h0v3.26a.29.29,0,0,1-.22.23l-4.28,1a.49.49,0,0,1-.29,0v-6.18a.54.54,0,0,0,.3,0l4.28-1A.25.25,0,0,0,205.21,397.05Z"
style="fill: currentcolor"></path>
<path
d="M205.21,397.05V400h0v3.26a.29.29,0,0,1-.22.23l-4.28,1a.49.49,0,0,1-.29,0v-6.18a.54.54,0,0,0,.3,0l4.28-1A.25.25,0,0,0,205.21,397.05Z"
style="opacity: 0.2"></path>
<path
d="M206.59,393.05v6.18a.91.91,0,0,0-.42.13,11.2,11.2,0,0,1-1,.6s0-2.83,0-3a.41.41,0,0,0-.05-.17l-1-2a.36.36,0,0,1,.12-.51,11.52,11.52,0,0,0,1.9-1.09A.87.87,0,0,1,206.59,393.05Z"
style="opacity: 0.15"></path>
<path
d="M213.17,391.06c0,.21,0,6.06,0,6.17a.17.17,0,0,1,0,.11l-1.7,2.37a.52.52,0,0,1-.29.17v-6.17a.66.66,0,0,0,.3-.17l1.7-2.38A.21.21,0,0,0,213.17,391.06Z"
style="fill: currentcolor"></path>
<path
d="M213.17,391.06c0,.21,0,6.06,0,6.17a.17.17,0,0,1,0,.11l-1.7,2.37a.52.52,0,0,1-.29.17v-6.17a.66.66,0,0,0,.3-.17l1.7-2.38A.21.21,0,0,0,213.17,391.06Z"
style="fill: currentcolor"></path>
<path
d="M213.17,391.06c0,.21,0,6.06,0,6.17a.17.17,0,0,1,0,.11l-1.7,2.37a.52.52,0,0,1-.29.17v-6.17a.66.66,0,0,0,.3-.17l1.7-2.38A.21.21,0,0,0,213.17,391.06Z"
style="opacity: 0.2"></path>
<path
d="M187.18,380v0a.37.37,0,0,0,0,.16l1,2a.37.37,0,0,1-.13.52c-.33.15-.64.31-.94.48a9.23,9.23,0,0,0-1,.61,1.12,1.12,0,0,1-.7.12l-3.93-.66a.69.69,0,0,0-.62.18l-1.7,2.37a.15.15,0,0,0,0,.11v0c0,.11.12.21.3.27l3.49,1.11a.49.49,0,0,1,.39.46,4,4,0,0,0,0,1.34.42.42,0,0,1-.27.47l-3.7,1.17a.25.25,0,0,0-.17.24.49.49,0,0,0,.08.24l1.55,2.16a.76.76,0,0,0,.64.3l4.05-.68a1.2,1.2,0,0,1,.78.22,12.15,12.15,0,0,0,1.64.94c.24.12.37.33.29.49l-1.11,2.2c-.08.16.06.33.3.4l4.11,1a.77.77,0,0,0,.67-.13l2-2.07a1,1,0,0,1,.64-.2,24,24,0,0,0,2.68,0,1,1,0,0,1,.72.31L200,398a.82.82,0,0,0,.68.26l4.28-1a.29.29,0,0,0,.17-.45l-1-2a.35.35,0,0,1,.13-.51,11.84,11.84,0,0,0,1.89-1.09,1,1,0,0,1,.71-.12l3.92.66a.69.69,0,0,0,.63-.19l1.7-2.37a.14.14,0,0,0,0-.1h0l0-.1h0a.47.47,0,0,0-.27-.19l-3.5-1.1c-.24-.08-.41-.29-.38-.47a4.56,4.56,0,0,0,0-1.33.43.43,0,0,1,.27-.48l3.7-1.17a.23.23,0,0,0,.17-.22h0a.4.4,0,0,0-.09-.24l-1.55-2.16a.71.71,0,0,0-.63-.3l-4.06.68a1.3,1.3,0,0,1-.77-.22,9.1,9.1,0,0,0-.8-.51c-.27-.15-.55-.3-.84-.44s-.38-.33-.3-.48l1.12-2.21a.29.29,0,0,0,0-.09c0-.13-.12-.25-.32-.3l-4.12-1a.79.79,0,0,0-.66.12l-2,2.07a.88.88,0,0,1-.64.2,21.77,21.77,0,0,0-2.68,0,1.1,1.1,0,0,1-.73-.32L192.36,379a.79.79,0,0,0-.68-.25l-4.28,1A.27.27,0,0,0,187.18,380Zm15.55,6.35a1.14,1.14,0,0,1,.11.11l.07.07.15.19c.06.07.11.15.16.22l.09.15,0,.06a2.65,2.65,0,0,1-.21,3,4.45,4.45,0,0,1-1,1,5.89,5.89,0,0,1-.64.42,11.82,11.82,0,0,1-8.16.92,9.18,9.18,0,0,1-2.41-.92c-.22-.13-.44-.27-.63-.41a4.26,4.26,0,0,1-1.28-1.43s0,0,0,0a.2.2,0,0,1,0-.08.36.36,0,0,1,0-.09.36.36,0,0,1,0-.09,2.66,2.66,0,0,1,.38-2.63c1.59-2.21,6-3.27,9.82-2.35A7.61,7.61,0,0,1,202.73,386.36Z"
style="fill: currentcolor"></path>
</g>
</g>
<g id="freepik--Wrench--inject-87">
<g id="freepik--wrench--inject-87">
<path
d="M236.85,372.18c-.85.49-2.44.47-2.94,1.05v2.08l9.68-1.41,3.66,2.14L245.86,379l-9.78-.65v2.08a6.19,6.19,0,0,0,.66.42,16.48,16.48,0,0,0,14.92.07c2.09-1.19,3.14-2.76,3.14-4.33h0v-2.08l-.58.09-.06-.11,36.63-21.15a16.63,16.63,0,0,0,11-1.38,6.13,6.13,0,0,0,2.94-3.13V346.7l-9.68,3.49-3.66-2.14,1.39-2.91,9.78-1.43v-2.09s-11.43-.76-15.58,1.6a6.89,6.89,0,0,0-2.59,2.39l-.55-.2v2.07h0a4,4,0,0,0,.64,2.17L247.87,370.8A16.6,16.6,0,0,0,236.85,372.18Z"
style="fill: #37474f"></path>
<polygon points="290.79 353.29 290.8 351.2 254.16 372.35 254.16 374.44 290.79 353.29" style="fill: #37474f">
</polygon>
<path
d="M284.51,347.57l-36.63,21.15a16.57,16.57,0,0,0-11,1.38,6.1,6.1,0,0,0-2.94,3.13l9.68-1.42,3.66,2.15-1.39,2.91-9.78,1.43c.21.14.42.28.66.42a16.48,16.48,0,0,0,14.92.06c3-1.73,3.87-4.26,2.5-6.43l36.63-21.15a16.57,16.57,0,0,0,11-1.38,6.12,6.12,0,0,0,2.94-3.12l-9.68,1.41L291.42,346l1.39-2.9,9.78-1.44-.66-.42a16.51,16.51,0,0,0-14.92-.06C284,342.87,283.14,345.4,284.51,347.57Z"
style="fill: #455a64"></path>
<polygon
points="292.2 346.42 291.42 345.96 292.81 343.06 302.59 341.62 302.59 343.71 292.81 345.14 292.2 346.42"
style="fill: #263238"></polygon>
<polygon
points="246.47 375.59 247.25 373.96 243.59 371.81 233.91 373.23 233.91 375.31 243.59 373.9 246.47 375.59"
style="fill: #263238"></polygon>
</g>
</g>
<g id="freepik--Screwdriver--inject-87">
<g id="freepik--screwdriver--inject-87">
<path
d="M259.26,403l7.66,13.26,25.83-14.91c1.06-.53,1.73-1.77,1.73-3.58a12,12,0,0,0-5.42-9.38,3.82,3.82,0,0,0-3.84-.38h0Z"
style="fill: currentcolor"></path>
<path
d="M257.72,405.71h0c-.11,2-3,2.45-3,2.45l5.41,9.38s1.81-2.22,3.62-1.34h0c2.67,1.16,4.74-.28,4.74-3.46a12,12,0,0,0-5.42-9.39C260.33,401.75,258.06,402.82,257.72,405.71Z"
style="fill: currentcolor"></path>
<path
d="M257.72,405.71h0c-.11,2-3,2.45-3,2.45l5.41,9.38s1.81-2.22,3.62-1.34h0c2.67,1.16,4.74-.28,4.74-3.46a12,12,0,0,0-5.42-9.39C260.33,401.75,258.06,402.82,257.72,405.71Z"
style="opacity: 0.05"></path>
<path d="M256,407.76a5.79,5.79,0,0,1-1.29.4l5.41,9.38a6,6,0,0,1,1-.91A12.1,12.1,0,0,0,256,407.76Z"
style="opacity: 0.05"></path>
<path
d="M249.11,408.82l.45.79a5.69,5.69,0,0,0-.23,1.68,12,12,0,0,0,5.42,9.38,5.36,5.36,0,0,0,1.57.64l.45.78,1.81-1h0a3.81,3.81,0,0,0,1.58-3.51,12,12,0,0,0-5.41-9.38,3.81,3.81,0,0,0-3.83-.38h0Z"
style="fill: currentcolor"></path>
<path
d="M258.36,418.59a12,12,0,0,0-5.42-9.39c-3-1.73-5.42-.32-5.42,3.13a12,12,0,0,0,5.42,9.38C255.93,423.44,258.36,422,258.36,418.59Z"
style="fill: currentcolor"></path>
<path
d="M258.36,418.59a12,12,0,0,0-5.42-9.39c-3-1.73-5.42-.32-5.42,3.13a12,12,0,0,0,5.42,9.38C255.93,423.44,258.36,422,258.36,418.59Z"
style="opacity: 0.15"></path>
<path d="M250.83,420a10.68,10.68,0,0,0,1.34,1.2l1.27-3.61-1.53-1.13Z" style="opacity: 0.15"></path>
<path
d="M290.07,394h0a1.49,1.49,0,0,1-.55,2l-18.45,10.65a1.49,1.49,0,0,1-2-.55h0a1.49,1.49,0,0,1,.55-2L288,393.47A1.49,1.49,0,0,1,290.07,394Z"
style="opacity: 0.2"></path>
<path
d="M286.74,390.05h0a.87.87,0,0,1-.07,1.53l-18.79,10.85a2.06,2.06,0,0,1-2.18-.23h0a.88.88,0,0,1,.07-1.54l18.8-10.85A2,2,0,0,1,286.74,390.05Z"
style="opacity: 0.2"></path>
<path
d="M291.84,398.89h0a.87.87,0,0,0-1.36-.71L271.68,409a2.06,2.06,0,0,0-.88,2h0a.87.87,0,0,0,1.36.71L291,400.89A2.05,2.05,0,0,0,291.84,398.89Z"
style="opacity: 0.2"></path>
<path
d="M205.43,440.47v3.61l9-2.93s1.81-3.32,3.61-4.37L252.39,417l1.05-3-1.05-.61-34.32,19.81a3.61,3.61,0,0,1-3.61-.19Z"
style="fill: #455a64"></path>
<path d="M206.49,441.08v3.61l9-2.93s1.81-3.32,3.61-4.36l34.31-19.81V414l-34.31,19.81a3.59,3.59,0,0,1-3.61-.19Z"
style="fill: #37474f"></path>
<polygon points="206.49 444.69 205.43 444.08 205.43 440.47 206.49 441.08 206.49 444.69" style="fill: #263238">
</polygon>
<polygon points="205.43 440.47 206.49 441.08 215.52 433.59 214.46 432.98 205.43 440.47" style="fill: #455a64">
</polygon>
</g>
</g>
<g id="freepik--Character--inject-87">
<g id="freepik--character--inject-87">
<path
d="M357.56,210c5.84-6,16.41-19.63,16.41-19.63l6-20.71c.15.06-3.05.07-4,0-6.46.43-8.36,1-12.38,5.38-3.19,3.49-15.36,20.12-19.6,25.71l-11.23-14.31c-2.69-4.07-2.25-8.62-3.65-11.94s-3.65-4.79-5.46-7.8-2.24-5-3.72-3.43.23,5.68.45,6.62,2.48,3.75-1.3,2.29-9.62-8.37-11.13-9.79-2.3.78-2,2.51-1.28,5.63-.69,8.49c.62,3,1.07,4.43,4,7.38,2.72,2.75,9.4,6.11,12,9.72s8.18,14.81,11.59,21.56c4.32,8.58,8,11.41,12.88,8.52S355.39,212.23,357.56,210Z"
style="fill: #ffa8a7"></path>
<path
d="M378.05,169.46a21.46,21.46,0,0,0-9.74,1.33c-3.51,1.58-5.89,5-9.31,9.56S347,196,347,196a25.79,25.79,0,0,1,10.42,14.65l20.9-23.1Z"
style="fill: #e0e0e0"></path>
<path d="M344,200.76A13.6,13.6,0,0,1,348,208.3s1.26-4.15-3.11-8.82Z" style="fill: #f28f8f"></path>
<path
d="M398.16,169.39c2.27.55,8.37,1.33,12.39,2.48,3,.85,6,4.53,6.58,7.25,2,8.71.22,14.19-.52,21.82s-.79,45.7-.79,45.7c-4.23,8.26-36.28,9.94-51.79-1.39,0,0,1.9-50.68,1.9-58.57s4.38-17.36,16.48-18.07Z"
style="fill: #f5f5f5"></path>
<path d="M384.46,144.43a1.68,1.68,0,1,0,1.67-1.74A1.71,1.71,0,0,0,384.46,144.43Z" style="fill: #263238"></path>
<path d="M386.13,138.77l3.46,1.91a2.07,2.07,0,0,0-.8-2.75A1.93,1.93,0,0,0,386.13,138.77Z" style="fill: #263238">
</path>
<path d="M384.88,154.65,381,156.1a2,2,0,0,0,2.63,1.29A2.17,2.17,0,0,0,384.88,154.65Z" style="fill: #f28f8f">
</path>
<path d="M371.1,140.16l3.15-2.43a1.91,1.91,0,0,0-2.74-.42A2.09,2.09,0,0,0,371.1,140.16Z" style="fill: #263238">
</path>
<path d="M371.81,144.43a1.62,1.62,0,1,0,1.62-1.68A1.65,1.65,0,0,0,371.81,144.43Z" style="fill: #263238"></path>
<polygon points="380.58 141.64 380.03 151.82 374.71 150.01 380.58 141.64" style="fill: #f28f8f"></polygon>
<path
d="M384.48,142.09l23.81-1.76c4.61,3.49,13.17,10.83,13.16,12.86h0v1.41h0a.48.48,0,0,1-.05.18c-.84,1.6-3.88,2.59-8.61,2.67-5.61.09-14.32-.42-16.61-2.39-3.44-3-11.7-11.63-11.7-11.63l1.2-.09Z"
style="fill: currentcolor"></path>
<path
d="M384.48,142.09l23.81-1.76c4.61,3.49,13.17,10.83,13.16,12.86h0v1.41h0a.48.48,0,0,1-.05.18c-.84,1.6-3.88,2.59-8.61,2.67-5.61.09-14.32-.42-16.61-2.39-3.44-3-11.7-11.63-11.7-11.63l1.2-.09Z"
style="opacity: 0.2"></path>
<path
d="M408.29,141.67c4.81,3.65,14,11.5,13.11,13.11s-3.88,2.59-8.61,2.67c-5.61.09-14.32-.42-16.61-2.39-3.44-3-11.7-11.63-11.7-11.63Z"
style="fill: currentcolor"></path>
<path
d="M408.29,141.67c4.81,3.65,14,11.5,13.11,13.11s-3.88,2.59-8.61,2.67c-5.61.09-14.32-.42-16.61-2.39-3.44-3-11.7-11.63-11.7-11.63Z"
style="opacity: 0.4"></path>
<path d="M408.29,141.67c.08.69-2.35,2.13-2.35,2.13l.68-4.18Z" style="fill: currentcolor"></path>
<path d="M408.29,141.67c.08.69-2.35,2.13-2.35,2.13l.68-4.18Z" style="opacity: 0.3"></path>
<path
d="M402,127.76s3.72.52,5.09,3.32c1.18,2.44.76,8.33-.83,14.75a59.07,59.07,0,0,1-4,12,4.9,4.9,0,0,1-2.84,2.28l.19-7.62.28-5.3s-3.41-4.65-3.78-8.46c-.49-4.91.55-6.91.55-6.91Z"
style="fill: #263238"></path>
<path
d="M396,135.13a14.22,14.22,0,0,1-14.26,14.17c-7.85,0-13.74-6.47-13.71-14.32s5.95-14.14,13.8-14.11A14.22,14.22,0,0,1,396,135.13Z"
style="fill: #263238"></path>
<path
d="M399.71,146.39c1.28,1.11,2.32-1.76,3.4-2.88s4.59-2.64,6.32,1.05-1.53,9-4.23,10.07a3.84,3.84,0,0,1-4.58-1.4V170.1c-4,7.29-11.18,7.07-15,6.65s-4.65-4.37-1.86-7.57l0-5.22a30.05,30.05,0,0,1-6.41.31c-3.49-.55-5.32-3.19-6.36-7-1.69-6.08-2.36-16.3,0-28.11,3.91-3,17.48-2.53,25.69,2.68C396.09,142.34,398.44,145.28,399.71,146.39Z"
style="fill: #ffa8a7"></path>
<path
d="M372.46,124a16.75,16.75,0,0,1,5.77-4,14.62,14.62,0,0,1,5.55-1.18c2.48,0,5-.37,7.43-.29,4.3.14,9.5,1.89,11.44,6.07.89,1.92,1,3.94-.72,5.26a12.14,12.14,0,0,1-5.24,2c-3.19.55-6.35,1.25-9.56,1.68a28.57,28.57,0,0,1-10.35-.15,13.61,13.61,0,0,1-4.5-1.92,12,12,0,0,1-1.94-1.62c-.23-.23-.84-.71-.91-1s.34-1,.51-1.26A15.87,15.87,0,0,1,372.46,124Z"
style="fill: #263238"></path>
<path
d="M383.79,164s7.81-1.54,10.54-3a9,9,0,0,0,3.78-3.72,12.37,12.37,0,0,1-2.15,4.39c-2,2.54-12.18,4.39-12.18,4.39Z"
style="fill: #f28f8f"></path>
<path d="M385.9,143.76a1.65,1.65,0,1,0,1.65-1.71A1.68,1.68,0,0,0,385.9,143.76Z" style="fill: #263238"></path>
<path d="M382.14,156.42a1.65,1.65,0,1,0,1.65-1.71A1.67,1.67,0,0,0,382.14,156.42Z" style="fill: #f28f8f"></path>
<path d="M388.15,137.39l3.17,2.48A2.12,2.12,0,0,0,391,137,2,2,0,0,0,388.15,137.39Z" style="fill: #263238">
</path>
<path d="M371.31,139.92l3.06-2.66a2,2,0,0,0-2.82-.27A2.14,2.14,0,0,0,371.31,139.92Z" style="fill: #263238">
</path>
<path d="M372.35,143.27a1.65,1.65,0,1,0,1.65-1.71A1.68,1.68,0,0,0,372.35,143.27Z" style="fill: #263238"></path>
<polygon points="381.39 140.45 380.77 152.13 375.23 150.67 381.39 140.45" style="fill: #f28f8f"></polygon>
<path
d="M409.31,135.88a20.63,20.63,0,0,1-1,5.91,7.23,7.23,0,0,0-1.46-1.65A35,35,0,0,0,396.13,134h0c-9-3.48-19.5-4-27.89-1.06a18.87,18.87,0,0,1,1.12-5c3.06-8,9.25-12.15,19.13-11.12C400.06,118,409.62,124.42,409.31,135.88Z"
style="fill: currentcolor"></path>
<path
d="M388.1,128.83c-2.69-.91-9.55-1.44-11.55-.81a12.35,12.35,0,0,1-2.41-2.66c-.94-1.49-.62-3.36.26-3.75s.94.78,4.35,2.47a5.68,5.68,0,0,1-.28-3.45c.56-1.38,1.73,1.1,4.27,2.71S387.78,125.75,388.1,128.83Z"
style="fill: #263238"></path>
<path d="M423.2,162.72c2.24-1.84,15.82,14.25,10.14,18.88s-12.62-7-11.68-12.74S423.2,162.72,423.2,162.72Z"
style="fill: #37474f"></path>
<path
d="M434.12,153.68c-3.4-4.17-12.43-14.19-14.43-16s-3.2-1.57-4.44-2a10.28,10.28,0,0,1-3.71-2.32,22.53,22.53,0,0,1-1.79-2.1A32.4,32.4,0,0,0,403,125c-2.68-1.85-5.62-3.22-8.36-5-1.64-1.05-3.42-2.82-1.56-4.63a4.48,4.48,0,0,1,2-1.07c4.65-1.22,8.81.22,13.45,1.2a39.46,39.46,0,0,1,5.93,1.73,10.13,10.13,0,0,1,2.65,1.38,36.9,36.9,0,0,1,4.35,4.4c3.19,3.91,5.89,5.12,9,7.83,3.67,3.17,20.12,14.8,23.59,18.26,2.88,2.87,2,5.24,1.62,6.06-2.05,4.71-4.49,6.46-7.37,9.44-.95,1-1.91,2-2.87,3-3.74,3.79-7.5,7.36-11.4,11-4.16,3.88-5.86,5.74-9.57,9.48a29.41,29.41,0,0,0-5.6,8.27c-6.71,1.53-11.29-12.67-8.89-20.9a10.64,10.64,0,0,1,3.9-5.13C420.71,164.86,434.12,153.68,434.12,153.68Z"
style="fill: #ffa8a7"></path>
<path d="M434.12,153.68a17.86,17.86,0,0,0,8.51,5.34s-4.27,1.28-10.4-3.77Z" style="fill: #f28f8f"></path>
<path
d="M410.55,171.87c1.53-1.2,5.25-3.76,12.65-9.15,0,0-1,2.56,1.21,8.7s6.42,9.88,8.93,10.18c0,0-4.11,3.66-7.85,7.74s-6.85,7-8.88,11.6c0,0-5.77-1.12-7.62-10.66C407.68,183.58,407.75,175.63,410.55,171.87Z"
style="fill: #e0e0e0"></path>
<path
d="M397.62,415.78c-.36.38-.13,3.14.32,3.77s3,2.73,7.64,2.81c4.45.08,8.38-.73,10.9-2.53s3.67-3.68,3.78-6.22-.3-5,.8-7c1-1.85,2.4-3.68,2.74-4.68a12.73,12.73,0,0,0,0-5.43Z"
style="fill: #263238"></path>
<path
d="M408.42,394.36a11.7,11.7,0,0,1-.39,2.84,25.51,25.51,0,0,1-2.42,5.7,23.18,23.18,0,0,1-1.7,2.71c-1.26,1.67-2.86,3.07-4.19,4.67a9.08,9.08,0,0,0-2.45,5.59c0,3.49,3.84,4.47,6.77,4.83a21.34,21.34,0,0,0,9.42-1,8.69,8.69,0,0,0,6-7.27c.11-1,0-2,.06-2.94a13.73,13.73,0,0,1,2.37-6.23,18.23,18.23,0,0,0,1.9-3.42c.79-2.2-.06-4.59-.76-6.7-.6-1.83-1.08-4-1.72-3.82,0,.38,0,1.19,0,1.19-.2.42-.66.72-.77,1.19a8.22,8.22,0,0,1-.45,1.46,3.77,3.77,0,0,1-1.45,1.79c-.12-1.31-.23-2.62-.35-3.93a1.79,1.79,0,0,0-.36-1.14,1.81,1.81,0,0,0-1.14-.42,24.67,24.67,0,0,0-7.47-.22,1.35,1.35,0,0,0-1,.49,1.44,1.44,0,0,0-.11.9A36,36,0,0,1,408.42,394.36Z"
style="fill: currentcolor"></path>
<path
d="M408.42,394.36a11.7,11.7,0,0,1-.39,2.84,25.51,25.51,0,0,1-2.42,5.7,23.18,23.18,0,0,1-1.7,2.71c-1.26,1.67-2.86,3.07-4.19,4.67a9.08,9.08,0,0,0-2.45,5.59c0,3.49,3.84,4.47,6.77,4.83a21.34,21.34,0,0,0,9.42-1,8.69,8.69,0,0,0,6-7.27c.11-1,0-2,.06-2.94a13.73,13.73,0,0,1,2.37-6.23,18.23,18.23,0,0,0,1.9-3.42c.79-2.2-.06-4.59-.76-6.7-.6-1.83-1.08-4-1.72-3.82,0,.38,0,1.19,0,1.19-.2.42-.66.72-.77,1.19a8.22,8.22,0,0,1-.45,1.46,3.77,3.77,0,0,1-1.45,1.79c-.12-1.31-.23-2.62-.35-3.93a1.79,1.79,0,0,0-.36-1.14,1.81,1.81,0,0,0-1.14-.42,24.67,24.67,0,0,0-7.47-.22,1.35,1.35,0,0,0-1,.49,1.44,1.44,0,0,0-.11.9A36,36,0,0,1,408.42,394.36Z"
style="opacity: 0.2"></path>
<path
d="M405.18,403.66c1.25-1,4.15-1.21,5.74-1.13a9.74,9.74,0,0,1,4.6,1.34,1,1,0,0,0,1.32-.18h0a1,1,0,0,0-.18-1.47,9.77,9.77,0,0,0-5.17-1.61c-3.92-.06-5,.67-5,.67S404.74,402.52,405.18,403.66Z"
style="fill: #455a64"></path>
<path
d="M402.4,407.38c1.57-1.05,4.77-1.08,6.37-1a9.15,9.15,0,0,1,4.48,1.43,1,1,0,0,0,1.32-.17h0a1,1,0,0,0-.18-1.48,10.2,10.2,0,0,0-5.29-1.75c-3.92-.06-4.9.79-4.9.79A3.24,3.24,0,0,0,402.4,407.38Z"
style="fill: #455a64"></path>
<path
d="M412.84,396.79a9.65,9.65,0,0,0-4.88.68c-.67.42-1.07,1.53-.61,1.79a9,9,0,0,1,4.32-.84,13,13,0,0,1,4.28.94,11.77,11.77,0,0,1,1.11.49.93.93,0,0,0,1.26-.47h0a.87.87,0,0,0-.4-1.1A12.54,12.54,0,0,0,412.84,396.79Z"
style="fill: #455a64"></path>
<path
d="M343.7,401.82a4.22,4.22,0,0,0,.34,3.08c.48.88,5.36,3.3,11.71,2.52a26.56,26.56,0,0,0,12.95-5.32c2.35-1.74,4.86-2.18,8-2.53s5.52-1.45,6.13-3-.32-4-.32-4Z"
style="fill: #263238"></path>
<path
d="M368.47,381.6a13.6,13.6,0,0,1-1.69-.48,1.42,1.42,0,0,0-.95-.06,1.4,1.4,0,0,0-.62,1.1,16.25,16.25,0,0,1-.55,2.81,6.92,6.92,0,0,1-1.69,2,28.79,28.79,0,0,1-4.93,3.57c-2,1.23-4,2.21-6.12,3.3s-5,1.86-6.68,3.11c-2.41,1.82-2.51,6.08.43,7.6,2.54,1.32,9.1,2.53,15.79.24,3.65-1.24,7.54-5.42,12.38-6.06,3.07-.41,7.17-.89,9-3.34.67-1.08.08-4.09-.47-7.66-.49-3.2-.94-8.2-2-7.87,0,0-.38,1.18-.45,1.31a9.65,9.65,0,0,1-.85,1.14,11.13,11.13,0,0,1-.87.82,12.79,12.79,0,0,1-1.09,1.12,3.11,3.11,0,0,1-1.78.74,1.71,1.71,0,0,1-.89-.19c-.53-.3-.6-1-1-1.42a5.07,5.07,0,0,0-1.72-1.12,9.48,9.48,0,0,0-2.79-.56Z"
style="fill: currentcolor"></path>
<path
d="M368.47,381.6a13.6,13.6,0,0,1-1.69-.48,1.42,1.42,0,0,0-.95-.06,1.4,1.4,0,0,0-.62,1.1,16.25,16.25,0,0,1-.55,2.81,6.92,6.92,0,0,1-1.69,2,28.79,28.79,0,0,1-4.93,3.57c-2,1.23-4,2.21-6.12,3.3s-5,1.86-6.68,3.11c-2.41,1.82-2.51,6.08.43,7.6,2.54,1.32,9.1,2.53,15.79.24,3.65-1.24,7.54-5.42,12.38-6.06,3.07-.41,7.17-.89,9-3.34.67-1.08.08-4.09-.47-7.66-.49-3.2-.94-8.2-2-7.87,0,0-.38,1.18-.45,1.31a9.65,9.65,0,0,1-.85,1.14,11.13,11.13,0,0,1-.87.82,12.79,12.79,0,0,1-1.09,1.12,3.11,3.11,0,0,1-1.78.74,1.71,1.71,0,0,1-.89-.19c-.53-.3-.6-1-1-1.42a5.07,5.07,0,0,0-1.72-1.12,9.48,9.48,0,0,0-2.79-.56Z"
style="opacity: 0.2"></path>
<path
d="M360.83,388.68A2.87,2.87,0,0,1,363,387c1.39-.34,3.93.56,5.54,1.75a1.15,1.15,0,0,1-.06,1.91h0a1.14,1.14,0,0,1-1.32-.07A8.79,8.79,0,0,0,360.83,388.68Z"
style="fill: #455a64"></path>
<path
d="M356.61,391.35a3.3,3.3,0,0,1,2.63-1.54s3.67-.09,6.06,1.9a1.13,1.13,0,0,1-.06,1.85h0a1.08,1.08,0,0,1-1.27-.08A8.9,8.9,0,0,0,356.61,391.35Z"
style="fill: #455a64"></path>
<path
d="M351.92,393.81a3.69,3.69,0,0,1,2.74-1.41,9.86,9.86,0,0,1,5.81,1.94,1.13,1.13,0,0,1-.06,1.85h0a1.12,1.12,0,0,1-1.27-.08A8.42,8.42,0,0,0,351.92,393.81Z"
style="fill: #455a64"></path>
<path
d="M362.17,243.55c-.17,14.61.77,63.89,1.09,71.24.28,6.44,1.4,69.82,1.4,69.82,7.38,2.29,17.48-.08,17.48-.08S387.28,345,387.61,338a119.81,119.81,0,0,0-1-19.28l3.78-40.33s4.13,30.2,6.12,43.42c2.28,15.15,10.81,73.17,10.81,73.17,6.79,2.64,16.3-1.11,16.3-1.11s-.49-45.14-1.17-60.48c-.48-10.59-3.43-15.74-3.75-18.68,0,0-1.47-55-1.63-68.94-.1-9.34-1.11-19.6-1.11-19.6s-10.2.82-11.1-2.15,0-31.52.38-37.07c0,0-21.44-4.77-40-1.25C365.25,185.66,362.35,228.94,362.17,243.55Z"
style="fill: #455a64"></path>
<path
d="M405.31,232c-.11,9.71,1.6,15.74,4.18,17.84s7.66,1.94,7.66,1.94v-1.45s-4.8.71-6.95-1.54S406.09,243.3,405.31,232Z"
style="fill: #37474f"></path>
<path
d="M372.31,196s11.13,0,21.66.72c0,0,.07,8.13-.84,11.09s-7.92,7.39-10.83,7.38c-2.52,0-9.53-5-10.08-7.62S372.31,196,372.31,196Z"
style="fill: #37474f"></path>
<path d="M390.37,278.35l-1-6.24c-3-.45-10.73-5.25-15.29-9.45a36.22,36.22,0,0,0,12.79,11.78l.32,39.8Z"
style="fill: #37474f"></path>
<path
d="M410.55,171.87c-2-.51-3.13-.09-4.14,2.44s-2.17,10.75-2.56,18.44c0,0-4.63.84-7.84-.52,0,0,.39-10.1,1.47-15.31a18.61,18.61,0,0,1,1.5-4.44,4.64,4.64,0,0,1,5-2.53l7.32,1.34Z"
style="fill: #37474f"></path>
<path d="M401.79,189.35a1.82,1.82,0,1,1-1.82-1.82A1.82,1.82,0,0,1,401.79,189.35Z" style="fill: currentcolor">
</path>
<path
d="M383.76,169.18a8.43,8.43,0,0,0-7.44,5.13c-1.51,3.84-1.52,12.36-1.61,16.59a10.1,10.1,0,0,1-7.19,0s0-13.41,2.29-17.85,6.7-4.71,9-4.88a41.71,41.71,0,0,1,4.93,0Z"
style="fill: #37474f"></path>
<path d="M373.13,187.93a1.82,1.82,0,1,1-1.82-1.82A1.82,1.82,0,0,1,373.13,187.93Z" style="fill: currentcolor">
</path>
</g>
</g>
<g id="freepik--error-500--inject-87">
<g id="freepik--speech-bubble--inject-87">
<g id="freepik--Text--inject-87">
<path
d="M220.56,123.12c.27.39.58.79.91,1.2a3.65,3.65,0,0,0,1.2,1,3.49,3.49,0,0,0,1.71.33,5.26,5.26,0,0,0,2.35-.81,10.8,10.8,0,0,0,2.34-1.86,13.47,13.47,0,0,0,2-2.64,14.18,14.18,0,0,0,1.38-3.24,13.43,13.43,0,0,0,.5-3.72c0-2-.52-3.42-1.56-4.12s-2.46-.52-4.25.52a6.7,6.7,0,0,0-1.56,1.26c-.49.52-.94,1-1.35,1.54L223.09,114a3.47,3.47,0,0,1-.89.87l-9.15,5.29a.91.91,0,0,1-1.18,0,1.85,1.85,0,0,1-.41-1.48l1.76-33.29a5.72,5.72,0,0,1,.5-2A2.89,2.89,0,0,1,214.81,82l25.12-14.51a.86.86,0,0,1,1.12.08,1.94,1.94,0,0,1,.47,1.45v9.58a4.71,4.71,0,0,1-.47,2,2.91,2.91,0,0,1-1.12,1.36L222.85,91.8l-.41,8.28a21.2,21.2,0,0,1,2.44-2.9,14.35,14.35,0,0,1,3-2.33,15.18,15.18,0,0,1,6.31-2.2,7.62,7.62,0,0,1,5,1.24,9.55,9.55,0,0,1,3.35,4.76,24.94,24.94,0,0,1,1.2,8.43,39.65,39.65,0,0,1-1.32,10.34,40.32,40.32,0,0,1-3.64,9.11,35.8,35.8,0,0,1-5.43,7.43,30.63,30.63,0,0,1-6.69,5.31,17.17,17.17,0,0,1-7.14,2.53,8.28,8.28,0,0,1-5.31-1.18,9,9,0,0,1-3.35-4.21,17.42,17.42,0,0,1-1.23-6.47,3.8,3.8,0,0,1,.38-1.62,2.52,2.52,0,0,1,.91-1.12l7.46-4.3c.62-.36,1.1-.46,1.44-.29A1.84,1.84,0,0,1,220.56,123.12Z"
style="fill: currentcolor"></path>
<path
d="M266.23,51.38q4.41-2.54,7.57-2.38a7.59,7.59,0,0,1,5.26,2.3,13.3,13.3,0,0,1,3.11,6,38.92,38.92,0,0,1,1.2,8.66q.12,3.83.12,8.07t-.12,8a60.14,60.14,0,0,1-1.2,10.05,43.56,43.56,0,0,1-3.11,9.61,37.46,37.46,0,0,1-5.26,8.37,27.9,27.9,0,0,1-7.57,6.36c-2.93,1.69-5.46,2.49-7.57,2.38a7.51,7.51,0,0,1-5.25-2.3,13.25,13.25,0,0,1-3.12-6,40,40,0,0,1-1.2-8.66Q249,98.23,249,94t.12-8.21a62.05,62.05,0,0,1,1.2-10,43.67,43.67,0,0,1,3.12-9.62,37.06,37.06,0,0,1,5.25-8.37A28.05,28.05,0,0,1,266.23,51.38Zm6.28,36.51q.24-7.81,0-15.19a27.71,27.71,0,0,0-.44-3.9,6.86,6.86,0,0,0-1-2.71A2.6,2.6,0,0,0,269.17,65a5.06,5.06,0,0,0-2.94.89,10,10,0,0,0-2.93,2.5,12.82,12.82,0,0,0-1.88,3.3,20.17,20.17,0,0,0-1.06,3.91A32.37,32.37,0,0,0,260,80q-.3,7.67,0,15.18a25.69,25.69,0,0,0,.38,3.94,6.45,6.45,0,0,0,1.06,2.68,2.66,2.66,0,0,0,1.91,1.12,5,5,0,0,0,2.93-.88,10.28,10.28,0,0,0,2.94-2.51,13.43,13.43,0,0,0,1.91-3.32,17.28,17.28,0,0,0,1.05-3.91A33.37,33.37,0,0,0,272.51,87.89Z"
style="fill: currentcolor"></path>
<path
d="M306.62,28.07c2.93-1.7,5.46-2.49,7.57-2.39a7.66,7.66,0,0,1,5.26,2.3,13.55,13.55,0,0,1,3.11,6,39.51,39.51,0,0,1,1.2,8.66q.12,3.83.12,8.07c0,2.83,0,5.51-.12,8a61.2,61.2,0,0,1-1.2,10,44.64,44.64,0,0,1-3.11,9.61,37.36,37.36,0,0,1-5.26,8.37,27.87,27.87,0,0,1-7.57,6.36c-2.94,1.7-5.46,2.49-7.57,2.39a7.64,7.64,0,0,1-5.26-2.3,13.45,13.45,0,0,1-3.11-6,39.51,39.51,0,0,1-1.2-8.66q-.12-3.64-.12-7.89c0-2.83,0-5.57.12-8.2a61.2,61.2,0,0,1,1.2-10.05,44.35,44.35,0,0,1,3.11-9.62,37.17,37.17,0,0,1,5.26-8.36A27.55,27.55,0,0,1,306.62,28.07Zm6.28,36.5q.24-7.81,0-15.19a29.28,29.28,0,0,0-.44-3.9,6.75,6.75,0,0,0-1-2.7,2.55,2.55,0,0,0-1.88-1.13,5,5,0,0,0-2.93.88A10.12,10.12,0,0,0,303.68,45a13.08,13.08,0,0,0-1.88,3.3,19.88,19.88,0,0,0-1.05,3.9,32.37,32.37,0,0,0-.41,4.4q-.3,7.67,0,15.18a24.49,24.49,0,0,0,.38,3.94,6.36,6.36,0,0,0,1.06,2.69,2.68,2.68,0,0,0,1.9,1.11,5,5,0,0,0,2.94-.88,10.08,10.08,0,0,0,2.93-2.51,13.23,13.23,0,0,0,1.91-3.31A18,18,0,0,0,312.52,69,35.52,35.52,0,0,0,312.9,64.57Z"
style="fill: currentcolor"></path>
<path
d="M243.26,179.32a.29.29,0,0,1,.39,0,.68.68,0,0,1,.17.51v3.4a1.64,1.64,0,0,1-.17.7,1.06,1.06,0,0,1-.39.49l-9.87,5.69a.29.29,0,0,1-.39,0,.68.68,0,0,1-.17-.51V168.9a1.64,1.64,0,0,1,.17-.7,1.06,1.06,0,0,1,.39-.49l9.7-5.6a.32.32,0,0,1,.4,0,.69.69,0,0,1,.16.51v3.4a1.62,1.62,0,0,1-.16.7,1.14,1.14,0,0,1-.4.49l-6.41,3.7v3.46l5.95-3.44a.33.33,0,0,1,.4,0,.7.7,0,0,1,.16.52v3.39a1.66,1.66,0,0,1-.16.71,1,1,0,0,1-.4.48l-5.95,3.44v3.59Z"
style="fill: #455a64"></path>
<path
d="M252.41,156.73a7.56,7.56,0,0,1,2.46-1,2.66,2.66,0,0,1,1.84.29,2.87,2.87,0,0,1,1.17,1.61,9.39,9.39,0,0,1,.4,3,13.87,13.87,0,0,1-.64,4.36,11.55,11.55,0,0,1-1.83,3.48l2.58,6.13a.91.91,0,0,1,.06.32,1.33,1.33,0,0,1-.14.57.84.84,0,0,1-.32.4l-2.83,1.63c-.28.16-.47.18-.59.06a1.62,1.62,0,0,1-.28-.42L252,171.69l-1.92,1.11v6.85a1.54,1.54,0,0,1-.17.71,1.08,1.08,0,0,1-.39.48l-2.73,1.58a.31.31,0,0,1-.39,0,.71.71,0,0,1-.17-.52V161.18a1.68,1.68,0,0,1,.17-.71,1.08,1.08,0,0,1,.39-.48Zm-2.35,11.07,2.35-1.36a4.46,4.46,0,0,0,1.45-1.35,3.83,3.83,0,0,0,.57-2.19c0-.89-.19-1.4-.57-1.52a1.81,1.81,0,0,0-1.45.32l-2.35,1.36Z"
style="fill: #455a64"></path>
<path
d="M266.88,148.38a7.43,7.43,0,0,1,2.45-1,2.65,2.65,0,0,1,1.84.29,2.87,2.87,0,0,1,1.17,1.61,9.36,9.36,0,0,1,.41,3,13.86,13.86,0,0,1-.65,4.36,11.33,11.33,0,0,1-1.83,3.48l2.58,6.13a.91.91,0,0,1,.06.32,1.31,1.31,0,0,1-.13.57.8.8,0,0,1-.33.4l-2.83,1.63c-.27.16-.47.18-.59.06a1.62,1.62,0,0,1-.28-.42l-2.31-5.52-1.92,1.11v6.85a1.66,1.66,0,0,1-.16.71,1,1,0,0,1-.4.48l-2.72,1.57a.31.31,0,0,1-.4,0,.71.71,0,0,1-.17-.52V152.83a1.68,1.68,0,0,1,.17-.71,1,1,0,0,1,.4-.48Zm-2.36,11.07,2.36-1.36a4.42,4.42,0,0,0,1.44-1.35,3.83,3.83,0,0,0,.57-2.19c0-.89-.19-1.4-.57-1.52a1.79,1.79,0,0,0-1.44.32l-2.36,1.36Z"
style="fill: #455a64"></path>
<path
d="M274.66,152.25a17.82,17.82,0,0,1,.51-3.67,16.31,16.31,0,0,1,1.27-3.49,14.33,14.33,0,0,1,2-3,10.27,10.27,0,0,1,2.71-2.26,5.43,5.43,0,0,1,2.71-.87,3,3,0,0,1,2,.69,4.47,4.47,0,0,1,1.28,2,11.08,11.08,0,0,1,.5,3.08c0,.91.05,1.86.05,2.86s0,1.95-.05,2.85a18.61,18.61,0,0,1-.5,3.67,16.62,16.62,0,0,1-1.28,3.5,13.54,13.54,0,0,1-2,3,10.55,10.55,0,0,1-2.71,2.24,5.61,5.61,0,0,1-2.71.89,2.91,2.91,0,0,1-2-.7,4.6,4.6,0,0,1-1.27-2,10.78,10.78,0,0,1-.51-3.09c0-.86,0-1.79,0-2.79S274.63,153.18,274.66,152.25Zm9.14.27c0-.39,0-.83,0-1.31s0-1,0-1.45,0-1,0-1.42,0-.85,0-1.2a5.57,5.57,0,0,0-.23-1.35,2,2,0,0,0-.49-.88,1.16,1.16,0,0,0-.8-.33,2.41,2.41,0,0,0-1.13.36,4.41,4.41,0,0,0-1.12.94,5.43,5.43,0,0,0-.8,1.25,6.79,6.79,0,0,0-.5,1.46,9.21,9.21,0,0,0-.22,1.6c0,.38-.05.8-.05,1.26s0,.94,0,1.43,0,1,0,1.44,0,.88.05,1.25a3.51,3.51,0,0,0,.72,2.25q.63.69,1.92-.06a4.6,4.6,0,0,0,1.92-2.16A9.15,9.15,0,0,0,283.8,152.52Z"
style="fill: #455a64"></path>
<path
d="M296.28,131.4a7.47,7.47,0,0,1,2.46-1,2.66,2.66,0,0,1,1.84.29,2.85,2.85,0,0,1,1.16,1.62,9,9,0,0,1,.41,3,13.87,13.87,0,0,1-.64,4.36,11.35,11.35,0,0,1-1.84,3.48l2.58,6.14a.87.87,0,0,1,.07.31,1.34,1.34,0,0,1-.14.58.86.86,0,0,1-.32.39L299,152.25c-.28.16-.48.17-.6.05a1.53,1.53,0,0,1-.27-.41l-2.32-5.53-1.91,1.11v6.85a1.65,1.65,0,0,1-.17.71,1,1,0,0,1-.39.48l-2.73,1.58a.29.29,0,0,1-.39,0,.66.66,0,0,1-.17-.51v-20.7a1.48,1.48,0,0,1,.17-.7,1.06,1.06,0,0,1,.39-.49Zm-2.35,11.07,2.35-1.36a4.25,4.25,0,0,0,1.45-1.35,3.82,3.82,0,0,0,.57-2.18q0-1.35-.57-1.53a1.85,1.85,0,0,0-1.45.32l-2.35,1.36Z"
style="fill: #455a64"></path>
<path
d="M210.63,172a.17.17,0,0,1-.23,0,.4.4,0,0,1-.09-.29v-12a1,1,0,0,1,.09-.4.7.7,0,0,1,.23-.29l1.58-.9a.16.16,0,0,1,.22,0,.38.38,0,0,1,.1.3v12a.88.88,0,0,1-.1.41.6.6,0,0,1-.22.28Z"
style="fill: #455a64"></path>
<path
d="M220,166.6a.29.29,0,0,1-.33,0,.59.59,0,0,1-.16-.17l-2.75-4.74V168a1,1,0,0,1-.1.41.55.55,0,0,1-.23.28l-1.57.91a.18.18,0,0,1-.23,0,.39.39,0,0,1-.1-.3v-12a.85.85,0,0,1,.1-.4.55.55,0,0,1,.23-.28l1.25-.73a.31.31,0,0,1,.33,0,.49.49,0,0,1,.16.17l2.75,4.74v-6.26a.91.91,0,0,1,.1-.41.6.6,0,0,1,.23-.28l1.57-.91a.18.18,0,0,1,.23,0,.38.38,0,0,1,.1.3v11.95a.88.88,0,0,1-.1.41.6.6,0,0,1-.23.28Z"
style="fill: #455a64"></path>
<path
d="M229.72,148a.18.18,0,0,1,.23,0,.41.41,0,0,1,.09.3v2a1,1,0,0,1-.09.41.67.67,0,0,1-.23.28l-2.12,1.22v9.49a1,1,0,0,1-.09.41.67.67,0,0,1-.23.28l-1.58.91a.18.18,0,0,1-.23,0,.41.41,0,0,1-.09-.3v-9.49l-2.12,1.22a.17.17,0,0,1-.22,0,.39.39,0,0,1-.1-.3v-2a.88.88,0,0,1,.1-.41.59.59,0,0,1,.22-.28Z"
style="fill: #455a64"></path>
<path
d="M237.45,153.56a.17.17,0,0,1,.23,0,.41.41,0,0,1,.09.3v2a1,1,0,0,1-.09.41.67.67,0,0,1-.23.28l-5.7,3.29a.18.18,0,0,1-.23,0,.41.41,0,0,1-.09-.3v-12a1,1,0,0,1,.09-.41.67.67,0,0,1,.23-.28l5.6-3.23a.18.18,0,0,1,.23,0,.38.38,0,0,1,.1.3v2a.88.88,0,0,1-.1.41.6.6,0,0,1-.23.28l-3.7,2.14v2l3.44-2a.17.17,0,0,1,.23,0,.4.4,0,0,1,.09.29v2a1,1,0,0,1-.09.41.61.61,0,0,1-.23.28l-3.44,2v2.07Z"
style="fill: #455a64"></path>
<path
d="M243,140.34a4,4,0,0,1,1.42-.56,1.49,1.49,0,0,1,1.06.16,1.69,1.69,0,0,1,.67.93,5.31,5.31,0,0,1,.24,1.75,8,8,0,0,1-.38,2.52,6.47,6.47,0,0,1-1.05,2l1.49,3.55a.57.57,0,0,1,0,.18.78.78,0,0,1-.07.33.57.57,0,0,1-.19.23l-1.64.94c-.16.1-.27.11-.34,0a1,1,0,0,1-.16-.25L242.79,149l-1.11.63v4a.86.86,0,0,1-.1.41.6.6,0,0,1-.22.28l-1.58.91a.18.18,0,0,1-.23,0,.43.43,0,0,1-.09-.3v-12a1,1,0,0,1,.09-.4.55.55,0,0,1,.23-.28Zm-1.36,6.39,1.36-.79a2.47,2.47,0,0,0,.83-.78,2.18,2.18,0,0,0,.33-1.26c0-.52-.11-.81-.33-.88a1.07,1.07,0,0,0-.83.18l-1.36.79Z"
style="fill: #455a64"></path>
<path
d="M253.58,147.2q-.21.12-.33,0a.41.41,0,0,1-.16-.17l-2.76-4.74v6.26a1,1,0,0,1-.09.41.63.63,0,0,1-.23.27l-1.58.91a.17.17,0,0,1-.22,0,.38.38,0,0,1-.1-.3v-12a.86.86,0,0,1,.1-.41.6.6,0,0,1,.22-.28l1.25-.72a.31.31,0,0,1,.34,0,.78.78,0,0,1,.16.17l2.75,4.74v-6.26a.85.85,0,0,1,.1-.4.6.6,0,0,1,.22-.28l1.58-.91a.18.18,0,0,1,.23,0,.41.41,0,0,1,.09.3v11.95a1,1,0,0,1-.09.41.61.61,0,0,1-.23.28Z"
style="fill: #455a64"></path>
<path
d="M261.59,129.63c.15-.1.28-.1.36,0a.75.75,0,0,1,.18.31l2.62,10.14a1,1,0,0,1,0,.25.78.78,0,0,1-.07.33.57.57,0,0,1-.19.23l-1.52.88c-.16.09-.27.1-.34,0a.39.39,0,0,1-.12-.24l-.34-1.34-3.2,1.85-.33,1.73a1.56,1.56,0,0,1-.13.38.82.82,0,0,1-.34.35l-1.52.88a.14.14,0,0,1-.18,0,.29.29,0,0,1-.08-.24,1.13,1.13,0,0,1,.05-.3l2.62-13.18a2.46,2.46,0,0,1,.17-.5.85.85,0,0,1,.37-.42Zm-1.95,9.21,1.95-1.13-1-3.87Z"
style="fill: #455a64"></path>
<path
d="M272,133.63a.18.18,0,0,1,.23,0,.4.4,0,0,1,.09.29v2a1,1,0,0,1-.09.4.61.61,0,0,1-.23.28l-5.57,3.22a.18.18,0,0,1-.23,0,.41.41,0,0,1-.09-.3v-12a1,1,0,0,1,.09-.41.67.67,0,0,1,.23-.28l1.58-.91a.17.17,0,0,1,.22,0,.37.37,0,0,1,.1.29v9.5Z"
style="fill: #455a64"></path>
<path
d="M279.3,119.21a3.21,3.21,0,0,1,1.41-.47,2,2,0,0,1,1.11.24,1.81,1.81,0,0,1,.74.76,2.34,2.34,0,0,1,.27,1.08.78.78,0,0,1-.07.33c-.06.11-.11.19-.18.22l-1.57.91a.42.42,0,0,1-.27.08.41.41,0,0,1-.21-.1.66.66,0,0,1-.12-.12.64.64,0,0,0-.22-.14,1,1,0,0,0-.36,0,1.54,1.54,0,0,0-.53.2,4.27,4.27,0,0,0-.44.3,3.23,3.23,0,0,0-.37.37,1.39,1.39,0,0,0-.26.44,1.27,1.27,0,0,0-.11.52.52.52,0,0,0,.12.39.54.54,0,0,0,.38.13,3.41,3.41,0,0,0,.72-.11l1.1-.29a3.66,3.66,0,0,1,1.16-.15,1.34,1.34,0,0,1,.82.32,1.59,1.59,0,0,1,.49.82,5,5,0,0,1,.16,1.41,6.42,6.42,0,0,1-.27,1.85,7.33,7.33,0,0,1-.78,1.71,7.69,7.69,0,0,1-1.17,1.49,7.32,7.32,0,0,1-1.49,1.13,3.59,3.59,0,0,1-1.49.53,2,2,0,0,1-1.16-.21A1.82,1.82,0,0,1,276,132a2.65,2.65,0,0,1-.29-1.22.67.67,0,0,1,.08-.33.45.45,0,0,1,.17-.22l1.58-.91a.42.42,0,0,1,.26-.09.52.52,0,0,1,.19.08l.15.16a.76.76,0,0,0,.26.19.72.72,0,0,0,.41.07,1.43,1.43,0,0,0,.6-.22,4.58,4.58,0,0,0,1.07-.82,1.49,1.49,0,0,0,.42-1c0-.19-.05-.31-.16-.37a.69.69,0,0,0-.46-.07,3.75,3.75,0,0,0-.8.15l-1.15.3a1.74,1.74,0,0,1-1.81-.32,3.31,3.31,0,0,1-.57-2.22,6.55,6.55,0,0,1,.23-1.65,8.25,8.25,0,0,1,.68-1.67,7.93,7.93,0,0,1,1.08-1.5A5.89,5.89,0,0,1,279.3,119.21Z"
style="fill: #455a64"></path>
<path
d="M290.6,122.87a.17.17,0,0,1,.23,0,.4.4,0,0,1,.09.29v2a1,1,0,0,1-.09.41.67.67,0,0,1-.23.28l-5.7,3.29a.18.18,0,0,1-.23,0,.4.4,0,0,1-.09-.29v-12a1,1,0,0,1,.09-.41.67.67,0,0,1,.23-.28l5.6-3.23a.17.17,0,0,1,.23,0,.37.37,0,0,1,.1.29v2a.86.86,0,0,1-.1.41.55.55,0,0,1-.23.28L286.8,118v2l3.44-2a.18.18,0,0,1,.23,0,.41.41,0,0,1,.09.3v2a1,1,0,0,1-.09.4.61.61,0,0,1-.23.28l-3.44,2v2.07Z"
style="fill: #455a64"></path>
<path
d="M296.19,109.65a4.24,4.24,0,0,1,1.42-.56,1.54,1.54,0,0,1,1.06.16,1.74,1.74,0,0,1,.68.94,5.51,5.51,0,0,1,.23,1.74,8,8,0,0,1-.38,2.52,6.42,6.42,0,0,1-1.05,2l1.49,3.54a.57.57,0,0,1,0,.18.86.86,0,0,1-.07.34.47.47,0,0,1-.19.22l-1.63,1c-.16.09-.28.1-.35,0a1,1,0,0,1-.16-.24l-1.33-3.19-1.11.64v4a.85.85,0,0,1-.1.4.6.6,0,0,1-.22.28l-1.58.91a.18.18,0,0,1-.23,0,.41.41,0,0,1-.09-.3v-12a1,1,0,0,1,.09-.41.61.61,0,0,1,.23-.28ZM294.83,116l1.36-.78a2.58,2.58,0,0,0,.83-.78,2.16,2.16,0,0,0,.34-1.27c0-.52-.11-.81-.34-.88a1,1,0,0,0-.83.19l-1.36.78Z"
style="fill: #455a64"></path>
<path
d="M303.53,118.36c-.31.18-.52.06-.63-.37l-2.46-10.15a.61.61,0,0,0,0-.15v-.07a.67.67,0,0,1,.08-.33.49.49,0,0,1,.18-.23l1.52-.88c.16-.09.27-.1.34,0a.47.47,0,0,1,.13.24l1.67,7.18,1.67-9.11a1.37,1.37,0,0,1,.12-.38.86.86,0,0,1,.35-.36l1.51-.87a.15.15,0,0,1,.19,0,.33.33,0,0,1,.08.24s0,0,0,.08a1.05,1.05,0,0,1,0,.18l-2.45,13a1.55,1.55,0,0,1-.64,1.11Z"
style="fill: #455a64"></path>
<path
d="M315.67,108.39a.18.18,0,0,1,.23,0,.37.37,0,0,1,.1.29v2a.85.85,0,0,1-.1.4.55.55,0,0,1-.23.28L310,114.64a.18.18,0,0,1-.23,0,.39.39,0,0,1-.1-.3v-12a.85.85,0,0,1,.1-.4.55.55,0,0,1,.23-.28l5.6-3.24a.18.18,0,0,1,.23,0,.41.41,0,0,1,.09.3v2a1,1,0,0,1-.09.4.61.61,0,0,1-.23.28l-3.7,2.14v2l3.43-2a.17.17,0,0,1,.23,0,.38.38,0,0,1,.1.3v2a.88.88,0,0,1-.1.41.6.6,0,0,1-.23.28l-3.43,2v2.07Z"
style="fill: #455a64"></path>
<path
d="M321.26,95.17a4.56,4.56,0,0,1,1.42-.56,1.57,1.57,0,0,1,1.07.16,1.73,1.73,0,0,1,.67.94,5.31,5.31,0,0,1,.23,1.74,7.94,7.94,0,0,1-.37,2.52,6.43,6.43,0,0,1-1.06,2l1.49,3.54a.41.41,0,0,1,0,.19.8.8,0,0,1-.08.33.49.49,0,0,1-.19.23l-1.63.94c-.16.09-.27.1-.34,0a.78.78,0,0,1-.16-.24L321,103.81l-1.1.64v4a1,1,0,0,1-.1.41.67.67,0,0,1-.23.28L318,110a.18.18,0,0,1-.23,0,.38.38,0,0,1-.1-.3v-12a.88.88,0,0,1,.1-.41.6.6,0,0,1,.23-.28Zm-1.35,6.39,1.35-.78a2.51,2.51,0,0,0,.84-.78,2.2,2.2,0,0,0,.33-1.26c0-.52-.11-.82-.33-.89a1.11,1.11,0,0,0-.84.19l-1.35.78Z"
style="fill: #455a64"></path>
</g>
<path
d="M252.08,191.4a1.47,1.47,0,0,0-2.18.27c-.67.83-.73,3.39-1,5.12a20.89,20.89,0,0,1-1.69,5.34,27.8,27.8,0,0,1-5.71,7.86,36.13,36.13,0,0,1-10.93,7.29,31.77,31.77,0,0,1-4.24,1.48c-1.43.39-3.35.43-4.58,1.24a.42.42,0,0,0,0,.62c1.5.62,3.34.35,4.9.14a25.91,25.91,0,0,0,5.79-1.6,35.36,35.36,0,0,0,10.44-6.35,30.94,30.94,0,0,0,7.44-9.28,21.71,21.71,0,0,0,2.06-6.06,20.93,20.93,0,0,0,.44-3.34A3.22,3.22,0,0,0,252.08,191.4Z"
style="fill: #455a64"></path>
</g>
</g>
</svg>
</template>
<script lang="ts" setup></script>
<style lang="scss" scoped></style>
-24
View File
@@ -1,24 +0,0 @@
/**
* 组件库出口。
*
* ⚠️ 这里的每一行都必须对应 `src/components/` 下的真实目录。
* 剥离 gi-demo 演示页时删掉过 6 个演示专用组件
* (GiCodeButton / GiCodeView / GiFooter / GiIconSelector / GiIframe / GiTrend),
* 但出口文件没同步 —— `export * from './已删除的组件'` 在构建时**不会报错**
* (Vite 只在使用到该导出时才解析),直到某天有人 import 它才炸。
* 所以增删组件时务必回来同步这一份清单。
*/
export * from './GiButton'
export * from './GiCell'
export * from './GiDot'
export * from './GiEditTable'
export * from './GiFlex'
export * from './GiForm'
export * from './GiIconBox'
export * from './GiInputSearch'
export * from './GiOption'
export * from './GiPageLayout'
export * from './GiTable'
export * from './GiTableSetting'
export * from './GiTag'
export * from './GiThemeBtn'
+37
View File
@@ -0,0 +1,37 @@
import type { PaginationProps } from 'naive-ui'
/**
* 列表页分页器的统一参数。
*
* ## 为什么要有这个文件
* 手写 `pagination` 对象时,`prefix` 的类型最容易写错:
* ```ts
* // ✗ 这样写 vue-tsc 会报 TS2322:naive 给的 info 里 itemCount 是 `number | undefined`
* pagination: { prefix: ({ itemCount }: { itemCount: number }) => `共 ${itemCount} 条` }
* ```
* 报错信息很长(说的是 `RenderPrefix` 不兼容),而真正的原因只是**少了个 `?`**。
* 三个列表页各踩一次不值得,所以收口到这里。
*
* ## 另一个踩过的坑(与类型无关,但同样只在运行时暴露)
* naive 的 `n-data-table` 在 `pagination` 非 false 时会**自己再切一次数据**
* (内部 `flattenData`)。所以远程分页必须同时:
* ① `remote` 打开;② `:pagination` 的 `page`/`pageSize` 由**我们**控制;
* ③ 处理 `@update:page` 与 `@update:page-size` **两个**事件并重新取数。
* 只改本地每页条数不重新取数,就会出现"分页器说 50 条/页、表里还是 20 条"。
*/
export function listPagination(opts: {
page: number
pageSize: number
itemCount: number
pageSizes?: number[]
}): PaginationProps {
return {
page: opts.page,
pageSize: opts.pageSize,
itemCount: opts.itemCount,
showSizePicker: true,
pageSizes: opts.pageSizes ?? [10, 20, 50, 100],
// ⚠️ `itemCount?: number` 里的 `?` 是必需的(见上方注释)
prefix: (info: { itemCount?: number }) => `共 ${info.itemCount ?? 0} 条`
}
}
-11
View File
@@ -1,11 +0,0 @@
{
"themeColor": "#0052D9",
"layout": "left",
"tabStyle": "card",
"isTabVisible": true,
"transitionName": "zoom-fade",
"isTransitionEnabled": true,
"isMenuCollapsed": false,
"isMenuAccordion": false,
"isMenuDark": false
}
+86 -191
View File
@@ -1,294 +1,189 @@
/**
* 业务菜单与路由表。
* 业务菜单表 —— **这一张表同时驱动三件事**:左侧菜单、路由注册、面包屑标题。
*
* 设计:**这一张表同时驱动三件事** —— 左侧菜单、路由注册、权限提示。
* 三者若各写一份,改一处漏一处几乎必然发生(表现是"菜单点进去 404"或"有权限但不显示")。
*
* 菜单可见性由**后端**决定:`/auth/me` 返回 `menus: string[]`(菜单键集合),
* 菜单可见性由**后端**决定:`/auth/me` 与登录响应返回 `menus: string[]`(菜单键集合),
* 这里按菜单键过滤。真正的访问控制也在后端(绕过前端只会拿到 40301),
* 前端的过滤只是"不显示没权限的入口"。
*
* ⚠️ `key` 必须与后端 `BuiltinRole` 里的菜单键逐字一致。
* ⚠️ `key` 必须与后端 `BuiltinRole` 里的菜单键**逐字一致** ——
* `scripts/check-wiring.py` 会双向核对,对不上会红。
* ⚠️ 2026-10 需求收敛:删掉了 `join`(加入申请)与 `cleanup`(历史整理器)两个菜单键,
* 后端 `BuiltinRole` 同步删除;权限码也去掉了 join:audit / cleanup:run。
*/
import type { UserRouteItem } from '@/apis/user'
/** 单个菜单定义 */
export interface XtMenu {
/** 菜单键,与后端一致 */
key: string
title: string
/** iconify 图标名(icon-park-outline 集) */
/** 图标短名(见 @/icons/icon-data.ts) */
icon: string
/** 路由路径(完整,以 / 开头) */
path: string
/** 视图路径(相对 src/views,不带扩展名);分组节点为空 */
component?: string
/** 分组标题;null 表示不分组 */
group: string | null
sort: number
/** 一期是否已实现。false 的走「待建」页,比直接隐藏更诚实 */
ready: boolean
/** 待建说明 */
note?: string
/** 视图路径(相对 src/views,不带扩展名) */
component: string
/** 所属分组 */
group: string
}
/** 分组顺序(决定左侧菜单顺序) */
const GROUPS: Array<{ id: string, title: string, icon: string, sort: number }> = [
{ id: 'collect', title: '收集管理', icon: 'icon-park-outline:application-two', sort: 10 },
{ id: 'setting', title: '配置', icon: 'icon-park-outline:setting-two', sort: 20 },
{ id: 'org', title: '组织与账号', icon: 'icon-park-outline:every-user', sort: 30 },
{ id: 'platform', title: '平台运维', icon: 'icon-park-outline:server', sort: 40 }
/** 分组(决定左侧菜单顺序) */
export interface XtMenuGroup {
id: string
title: string
icon: string
sort: number
}
export const GROUPS: XtMenuGroup[] = [
{ id: 'collect', title: '收集管理', icon: 'collect', sort: 10 },
{ id: 'setting', title: '配置', icon: 'setting', sort: 20 },
{ id: 'org', title: '组织与账号', icon: 'org-group', sort: 30 },
{ id: 'platform', title: '平台运维', icon: 'platform', sort: 40 }
]
/** 业务菜单(工作台在 baseRoutes 里,不列这里) */
/** 工作台不在分组里(所有角色都有,且是落地页) */
export const DASHBOARD: XtMenu = {
key: 'dashboard',
title: '工作台',
icon: 'dashboard',
path: '/dashboard',
component: 'dashboard/index',
group: ''
}
/** 业务菜单(按分组顺序排列) */
export const XT_MENUS: XtMenu[] = [
// ── 收集管理 ──────────────────────────────────────
{
key: 'task',
title: '收集任务',
icon: 'icon-park-outline:list-two',
icon: 'task',
path: '/collect/task',
component: 'task/index',
group: 'collect',
sort: 11,
ready: true
},
{
key: 'join',
title: '加入申请',
icon: 'icon-park-outline:user-to-user-transmission',
path: '/collect/join',
component: 'join/index',
group: 'collect',
sort: 13,
ready: true
group: 'collect'
},
{
key: 'audit',
title: '审核',
icon: 'icon-park-outline:check-one',
icon: 'audit',
path: '/collect/audit',
component: 'audit/index',
group: 'collect',
sort: 14,
ready: true
group: 'collect'
},
{
key: 'export',
title: '导出中心',
icon: 'icon-park-outline:download-two',
icon: 'export',
path: '/collect/export',
component: 'export/index',
group: 'collect',
sort: 15,
ready: true
group: 'collect'
},
{
// 通知记录:把「通知到底发出去没有」变成可回答的(§13.3)。
// 刻意**不**并到审核页里 —— 它是运营视角的排查工具,
// 而审核页是老师视角的操作台,两者的"该看什么"完全不同
// 通知记录:把「通知到底发出去没有」变成可回答的。
// 刻意**不**并到审核页里 —— 它是运营视角的排查工具,而审核页是老师视角的操作台。
key: 'notify',
title: '通知记录',
icon: 'icon-park-outline:remind',
icon: 'notify',
path: '/collect/notify',
component: 'notify/index',
group: 'collect',
sort: 17,
ready: true
group: 'collect'
},
// ── 配置 ─────────────────────────────────────────
{
key: 'cleanup',
title: '历史整理器',
icon: 'icon-park-outline:magic-wand',
path: '/setting/cleanup',
component: 'cleanup/index',
group: 'setting',
sort: 23,
ready: true
},
{
// 字典管理(§13.3)。内置项照抄官方表格、不可改名(只可停用单项),
// 所以这一屏的主要用途是"追加客户自己的取值"(例如多了个学历写法)
// 字典管理:内置项照抄官方表格、不可改名(只可停用单项),
// 所以这一屏的主要用途是"追加客户自己的取值"。
key: 'dict',
title: '字典管理',
icon: 'icon-park-outline:list-two',
icon: 'dict',
path: '/setting/dict',
component: 'dict/index',
group: 'setting',
sort: 24,
ready: true
group: 'setting'
},
// ── 组织与账号 ────────────────────────────────────
{
key: 'org',
title: '组织架构',
icon: 'icon-park-outline:tree-list',
icon: 'org',
path: '/org/manage',
component: 'org/index',
group: 'org',
sort: 31,
ready: true
group: 'org'
},
{
key: 'user',
title: '账号管理',
icon: 'icon-park-outline:peoples',
icon: 'user',
path: '/org/user',
component: 'user/index',
group: 'org',
sort: 32,
ready: true
group: 'org'
},
{
// 内置角色只读展示(权限由后端代码决定)+ 自定义角色的权限码/菜单可配。
// 改授权立即生效(服务端写授权时清缓存),不需要重新登录。
key: 'role',
title: '角色与授权',
icon: 'icon-park-outline:permissions',
icon: 'role',
path: '/org/role',
component: 'role/index',
group: 'org',
sort: 33,
ready: false,
note: '内置角色的权限由代码决定、不可改;自定义角色属二期。'
group: 'org'
},
// ── 平台运维 ──────────────────────────────────────
{
key: 'tenant',
title: '租户管理',
icon: 'icon-park-outline:school',
icon: 'tenant',
path: '/platform/tenant',
component: 'tenant/index',
group: 'platform',
sort: 41,
ready: true
group: 'platform'
},
{
key: 'log',
title: '操作日志',
icon: 'icon-park-outline:log',
icon: 'log',
path: '/platform/log',
component: 'log/index',
group: 'platform',
sort: 42,
ready: true,
note: '登录、查看明文、下载、导出、代传、删除的审计记录。'
group: 'platform'
}
]
/** 构造一个「待建」路由项(组件统一指向 coming-soon) */
function placeholder(menu: XtMenu): UserRouteItem {
return {
id: menu.key,
parentId: '0',
path: menu.path,
component: 'coming-soon/index',
title: menu.title,
icon: menu.icon,
sort: menu.sort,
type: 2,
status: '1',
hidden: false,
keepAlive: false,
affix: false,
breadcrumb: true,
showInTabs: true,
alwaysShow: false,
activeMenu: '',
permission: '',
roles: [],
redirect: '',
children: []
} as UserRouteItem
/** 按后端下发的菜单键过滤出可见菜单 */
export function filterMenus(menuKeys: string[]): XtMenu[] {
const keys = new Set(menuKeys ?? [])
return XT_MENUS.filter((m) => keys.has(m.key))
}
/**
* 按后端下发的菜单键,生成异步路由树。
*
* @param menuKeys `/auth/me` 返回的菜单键集合
* @returns 分组 → 页面的两级路由树(`component: 'Layout'` 由上层 formatAsyncRoutes 处理)
*/
export function buildXtRoutes(menuKeys: string[]): UserRouteItem[] {
const keys = new Set(menuKeys)
const visible = XT_MENUS.filter((m) => keys.has(m.key))
if (!visible.length) {
return []
/** 可见菜单按分组归拢(左侧菜单用;空分组不返回) */
export function visibleGroups(menuKeys: string[]): Array<XtMenuGroup & { items: XtMenu[] }> {
const visible = filterMenus(menuKeys)
return GROUPS
.map((g) => ({ ...g, items: visible.filter((m) => m.group === g.id) }))
.filter((g) => g.items.length > 0)
}
/** 按路径取菜单(面包屑/标题用;工作台也在内) */
export function menuByPath(path: string): XtMenu | undefined {
if (path === DASHBOARD.path) {
return DASHBOARD
}
const routes: UserRouteItem[] = []
for (const g of GROUPS) {
const items = visible.filter((m) => m.group === g.id)
if (!items.length) {
continue
}
routes.push({
id: g.id,
parentId: '0',
path: `/${g.id}`,
// 'Layout' 是约定的布局组件标识,formatAsyncRoutes 会替换成真实组件
component: 'Layout',
title: g.title,
icon: g.icon,
sort: g.sort,
type: 1,
status: '1',
hidden: false,
keepAlive: false,
affix: false,
breadcrumb: true,
showInTabs: false,
alwaysShow: true,
activeMenu: '',
permission: '',
roles: [],
redirect: items[0].path,
children: items
.sort((a, b) => a.sort - b.sort)
.map((m) => (m.ready ? readyItem(m) : placeholder(m)))
} as UserRouteItem)
}
return routes
}
/** 已实现页面 */
function readyItem(menu: XtMenu): UserRouteItem {
return {
id: menu.key,
parentId: menu.group ?? '0',
path: menu.path,
component: menu.component!,
title: menu.title,
icon: menu.icon,
sort: menu.sort,
type: 2,
status: '1',
hidden: false,
keepAlive: false,
affix: false,
breadcrumb: true,
showInTabs: true,
alwaysShow: false,
activeMenu: '',
permission: '',
roles: [],
redirect: '',
children: []
} as UserRouteItem
}
/** 按路由路径取菜单定义(「待建」页要显示说明用) */
export function findMenuByPath(path: string): XtMenu | undefined {
return XT_MENUS.find((m) => m.path === path)
}
/** 角色码 → 中文名(与后端 BuiltinRole 对齐) */
/** 角色码 → 中文名(与后端 `BuiltinRole` 对齐;2026-10 收敛后只剩 4 个) */
export const ROLE_NAMES: Record<string, string> = {
PLATFORM_ADMIN: '平台运营',
SCHOOL_ADMIN: '学校管理员',
HEAD_TEACHER: '班主任',
DEPUTY_TEACHER: '副班主任',
AUDITOR: '审核员',
STUDENT: '学生'
}
/** 角色码数组 → 中文名(多角色用「、」连接) */
export function roleLabel(codes?: string[] | null): string {
if (!codes || !codes.length) {
return '—'
}
return codes.map((c) => ROLE_NAMES[c] ?? c).join('、')
}
-44
View File
@@ -1,44 +0,0 @@
import type { Directive, DirectiveBinding } from 'vue'
import { hasPermOr } from '@/utils/permission'
/**
* 权限检查函数
* @description 检查元素是否具有指定的权限,如果没有权限则移除该元素
* @param el - 要检查的 DOM 元素
* @param binding - 指令绑定对象
* @throws {Error} 当权限参数格式不正确时抛出错误
*/
function checkPermission(el: HTMLElement, binding: DirectiveBinding<string[]>) {
const { value } = binding
// 检查权限参数是否有效
if (!value || !Array.isArray(value) || value.length === 0) {
throw new Error('权限参数格式错误,示例:v-hasPerm="[\'home:btn:edit\',\'home:btn:delete\']"')
}
// 检查是否具有权限
const hasPermission = hasPermOr(value)
if (!hasPermission) {
el.parentNode?.removeChild(el)
}
}
/**
* 权限指令
* @description 用于控制元素的显示/隐藏,基于用户权限
* @example
* ```vue
* <button v-hasPerm="['home:btn:add']">添加</button>
* <button v-hasPerm="['home:btn:edit', 'home:btn:delete']">编辑/删除</button>
* ```
*/
const hasPermDirective: Directive = {
mounted(el: HTMLElement, binding: DirectiveBinding<string[]>) {
checkPermission(el, binding)
},
updated(el: HTMLElement, binding: DirectiveBinding<string[]>) {
checkPermission(el, binding)
}
}
export default hasPermDirective
-44
View File
@@ -1,44 +0,0 @@
import type { Directive, DirectiveBinding } from 'vue'
import { hasRoleOr } from '@/utils/permission'
/**
* 角色检查函数
* @description 检查元素是否具有指定的角色,如果没有角色则移除该元素
* @param el - 要检查的 DOM 元素
* @param binding - 指令绑定对象
* @throws {Error} 当角色参数格式不正确时抛出错误
*/
function checkRole(el: HTMLElement, binding: DirectiveBinding<string[]>) {
const { value } = binding
// 检查角色参数是否有效
if (!value || !Array.isArray(value) || value.length === 0) {
throw new Error('角色参数格式错误,示例:v-hasRole="[\'admin\',\'user\']"')
}
// 检查是否具有角色
const hasRole = hasRoleOr(value)
if (!hasRole) {
el.parentNode?.removeChild(el)
}
}
/**
* 角色权限指令
* @description 用于控制元素的显示/隐藏,基于用户角色
* @example
* ```vue
* <div v-hasRole="['admin']">管理员可见</div>
* <div v-hasRole="['admin', 'user']">管理员或用户可见</div>
* ```
*/
const hasRoleDirective: Directive = {
mounted(el: HTMLElement, binding: DirectiveBinding<string[]>) {
checkRole(el, binding)
},
updated(el: HTMLElement, binding: DirectiveBinding<string[]>) {
checkRole(el, binding)
}
}
export default hasRoleDirective
-10
View File
@@ -1,10 +0,0 @@
import type { App } from 'vue'
import hasPerm from './hasPerm'
import hasRole from './hasRole'
export default {
install(Vue: App) {
Vue.directive('hasPerm', hasPerm)
Vue.directive('hasRole', hasRole)
}
}
-2
View File
@@ -1,2 +0,0 @@
export * from './useDept'
export * from './useRole'
-27
View File
@@ -1,27 +0,0 @@
import type * as T from '@/apis/system/dept'
import { ref } from 'vue'
import { mapTree } from 'xe-utils'
import { baseAPI } from '@/apis/system/dept'
/** 部门模块 */
export function useDept(options?: { onSuccess?: () => void }) {
const loading = ref(false)
const deptList = ref<T.ListItem[]>([])
const getDeptList = async () => {
try {
loading.value = true
const res = await baseAPI.getList()
deptList.value = mapTree(res.data, (i) => {
if (i.children?.length) {
i.children = i.children.filter((i) => i.status === '1')
}
return i
})
options?.onSuccess && options.onSuccess()
} finally {
loading.value = false
}
}
return { deptList, getDeptList, loading }
}
-21
View File
@@ -1,21 +0,0 @@
import type * as T from '@/apis/system/role'
import { ref } from 'vue'
import { baseAPI } from '@/apis/system/role'
/** 角色模块 */
export function useRole() {
const loading = ref(false)
const roleList = ref<T.ListItem[]>([])
const total = ref(0)
const getRoleList = async () => {
try {
loading.value = true
const res = await baseAPI.getList({ page: 1, size: 99 })
roleList.value = res.data.records.filter((i) => i.status === '1')
total.value = res.data.total
} finally {
loading.value = false
}
}
return { roleList, getRoleList, loading, total }
}
-11
View File
@@ -1,11 +0,0 @@
export * from './useBreakpoint'
export * from './useChart'
export * from './useDevice'
export * from './useDict'
export * from './useLoading'
export * from './usePagination'
export * from './useRequest'
export * from './useResetReactive'
export * from './useRouteListener'
export * from './useTable'
export * from './useTheme'
-37
View File
@@ -1,37 +0,0 @@
import type { ColProps } from '@arco-design/web-vue'
import type { ComputedRef } from 'vue'
import { useBreakpoints } from '@vueuse/core'
import { computed } from 'vue'
type ColBreakpoint = Pick<ColProps, 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'xxl'>
type Breakpoint = keyof ColBreakpoint
// 定义断点配置
const BREAKPOINT_CONFIG = {
xs: 576, // <576px
sm: 576, // ≥576px
md: 768, // ≥768px
lg: 992, // ≥992px
xl: 1200, // ≥1200px
xxl: 1600 // ≥1600px
} as const
/**
* 响应式断点 Hook
* @returns {{ breakpoint: ComputedRef<Breakpoint> }} 当前激活的最大断点值
*/
export function useBreakpoint() {
const breakpoints = useBreakpoints(BREAKPOINT_CONFIG)
const currentBreakpoints = breakpoints.current() as ComputedRef<Breakpoint[]>
const breakpoint = computed<Breakpoint>(() => {
const arr = currentBreakpoints.value
// arr.at(-1) 的类型是 Breakpoint | undefined —— 空数组时就是 undefined。
// 原来写成 `arr.length ? arr.at(-1) : 'xs'` 是个类型谎:
// 长度判断并不能让 TS 窄化 at() 的结果,严格模式下会报 TS2769。
return arr.length ? (arr.at(-1) ?? 'xs') : 'xs'
})
return { breakpoint }
}

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