Commit ee8406a7 by qinjianhui

Initial commit

parents
/* eslint-env node */
require('@rushstack/eslint-patch/modern-module-resolution')
module.exports = {
root: true,
ignorePatterns: ['/auto-imports.d.ts', '/components.d.ts'],
extends: [
'plugin:vue/vue3-essential',
'eslint:recommended',
'@vue/eslint-config-typescript/recommended',
'@vue/eslint-config-prettier',
'./.eslintrc-auto-import.json',
],
rules: {
'prettier/prettier': [
'warn',
{
semi: false,
singleQuote: true,
printWidth: 80,
proseWrap: 'preserve',
bracketSameLine: false,
endOfLine: 'lf',
tabWidth: 2,
useTabs: false,
trailingComma: 'none',
},
],
'vue/multi-word-component-names': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/ban-ts-comment': 'off',
'no-undef': 'off',
'vue/prefer-import-from-vue': 'off',
'no-prototype-builtins': 'off',
'prefer-spread': 'off',
'@typescript-eslint/no-non-null-assertion': 'off',
'@typescript-eslint/no-non-null-asserted-optional-chain': 'off',
},
globals: {
module: 'readonly',
},
}
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
.DS_Store
dist
dist-ssr
coverage
*.local
# unplugin-auto-import
auto-imports.d.ts
components.d.ts
.eslintrc-auto-import.json
/cypress/videos/
/cypress/screenshots/
# Editor directories and files
.idea
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
# .env
.env.development
.env.production
\ No newline at end of file
# vue-project
This template should help get you started developing with Vue 3 in Vite.
## Recommended IDE Setup
[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
## Type Support for `.vue` Imports in TS
TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.
If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
1. Disable the built-in TypeScript Extension
1) Run `Extensions: Show Built-in Extensions` from VSCode's command palette
2) Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.
## Customize configuration
See [Vite Configuration Reference](https://vitejs.dev/config/).
## Project Setup
```sh
npm install
```
### Compile and Hot-Reload for Development
```sh
npm run dev
```
### Type-Check, Compile and Minify for Production
```sh
npm run build
```
### Lint with [ESLint](https://eslint.org/)
```sh
npm run lint
```
/// <reference types="vite/client" />
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>后台管理系统</title>
<style>
* {
margin: 0;
padding: 0;
}
.preload {
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
width: 100vw;
}
.circular {
height: 42px;
width: 42px;
animation: loading-rotate 2s linear infinite;
}
.circular .path {
animation: loading-dash 1.5s ease-in-out infinite;
stroke-dasharray: 90, 150;
stroke-dashoffset: 0;
stroke-width: 2;
stroke: #4073fa;
stroke-linecap: round;
}
@keyframes loading-rotate {
100% {
transform: rotate(1turn);
}
}
@keyframes loading-dash {
0% {
stroke-dasharray: 90, 150;
stroke-dashoffset: -40px;
}
100% {
stroke-dasharray: 90, 150;
stroke-dashoffset: -120px;
}
}
</style>
</head>
<body>
<div id="app">
<div class="preload">
<svg viewBox="25 25 50 50" class="circular">
<circle cx="50" cy="50" r="20" fill="none" class="path"></circle>
</svg>
</div>
</div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
{
"name": "vue-project",
"version": "0.0.0",
"license": "MIT",
"scripts": {
"dev": "vite",
"dev2": "vite --port 8080",
"preview": "vite preview --port 4173",
"build": "vite build && node scripts/release.mjs",
"type-check": "vue-tsc --noEmit",
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore"
},
"dependencies": {
"@element-plus/icons-vue": "^2.0.6",
"@highlightjs/vue-plugin": "^2.1.0",
"@wangeditor/editor": "^5.1.12",
"@wangeditor/editor-for-vue": "^5.1.12",
"axios": "^0.27.2",
"css-color-function": "^1.3.3",
"echarts": "^5.3.3",
"element-plus": "^2.2.9",
"highlight.js": "^11.6.0",
"nprogress": "^0.2.0",
"pinia": "^2.0.14",
"vue": "^3.2.37",
"vue-clipboard3": "^2.0.0",
"vue-echarts": "^6.2.3",
"vue-router": "^4.0.16",
"vue3-video-play": "^1.3.1-beta.6",
"vuedraggable": "^4.1.0"
},
"devDependencies": {
"@rushstack/eslint-patch": "^1.1.0",
"@tailwindcss/line-clamp": "^0.4.2",
"@types/lodash-es": "^4.17.6",
"@types/node": "^16.11.41",
"@types/nprogress": "^0.2.0",
"@vitejs/plugin-legacy": "^2.3.1",
"@vitejs/plugin-vue": "^3.0.0",
"@vitejs/plugin-vue-jsx": "^2.0.0",
"@vue/eslint-config-prettier": "^7.0.0",
"@vue/eslint-config-typescript": "^11.0.0",
"@vue/tsconfig": "^0.1.3",
"autoprefixer": "^10.4.7",
"consola": "^2.15.3",
"eslint": "^8.5.0",
"eslint-plugin-vue": "^9.0.0",
"execa": "^6.1.0",
"fs-extra": "^10.1.0",
"postcss": "^8.4.14",
"prettier": "^2.5.1",
"sass": "^1.53.0",
"tailwindcss": "^3.0.24",
"terser": "^5.15.1",
"typescript": "~4.7.4",
"unplugin-auto-import": "^0.9.2",
"unplugin-vue-components": "^0.19.9",
"vite": "^3.0.0",
"vite-plugin-style-import": "^2.0.0",
"vite-plugin-svg-icons": "^2.0.1",
"vite-plugin-vue-setup-extend": "^0.4.0",
"vue-tsc": "^0.38.1"
}
}
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}
import path from 'path'
import fsExtra from 'fs-extra'
const { existsSync, remove, copy } = fsExtra
const cwd = process.cwd()
//打包发布路径,谨慎改动
const releaseRelativePath = '../server/view/frontEnd'
const distPath = path.resolve(cwd, 'dist')
const releasePath = path.resolve(cwd, releaseRelativePath)
async function build() {
if (existsSync(releasePath)) {
await remove(releasePath)
}
console.log(`文件正在复制 ==> ${releaseRelativePath}`)
try {
await copyFile(distPath, releasePath)
} catch (error) {
console.log(`\n ${error}`)
}
console.log(`文件已复制 ==> ${releaseRelativePath}`)
}
function copyFile(sourceDir, targetDir) {
return new Promise((resolve, reject) => {
copy(sourceDir, targetDir, (err) => {
if (err) {
reject(err)
} else {
resolve()
}
})
})
}
build()
<script setup lang="ts">
import { useDark, useWindowSize, useThrottleFn } from '@vueuse/core'
import zhCn from 'element-plus/lib/locale/lang/zh-cn'
import useAppStore from './stores/modules/app'
import useSettingStore from './stores/modules/setting'
import { ScreenEnum } from './enums/appEnums'
const appStore = useAppStore()
const settingStore = useSettingStore()
const elConfig = {
zIndex: 3000,
locale: zhCn,
}
const isDark = useDark()
onMounted(async () => {
//设置主题色
settingStore.setTheme(isDark.value)
// 获取配置
const data: any = await appStore.getConfig()
// 设置网站logo
let favicon: HTMLLinkElement = document.querySelector('link[rel="icon"]')!
if (favicon) {
favicon.href = data.web_favicon
return
}
favicon = document.createElement('link')
favicon.rel = 'icon'
favicon.href = data.web_favicon
document.head.appendChild(favicon)
})
const { width } = useWindowSize()
watch(
width,
useThrottleFn((value: any) => {
if (value > ScreenEnum.SM) {
appStore.setMobile(false)
appStore.toggleCollapsed(false)
} else {
appStore.setMobile(true)
appStore.toggleCollapsed(true)
}
if (value < ScreenEnum.MD) {
appStore.toggleCollapsed(true)
}
}),
{
immediate: true,
}
)
</script>
<template>
<el-config-provider :locale="elConfig.locale" :z-index="elConfig.zIndex">
<router-view />
</el-config-provider>
</template>
<style></style>
import request from '@/utils/request'
// 配置
export function getConfig() {
return request.get({ url: '/config/getConfig' })
}
// 工作台主页
export function getWorkbench() {
return request.get({ url: '/workbench/index' })
}
//字典数据
export function getDictData(params?: any) {
return request.get({ url: '/config/dict', params })
}
//字典数据
export function shopData(params?: any) {
return request.get({ url: '/shop/data', params })
}
import request from '@/utils/request'
export function fileCateAdd(params: Record<string, any>) {
return request.post({ url: '/foxpsdData/api/diy/image/type/create', params }, {
headers: {
'Content-Type': 'application/json;charset=UTF-8'
}
})
}
export function fileCateEdit(params: Record<string, any>) {
return request.post({ url: '/foxpsdData/api/diy/image/type/update', params }, {
headers: {
'Content-Type': 'application/json;charset=UTF-8'
}
})
}
// 文件分类删除
export function fileCateDelete(params: Record<string, any>) {
return request.post({ url: '/foxpsdData/api/diy/image/type/delete', params }, {
headers: {
'Content-Type': 'application/json;charset=UTF-8'
}
})
}
// 文件分类列表
export function fileCateLists(params: Record<string, any>) {
return request.get({ url: '/foxpsdData/api/diy/image/type', params })
}
// 文件保存
export function apiDiyImageSave(params: Record<string, any>) {
return request.post({ url: '/foxpsdData/api/diy/image/save', params }, {
headers: {
'Content-Type': 'application/json;charset=UTF-8'
}
})
}
// 文件列表
export function fileList(params: Record<string, any>) {
return request.get({ url: '/foxpsdData/api/diy/image/list', params })
}
// 文件删除
export function fileDelete(params: Record<string, any>) {
return request.post({ url: '/foxpsdData/api/diy/image/delete', params }, {
headers: {
'Content-Type': 'application/json;charset=UTF-8'
}
})
}
// 文件移动
export function fileMove(params: Record<string, any>) {
return request.post({ url: '/file/move', params })
}
// 文件重命名
export function fileRename(params: { id: number; name: string }) {
return request.post({ url: '/file/rename', params })
}
import request from '@/utils/request'
//图库分类
export function apiDiyImageTypeList(params?: any) {
return request.get({ url: '/api/diy/image/type/list', params })
}
export function apiDiyImageTypeCreate(params?: any) {
return request.post({ url: '/api/diy/image/type/create', params })
}
export function apiDiyImageTypeUpdate(params?: any) {
return request.post({ url: '/api/diy/image/type/update', params })
}
export function apiDiyImageTypeDelete(params?: any) {
return request.post({ url: '/api/diy/image/type/delete', params })
}
//图库
export function apiDiyImageList(params?: any) {
return request.get({ url: '/api/diy/image/list', params })
}
export function apiDiyImageCreate(params?: any) {
return request.post({ url: '/api/diy/image/create', params })
}
export function apiDiyImageDelete(params?: any) {
return request.post({ url: '/api/diy/image/delete', params })
}
export function apiDiyImageMove(params?: any) {
return request.post({ url: '/api/diy/image/move', params })
}
\ No newline at end of file
import request from '@/utils/request'
//
export function apiDiyUserList(params?: any) {
return request.post({ url: '/api/diy/user/list', params })
}
export function apiDiyUserCreate(params?: any) {
return request.post({ url: '/api/diy/user/create', params })
}
export function apiDiyUserUpdate(params?: any) {
return request.post({ url: '/api/diy/user/update', params })
}
export function apiDiyUserDelete(params?: any) {
return request.post({ url: '/api/diy/user/delete', params })
}
export function apiDiyUserItem(params?: any) {
return request.get({ url: '/api/diy/user/item', params })
}
//用户保存记录
export function apiDiyUserSaveList(params?: any) {
return request.post({ url: '/api/diy/userSave/list', params })
}
//用户保存详情
export function apiDiyUserSaveItem(params?: any) {
return request.get({ url: '/api/diy/userSave/item', params })
}
export function apiDiyUserSaveDelete(params?: any) {
return request.post({ url: '/api/diy/userSave/delete', params })
}
export function apiDiyUserSaveItems(params?: any) {
return request.post({ url: '/api/diy/userSave/items', params })
}
// 重新生成尺码
export function apiDiyUserSaveChimaRender(params?: any) {
return request.post({ url: '/api/diy/userSave/chima/render', params })
}
//用户下载保存记录
export function apiDiyUserDownCreate(params?: any) {
return request.post({ url: '/api/diy/userDown/create', params })
}
export function apiDiyUserDownList(params?: any) {
return request.post({ url: '/api/diy/userDown/list', params })
}
export function apiDiyUserDownDelete(params?: any) {
return request.post({ url: '/api/diy/userDown/delete', params })
}
import request from '@/utils/request'
//设计产品/成品/系统素材三级分类列表
export function shopTypeList(params?: any) {
return request.get({ url: '/api/diy/template/type/list', params })
}
//新增设计产品/成品/系统素材三级分类
export function shopTypeSave(params?: any) {
return request.post({ url: '/api/diy/template/type/create', params })
}
//设计产品/成品/系统素材三级分类详情
export function shopTypeUpdate(params?: any) {
return request.post({ url: '/api/diy/template/type/update', params })
}
//启用/禁用/删除设计产品/成品/系统素材三级分类
export function shopTypeChangeStatus(params?: any) {
return request.post({ url: '/api/diy/template/type/delete', params })
}
// 分类首页/取消首页显示
export function shopTypeChangeTop(params?: any) {
return request.post({ url: '/shop/type/changeTop', params })
}
//模板列表
export function foxpsdDiyTemplateListFindAndCountAll(params: Record<string, any>) {
return request.post({ url: '/api/diy/template/listFindAndCountAll', params })
}
//foxpsd 模板详情
export function foxpsdDiyTemplateItem(params: Record<string, any>) {
return request.get({ url: '/foxpsdData/api/diy/template/item', params })
}
//默认绑定模板
export function apiDiyTemplateBindDiy(params?: any) {
return request.post({ url: '/api/diy/template/bind/diy', params })
}
// 解绑模板
export function apiDiyTemplateUnbindDiy(params?: any) {
return request.post({ url: '/api/diy/template/unbind/diy', params })
}
// 模板创建
export function apiDiyTemplateCreate(params?: any) {
return request.post({ url: '/api/diy/template/create', params })
}
// 模板创建
export function apiDiyTemplateUpdate(params?: any) {
return request.post({ url: '/api/diy/template/update', params })
}
// 模板删除
export function apiDiyTemplateDelete(params?: any) {
return request.post({ url: '/api/diy/template/delete', params })
}
// 模板详情
export function apiDiyTemplateItem(params?: any) {
return request.get({ url: '/api/diy/template/item', params })
}
// 模板上下架
export function apiDiyTemplateStatus(params?: any) {
return request.post({ url: '/api/diy/template/status', params })
}
// 模板绑定用户
export function apiDiyTemplateBindUser(params?: any) {
return request.post({ url: '/api/diy/template/bind/user', params })
}
//层面列表
export function apiDiyTemplateFaceList(params?: any) {
return request.get({ url: '/api/diy/template/face/list', params })
}
//层面创建
export function apiDiyTemplateFaceCreate(params?: any) {
return request.post({ url: '/api/diy/template/face/create', params })
}
//层面更新
export function apiDiyTemplateFaceUpdate(params?: any) {
return request.post({ url: '/api/diy/template/face/update', params })
}
//层面删除
export function apiDiyTemplateFaceDelete(params?: any) {
return request.post({ url: '/api/diy/template/face/delete', params })
}
// 效果图
export function apiDiyTemplateXiaoguotuList(params?: any) {
return request.get({ url: '/api/diy/template/xiaoguotu/list', params })
}
// 效果图
export function apiDiyTemplateXiaoguotuCreate(params?: any) {
return request.post({ url: '/api/diy/template/xiaoguotu/create', params })
}
export function apiDiyTemplateXiaoguotuUpdate(params?: any) {
return request.post({ url: '/api/diy/template/xiaoguotu/update', params })
}
export function apiDiyTemplateXiaoguotuDelete(params?: any) {
return request.post({ url: '/api/diy/template/xiaoguotu/delete', params })
}
export function apiPsdParser(params?: any) {
return request.post({ url: '/api/psd/parser', params })
}
// 颜色
export function apiDiyTemplateColorList(params?: any) {
return request.get({ url: '/api/diy/template/color/list', params })
}
export function apiDiyTemplateColorCreate(params?: any) {
return request.post({ url: '/api/diy/template/color/create', params })
}
export function apiDiyTemplateColorUpdate(params?: any) {
return request.post({ url: '/api/diy/template/color/update', params })
}
export function apiDiyTemplateColorDelete(params?: any) {
return request.post({ url: '/api/diy/template/color/delete', params })
}
//尺码
export function apiDiyTemplateChimaList(params?: any) {
return request.get({ url: '/api/diy/template/chima/list', params })
}
export function apiDiyTemplateChimaCreate(params?: any) {
return request.post({ url: '/api/diy/template/chima/create', params })
}
export function apiDiyTemplateChimaUpdate(params?: any) {
return request.post({ url: '/api/diy/template/chima/update', params })
}
export function apiDiyTemplateChimaDelete(params?: any) {
return request.post({ url: '/api/diy/template/chima/delete', params })
}
import request from '@/utils/request'
// 网站基本信息
export function shopSystemMsg(params?: Record<string, any>) {
return request.post({ url: '/shop/system/msg', params })
}
// 网站基本信息
export function shopSystemDoMsg(params: Record<string, any>) {
return request.post({ url: '/shop/system/doMsg', params })
}
//管理员角色列表
export function shopAdminJueseList(params?: Record<string, any>) {
return request.post({ url: '/shop/admin/juese/list', params })
}
//管理员角色列表
export function shopAdminJueseSave(params: Record<string, any>) {
return request.post({ url: '/shop/admin/juese/save', params })
}
//管理员角色列表
export function shopAdminJueseItem(params: Record<string, any>) {
return request.post({ url: '/shop/admin/juese/item', params })
}
//更新管理员角色
export function shopAdminJueseUpdate(params: Record<string, any>) {
return request.post({ url: '/shop/admin/juese/update', params })
}
//启用/禁用/删除管理员角色
export function shopAdminJueseChangeStatus(params: Record<string, any>) {
return request.post({ url: '/shop/admin/juese/changeStatus', params })
}
import request from '@/utils/request'
// 登录
export function login(params: Record<string, any>) {
return request.post({ url: '/api/admin/login', params: { ...params } }, { withToken: false })
}
// 用户信息
export async function getUserInfo() {
return request.get({ url: '/api/admin/business/msg'})
}
// 退出登录
export function logout() {
return request.post({ url: '/login/logout' })
}
// 编辑管理员信息
export function setUserInfo(params: any) {
return request.post({ url: '/shop/pwd', params })
}
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M502.869333 201.408a32.853333 32.853333 0 0 1 0 45.44L276.906667 480h544.384a32 32 0 0 1 0 64H276.885333l225.984 233.130667a32.853333 32.853333 0 0 1 0 45.44 30.485333 30.485333 0 0 1-44.053333 0L179.776 534.741333a32.128 32.128 0 0 1-6.848-10.688 32.213333 32.213333 0 0 1-0.085333-23.808l0.106666-0.32c1.514667-3.861333 3.797333-7.488 6.826667-10.624L458.837333 201.386667a30.485333 30.485333 0 0 1 44.053334 0z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M853.333333 170.666667a85.333333 85.333333 0 0 1 85.333334 85.333333v426.666667a85.333333 85.333333 0 0 1-85.333334 85.333333H576v42.666667h74.666667a32 32 0 0 1 0 64h-277.333334a32 32 0 0 1 0-64H448v-42.666667H170.666667a85.333333 85.333333 0 0 1-85.333334-85.333333V256a85.333333 85.333333 0 0 1 85.333334-85.333333h682.666666z m-127.957333 213.333333c-37.056 0.277333-77.824 17.258667-77.824 58.666667 0 45.12 37.909333 56.042667 78.976 60.928 26.709333 2.88 46.506667 10.666667 46.506667 29.632 0 21.845333-22.4 30.186667-46.229334 30.186666-24.405333 0-47.658667-9.792-56.576-31.914666l-31.573333 16.384c14.933333 36.8 46.506667 49.450667 87.573333 49.450666 44.8 0 84.437333-19.264 84.437334-64.106666 0-46.506667-36.650667-58.24-77.056-63.616l-3.925334-0.512c-24.106667-2.88-44.8-7.765333-44.8-25.301334 0-14.933333 13.504-26.730667 41.642667-26.730666 21.824 0 40.768 10.922667 47.658667 22.421333l30.165333-15.530667C789.12 392.917333 756.672 384 725.376 384z m-280 7.189333H401.706667v201.258667h37.909333v-146.346667l64.042667 87.68h7.466666l65.472-87.381333v146.048h37.909334v-201.258667h-43.370667l-62.890667 86.549334-62.890666-86.549334z m-194.133333-0.298666H213.333333v201.258666h37.909334V503.04l84.138666 89.109333h46.805334v-2.282666l-96.768-101.504 89.301333-96.32v-1.152h-47.082667l-76.394666 85.12v-85.12z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M385.6 371.242667c12.16 113.578667 92.906667 206.634667 200 236.949333l1.664 0.448-2.453333 2.005333-317.888 237.418667c-12.16 9.066667-28.8 8.533333-40.32-0.917333l-2.410667-2.154667-28.928-28.885333c0.213333 1.898667 0.490667 3.797333 0.810667 5.717333 6.186667 35.754667 31.338667 57.962667 79.808 49.322667 26.986667-4.821333 44.117333-11.242667 63.509333-22.464l6.336-3.776 11.541333-7.168 5.397334-3.285334c35.562667-21.248 64.96-29.909333 117.973333-30.442666 69.909333-0.704 129.088 21.056 175.701333 65.173333a32.853333 32.853333 0 0 1 1.28 46.4 32.746667 32.746667 0 0 1-46.293333 1.28c-33.898667-32.042667-76.608-47.744-130.026667-47.210667-40.597333 0.426667-59.029333 5.632-84.864 21.056l-17.642666 10.88c-28.266667 17.216-53.461333 27.413333-91.413334 34.176-87.808 15.658667-144-33.92-155.882666-102.741333a151.765333 151.765333 0 0 1 4.522666-72.042667l1.066667-2.965333-20.778667-20.736a32.853333 32.853333 0 0 1-3.968-41.706667l2.048-2.688 268.437334-318.72c0.874667-1.045333 1.813333-2.005333 2.773333-2.922666z m4.181333 169.344l-2.474666 2.24-46.357334 46.421333-2.24 2.496a32.853333 32.853333 0 0 0 2.24 43.925333 32.746667 32.746667 0 0 0 43.861334 2.24l2.496-2.24 46.336-46.421333 2.261333-2.496a32.853333 32.853333 0 0 0-2.261333-43.925333 32.746667 32.746667 0 0 0-43.861334-2.24zM661.333333 85.333333c141.376 0 256 114.624 256 256s-114.624 256-256 256-256-114.624-256-256S519.957333 85.333333 661.333333 85.333333z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M579.2 874.666667a21.333333 21.333333 0 0 1 14.421333 37.056C574.037333 929.685333 546.837333 938.666667 512 938.666667s-62.037333-8.981333-81.621333-26.944A21.333333 21.333333 0 0 1 444.821333 874.666667h134.357334z m28.8-85.333334a32 32 0 0 1 0 64h-192a32 32 0 0 1 0-64h192zM512 85.333333c176.725333 0 320 143.274667 320 320 0 114.090667-59.733333 214.250667-149.610667 270.912A85.333333 85.333333 0 0 1 597.333333 768h-170.666666a85.333333 85.333333 0 0 1-85.098667-91.776C251.733333 619.584 192 519.424 192 405.333333c0-176.725333 143.274667-320 320-320z m29.098667 106.666667a29.098667 29.098667 0 1 0 0 58.176 126.08 126.08 0 0 1 126.058666 126.08 29.098667 29.098667 0 1 0 58.176 0A184.234667 184.234667 0 0 0 541.098667 192z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M486.570667 97.216a33.130667 33.130667 0 0 1 51.264 0.512c34.709333 43.328 152.064 98.261333 307.776 117.034667 16.576 2.005333 29.056 16 29.056 32.64v372.629333a167.04 167.04 0 0 1-20.096 79.402667C761.813333 871.146667 633.770667 938.666667 511.530667 938.666667l-6.528-0.106667c-118.954667-3.413333-244.586667-70.741333-335.573334-239.125333a167.808 167.808 0 0 1-19.925333-71.914667L149.333333 620.032V247.402667c0-16.64 12.48-30.634667 29.056-32.64 152.426667-18.368 269.077333-72.277333 305.237334-114.005334z m25.408 67.178667l-1.792 1.450666c-52.693333 41.813333-163.456 91.882667-290.389334 109.802667l-4.416 0.597333v342.976l0.149334 5.866667c0.746667 15.104 4.864 29.866667 12.074666 43.221333 80.96 149.845333 188.714667 201.962667 278.826667 204.544l5.568 0.085334c92.522667 0 201.92-51.989333 284.373333-204.629334a101.546667 101.546667 0 0 0 12.224-48.277333V276.245333l-16.277333-2.325333c-120.938667-18.048-227.904-67.690667-278.954667-108.416l-1.386666-1.109333z m161.194666 250.517333a32.853333 32.853333 0 0 1 0 46.186667l-187.306666 190.656a32.256 32.256 0 0 1-45.845334 0l-89.173333-91.157334a32.853333 32.853333 0 0 1 0-46.208 32.256 32.256 0 0 1 45.845333 0l51.029334 52.416a21.333333 21.333333 0 0 0 30.165333 0.426667l0.341333-0.362667 149.077334-151.957333a32.256 32.256 0 0 1 45.866666 0z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M486.570667 97.216a33.130667 33.130667 0 0 1 51.264 0.512c34.709333 43.328 152.064 98.261333 307.776 117.034667 16.576 2.005333 29.056 16 29.056 32.64v372.629333a167.04 167.04 0 0 1-20.096 79.402667C761.813333 871.146667 633.770667 938.666667 511.530667 938.666667l-6.528-0.106667c-118.954667-3.413333-244.586667-70.741333-335.573334-239.125333a167.808 167.808 0 0 1-19.925333-71.914667L149.333333 620.032V247.402667c0-16.64 12.48-30.634667 29.056-32.64 152.426667-18.368 269.077333-72.277333 305.237334-114.005334z m186.602666 317.696a32.256 32.256 0 0 0-45.866666 0l-149.077334 151.957333-0.341333 0.341334a21.333333 21.333333 0 0 1-30.165333-0.405334l-51.029334-52.416a32.256 32.256 0 0 0-45.866666 0 32.853333 32.853333 0 0 0 0 46.208l89.194666 91.157334a32.256 32.256 0 0 0 45.866667 0l187.285333-190.656a32.853333 32.853333 0 0 0 0-46.186667z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M486.570667 97.216a33.130667 33.130667 0 0 1 51.264 0.512c34.709333 43.328 152.064 98.261333 307.776 117.034667 16.576 2.005333 29.056 16 29.056 32.64v372.629333a167.04 167.04 0 0 1-20.096 79.402667C761.813333 871.146667 633.770667 938.666667 511.530667 938.666667l-6.528-0.106667c-118.954667-3.413333-244.586667-70.741333-335.573334-239.125333a167.808 167.808 0 0 1-19.925333-71.914667L149.333333 620.032V247.402667c0-16.64 12.48-30.634667 29.056-32.64 152.426667-18.368 269.077333-72.277333 305.237334-114.005334z m186.602666 317.696a32.256 32.256 0 0 0-45.866666 0l-149.077334 151.957333-0.341333 0.341334a21.333333 21.333333 0 0 1-30.165333-0.405334l-51.029334-52.416a32.256 32.256 0 0 0-45.866666 0 32.853333 32.853333 0 0 0 0 46.208l89.194666 91.157334a32.256 32.256 0 0 0 45.866667 0l187.285333-190.656a32.853333 32.853333 0 0 0 0-46.186667z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 107.136v707.093333l-221.248 99.434667a32 32 0 0 1-44.586667-34.986667l41.834667-227.413333-182.826667-195.84a32 32 0 0 1 18.474667-53.461333l228.586667-35.733334 141.226666-248.298666A21.333333 21.333333 0 0 1 512 107.136z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M486.570667 97.216a33.130667 33.130667 0 0 1 51.264 0.512c34.709333 43.328 152.064 98.261333 307.776 117.034667 16.576 2.005333 29.056 16 29.056 32.64v372.629333a167.04 167.04 0 0 1-20.096 79.402667C761.813333 871.146667 633.770667 938.666667 511.530667 938.666667l-6.528-0.106667c-118.954667-3.413333-244.586667-70.741333-335.573334-239.125333a167.808 167.808 0 0 1-19.925333-71.914667L149.333333 620.032V247.402667c0-16.64 12.48-30.634667 29.056-32.64 152.426667-18.368 269.077333-72.277333 305.237334-114.005334z m-10.026667 256.213333h-122.090667v346.026667h38.442667V389.845333h45.205333c-9.045333 30.997333-21.845333 65.493333-38.058666 104.234667 24.490667 32.170667 36.906667 61.226667 36.906666 87.189333 0 6.186667-1.493333 10.453333-4.117333 12.8-3.029333 2.304-9.045333 3.861333-17.706667 4.629334-5.290667 0-12.053333-0.768-20.352-2.325334l12.437334 40.32c26.752-0.405333 45.589333-5.44 56.874666-15.509333 7.552-8.149333 11.306667-21.333333 11.306667-39.914667-2.261333-26.346667-14.293333-57.344-36.906667-93.397333a1520.768 1520.768 0 0 0 38.037334-104.234667v-30.208z m155.946667 148.8c-11.306667 58.112-24.106667 107.306667-39.168 147.626667h-132.608v38.741333h226.773333v-38.741333h-55.744c15.445333-40.32 28.629333-85.632 39.189333-136.789333l-38.442666-10.837334z m-121.685334 11.221334l-33.514666 11.626666c12.8 34.88 23.722667 71.68 32 110.058667l33.92-8.533333c-9.813333-42.624-20.352-80.213333-32.405334-113.152z m59.904-13.952l-33.514666 11.626666c11.306667 33.706667 20.330667 68.970667 27.861333 106.176l33.536-8.917333c-8.277333-41.066667-17.322667-77.098667-27.882667-108.885333z m21.12-158.869334h-34.688c-23.338667 51.541333-57.258667 93.397333-101.333333 125.930667l19.968 31.786667c13.568-9.685333 26.752-20.928 39.189333-33.322667v20.522667h120.533334v-19.370667a338.133333 338.133333 0 0 0 38.826666 32.554667l21.461334-33.706667c-49.344-35.648-84.010667-77.12-103.978667-124.373333z m-17.344 39.530667a279.530667 279.530667 0 0 0 44.821334 68.970667h-90.026667a370.410667 370.410667 0 0 0 45.205333-68.970667z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M789.333333 486.250667V746.666667c0 58.901333-124.16 106.666667-277.333333 106.666666-150.570667 0-273.109333-46.144-277.226667-103.68L234.666667 746.666667V486.250667l260.053333 115.285333a42.666667 42.666667 0 0 0 30.848 1.450667l3.733333-1.450667L789.333333 486.250667zM529.28 166.464l398.592 176.704a21.333333 21.333333 0 0 1 0 38.997333L874.666667 405.76 874.666667 603.093333A42.666667 42.666667 0 1 1 832 603.029333v-178.410666l-302.72 134.229333a42.666667 42.666667 0 0 1-34.56 0L96.106667 382.165333a21.333333 21.333333 0 0 1 0-38.997333l398.570666-176.704a42.666667 42.666667 0 0 1 34.602667 0z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M864 832a32 32 0 0 1 0 64h-704a32 32 0 0 1 0-64h704zM710.613333 152.533333l3.541334 3.413334 89.92 89.898666a95.36 95.36 0 0 1 3.370666 131.285334l-3.370666 3.562666-332.309334 332.309334c-9.386667 9.386667-21.077333 16.042667-33.856 19.349333l-4.842666 1.088-178.261334 33.642667a52.970667 52.970667 0 0 1-62.464-57.984l0.576-3.904L226.56 526.933333c2.453333-13.013333 8.362667-25.130667 17.045333-35.072l3.392-3.626666L579.306667 155.946667a95.36 95.36 0 0 1 131.285333-3.370667z m-83.946666 46.165334l-2.410667 2.176-332.309333 332.309333a10.602667 10.602667 0 0 0-2.517334 3.989333l-0.405333 1.536-30.741333 162.986667 119.978666-22.634667-51.968-51.968a31.786667 31.786667 0 1 1 44.949334-44.949333l70.72 70.72 317.141333-317.12a31.786667 31.786667 0 0 0 2.197333-42.538667l-2.197333-2.410666-89.898667-89.92a31.786667 31.786667 0 0 0-42.538666-2.176z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 85.333333c235.648 0 426.666667 191.018667 426.666667 426.666667s-191.018667 426.666667-426.666667 426.666667S85.333333 747.648 85.333333 512 276.352 85.333333 512 85.333333z m0 64C311.701333 149.333333 149.333333 311.701333 149.333333 512s162.368 362.666667 362.666667 362.666667 362.666667-162.368 362.666667-362.666667S712.298667 149.333333 512 149.333333z m-145.173333 471.338667A180.970667 180.970667 0 0 0 512 693.333333a180.650667 180.650667 0 0 0 128.746667-53.653333c5.888-5.930667 11.370667-12.266667 16.384-18.944a32 32 0 0 1 51.2 38.421333c-6.784 9.024-14.186667 17.578667-22.122667 25.6A244.629333 244.629333 0 0 1 512 757.333333c-78.208 0-150.357333-36.906667-196.373333-98.261333a32 32 0 1 1 51.2-38.4zM341.333333 384a42.666667 42.666667 0 1 1 0 85.333333 42.666667 42.666667 0 0 1 0-85.333333z m341.333334 0a42.666667 42.666667 0 1 1 0 85.333333 42.666667 42.666667 0 0 1 0-85.333333z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512.042667 213.333333c82.752 0 161.088 24.106667 234.88 71.786667l53.525333-53.482667a32 32 0 1 1 45.248 45.248L287.573333 835.029333a32 32 0 1 1-45.248-45.248l44.693334-44.714666c-62.72-38.528-122.154667-93.909333-178.261334-165.802667a108.522667 108.522667 0 0 1-3.093333-130.56l3.136-4.202667 6.805333-8.64C233.045333 288.533333 365.546667 213.333333 512.042667 213.333333z m334.506666 153.216a842.88 842.88 0 0 1 68.693334 78.08 108.522667 108.522667 0 0 1 3.029333 130.688l-3.136 4.202667-6.826667 8.64C790.570667 735.466667 658.133333 810.666667 512.042667 810.666667a410.88 410.88 0 0 1-97.898667-11.733334l53.013333-52.970666a344.32 344.32 0 0 0 44.885334 2.901333c120.896 0 233.088-62.229333 337.408-189.482667l6.784-8.405333 6.613333-8.341333a49.344 49.344 0 0 0 0-61.226667 787.370667 787.370667 0 0 0-61.205333-69.973333l44.906666-44.885334z m-334.506666-91.413333c-121.28 0-233.493333 62.229333-337.557334 189.44l-6.784 8.405333-6.570666 8.341334a49.344 49.344 0 0 0 0.042666 61.205333c54.954667 70.442667 112.106667 122.581333 171.562667 156.8l92.864-92.885333a128 128 0 1 1 180.842667-180.842667l94.976-94.933333c-60.650667-37.184-123.733333-55.530667-189.376-55.530667zM512 443.072a68.906667 68.906667 0 0 0-44.522667 121.536l97.130667-97.130667A68.778667 68.778667 0 0 0 512 443.072z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M384 554.666667a85.333333 85.333333 0 0 1 85.333333 85.333333v170.666667a85.333333 85.333333 0 0 1-85.333333 85.333333h-170.666667a85.333333 85.333333 0 0 1-85.333333-85.333333v-170.666667a85.333333 85.333333 0 0 1 85.333333-85.333333h170.666667z m245.333333 213.333333a32 32 0 0 1 32 32v42.666667a32 32 0 0 1-64 0v-42.666667a32 32 0 0 1 32-32z m192-21.333333a32 32 0 0 1 32 32v64a32 32 0 0 1-64 0v-64a32 32 0 0 1 32-32zM384 618.666667h-170.666667a21.333333 21.333333 0 0 0-21.184 18.837333L192 640v170.666667a21.333333 21.333333 0 0 0 18.837333 21.184L213.333333 832h170.666667a21.333333 21.333333 0 0 0 21.184-18.837333L405.333333 810.666667v-170.666667a21.333333 21.333333 0 0 0-18.837333-21.184L384 618.666667z m245.333333-42.666667a32 32 0 0 1 32 32v85.333333a32 32 0 0 1-64 0v-85.333333a32 32 0 0 1 32-32z m192 0a32 32 0 0 1 32 32v64a32 32 0 0 1-64 0v-64a32 32 0 0 1 32-32zM384 128a85.333333 85.333333 0 0 1 85.333333 85.333333v170.666667a85.333333 85.333333 0 0 1-85.333333 85.333333h-170.666667a85.333333 85.333333 0 0 1-85.333333-85.333333v-170.666667a85.333333 85.333333 0 0 1 85.333333-85.333333h170.666667z m426.666667 0a85.333333 85.333333 0 0 1 85.333333 85.333333v170.666667a85.333333 85.333333 0 0 1-85.333333 85.333333h-170.666667a85.333333 85.333333 0 0 1-85.333333-85.333333v-170.666667a85.333333 85.333333 0 0 1 85.333333-85.333333h170.666667zM384 192h-170.666667a21.333333 21.333333 0 0 0-21.184 18.837333L192 213.333333v170.666667a21.333333 21.333333 0 0 0 18.837333 21.184L213.333333 405.333333h170.666667a21.333333 21.333333 0 0 0 21.184-18.837333L405.333333 384v-170.666667a21.333333 21.333333 0 0 0-18.837333-21.184L384 192z m426.666667 0h-170.666667a21.333333 21.333333 0 0 0-21.184 18.837333L618.666667 213.333333v170.666667a21.333333 21.333333 0 0 0 18.837333 21.184L640 405.333333h170.666667a21.333333 21.333333 0 0 0 21.184-18.837333L832 384v-170.666667a21.333333 21.333333 0 0 0-18.837333-21.184L810.666667 192z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64z m265.9 713.9a377.2 377.2 0 0 1-119.6 80.6 377.5 377.5 0 0 1-292.6 0 377.1 377.1 0 0 1-200.2-200.2 377.5 377.5 0 0 1 0-292.6 377.1 377.1 0 0 1 200.2-200.2 377.5 377.5 0 0 1 292.6 0 377.1 377.1 0 0 1 200.2 200.2 377.5 377.5 0 0 1 0 292.6 377.2 377.2 0 0 1-80.6 119.6zM651.3 258.8a3.9 3.9 0 0 0-5.6 0L512 392.5 378.3 258.8a3.9 3.9 0 0 0-5.6 0l-39.6 39.6a3.9 3.9 0 0 0 0 5.6l102.3 102.4H376a4 4 0 0 0-4 4v56a4 4 0 0 0 4 4h104v80H376a4 4 0 0 0-4 4v56a4 4 0 0 0 4 4h104v148a4 4 0 0 0 4 4h56a4 4 0 0 0 4-4v-148h104a4 4 0 0 0 4-4v-56a4 4 0 0 0-4-4H544v-80h104a4 4 0 0 0 4-4v-56a4 4 0 0 0-4-4h-59.4L690.9 304a3.9 3.9 0 0 0 0-5.6z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M511 64C263.6 64 63 264.6 63 512s200.6 448 448 448 448-200.6 448-448S758.4 64 511 64z m265.9 713.9a377.2 377.2 0 0 1-119.6 80.6 377.5 377.5 0 0 1-292.6 0 377.1 377.1 0 0 1-200.2-200.2 377.5 377.5 0 0 1 0-292.6 377.1 377.1 0 0 1 200.2-200.2 377.5 377.5 0 0 1 292.6 0 377.1 377.1 0 0 1 200.2 200.2 377.5 377.5 0 0 1 0 292.6 377.2 377.2 0 0 1-80.6 119.6zM513.8 288.6a3.9 3.9 0 0 0-5.6 0L287.6 509.2a3.9 3.9 0 0 0 0 5.6l220.6 220.6a3.9 3.9 0 0 0 5.6 0l220.6-220.6a3.9 3.9 0 0 0 0-5.6zM511 636.5L386.5 512 511 387.5 635.5 512z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M285.8 406.9l137.3 83.7a7.7 7.7 0 0 0 11.8-6.6v-51.7h175a68.1 68.1 0 0 1 67.9 64.1 4.1 4.1 0 0 0 4 3.9h56.1a4.1 4.1 0 0 0 4-4.2c-2.2-70.8-60.6-127.8-132-127.8h-175v-51.8a7.7 7.7 0 0 0-11.8-6.6l-137.3 83.7a7.8 7.8 0 0 0 0 13.3z m452.4 210.2l-137.3-83.7a7.7 7.7 0 0 0-11.8 6.6v51.7h-175a68.1 68.1 0 0 1-67.9-64.1 4.1 4.1 0 0 0-4-3.9h-56.1a4.1 4.1 0 0 0-4 4.2c2.2 70.8 60.6 127.8 132 127.8h175v51.8a7.7 7.7 0 0 0 11.8 6.6l137.3-83.7a7.8 7.8 0 0 0 0-13.3zM856 128H168a40 40 0 0 0-40 40v688a40 40 0 0 0 40 40h688a40 40 0 0 0 40-40V168a40 40 0 0 0-40-40z m-32 696H200V200h624z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 106.666667c103.68 0 192.96 61.632 233.194667 150.250666C853.717333 266.944 938.666667 358.186667 938.666667 469.333333c0 95.509333-62.762667 176.362667-149.333334 203.562667V832a85.333333 85.333333 0 0 1-85.333333 85.333333H320a85.333333 85.333333 0 0 1-85.333333-85.333333v-180.437333C148.117333 624.384 85.333333 543.530667 85.333333 448c0-114.986667 90.944-208.704 204.8-213.162667A255.893333 255.893333 0 0 1 512 106.666667z m-104.725333 583.893333a25.557333 25.557333 0 0 0-36.949334 0 27.605333 27.605333 0 0 0 0 38.186667c78.250667 80.789333 205.098667 80.789333 283.349334 0a27.605333 27.605333 0 0 0 0-38.186667 25.557333 25.557333 0 0 0-36.949334 0 144.810667 144.810667 0 0 1-209.450666 0z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M880 184H712v-64c0-4.4-3.6-8-8-8h-56c-4.4 0-8 3.6-8 8v64H384v-64c0-4.4-3.6-8-8-8h-56c-4.4 0-8 3.6-8 8v64H144c-17.7 0-32 14.3-32 32v664c0 17.7 14.3 32 32 32h736c17.7 0 32-14.3 32-32V216c0-17.7-14.3-32-32-32z m-40 656H184V256h128v48c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8v-48h256v48c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8v-48h128v584zM688 420h-55.2c-5.1 0-10 2.5-13 6.6L468.9 634.4l-64.7-89c-3-4.1-7.8-6.6-13-6.6H336c-6.5 0-10.3 7.4-6.5 12.7l126.4 174c6.4 8.8 19.6 8.8 26 0l212.6-292.7c3.8-5.4 0-12.8-6.5-12.8z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M332.202667 347.136c12.16 12.373333 12.16 32.426667 0 44.821333-12.16 12.373333-31.893333 12.373333-44.053334 0l-151.04-115.584a32.085333 32.085333 0 0 1 0-44.842666l151.04-115.584c12.16-12.373333 31.893333-12.373333 44.053334 0 12.16 12.373333 12.16 32.448 0 44.842666l-85.290667 61.589334H565.333333c182.613333 0 330.666667 146.026667 330.666667 326.144 0 177.92-144.426667 322.538667-323.925333 326.08L565.333333 874.666667h-213.333333a31.786667 31.786667 0 0 1-32-31.573334c0-16.384 12.693333-29.866667 28.928-31.402666l3.072-0.149334h213.333333c147.285333 0 266.666667-117.76 266.666667-263.018666 0-143.082667-115.84-259.477333-260.096-262.933334l-6.570667-0.064-318.442666-0.021333 85.333333 61.632z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M853.333333 338.944V537.6c-32-16.362667-68.266667-25.6-106.666666-25.6-129.6 0-234.666667 105.066667-234.666667 234.666667 0 79.381333 39.424 149.546667 99.754667 192.021333L256 938.666667a85.333333 85.333333 0 0 1-85.333333-85.333334V338.965333a510.229333 510.229333 0 0 0 257.216 123.498667 85.312 85.312 0 0 0 168.192 0 510.165333 510.165333 0 0 0 257.28-123.52zM768 85.333333a85.333333 85.333333 0 0 1 85.333333 85.333334l0.021334 108.778666a468.437333 468.437333 0 0 1-260.842667 140.330667 85.354667 85.354667 0 0 0-161.088 0 468.373333 468.373333 0 0 1-260.778667-140.330667L170.666667 170.666667a85.333333 85.333333 0 0 1 85.333333-85.333334h512z m-21.354667 469.333334a191.957333 191.957333 0 0 1 168.597334 100.053333L746.666667 746.666667l135.765333 135.744A192 192 0 1 1 746.645333 554.666667z m32 106.666666a32 32 0 1 0 0-64 32 32 0 0 0 0 64z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M103.082667 632.704c1.493333 1.130667 3.093333 2.176 4.778666 3.136l2.56 1.344L490.666667 822.421333a49.066667 49.066667 0 0 0 38.976 1.621334l3.690666-1.621334 380.224-185.237333c2.624-1.28 5.077333-2.773333 7.36-4.458667 17.216 12.650667 22.954667 35.477333 12.544 54.4a45.162667 45.162667 0 0 1-19.904 18.752L533.333333 891.093333a49.024 49.024 0 0 1-42.666666 0L110.442667 705.877333c-22.784-11.093333-31.701333-37.482667-19.904-58.922666 3.072-5.546667 7.338667-10.410667 12.544-14.250667z m0-153.6c1.493333 1.130667 3.093333 2.176 4.778666 3.136l2.56 1.344L490.666667 668.821333a49.066667 49.066667 0 0 0 38.976 1.621334l3.690666-1.621334 380.224-185.237333c2.624-1.28 5.077333-2.773333 7.36-4.458667 17.216 12.650667 22.954667 35.477333 12.544 54.4a45.162667 45.162667 0 0 1-19.904 18.752L533.333333 737.493333a49.024 49.024 0 0 1-42.666666 0L110.442667 552.277333c-22.784-11.093333-31.701333-37.482667-19.904-58.922666 3.072-5.546667 7.338667-10.410667 12.544-14.250667zM533.333333 132.970667l380.224 187.968c22.784 11.264 31.701333 38.037333 19.904 59.776a45.44 45.44 0 0 1-19.904 19.008L533.333333 587.733333c-13.376 6.613333-29.290667 6.613333-42.666666 0L110.442667 399.722667c-22.784-11.264-31.701333-38.016-19.904-59.776a45.44 45.44 0 0 1 19.904-18.986667L490.666667 132.949333a48.362667 48.362667 0 0 1 42.666666 0z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M853.333333 725.034667v64H170.666667v-64h682.666666z m-149.333333-309.333334l149.333333 106.666667-149.333333 106.666667v-213.333334z m-85.333333 74.666667v64H170.666667v-64h448zM853.333333 256v64H170.666667v-64h682.666666z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M857.770667 163.882667c75.157333 75.136 72.448 209.237333 6.122666 346.944-17.792 36.309333-41.130667 72.725333-69.248 107.904a64 64 0 1 0 48.533334 41.792 697.173333 697.173333 0 0 0 51.328-72.682667c33.962667 109.098667 24.277333 208.938667-36.736 269.930667-67.84 67.84-183.701333 72.234667-306.922667 23.658666l-1.642667-0.938666-2.816-1.237334a475.690667 475.690667 0 0 1-34.410666-14.784v-0.021333c-40.170667-19.093333-80.64-44.842667-119.530667-76.288a32 32 0 0 0-40.234667 49.792c26.368 21.312 53.504 40.32 80.96 56.746667-108.842667 33.728-208.426667 23.957333-269.290666-36.906667-73.749333-73.749333-72.533333-204.309333-9.749334-339.328l3.434667-7.253333c19.882667-34.432 45.141333-68.693333 74.986667-101.482667a64 64 0 1 0-43.733334-46.997333 688.085333 688.085333 0 0 0-60.394666 75.093333c-35.477333-110.656-26.304-212.202667 35.456-273.941333 75.136-75.157333 209.237333-72.448 346.944-6.122667 137.706667-66.325333 271.808-69.034667 346.944 6.122667z m-347.306667 261.248a85.333333 85.333333 0 1 0 0 170.666666 85.333333 85.333333 0 0 0 0-170.666666z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M683.918222 910.222222h-341.333333a227.555556 227.555556 0 0 1-227.555556-227.555555V341.333333a227.555556 227.555556 0 0 1 227.555556-227.555555h341.333333a227.555556 227.555556 0 0 1 227.555556 227.555555v341.333334a227.555556 227.555556 0 0 1-227.555556 227.555555z m-341.333333-728.177778a159.288889 159.288889 0 0 0-159.288889 159.288889v341.333334a159.288889 159.288889 0 0 0 159.288889 159.288889h341.333333a159.288889 159.288889 0 0 0 159.288889-159.288889V341.333333a159.288889 159.288889 0 0 0-159.288889-159.288889z" /><path d="M513.251556 711.111111a199.111111 199.111111 0 1 1 199.111111-199.111111 199.395556 199.395556 0 0 1-199.111111 199.111111z m0-329.955555a130.844444 130.844444 0 1 0 130.844444 130.844444 130.844444 130.844444 0 0 0-130.844444-130.901333z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 85.333333c235.648 0 426.666667 191.018667 426.666667 426.666667s-191.018667 426.666667-426.666667 426.666667S85.333333 747.648 85.333333 512 276.352 85.333333 512 85.333333z m0 64C311.701333 149.333333 149.333333 311.701333 149.333333 512s162.368 362.666667 362.666667 362.666667 362.666667-162.368 362.666667-362.666667S712.298667 149.333333 512 149.333333z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 85.333333c235.648 0 426.666667 191.018667 426.666667 426.666667s-191.018667 426.666667-426.666667 426.666667S85.333333 747.648 85.333333 512 276.352 85.333333 512 85.333333z m0 64C311.701333 149.333333 149.333333 311.701333 149.333333 512s162.368 362.666667 362.666667 362.666667 362.666667-162.368 362.666667-362.666667S712.298667 149.333333 512 149.333333z m0 149.333334c117.824 0 213.333333 95.509333 213.333333 213.333333s-95.509333 213.333333-213.333333 213.333333-213.333333-95.509333-213.333333-213.333333 95.509333-213.333333 213.333333-213.333333z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M714.666667 106.666667a74.666667 74.666667 0 0 1 74.56 70.570666L789.333333 181.333333V213.333333h10.666667a117.333333 117.333333 0 0 1 117.248 112.618667L917.333333 330.666667v320a117.333333 117.333333 0 0 1-112.618666 117.248L800 768H789.333333v10.666667a117.333333 117.333333 0 0 1-117.333333 117.333333h-320a117.333333 117.333333 0 0 1-117.333333-117.333333V768h-10.666667a117.333333 117.333333 0 0 1-117.248-112.618667L106.666667 650.666667v-320a117.333333 117.333333 0 0 1 112.618666-117.248L224 213.333333h10.666667V181.333333a74.666667 74.666667 0 0 1 70.570666-74.56L309.333333 106.666667h405.333334z m-42.666667 490.666666h-320a53.333333 53.333333 0 0 0-53.333333 53.333334v128a53.333333 53.333333 0 0 0 53.333333 53.333333h320a53.333333 53.333333 0 0 0 53.333333-53.333333v-128a53.333333 53.333333 0 0 0-53.333333-53.333334z m128-320h-576a53.333333 53.333333 0 0 0-53.226667 49.834667L170.666667 330.666667v320a53.333333 53.333333 0 0 0 49.834666 53.226666L224 704h10.666667v-53.333333a117.333333 117.333333 0 0 1 117.333333-117.333334h320a117.333333 117.333333 0 0 1 117.333333 117.333334V704h10.666667a53.333333 53.333333 0 0 0 53.226667-49.834667L853.333333 650.666667v-320a53.333333 53.333333 0 0 0-49.834666-53.226667L800 277.333333z m-42.666667 64a32 32 0 0 1 0 64h-42.666666a32 32 0 0 1 0-64h42.666666z m-42.666666-170.666666h-405.333334a10.666667 10.666667 0 0 0-10.496 8.746666L298.666667 181.333333V213.333333h426.666666V181.333333a10.666667 10.666667 0 0 0-8.746666-10.496L714.666667 170.666667z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M672 640a53.333333 53.333333 0 0 1 53.333333 53.333333v128a53.333333 53.333333 0 0 1-53.333333 53.333334h-320a53.333333 53.333333 0 0 1-53.333333-53.333334v-128a53.333333 53.333333 0 0 1 53.333333-53.333333h320z m42.666667-490.666667a74.666667 74.666667 0 0 1 74.56 70.570667L789.333333 224V256h10.666667a117.333333 117.333333 0 0 1 117.248 112.618667L917.333333 373.333333v320a117.333333 117.333333 0 0 1-112.618666 117.248L800 810.666667H789.333333v-117.333334a117.333333 117.333333 0 0 0-117.333333-117.333333h-320a117.333333 117.333333 0 0 0-117.333333 117.333333V810.666667h-10.666667a117.333333 117.333333 0 0 1-117.248-112.618667L106.666667 693.333333v-320a117.333333 117.333333 0 0 1 112.618666-117.248L224 256h10.666667v-32a74.666667 74.666667 0 0 1 70.570666-74.56L309.333333 149.333333h405.333334z m42.666666 234.666667h-42.666666a32 32 0 0 0-3.072 63.850667L714.666667 448h42.666666a32 32 0 0 0 0-64z m-42.666666-170.666667h-405.333334a10.666667 10.666667 0 0 0-10.496 8.746667L298.666667 224V256h426.666666v-32a10.666667 10.666667 0 0 0-8.746666-10.496L714.666667 213.333333z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M889.287111 219.420444h-178.005333V154.737778a97.28 97.28 0 0 0-96.995556-96.711111h-193.991111a97.28 97.28 0 0 0-96.995555 96.711111v64.682666H145.464889a32.312889 32.312889 0 0 0-32.312889 32.312889 32.312889 32.312889 0 0 0 32.312889 32.369778h48.469333v517.290667a129.706667 129.706667 0 0 0 129.308445 129.308444h387.982222a129.706667 129.706667 0 0 0 129.308444-129.308444V284.103111h48.469334a32.369778 32.369778 0 0 0 32.369777-32.369778 32.312889 32.312889 0 0 0-32.369777-32.312889zM388.152889 154.737778a32.426667 32.426667 0 0 1 32.312889-32.312889h193.991111a32.426667 32.426667 0 0 1 32.312889 32.312889v64.682666H388.152889z m387.982222 646.599111a64.853333 64.853333 0 0 1-64.682667 64.682667h-387.982222a64.910222 64.910222 0 0 1-64.682666-64.682667V284.046222h517.290666zM420.750222 413.411556a32.426667 32.426667 0 0 0-32.312889 32.312888v258.616889a32.312889 32.312889 0 0 0 32.369778 32.312889 32.312889 32.312889 0 0 0 32.312889-32.312889V445.724444a32.426667 32.426667 0 0 0-32.312889-32.312888z m193.991111 0a32.426667 32.426667 0 0 0-32.312889 32.312888v258.616889a32.312889 32.312889 0 0 0 32.369778 32.312889 32.312889 32.312889 0 0 0 32.312889-32.312889V445.724444a32.426667 32.426667 0 0 0-32.312889-32.312888z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M502.016 789.333333l37.056 64H96a32 32 0 0 1 0-64h406.016zM512 149.333333a106.666667 106.666667 0 0 1 105.770667 120.597334 406.122667 406.122667 0 0 1 240.384 180.416 72.981333 72.981333 0 0 0-27.562667-5.397334h-210.517333c-26.090667 0-50.197333 13.866667-63.253334 36.416l-95.488 164.906667a72.64 72.64 0 0 0 0 72.810667l3.626667 6.250666H96a32 32 0 0 1 0-64H106.666667c0-187.264 126.997333-344.874667 299.584-391.402666A106.666667 106.666667 0 0 1 512 149.333333z m0 64a42.666667 42.666667 0 0 0-42.602667 44.864 411.584 411.584 0 0 1 85.184 0L554.666667 256a42.666667 42.666667 0 0 0-42.666667-42.666667z" /><path d="M802.496 490.666667c21.077333 0 40.554667 11.2 51.114667 29.397333l77.141333 133.205333a58.645333 58.645333 0 0 1 0 58.794667l-77.141333 133.205333A59.050667 59.050667 0 0 1 802.496 874.666667h-154.325333a59.050667 59.050667 0 0 1-51.114667-29.397334l-77.141333-133.205333a58.645333 58.645333 0 0 1 0-58.794667l77.141333-133.205333A59.050667 59.050667 0 0 1 648.170667 490.666667zM725.333333 618.666667a64 64 0 1 0 0 128 64 64 0 0 0 0-128z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M219.093333 197.717333l-2.986666 3.2c-1.898667 2.24-3.626667 4.608-5.141334 7.125334l-0.938666 1.514666 1.984-2.432a172.8 172.8 0 0 0-28.586667 47.488C139.114667 365.589333 214.037333 546.133333 348.821333 680.533333c108.693333 108.373333 262.4 194.176 362.24 194.133334 28.757333 0 55.68-4.714667 79.786667-14.314667 22.549333-8.917333 42.154667-21.482667 58.133333-37.418667l30.848-30.762666a54.976 54.976 0 0 0 0-77.824l-141.696-141.226667-2.986666-2.773333a55.082667 55.082667 0 0 0-74.816 2.816l-48.768 48.64-5.077334 0.042666c-35.221333-0.725333-74.794667-21.738667-118.72-65.514666l-5.610666-5.696c-40.085333-41.493333-59.306667-79.04-59.84-112.704l0.042666-5.077334 48.512-48.384a54.869333 54.869333 0 0 0 0-77.824L329.344 165.546667a54.997333 54.997333 0 0 0-77.994667 0L219.093333 197.717333z m49.152 47.018667l22.101334-22.058667 123.242666 122.88-42.282666 42.24a56.661333 56.661333 0 0 0-16.426667 35.264c-5.162667 60.437333 24.213333 120.96 84.885333 181.418667 60.586667 60.373333 121.045333 89.749333 181.312 84.906667l4.416-0.554667a56.682667 56.682667 0 0 0 31.04-15.829333l42.730667-42.624 123.306667 122.88-21.589334 21.525333c-9.258667 9.216-20.992 16.746667-35.2 22.357333-15.829333 6.293333-34.218667 9.536-54.72 9.536-78.314667 0.021333-217.024-77.44-314.176-174.293333-117.653333-117.290667-182.165333-272.725333-150.293333-352.576 3.328-8.341333 7.722667-16.170667 13.162667-23.488l5.909333-7.509333 1.493333-2.24 1.088-1.834667z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M197.76 197.717333l-2.986667 3.2c-1.898667 2.24-3.626667 4.608-5.141333 7.125334l-0.938667 1.514666 1.984-2.432a172.8 172.8 0 0 0-28.586666 47.488C117.781333 365.589333 192.704 546.133333 327.488 680.533333c108.693333 108.373333 262.4 194.176 362.24 194.133334 28.757333 0 55.68-4.714667 79.786667-14.314667 22.549333-8.917333 42.154667-21.482667 58.133333-37.418667l30.848-30.762666a54.976 54.976 0 0 0 0-77.824l-141.696-141.226667-2.986667-2.773333a55.082667 55.082667 0 0 0-74.816 2.816l-48.768 48.64-5.077333 0.042666c-35.221333-0.725333-74.794667-21.738667-118.72-65.514666l-5.610667-5.696c-40.085333-41.493333-59.306667-79.04-59.84-112.704l0.042667-5.077334 48.512-48.384a54.869333 54.869333 0 0 0 0-77.824L308.010667 165.546667a54.997333 54.997333 0 0 0-77.994667 0L197.76 197.717333z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 65C264.6 65 64 265.6 64 513.1a448.9 448.9 0 0 0 19.2 130.3c28.8 43.7 88.5 57.2 124.8 64.8 198 41 235 20 348.8 250.8C783.2 936.5 960 745.5 960 513.1 960 265.6 759.4 65 512 65z m278.1 701.3a375.3 375.3 0 0 1-193 113.2c-17.2-32.3-32.6-58.4-47.3-80.2-24.6-36.2-48.6-62.6-75.8-83.2s-54.6-33.6-90.4-44.4c-29.3-8.8-61.4-14.9-98.6-21.9-19.5-3.7-39.7-7.4-62.4-12.1-16.4-3.4-35.3-7.7-51.7-14.6-9.6-4.1-17.2-8.7-22.4-13.4a377.6 377.6 0 0 1-12.5-96.6 376 376 0 1 1 725.9 138.1 377.6 377.6 0 0 1-71.8 115.1zM512 208a48 48 0 1 0 48 48 48 48 0 0 0-48-48z m-181 75a48 48 0 1 0 0 96 48 48 0 1 0 0-96z m-75 181a48 48 0 1 0 48 48 48 48 0 0 0-48-48z m437 157a72 72 0 1 0 50.9 21.1A71.5 71.5 0 0 0 693 621z m75-157a48 48 0 1 0 48 48 48 48 0 0 0-48-48z m-75-85a48.1 48.1 0 1 0-33.9-14.1A47.9 47.9 0 0 0 693 379z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M377.258667 597.333333c39.68 28.437333 84.608 42.666667 134.741333 42.666667 7.914667 0 15.701333-0.362667 23.36-1.066667-22.314667 41.6-34.026667 87.637333-34.026667 130.581334 0 65.834667 25.173333 114.752 67.477334 147.84L238.037333 917.333333a85.333333 85.333333 0 0 1-85.333333-85.333333V618.666667c29.930667 14.229333 59.882667 21.333333 89.813333 21.333333 29.952 0 74.88-14.229333 134.741334-42.666667zM746.666667 469.333333c58.901333 0 106.666667 28.650667 106.666666 64 0 15.786667-9.514667 30.208-25.28 41.386667C897.813333 611.541333 938.666667 693.376 938.666667 768c0 100.138667-85.973333 149.333333-192 149.333333s-192-49.194667-192-149.333333c0-74.602667 40.832-156.437333 110.613333-193.344C649.493333 563.562667 640 549.12 640 533.333333c0-35.349333 47.765333-64 106.666667-64z m-38.378667 171.989334l-2.026667 0.938666-0.981333 0.554667-1.024 0.64a14.613333 14.613333 0 0 0-5.056 18.389333l1.066667 1.877334 12.757333 19.008H688a16 16 0 0 0-2.176 31.850666l2.176 0.149334h42.666667v21.312h-32a16 16 0 0 0-2.176 31.850666l2.176 0.149334 32-0.021334v37.312a16 16 0 0 0 31.850666 2.176l0.149334-2.176V768l32 0.042667a16 16 0 0 0 2.176-31.850667l-2.176-0.149333h-32v-21.333334l42.666666 0.021334a16 16 0 0 0 2.176-31.829334l-2.176-0.149333h-25.045333l12.778667-19.029333 1.066666-1.877334a14.634667 14.634667 0 0 0-3.2-16.896l-1.856-1.493333-1.024-0.64-0.981333-0.554667-2.026667-0.938666a16 16 0 0 0-17.536 4.053333l-1.536 1.941333-19.328 28.8-19.285333-28.8a16 16 0 0 0-19.072-5.994666zM811.413333 106.666667c57.216 0 104.981333 40.789333 111.530667 94.293333l0.469333 4.608 13.632 199.573333a144.042667 144.042667 0 0 1-31.637333 113.408C895.488 460.736 828.16 416 746.666667 416c-88.362667 0-160 52.522667-160 117.333333 0 7.893333 1.066667 15.637333 3.114666 23.125334-19.754667 10.730667-42.24 17.493333-66.197333 19.136l-6.186667 0.32L512 576c-53.973333 0-101.632-25.856-129.92-65.258667l-3.2-4.608-1.621333-2.538666-1.621334 2.56c-25.898667 39.04-70.314667 65.92-121.536 69.44l-6.186666 0.32-5.397334 0.085333C155.733333 576 85.333333 509.141333 85.333333 426.666667c0-5.930667 0.362667-11.84 1.002667-16.853334l0.512-3.626666 13.738667-200.597334c4.16-54.208 50.474667-96.512 107.114666-98.816L212.586667 106.666667h598.826666z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M768 85.333333a85.333333 85.333333 0 0 1 85.333333 85.333334v768a42.666667 42.666667 0 0 1-42.56-39.466667L810.666667 896a42.666667 42.666667 0 0 0-85.226667-3.2L725.333333 896a42.666667 42.666667 0 0 1-85.226666 3.2L640 896a42.666667 42.666667 0 0 0-85.226667-3.2L554.666667 896a42.666667 42.666667 0 0 1-85.226667 3.2L469.333333 896a42.666667 42.666667 0 0 0-85.226666-3.2L384 896a42.666667 42.666667 0 0 1-85.226667 3.2L298.666667 896a42.666667 42.666667 0 0 0-85.226667-3.2L213.333333 896a42.666667 42.666667 0 0 1-39.466666 42.56L170.666667 938.666667V170.666667a85.333333 85.333333 0 0 1 85.333333-85.333334h512z m-53.333333 469.333334h-405.333334a32 32 0 0 0 0 64h405.333334a32 32 0 0 0 0-64z m0-234.666667h-405.333334a32 32 0 0 0 0 64h405.333334a32 32 0 0 0 0-64z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M928 789.333333a32 32 0 0 1 0 64h-832a32 32 0 0 1 0-64h832zM512 149.333333a106.666667 106.666667 0 0 1 105.770667 120.597334c170.346667 45.930667 296.298667 200.106667 299.52 384.213333L917.333333 661.333333h10.666667a32 32 0 0 1 0 64h-832a32 32 0 0 1 0-64H106.666667c0-187.264 126.997333-344.874667 299.584-391.402666A106.666667 106.666667 0 0 1 512 149.333333z m0 64a42.666667 42.666667 0 0 0-42.602667 44.864 411.584 411.584 0 0 1 85.184 0L554.666667 256a42.666667 42.666667 0 0 0-42.666667-42.666667z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M810.666667 85.333333a85.333333 85.333333 0 0 1 85.333333 85.333334v682.666666a85.333333 85.333333 0 0 1-85.333333 85.333334H213.333333a85.333333 85.333333 0 0 1-85.333333-85.333334V170.666667a85.333333 85.333333 0 0 1 85.333333-85.333334h597.333334z m0 64H213.333333a21.333333 21.333333 0 0 0-21.184 18.837334L192 170.666667v682.666666a21.333333 21.333333 0 0 0 18.837333 21.184L213.333333 874.666667h597.333334a21.333333 21.333333 0 0 0 21.184-18.837334L832 853.333333V170.666667a21.333333 21.333333 0 0 0-18.837333-21.184L810.666667 149.333333z m-117.333334 362.666667a32 32 0 0 1 0 64h-362.666666a32 32 0 0 1 0-64h362.666666z m-170.666666-170.666667a32 32 0 0 1 0 64h-192a32 32 0 0 1 0-64h192z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M789.333333 106.666667a85.333333 85.333333 0 0 1 85.333334 85.333333v640a85.333333 85.333333 0 0 1-85.333334 85.333333H277.333333a85.333333 85.333333 0 0 1-85.333333-85.333333v-64a42.666667 42.666667 0 1 1 0-85.333333v-128a42.666667 42.666667 0 1 1 0-85.333334v-128a42.666667 42.666667 0 1 1 0-85.333333V192a85.333333 85.333333 0 0 1 85.333333-85.333333h512z m-74.666666 426.666666h-362.666667a32 32 0 0 0 0 64h362.666667a32 32 0 0 0 0-64z m-170.666667-170.666666h-192a32 32 0 0 0 0 64h192a32 32 0 0 0 0-64z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M810.666667 85.333333a85.333333 85.333333 0 0 1 85.333333 85.333334v682.666666a85.333333 85.333333 0 0 1-85.333333 85.333334H213.333333a85.333333 85.333333 0 0 1-85.333333-85.333334V170.666667a85.333333 85.333333 0 0 1 85.333333-85.333334h597.333334z m-117.333334 426.666667h-362.666666a32 32 0 0 0 0 64h362.666666a32 32 0 0 0 0-64z m-170.666666-170.666667h-192a32 32 0 0 0 0 64h192a32 32 0 0 0 0-64z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 85.333333c188.373333 0 341.333333 150.250667 341.333333 335.914667 0 108.032-82.453333 263.402667-246.293333 471.274667a120.96 120.96 0 0 1-190.144-0.064l-16.746667-21.44C247.509333 673.92 170.666667 525.568 170.666667 421.248 170.666667 235.584 323.626667 85.333333 512 85.333333z m0 64c-153.322667 0-277.333333 121.642667-277.333333 271.36 0 87.296 74.816 229.717333 225.472 422.250667l8.32 10.624a55.445333 55.445333 0 0 0 87.061333 0C711.744 655.637333 789.333333 509.632 789.333333 420.693333 789.333333 270.954667 665.322667 149.333333 512 149.333333z m0 128a128 128 0 1 1 0 256 128 128 0 0 1 0-256z m0 64a64 64 0 1 0 0 128 64 64 0 0 0 0-128z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 85.333333c188.373333 0 341.333333 150.250667 341.333333 335.914667 0 108.032-82.453333 263.402667-246.293333 471.274667a120.96 120.96 0 0 1-190.144-0.064l-16.746667-21.44C247.509333 673.92 170.666667 525.568 170.666667 421.248 170.666667 235.584 323.626667 85.333333 512 85.333333z m0 192a128 128 0 1 0 0 256 128 128 0 0 0 0-256z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M224 554.666667a32 32 0 0 1 3.072 63.850666L224 618.666667h-21.333333a10.666667 10.666667 0 0 0-10.496 8.746666L192 629.333333v192a53.333333 53.333333 0 0 0 49.834667 53.226667L245.333333 874.666667h533.333334a53.333333 53.333333 0 0 0 53.226666-49.834667L832 821.333333v-192a10.666667 10.666667 0 0 0-8.746667-10.496L821.333333 618.666667h-21.333333a32 32 0 0 1-3.072-63.850667L800 554.666667h21.333333a74.666667 74.666667 0 0 1 74.56 70.570666L896 629.333333v192a117.333333 117.333333 0 0 1-112.618667 117.248L778.666667 938.666667h-533.333334a117.333333 117.333333 0 0 1-117.248-112.618667L128 821.333333v-192a74.666667 74.666667 0 0 1 70.570667-74.56L202.666667 554.666667h21.333333zM512 85.333333c153.045333 0 277.333333 123.946667 277.333333 277.12 0 89.130667-66.986667 217.322667-200.106666 388.821334a99.285333 99.285333 0 0 1-16.213334 16.512 97.28 97.28 0 0 1-138.282666-16.576l-13.610667-17.706667C297.088 570.944 234.666667 448.533333 234.666667 362.496 234.666667 209.28 358.954667 85.333333 512 85.333333z m0 64c-117.930667 0-213.333333 96.597333-213.333333 215.488 0 69.333333 57.536 182.421333 173.44 335.317334l6.4 8.426666a41.749333 41.749333 0 0 0 59.946666 7.274667c2.602667-2.133333 4.970667-4.565333 7.04-7.253333C665.642667 551.36 725.333333 435.413333 725.333333 364.8 725.333333 245.930667 629.930667 149.333333 512 149.333333z m0 106.666667a106.666667 106.666667 0 1 1 0 213.333333 106.666667 106.666667 0 0 1 0-213.333333z m0 64a42.666667 42.666667 0 1 0 0 85.333333 42.666667 42.666667 0 0 0 0-85.333333z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M393.173333 785.685333l17.792 21.44c44.096 52.672 125.013333 61.632 180.8 20.074667 7.893333-5.866667 14.997333-12.586667 21.226667-20.010667 79.509333-94.954667 141.013333-178.986667 184.32-252.501333L821.333333 554.666667a74.666667 74.666667 0 0 1 74.56 70.570666L896 629.333333v192a117.333333 117.333333 0 0 1-112.618667 117.248L778.666667 938.666667h-533.333334a117.333333 117.333333 0 0 1-117.248-112.618667L128 821.333333v-192a74.666667 74.666667 0 0 1 70.570667-74.56L202.666667 554.666667h24.021333c40.021333 67.946667 95.552 144.832 166.464 231.018666zM512 85.333333c153.045333 0 277.333333 123.946667 277.333333 277.12 0 89.130667-66.986667 217.322667-200.106666 388.821334a99.285333 99.285333 0 0 1-16.213334 16.512 97.28 97.28 0 0 1-138.282666-16.576l-13.610667-17.706667C297.088 570.944 234.666667 448.533333 234.666667 362.496 234.666667 209.28 358.954667 85.333333 512 85.333333z m0 170.666667a106.666667 106.666667 0 1 0 0 213.333333 106.666667 106.666667 0 0 0 0-213.333333z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M789.333333 106.666667a85.333333 85.333333 0 0 1 85.333334 85.333333v640a85.333333 85.333333 0 0 1-85.333334 85.333333H277.333333a85.333333 85.333333 0 0 1-85.333333-85.333333v-64a42.666667 42.666667 0 1 1 0-85.333333v-128a42.666667 42.666667 0 1 1 0-85.333334v-128a42.666667 42.666667 0 1 1 0-85.333333V192a85.333333 85.333333 0 0 1 85.333333-85.333333h512zM473.109333 371.456a32 32 0 0 0-44.074666 0l-0.832 0.789333a29.952 29.952 0 0 0 0 43.456l40.085333 38.08h-32.213333a30.72 30.72 0 0 0 0 61.44h66.282666v40.96h-44.736a30.72 30.72 0 1 0 0 61.461334h44.736v49.92a32 32 0 0 0 32 32h0.704a32 32 0 0 0 32-32l-0.021333-49.92h44.757333a30.72 30.72 0 0 0 0-61.44l-44.757333-0.021334v-40.96h66.325333a30.72 30.72 0 0 0 0-61.44h-37.034666l40.106666-38.08 2.112-2.218666a29.973333 29.973333 0 0 0-2.133333-41.237334l-0.810667-0.789333-2.389333-2.048a32 32 0 0 0-41.685333 2.048l-59.221334 56.234667z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M513.557333 85.333333a428.266667 428.266667 0 0 1 362.624 199.616l4.416 7.146667c23.893333 39.466667-15.445333 68.757333-348.416 296.213333a33.024 33.024 0 0 1-45.781333-8.533333 32.746667 32.746667 0 0 1 8.533333-45.610667l55.317334-37.930666c88.042667-60.629333 155.456-108.352 202.154666-143.104l17.92-13.461334c14.869333-11.306667 26.922667-20.864 36.117334-28.565333l5.162666-4.458667-0.533333-0.789333A362.282667 362.282667 0 0 0 521.749333 151.04l-8.192-0.085333c-200.106667 0-362.346667 161.642667-362.346666 361.024 0 199.381333 162.24 361.024 362.346666 361.024 82.922667 0 161.493333-27.797333 225.066667-78.08a33.024 33.024 0 0 1 46.293333 5.333333c11.306667 14.186667 8.917333 34.837333-5.333333 46.101333A427.477333 427.477333 0 0 1 513.557333 938.666667C277.056 938.666667 85.333333 747.648 85.333333 512S277.056 85.333333 513.557333 85.333333z m401.28 433.514667a32.853333 32.853333 0 0 1 22.528 40.661333c-6.016 20.757333-16.512 40.256-30.997333 58.069334a33.002667 33.002667 0 0 1-46.336 4.821333 32.746667 32.746667 0 0 1-4.885333-46.165333c9.109333-11.2 15.402667-22.890667 18.901333-34.986667a32.917333 32.917333 0 0 1 40.789333-22.4z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M682.773333 128a152.576 152.576 0 0 1 130.645334 73.749333L947.882667 424.533333a76.288 76.288 0 0 1-12.288 94.250667l-369.706667 357.44a76.288 76.288 0 0 1-107.136-1.066667L87.338667 501.354667a76.288 76.288 0 0 1-10.197334-94.784l132.565334-208A152.576 152.576 0 0 1 338.389333 128h344.384z m-172.330666 149.333333a188.714667 188.714667 0 0 0-103.594667 30.997334 190.72 190.72 0 0 0-82.624 121.088 191.957333 191.957333 0 0 0 26.581333 144.490666A189.610667 189.610667 0 0 0 510.72 661.333333a187.904 187.904 0 0 0 100.949333-29.312c1.088-0.576 1.984-1.066667 2.816-1.6a17.6 17.6 0 0 0 1.92-1.408l0.213334-0.149333a192.704 192.704 0 0 0 11.2-8.192 12.16 12.16 0 0 0 3.392-14.72 2.389333 2.389333 0 0 0-0.234667-0.597333l-0.170667-0.213334-0.362666-0.682666-7.914667-12.650667a27.370667 27.370667 0 0 0-36.992-8.704h-0.021333l-0.597334 0.384a3.498667 3.498667 0 0 0-0.490666 0.277333 3.626667 3.626667 0 0 0-0.725334 0.533334 134.848 134.848 0 0 1-186.752-40.576 136.533333 136.533333 0 0 1-18.901333-102.762667 135.765333 135.765333 0 0 1 58.752-86.122667 134.08 134.08 0 0 1 73.642667-22.037333c32.853333 0 64.533333 11.946667 89.173333 33.6a8.682667 8.682667 0 0 1 2.816 5.546667 7.338667 7.338667 0 0 1-3.541333 6.592l-116.821334 76.437333a27.52 27.52 0 0 0-11.946666 17.493333c-1.536 7.253333-0.149333 14.634667 3.84 20.864l8.384 13.013334a12.117333 12.117333 0 0 0 16.789333 3.562666l172.16-112.64c4.650667-3.328 6.741333-8.618667 6.464-14.4-0.341333-7.68-4.693333-13.973333-7.338667-18.090666a189.717333 189.717333 0 0 0-160-87.445334z m167.04 186.026667a13.717333 13.717333 0 0 0-7.509334 2.24l-30.122666 19.733333-0.704 0.469334a13.845333 13.845333 0 0 0-5.269334 8.32 13.952 13.952 0 0 0 1.92 10.453333l19.541334 30.357333 0.512 0.725334a13.76 13.76 0 0 0 18.602666 3.349333l15.061334-9.834667 1.002666-0.682666c6.570667-4.650667 11.093333-11.562667 12.778667-19.52 1.770667-8.362667 0.213333-16.938667-4.416-24.106667l-9.770667-15.146667-0.512-0.746666a13.824 13.824 0 0 0-11.093333-5.632z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M561.621333 174.186667c76.736 6.848 152.042667 19.925333 212.714667 76.778666 20.565333 19.242667 93.141333 2.688 101.44 1.344 20.096-3.221333 53.866667-18.88 61.354667 18.922667 6.442667 32.533333-7.530667 60.416-38.890667 75.904-7.722667 3.84-16.384 8.064-24.618667 8.106667-30.549333 0.128-27.349333 14.997333-18.624 36.245333 22.293333 54.293333 36.266667 110.976 45.290667 169.088 19.434667 125.397333-53.397333 230.826667-177.322667 254.250667-69.973333 13.226667-140.714667 19.242667-211.989333 16.533333-71.317333 2.688-142.037333-3.498667-211.946667-17.024-121.002667-23.402667-193.6-129.408-174.72-252.309333 9.173333-59.584 23.424-117.696 46.677334-173.226667 8.746667-20.906667 8.192-31.701333-18.282667-33.578667-18.645333-1.322667-37.12-8.874667-48.96-25.365333-14.016-19.562667-24.469333-41.728-14.421333-65.557333 11.093333-26.368 36.181333-15.722667 53.824-12.202667 56.256 11.242667 101.994667 1.834667 153.173333-31.808 78.506667-51.626667 173.248-54.293333 265.301333-46.08z m-175.36 139.157333c-108.373333 8.789333-165.333333 49.642667-203.2 187.690667-5.717333 20.821333-8.96 42.602667-11.050666 64.149333-9.493333 96.789333 23.872 149.461333 114.645333 181.610667 72.234667 25.578667 147.285333 30.186667 222.976 28.928 80.405333 1.749333 160.021333-3.498667 236.48-31.36 55.552-20.245333 99.2-54.506667 105.109333-117.717334 8.661333-92.821333-11.882667-179.136-71.082666-253.226666-19.882667-24.853333-45.909333-40.661333-77.12-48-104.853333-24.725333-210.56-20.693333-316.757334-12.074667z m304.810667 31.68c29.269333 6.698667 53.653333 21.077333 72.298667 43.669333 55.488 67.349333 74.752 145.813333 66.624 230.186667-5.525333 57.472-46.464 88.64-98.538667 107.029333-71.68 25.322667-146.304 30.08-221.696 28.501334-70.954667 1.152-141.312-3.050667-209.024-26.304-85.12-29.226667-116.394667-77.098667-107.498667-165.077334 1.962667-19.605333 5.013333-39.402667 10.368-58.346666 35.477333-125.482667 88.874667-162.624 190.506667-170.624 99.541333-7.829333 198.656-11.477333 296.96 10.965333z m-318.101333 125.205333c-19.264 0-34.88 15.594667-34.88 34.858667v62.421333a34.858667 34.858667 0 1 0 69.738666 0v-62.421333c0-19.264-15.616-34.858667-34.858666-34.858667z m278.912 0c-19.264 0-34.88 15.594667-34.88 34.858667v62.421333a34.858667 34.858667 0 1 0 69.738666 0v-62.421333c0-19.264-15.616-34.858667-34.858666-34.858667zM510.144 213.333333c2.090667 27.797333-9.6 44.096-40.810667 54.613334 30.314667 14.613333 46.826667 12.074667 58.154667-6.954667 11.2-18.816 6.4-34.133333-17.344-47.658667z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M725.333333 128a170.666667 170.666667 0 0 1 170.666667 170.666667v426.666666a170.666667 170.666667 0 0 1-170.666667 170.666667H298.666667a170.666667 170.666667 0 0 1-170.666667-170.666667V298.666667a170.666667 170.666667 0 0 1 170.666667-170.666667h426.666666z m-94.72 308.330667H192c0.277333 1.984 3.264 18.368 24.426667 21.44 44.842667 6.528 110.144 14.101333 153.856 40.533333 39.146667 23.68 56.064 59.072 47.04 114.730667C410.837333 652.928 393.813333 704 393.813333 704c87.850667 0 161.493333-69.44 193.002667-150.272a5850.56 5850.56 0 0 0 43.776-117.397333zM832 320h-199.893333l-5.866667 0.085333c-66.154667 2.005333-127.296 37.76-146.304 97.472h155.093333l1.194667-3.072c0.746667-1.898667 1.429333-3.541333 2.24-5.333333 21.482667-48.618667 59.157333-70.208 114.389333-75.349333 23.466667-2.176 45.994667-3.733333 59.989334-5.013334 10.346667-0.938667 17.28-1.813333 19.157333-8.789333z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M490.666667 128a31.146667 31.146667 0 0 1 2.986666 62.122667L490.666667 190.293333H242.154667a51.904 51.904 0 0 0-51.776 48.469334l-0.106667 3.413333V781.866667a51.904 51.904 0 0 0 48.469333 51.776l3.413334 0.106666H781.866667a51.904 51.904 0 0 0 51.776-48.469333l0.106666-3.413333V533.333333a31.146667 31.146667 0 0 1 62.122667-2.986666L896 533.333333v248.512a114.154667 114.154667 0 0 1-109.568 114.069334l-4.586667 0.085333H242.133333a114.154667 114.154667 0 0 1-114.069333-109.568L128 781.845333V242.133333a114.154667 114.154667 0 0 1 109.568-114.069333L242.154667 128H490.666667z m291.178666 0a114.154667 114.154667 0 0 1 114.069334 109.568l0.085333 4.586667v145.301333a31.146667 31.146667 0 0 1-62.122667 2.986667l-0.149333-2.986667v-145.28c0-2.496-0.170667-4.949333-0.512-7.338667L471.744 596.266667a31.146667 31.146667 0 0 1-46.165333-41.664l2.133333-2.368L789.184 190.784a52.074667 52.074667 0 0 0-3.925333-0.405333l-3.413334-0.106667h-145.301333a31.146667 31.146667 0 0 1-2.986667-62.122667l2.986667-0.149333h145.28z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 85.333333c235.648 0 426.666667 191.018667 426.666667 426.666667s-191.018667 426.666667-426.666667 426.666667S85.333333 747.648 85.333333 512 276.352 85.333333 512 85.333333z m0 64C311.701333 149.333333 149.333333 311.701333 149.333333 512s162.368 362.666667 362.666667 362.666667 362.666667-162.368 362.666667-362.666667S712.298667 149.333333 512 149.333333z m98.389333 173.290667l2.88 1.429333 2.816 1.578667a28.266667 28.266667 0 0 1 10.730667 38.784l-1.578667 2.432-43.242666 59.968h68.693333a32 32 0 1 1 0 64l-106.688-0.021333v63.957333h85.333333a32 32 0 1 1 0 64l-85.333333-0.021333V714.666667a32 32 0 0 1-64 0v-95.936h-85.333333a32 32 0 1 1 0-63.957334l85.333333-0.021333v-63.957333h-106.666667a32 32 0 1 1 0-63.957334l68.650667-0.021333-43.221333-59.968a28.266667 28.266667 0 0 1 9.152-41.216l2.816-1.578667a32 32 0 0 1 41.557333 9.237334l59.690667 82.816 59.733333-82.816a32 32 0 0 1 38.677333-10.666667z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 85.333333c235.648 0 426.666667 191.018667 426.666667 426.666667s-191.018667 426.666667-426.666667 426.666667S85.333333 747.648 85.333333 512 276.352 85.333333 512 85.333333z m98.389333 237.290667a32 32 0 0 0-38.677333 10.666667L512 416.106667l-59.690667-82.816a32 32 0 0 0-41.557333-9.237334l-2.816 1.578667a28.266667 28.266667 0 0 0-9.173333 41.216l43.242666 59.968h-68.672a32 32 0 1 0 0 64l106.688-0.021333v63.957333h-85.333333a32 32 0 1 0 0 64l85.333333-0.021333V714.666667a32 32 0 0 0 64 0v-95.936h85.333334a32 32 0 1 0 0-63.957334l-85.333334-0.021333v-63.957333h106.666667a32 32 0 1 0 0-63.957334l-68.672-0.021333 43.242667-59.968 1.578666-2.432a28.266667 28.266667 0 0 0-10.730666-38.784l-2.816-1.578667z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="64px" height="64.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M379.336 697.237L153.362 921.55c-14.11 14.007-36.905 13.922-50.912-0.188-14.007-14.11-13.922-36.905 0.188-50.912l227.6-225.927H138.645c-18.99 0-34.385-15.446-34.385-34.5 0-19.053 15.395-34.5 34.385-34.5H413.72c18.99 0 34.384 15.447 34.384 34.5v276c0 9.15-3.622 17.926-10.07 24.396a34.326 34.326 0 0 1-24.314 10.104 34.326 34.326 0 0 1-24.314-10.104 34.559 34.559 0 0 1-10.071-24.396V697.237z m263.395-366.88l227.813-227.813c14.059-14.059 36.853-14.059 50.912 0 14.059 14.059 14.059 36.853 0 50.912l-225.18 225.18h187.147c18.99 0 34.385 15.445 34.385 34.5 0 19.053-15.395 34.5-34.385 34.5H608.346c-18.99 0-34.384-15.447-34.384-34.5v-276c0-9.15 3.622-17.926 10.07-24.396a34.326 34.326 0 0 1 24.314-10.105c9.12 0 17.865 3.635 24.314 10.105a34.559 34.559 0 0 1 10.07 24.395v193.223zM99.385 410a34.326 34.326 0 0 1-24.314-10.105A34.559 34.559 0 0 1 65 375.5v-276C65 80.446 80.395 65 99.385 65h275.077c18.99 0 34.384 15.446 34.384 34.5 0 19.054-15.394 34.5-34.384 34.5H133.769v241.5c0 9.15-3.622 17.925-10.07 24.395A34.326 34.326 0 0 1 99.384 410z m825.23 552H649.538c-18.99 0-34.384-15.446-34.384-34.5 0-19.054 15.394-34.5 34.384-34.5h240.693V651.5c0-19.054 15.394-34.5 34.384-34.5 18.99 0 34.385 15.446 34.385 34.5v276c0 19.054-15.395 34.5-34.385 34.5z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="64px" height="64.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M924 616a36 36 0 0 0-36 36v236H652a36 36 0 0 0 0 72h272a36 36 0 0 0 36-36V652a36 36 0 0 0-36-36zM372 64H100a36 36 0 0 0-36 36v272a36 36 0 0 0 72 0V136h236a36 36 0 0 0 0-72zM924 64H652a36 36 0 0 0 0 72h185.09L626.54 346.54a36 36 0 1 0 50.92 50.91L888 186.91V372a36 36 0 0 0 72 0V100a36 36 0 0 0-36-36zM372 616a35.87 35.87 0 0 0-25.46 10.55L136 837.09V652a36 36 0 0 0-72 0v272a36 36 0 0 0 36 36h272a36 36 0 0 0 0-72H186.91l210.55-210.54A36 36 0 0 0 372 616z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M777.045333 128a85.333333 85.333333 0 0 1 85.205334 80.533333l33.6 597.333334A85.333333 85.333333 0 0 1 810.666667 896H213.333333a85.333333 85.333333 0 0 1-85.205333-90.133333l33.621333-597.333334A85.333333 85.333333 0 0 1 246.954667 128h530.090666zM682.666667 256a42.666667 42.666667 0 0 0-37.738667 62.528c-25.237333 56.768-72.789333 86.826667-132.928 86.826667-60.522667 0-107.882667-29.866667-132.949333-86.741334a42.666667 42.666667 0 1 0-63.36 14.165334C349.184 420.16 421.973333 469.333333 512 469.333333c89.642667 0 162.602667-49.408 196.266667-136.533333A42.666667 42.666667 0 0 0 682.666667 256z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M650.666667 277.333333h-405.333334A53.333333 53.333333 0 0 0 192 330.666667v490.666666a53.333333 53.333333 0 0 0 53.333333 53.333334h405.333334a53.333333 53.333333 0 0 0 53.333333-53.333334v-490.666666a53.333333 53.333333 0 0 0-53.333333-53.333334zM768 746.666667h10.666667a53.333333 53.333333 0 0 0 53.226666-49.834667L832 693.333333v-490.666666a53.333333 53.333333 0 0 0-49.834667-53.226667L778.666667 149.333333h-405.333334a53.333333 53.333333 0 0 0-53.226666 49.834667L320 202.666667v10.666666h330.666667a117.333333 117.333333 0 0 1 117.333333 117.333334V746.666667z m-181.333333-106.666667a32 32 0 0 1 0 64h-277.333334a32 32 0 0 1 0-64h277.333334z m0-192a32 32 0 0 1 0 64h-277.333334a32 32 0 0 1 0-64h277.333334zM768 821.333333a117.333333 117.333333 0 0 1-117.333333 117.333334h-405.333334A117.333333 117.333333 0 0 1 128 821.333333v-490.666666a117.333333 117.333333 0 0 1 117.333333-117.333334h10.666667v-10.666666a117.333333 117.333333 0 0 1 112.618667-117.248L373.333333 85.333333h405.333334a117.333333 117.333333 0 0 1 117.248 112.618667L896 202.666667v490.666666a117.333333 117.333333 0 0 1-112.618667 117.248L778.666667 810.666667H768z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M652.288 798.784l-190.4-119.466667-86.677333 86.058667 33.578666-118.485333 384.533334-395.989334-430.976 365.952-154.176-96.768 585.173333-269.184-141.056 547.882667z m-263.253333-429.376h92.16l-92.16 39.68v-39.68z m506.965333 0v-56.533333C896 210.261333 816.085333 128 715.2 128h-63.637333v168.064l-60.352 25.984V128H309.973333C209.066667 128 128 210.282667 128 312.874667v56.533333h146.346667v60.373333H128v282.197334C128 814.592 209.066667 896 309.973333 896h281.237334v-109.44l60.373333 38.464V896h63.616C816.085333 896 896 814.570667 896 711.978667V429.76h-129.194667l15.530667-60.352H896z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M256 448a64 64 0 1 1 0 128 64 64 0 0 1 0-128z m256 0a64 64 0 1 1 0 128 64 64 0 0 1 0-128z m256 0a64 64 0 1 1 0 128 64 64 0 0 1 0-128z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 704a64 64 0 1 1 0 128 64 64 0 0 1 0-128z m0-256a64 64 0 1 1 0 128 64 64 0 0 1 0-128z m0-256a64 64 0 1 1 0 128 64 64 0 0 1 0-128z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M880 310H732.4c13.6-21.4 21.6-46.8 21.6-74 0-76.1-61.9-138-138-138-41.4 0-78.7 18.4-104 47.4-25.3-29-62.6-47.4-104-47.4-76.1 0-138 61.9-138 138 0 27.2 7.9 52.6 21.6 74H144c-17.7 0-32 14.3-32 32v200c0 4.4 3.6 8 8 8h40v344c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V550h40c4.4 0 8-3.6 8-8V342c0-17.7-14.3-32-32-32z m-334-74c0-38.6 31.4-70 70-70s70 31.4 70 70-31.4 70-70 70h-70v-70z m-138-70c38.6 0 70 31.4 70 70v70h-70c-38.6 0-70-31.4-70-70s31.4-70 70-70zM180 482V378h298v104H180z m48 68h250v308H228V550z m568 308H546V550h250v308z m48-376H546V378h298v104z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M412.444444 335.815111z m70.940445 0" /><path d="M768.739556 595.399111l-1.536-1.422222z m45.511111-54.556444l3.299555 3.072c-1.251556-1.080889-2.218667-2.104889-3.470222-3.072z" /><path d="M540.046222 114.460444a212.423111 212.423111 0 1 0 212.423111 212.48 212.48 212.48 0 0 0-212.423111-212.48z m0 354.076445a141.653333 141.653333 0 1 1 141.596445-141.596445 141.596444 141.596444 0 0 1-141.596445 141.596445z" /><path d="M737.507556 521.443556l-3.413334-1.877334a396.686222 396.686222 0 0 0-590.506666 345.827556v6.769778a23.324444 23.324444 0 0 0 0 2.787555 35.441778 35.441778 0 1 0 70.826666-1.649778v-7.907555a325.802667 325.802667 0 0 1 485.489778-283.932445l2.104889 1.251556a35.441778 35.441778 0 0 0 36.295111-60.871111l-0.625778-0.398222z m112.071111 164.522666h-102.513778a30.378667 30.378667 0 0 0-30.378667 30.378667v2.218667a30.378667 30.378667 0 0 0 30.378667 30.378666h25.713778l-82.830223 82.830222-93.468444-93.468444a31.402667 31.402667 0 0 0-44.430222 0L436.337778 854.016a31.459556 31.459556 0 1 0 44.487111 44.544l93.468444-93.468444 93.468445 93.468444a31.630222 31.630222 0 0 0 44.544 0l105.073778-105.130667v25.713778a30.321778 30.321778 0 0 0 30.321777 30.321778h2.275556a30.264889 30.264889 0 0 0 30.321778-30.321778v-102.798222a30.321778 30.321778 0 0 0-30.321778-30.378667z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M796.444444 910.222222H227.555556a113.777778 113.777778 0 0 1-113.777778-113.777778V227.555556a113.777778 113.777778 0 0 1 113.777778-113.777778h568.888888a113.777778 113.777778 0 0 1 113.777778 113.777778v568.888888a113.777778 113.777778 0 0 1-113.777778 113.777778zM227.555556 182.044444a45.511111 45.511111 0 0 0-45.511112 45.511112v568.888888a45.511111 45.511111 0 0 0 45.511112 45.511112h568.888888a45.511111 45.511111 0 0 0 45.511112-45.511112V227.555556a45.511111 45.511111 0 0 0-45.511112-45.511112z" /><path d="M671.288889 270.222222a159.288889 159.288889 0 0 1-318.577778 0H284.444444a230.343111 230.343111 0 0 0 227.555556 227.555556c1.365333 0 2.616889-0.398222 3.925333-0.398222A230.001778 230.001778 0 0 0 739.555556 270.222222z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M137.493333 450.389333a32.256 32.256 0 0 1 45.866667 0L405.12 673.856a21.333333 21.333333 0 0 0 30.293333 0L840.64 265.6a32.256 32.256 0 0 1 45.866667 0 32.853333 32.853333 0 0 1 0 46.186667l-443.306667 446.656a32.256 32.256 0 0 1-45.845333 0L137.514667 496.597333a32.853333 32.853333 0 0 1 0-46.208z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M384 768a42.666667 42.666667 0 1 1 0 85.333333 42.666667 42.666667 0 0 1 0-85.333333z m341.333333 0a42.666667 42.666667 0 1 1 0 85.333333 42.666667 42.666667 0 0 1 0-85.333333zM188.352 128c33.685333 0 62.869333 23.253333 71.146667 56.064l0.896 3.989333 84.586666 430.4a52.778667 52.778667 0 0 0 47.914667 42.752l3.541333 0.128h331.733334c24.021333 0 44.8-16.533333 50.773333-39.872l0.789333-3.541333 53.098667-284.949333a10.666667 10.666667 0 0 0-8.362667-12.458667l-0.981333-0.149333-0.981333-0.042667H390.549333a31.744 31.744 0 0 1-31.488-32c0-16.64 12.48-30.293333 28.458667-31.850667l3.029333-0.149333h431.957334c4.586667 0 9.173333 0.426667 13.674666 1.301333 38.549333 7.424 64.32 44.16 59.157334 83.2l-0.64 4.053334-53.077334 284.949333c-10.026667 53.717333-55.104 93.056-108.416 95.402667l-5.034666 0.106666h-331.733334c-53.376 0-99.541333-37.12-112.128-89.408l-1.066666-4.949333L198.613333 200.576a10.581333 10.581333 0 0 0-8.448-8.405333L188.373333 192H159.488A31.744 31.744 0 0 1 128 160c0-16.64 12.48-30.293333 28.458667-31.850667L159.488 128h28.864z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 85.333333c235.648 0 426.666667 191.018667 426.666667 426.666667s-191.018667 426.666667-426.666667 426.666667S85.333333 747.648 85.333333 512 276.352 85.333333 512 85.333333z m0 64C311.701333 149.333333 149.333333 311.701333 149.333333 512s162.368 362.666667 362.666667 362.666667 362.666667-162.368 362.666667-362.666667S712.298667 149.333333 512 149.333333z m225.173333 201.578667a32.853333 32.853333 0 0 1 0 46.186667l-272.64 275.989333a32.256 32.256 0 0 1-45.845333 0l-131.84-133.824a32.853333 32.853333 0 0 1 0-46.208 32.256 32.256 0 0 1 45.845333 0l93.738667 95.296a21.333333 21.333333 0 0 0 30.165333 0.256l0.213334-0.213333 234.496-237.482667a32.256 32.256 0 0 1 45.866666 0z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 85.333333c235.648 0 426.666667 191.018667 426.666667 426.666667s-191.018667 426.666667-426.666667 426.666667S85.333333 747.648 85.333333 512 276.352 85.333333 512 85.333333z m225.173333 265.578667a32.256 32.256 0 0 0-45.866666 0L456.832 588.373333l-0.213333 0.213334a21.333333 21.333333 0 0 1-30.186667-0.256l-93.738667-95.296a32.256 32.256 0 0 0-45.866666 0 32.853333 32.853333 0 0 0 0 46.208l131.861333 133.824a32.256 32.256 0 0 0 45.866667 0l272.618666-275.989334a32.853333 32.853333 0 0 0 0-46.186666z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M844.330667 179.669333a30.72 30.72 0 0 1 0 43.456l-288.853334 288.853334 288.853334 288.896a30.72 30.72 0 1 1-43.456 43.456l-288.853334-288.896-288.896 288.896a30.72 30.72 0 1 1-43.456-43.456L468.565333 512 179.669333 223.146667a30.72 30.72 0 0 1 43.456-43.456L512 468.522667l288.853333-288.853334a30.72 30.72 0 0 1 43.456 0z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M804.224 106.666667c62.805333 0 115.029333 47.061333 119.978667 108.096l12.757333 178.496 0.832 6.101333c0.277333 2.752 0.512 5.525333 0.64 8.298667L938.666667 416c0 53.098667-26.517333 100.138667-67.349334 129.258667V800c0 63.210667-52.650667 114.773333-118.570666 117.248l-4.949334 0.085333H276.202667c-66.56 0-120.789333-50.005333-123.413334-112.618666l-0.085333-4.714667V545.258667C111.829333 516.138667 85.333333 469.098667 85.333333 416c0-8.469333 0.682667-16.853333 2.026667-25.130667l-0.213333 1.344 12.650666-177.450666c4.693333-57.770667 51.733333-103.04 110.016-107.690667l5.013334-0.298667 4.949333-0.106666z m-160.938667 405.312l-1.429333 1.898666a165.461333 165.461333 0 0 1-123.861333 62.016L512 576a165.589333 165.589333 0 0 1-129.856-62.122667l-1.450667-1.898666-1.408 1.898666a165.461333 165.461333 0 0 1-123.861333 62.016l-5.973333 0.106667c-10.026667 0-19.861333-0.874667-29.397334-2.56V800c0 28.266667 23.189333 51.413333 52.48 53.226667l3.669334 0.106666h471.594666c29.76 0 54.122667-22.016 56.021334-49.834666l0.106666-3.498667V573.44a169.173333 169.173333 0 0 1-29.354666 2.56 165.589333 165.589333 0 0 1-129.856-62.122667l-1.429334-1.898666zM804.224 170.666667H219.776C191.232 170.666667 167.466667 192.064 165.226667 219.797333l-12.736 178.581334-0.981334 7.466666a95.061333 95.061333 0 0 0-0.533333 10.154667c0 53.013333 44.074667 96 98.453333 96 42.069333 0 79.082667-25.962667 92.864-64 4.650667-12.778667 17.045333-21.333333 30.933334-21.333333h14.976c13.909333 0 26.304 8.554667 30.933333 21.333333 13.802667 38.037333 50.794667 64 92.864 64s79.061333-25.962667 92.864-64c4.629333-12.778667 17.024-21.333333 30.933333-21.333333h14.954667c13.909333 0 26.304 8.554667 30.933333 21.333333 13.802667 38.037333 50.816 64 92.885334 64 54.378667 0 98.453333-42.986667 98.453333-96 0-5.056-0.405333-10.069333-1.194667-14.976l-0.277333-2.410667-12.8-178.816C856.533333 192.064 832.789333 170.666667 804.245333 170.666667z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M871.296 832a85.333333 85.333333 0 0 1-85.333333 85.333333H238.037333a85.333333 85.333333 0 0 1-85.333333-85.333333V618.666667c29.930667 14.229333 59.882667 21.333333 89.813333 21.333333 29.952 0 74.88-14.229333 134.741334-42.666667 39.68 28.437333 84.608 42.666667 134.741333 42.666667 50.133333 0 95.061333-14.229333 134.741333-42.666667 60.501333 28.437333 105.408 42.666667 134.741334 42.666667 29.312 0 59.242667-7.104 89.813333-21.333333v213.333333zM811.413333 106.666667c58.858667 0 107.712 43.157333 112 98.901333l13.632 199.573333c1.066667 7.104 1.621333 14.293333 1.621334 21.525334 0 82.474667-70.378667 149.333333-157.184 149.333333-56.085333 0-105.28-27.882667-133.12-69.866667l-1.621334-2.538666-1.642666 2.56c-26.922667 40.597333-73.877333 68.032-127.701334 69.76L512 576c-56.064 0-105.28-27.882667-133.12-69.866667l-1.621333-2.538666-1.621334 2.56c-26.922667 40.597333-73.898667 68.032-127.701333 69.76l-5.418667 0.085333C155.733333 576 85.333333 509.141333 85.333333 426.666667c0-7.424 0.576-14.784 1.514667-20.48l13.738667-200.597334C104.874667 149.824 153.728 106.666667 212.586667 106.666667z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M298.986667 512c65.450667 0 118.506667 54.208 118.506666 121.088 0 52.138667-32.277333 96.597333-77.525333 113.642667 32.448 2.709333 64.917333 8.746667 97.365333 17.984 44.16 12.586667 74.666667 53.674667 74.666667 100.48v25.045333c0 26.752-21.226667 48.426667-47.402667 48.426667H132.736C106.56 938.666667 85.333333 916.992 85.333333 890.24v-25.024c0-46.826667 30.506667-87.893333 74.666667-100.48 32.64-9.322667 65.258667-15.36 97.877333-18.090667C212.693333 729.6 180.48 685.226667 180.48 633.088 180.48 566.186667 233.536 512 298.986667 512zM810.666667 106.666667a85.333333 85.333333 0 0 1 85.333333 85.333333v725.333333a42.666667 42.666667 0 0 1-42.56-39.466666L853.333333 874.666667a42.666667 42.666667 0 0 0-85.226666-3.2L768 874.666667a42.666667 42.666667 0 0 1-85.226667 3.2L682.666667 874.666667a42.666667 42.666667 0 0 0-85.226667-3.2L597.333333 874.666667a42.666667 42.666667 0 0 1-42.666666 42.666666l-3.349334-0.128 0.917334-3.029333c1.194667-4.330667 1.962667-8.832 2.282666-13.482667L554.666667 896v-33.066667c0-61.866667-38.144-116.16-93.312-132.8a641.877333 641.877333 0 0 0-29.013334-8A160 160 0 0 0 213.333333 496.917333V192a85.333333 85.333333 0 0 1 85.333334-85.333333h512z m-53.333334 469.333333h-192a32 32 0 0 0-3.072 63.850667L565.333333 640h192a32 32 0 0 0 0-64z m0-234.666667h-405.333333a32 32 0 0 0-3.072 63.850667L352 405.333333h405.333333a32 32 0 0 0 0-64z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M661.333333 128a64 64 0 0 1 64 64v640a64 64 0 0 1-64 64H362.666667a64 64 0 0 1-64-64V192a64 64 0 0 1 64-64h298.666666z m-448 106.666667a42.666667 42.666667 0 0 1 42.666667 42.666666v512a42.666667 42.666667 0 0 1-42.666667 42.666667H128V234.666667h85.333333z m682.666667 0v597.333333h-85.333333a42.666667 42.666667 0 0 1-42.666667-42.666667V277.333333a42.666667 42.666667 0 0 1 42.666667-42.666666h85.333333z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M693.333333 106.666667A32 32 0 0 1 725.333333 138.666667V149.333333h96a117.333333 117.333333 0 0 1 117.248 112.618667L938.666667 266.666667v512a117.333333 117.333333 0 0 1-112.618667 117.248L821.333333 896h-618.666666a117.333333 117.333333 0 0 1-117.248-112.618667L85.333333 778.666667v-512a117.333333 117.333333 0 0 1 112.618667-117.248L202.666667 149.333333H298.666667v-10.666666a32 32 0 0 1 64 0V149.333333h298.666666v-10.666666A32 32 0 0 1 693.333333 106.666667zM298.666667 213.333333H202.666667a53.333333 53.333333 0 0 0-53.226667 49.834667L149.333333 266.666667v512a53.333333 53.333333 0 0 0 49.834667 53.226666L202.666667 832h618.666666a53.333333 53.333333 0 0 0 53.226667-49.834667L874.666667 778.666667v-512a53.333333 53.333333 0 0 0-49.834667-53.226667L821.333333 213.333333H725.333333v10.666667a32 32 0 0 1-64 0V213.333333H362.666667v10.666667a32 32 0 0 1-64 0V213.333333z m138.666666 405.333334a32 32 0 0 1 0 64h-149.333333a32 32 0 0 1 0-64h149.333333z m277.333334-213.333334a32 32 0 0 1 0 64h-426.666667a32 32 0 0 1 0-64h426.666667z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M693.333333 106.666667A32 32 0 0 1 725.333333 138.666667V170.666667h74.666667a117.333333 117.333333 0 0 1 117.248 112.618666L917.333333 288v448a117.333333 117.333333 0 0 1-112.618666 117.248L800 853.333333h-576a117.333333 117.333333 0 0 1-117.248-112.618666L106.666667 736v-448a117.333333 117.333333 0 0 1 112.618666-117.248L224 170.666667H298.666667V138.666667a32 32 0 0 1 64 0V170.666667h298.666666V138.666667A32 32 0 0 1 693.333333 106.666667zM451.776 350.122667a32 32 0 0 0-44.074667 0l-0.832 0.789333a29.952 29.952 0 0 0 0 43.456l40.085334 38.08h-32.213334a30.72 30.72 0 0 0 0 61.44h66.282667v40.96h-44.736a30.72 30.72 0 1 0 0 61.461333h44.736v49.92a32 32 0 0 0 32 32h0.704a32 32 0 0 0 32-32l-0.021333-49.92h44.757333a30.72 30.72 0 0 0 0-61.44l-44.757333-0.021333v-40.96h66.325333a30.72 30.72 0 0 0 0-61.44h-37.034667l40.106667-38.08 2.112-2.218667a29.973333 29.973333 0 0 0-2.133333-41.237333l-0.810667-0.789333-2.389333-2.048a32 32 0 0 0-41.685334 2.048l-59.221333 56.234666z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M688 312v-48c0-4.4-3.6-8-8-8H296c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8h384c4.4 0 8-3.6 8-8zM296 400c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8h184c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8H296zM672 516c-119.3 0-216 96.7-216 216s96.7 216 216 216 216-96.7 216-216-96.7-216-216-216z m107.5 323.5C750.8 868.2 712.6 884 672 884s-78.8-15.8-107.5-44.5C535.8 810.8 520 772.6 520 732s15.8-78.8 44.5-107.5C593.2 595.8 631.4 580 672 580s78.8 15.8 107.5 44.5C808.2 653.2 824 691.4 824 732s-15.8 78.8-44.5 107.5z" /><path d="M761 656h-44.3c-2.6 0-5 1.2-6.5 3.3l-63.5 87.8-23.1-31.9c-1.5-2.1-3.9-3.3-6.5-3.3H573c-6.5 0-10.3 7.4-6.5 12.7l73.8 102.1c3.2 4.4 9.7 4.4 12.9 0l114.2-158c3.9-5.3 0.1-12.7-6.4-12.7z" /><path d="M440 852H208V148h560v344c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8V108c0-17.7-14.3-32-32-32H168c-17.7 0-32 14.3-32 32v784c0 17.7 14.3 32 32 32h272c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1663309724004" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="117083" xmlns:xlink="http://www.w3.org/1999/xlink" width="32" height="32"><path d="M904.758613 172.088889L228.975502 847.872a34.133333 34.133333 0 0 1-48.298666 0 34.133333 34.133333 0 0 1 0-48.241778l675.783111-675.84a34.133333 34.133333 0 0 1 48.298666 0 34.133333 34.133333 0 0 1 0 48.298667z" p-id="117084"></path><path d="M512.054613 234.040889a494.933333 494.933333 0 0 0-299.918222 130.161778 823.352889 823.352889 0 0 0-132.949333 140.856889 886.272 886.272 0 0 0 130.389333 140.288A491.349333 491.349333 0 0 0 512.054613 780.174222a494.193778 494.193778 0 0 0 302.990223-139.605333 994.133333 994.133333 0 0 0 124.359111-131.811556 1035.377778 1035.377778 0 0 0-133.916445-141.596444A461.653333 461.653333 0 0 0 512.054613 234.040889m0-68.266667c282.737778 0 508.757333 339.854222 512 341.333334s-229.205333 341.333333-512 341.333333-507.847111-321.479111-512-341.333333 229.432889-341.333333 512-341.333334z" p-id="117085"></path><path d="M511.997724 677.774222a170.666667 170.666667 0 0 1-170.666666-170.666666 170.666667 170.666667 0 0 1 170.666666-170.666667 170.666667 170.666667 0 0 1 170.666667 170.666667 170.666667 170.666667 0 0 1-170.666667 170.666666z m0-273.066666a102.4 102.4 0 0 0-102.4 102.4 102.4 102.4 0 0 0 102.4 102.4 102.4 102.4 0 0 0 102.4-102.4 102.4 102.4 0 0 0-102.4-102.456889z" p-id="117086"></path></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512.1 384c-69.7 0.5-126.6 57.4-127.1 127.1a128.3 128.3 0 0 0 7.6 44.4 4 4 0 0 0 6.6 1.4l49-49a3.7 3.7 0 0 0 1.2-2.4 63.9 63.9 0 0 1 57.1-57.1 3.7 3.7 0 0 0 2.4-1.2l49-49a4 4 0 0 0-1.4-6.6 128.3 128.3 0 0 0-44.4-7.6zM249.5 701.8a4 4 0 0 0 5.2-0.4l45.9-45.8a4 4 0 0 0-0.6-6.1q-17.1-12.2-34.4-26c-48.7-39.2-88.3-81.7-113.7-111.5 25.4-29.8 65-72.3 113.7-111.5 39.7-31.9 79.4-57 118.1-74.4 44.2-20 87.4-30.1 128.3-30.1 37.9 0 77.8 8.7 118.7 25.9a4 4 0 0 0 4.4-0.9l48.3-48.3a4 4 0 0 0-1-6.4C629.8 240.8 572.3 224 512 224c-222.2 0-407 228.3-444.8 278.4a15.9 15.9 0 0 0 0 19.2c21.2 28 88.3 111.8 182.3 180.2z m707.3-199.4c-21.4-28.3-89.7-113.5-185.1-182.2l133.5-133.5a4 4 0 0 0 0-5.6l-34-34a4 4 0 0 0-5.6 0L551.7 461 448.5 564.2l-32 31.9-78.1 78.2-52.4 52.4-138.9 138.9a4 4 0 0 0 0 5.6l34 34a4 4 0 0 0 5.6 0l149.9-150c54 26.9 113.2 44.8 175.4 44.8 222.2 0 406.9-228.3 444.8-278.4a15.9 15.9 0 0 0 0-19.2zM576.9 515a64.2 64.2 0 0 1-60.9 60.9z m181.5 108.5c-39.7 31.9-79.4 57-118.1 74.4-44.2 20-87.4 30.1-128.3 30.1-38.7 0-79.4-9.1-121.2-26.9l71.5-71.5a127.8 127.8 0 0 0 52.2 10.4c69.2-0.8 125.7-57.3 126.5-126.5a127.8 127.8 0 0 0-10.4-52.2l89.5-89.5q19 13.2 38.3 28.7c48.7 39.2 88.3 81.7 113.7 111.5-25.4 29.8-65 72.3-113.7 111.5z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M853.333333 338.944V853.333333a85.333333 85.333333 0 0 1-85.333333 85.333334H256a85.333333 85.333333 0 0 1-85.333333-85.333334V338.965333a510.229333 510.229333 0 0 0 257.216 123.498667 85.312 85.312 0 0 0 168.192 0 510.165333 510.165333 0 0 0 257.28-123.52zM768 85.333333a85.333333 85.333333 0 0 1 85.333333 85.333334l0.021334 108.778666a468.437333 468.437333 0 0 1-260.842667 140.330667 85.354667 85.354667 0 0 0-161.088 0 468.373333 468.373333 0 0 1-260.778667-140.330667L170.666667 170.666667a85.333333 85.333333 0 0 1 85.333333-85.333334h512z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M691.797333 347.136c-12.16 12.373333-12.16 32.426667 0 44.821333 12.16 12.373333 31.893333 12.373333 44.053334 0l151.04-115.584c12.16-12.373333 12.16-32.448 0-44.842666l-151.04-115.584a30.784 30.784 0 0 0-44.053334 0c-12.16 12.373333-12.16 32.448 0 44.842666l85.290667 61.589334H458.666667C276.053333 222.4 128 368.426667 128 548.544c0 177.92 144.426667 322.538667 323.925333 326.08L458.666667 874.666667h213.333333c17.664 0 32-14.122667 32-31.573334 0-16.384-12.693333-29.866667-28.928-31.402666l-3.072-0.149334h-213.333333c-147.285333 0-266.666667-117.76-266.666667-263.018666 0-143.082667 115.84-259.477333 260.096-262.933334l6.570667-0.064 318.442666-0.021333-85.333333 61.632z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M664.32 149.333333a142.229333 142.229333 0 0 1 123.349333 71.402667L911.786667 436.906667a71.104 71.104 0 0 1-10.986667 85.290666l-337.066667 342.570667a71.104 71.104 0 0 1-102.4-1.024L122.581333 505.386667a71.104 71.104 0 0 1-9.130666-85.717334l122.389333-201.813333A142.229333 142.229333 0 0 1 357.418667 149.333333H664.32z m34.090667 295.232a32 32 0 0 0-45.248 0l-143.317334 143.296-143.296-143.296a32 32 0 1 0-45.248 45.248l165.930667 165.930667a32 32 0 0 0 45.248 0l165.930667-165.930667a32 32 0 0 0 0-45.248z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M693.333333 128A32 32 0 0 1 725.333333 160V192h74.666667a117.333333 117.333333 0 0 1 117.248 112.618667L917.333333 309.333333v448a117.333333 117.333333 0 0 1-117.333333 117.333334h-576A117.333333 117.333333 0 0 1 106.666667 757.333333v-448A117.333333 117.333333 0 0 1 224 192H298.666667V160a32 32 0 0 1 64 0V192h298.666666V160A32 32 0 0 1 693.333333 128z m-362.666666 490.666667h-64a32 32 0 0 0 0 64h64a32 32 0 0 0 0-64z m213.333333 0h-64a32 32 0 0 0 0 64h64a32 32 0 0 0 0-64z m213.333333 0h-64a32 32 0 0 0 0 64h64a32 32 0 0 0 0-64z m-426.666666-192h-64a32 32 0 0 0 0 64h64a32 32 0 0 0 0-64z m213.333333 0h-64a32 32 0 0 0 0 64h64a32 32 0 0 0 0-64z m213.333333 0h-64a32 32 0 0 0 0 64h64a32 32 0 0 0 0-64z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M777.6 536.384c19.690667 0 37.973333 9.770667 48.896 25.856l2.218667 3.541333 77.162666 133.184c9.813333 17.002667 10.496 37.653333 1.962667 55.125334l-1.962667 3.690666-77.162666 133.184a59.050667 59.050667 0 0 1-46.933334 29.269334l-4.181333 0.149333h-154.304a59.093333 59.093333 0 0 1-48.896-25.856l-2.218667-3.562667-77.162666-133.184a58.645333 58.645333 0 0 1-1.962667-55.125333l1.962667-3.690667 77.162666-133.184a59.050667 59.050667 0 0 1 46.912-29.248l4.202667-0.149333h154.304zM480 448v168.725333l-43.541333 75.242667a72.64 72.64 0 0 0 0 72.832l43.541333 75.221333V896H234.666667a85.333333 85.333333 0 0 1-85.333334-85.333333V448h330.666667z m220.437333 216.384a64 64 0 1 0 0 128 64 64 0 0 0 0-128zM874.666667 448v88.938667l-5.717334-9.856A73.066667 73.066667 0 0 0 805.696 490.666667H595.2c-19.413333 0-37.717333 7.68-51.2 20.885333L544 448H874.666667zM283.818667 134.848l2.816 2.005333L422.186667 241.066667A106.581333 106.581333 0 0 1 512 192c37.696 0 70.826667 19.562667 89.813333 49.088l135.552-104.234667c19.306667-14.848 46.506667-10.581333 60.736 9.557334 1.984 2.773333 3.626667 5.802667 4.949334 9.002666L853.333333 277.333333h42.666667a42.666667 42.666667 0 0 1 42.666667 42.666667v42.666667a42.666667 42.666667 0 0 1-42.666667 42.666666H128a42.666667 42.666667 0 0 1-42.666667-42.666666v-42.666667a42.666667 42.666667 0 0 1 42.666667-42.666667h42.666667l50.282666-121.92c1.301333-3.2 2.965333-6.208 4.949334-9.002666 13.546667-19.178667 38.869333-23.978667 57.92-11.562667z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M874.666667 448v362.666667a85.333333 85.333333 0 0 1-85.333334 85.333333H544V448H874.666667z m-394.666667 0v448H234.666667a85.333333 85.333333 0 0 1-85.333334-85.333333V448h330.666667zM283.818667 134.848l2.816 2.005333L422.186667 241.066667A106.581333 106.581333 0 0 1 512 192c37.696 0 70.826667 19.562667 89.813333 49.088l135.552-104.234667c19.306667-14.848 46.506667-10.581333 60.736 9.557334 1.984 2.773333 3.626667 5.802667 4.949334 9.002666L853.333333 277.333333h42.666667a42.666667 42.666667 0 0 1 42.666667 42.666667v42.666667a42.666667 42.666667 0 0 1-42.666667 42.666666H128a42.666667 42.666667 0 0 1-42.666667-42.666666v-42.666667a42.666667 42.666667 0 0 1 42.666667-42.666667h42.666667l50.282666-121.92c1.301333-3.2 2.965333-6.208 4.949334-9.002666 13.546667-19.178667 38.869333-23.978667 57.92-11.562667z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M361.365333 670.997333c49.578667 50.389333 55.317333 104.554667 0.362667 160.405334-34.048 34.581333-89.173333 55.36-165.034667 64.256-3.925333 0.469333-7.893333 0.448-11.84-0.021334-26.666667-3.242667-46.144-26.944-44.864-54.016l0.277334-3.541333 1.088-8.96c9.301333-72.32 29.44-125.269333 62.144-158.506667 54.954667-55.829333 108.266667-49.984 157.866666 0.384zM318.4 714.666667c-27.52-27.968-42.773333-29.653333-71.744-0.213334-18.730667 19.029333-32.874667 52.16-41.344 99.498667l-1.344 8.021333-1.557333 10.496 2.496-0.32c49.834667-7.36 85.504-20.629333 107.242666-38.698666l3.477334-3.072 2.944-2.837334c28.992-29.44 27.349333-44.906667-0.170667-72.874666z m514.133333-567.594667a72.042667 72.042667 0 0 1 44.394667 44.864c33.429333 97.664 22.805333 196.608-31.082667 294.698667-22.208 40.405333-50.624 78.656-85.205333 114.730666l-9.578667 9.792-9.066666 8.874667-0.256 2.752c-6.293333 58.752-50.858667 136.448-132.970667 236.906667l-7.125333 8.682666-13.12 15.68c-14.848 17.621333-42.496 12.714667-51.157334-8.106666l-1.024-2.794667-45.909333-146.517333-4.16-2.88a728.938667 728.938667 0 0 1-73.557333-59.989334l-11.413334-10.88-11.178666-11.093333a736.405333 736.405333 0 0 1-88.746667-109.568l-2.538667-3.946667L149.333333 479.936c-21.034667-6.826667-27.818667-32.832-14.464-49.173333l1.770667-2.005334 1.92-1.792c122.965333-107.434667 213.696-160.704 278.677333-156.266666l4.181334 0.362666 2.432 0.298667 5.482666-5.546667c29.482667-29.312 60.352-54.250667 92.629334-74.752l10.794666-6.677333 9.92-5.802667c90.069333-51.072 181.504-63.637333 272.896-36.906666l8.576 2.602666 8.384 2.794667z m-13.866666 63.232a10.304 10.304 0 0 0-3.690667-3.84l-1.536-0.725333-7.68-2.56c-77.461333-24.725333-154.56-15.146667-233.216 29.461333-40.938667 23.232-79.786667 54.549333-116.544 94.08a30.037333 30.037333 0 0 1-29.653333 8.661333l-5.098667-1.642666c-31.573333-9.28-96.362667 21.397333-188.864 95.018666l-11.690667 9.386667 106.709334 34.56c4.842667 1.557333 9.173333 4.309333 12.672 7.978667l2.005333 2.304 1.770667 2.496a677.376 677.376 0 0 0 89.237333 112.64 666.581333 666.581333 0 0 0 100.032 83.413333c4.928 3.349333 8.768 8.085333 11.093333 13.589333l1.024 2.816 32.213334 102.677334 6.186666-7.872c62.890667-80.874667 95.296-141.781333 97.813334-179.498667l0.149333-3.456v-2.986667a31.04 31.04 0 0 1 9.856-23.68c42.837333-39.68 76.522667-81.941333 101.184-126.826666 44.181333-80.426667 53.738667-158.592 29.333333-236.48l-2.56-7.786667-0.746666-1.706667zM690.773333 333.226667c45.909333 45.930667 46.08 120.213333 0.341334 165.930666-45.717333 45.738667-120 45.568-165.930667-0.341333-45.909333-45.930667-46.08-120.213333-0.341333-165.930667 45.717333-45.738667 120-45.568 165.930666 0.341334z m-45.162666 45.162666a53.333333 53.333333 0 0 0-75.434667-0.170666 53.333333 53.333333 0 0 0 0.170667 75.434666 53.333333 53.333333 0 0 0 75.434666 0.170667 53.333333 53.333333 0 0 0-0.170666-75.434667z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M361.365333 670.997333c49.578667 50.389333 55.317333 104.554667 0.362667 160.405334-34.048 34.581333-89.173333 55.36-165.034667 64.256-3.925333 0.469333-7.893333 0.448-11.84-0.021334-26.666667-3.242667-46.144-26.944-44.864-54.016l0.277334-3.541333 1.088-8.96c9.301333-72.32 29.44-125.269333 62.144-158.506667 54.954667-55.829333 108.266667-49.984 157.866666 0.384zM815.573333 141.653333l8.576 2.624 8.384 2.794667a72.042667 72.042667 0 0 1 44.394667 44.864c33.429333 97.664 22.805333 196.608-31.082667 294.698667-22.208 40.405333-50.624 78.656-85.205333 114.730666l-9.578667 9.792-9.066666 8.874667-0.256 2.752c-6.293333 58.752-50.858667 136.448-132.970667 236.906667l-7.125333 8.682666-13.12 15.68c-14.848 17.621333-42.496 12.714667-51.157334-8.106666l-1.024-2.794667-45.909333-146.517333-4.16-2.88a728.938667 728.938667 0 0 1-73.557333-59.989334l-11.413334-10.88-11.178666-11.093333a736.405333 736.405333 0 0 1-88.746667-109.568l-2.538667-3.946667L149.333333 479.936c-21.034667-6.826667-27.818667-32.832-14.464-49.173333l1.770667-2.005334 1.92-1.792c122.965333-107.434667 213.696-160.704 278.677333-156.266666l4.181334 0.362666 2.432 0.298667 5.482666-5.546667c29.482667-29.312 60.352-54.250667 92.629334-74.752l10.794666-6.677333 9.92-5.802667c90.069333-51.072 181.504-63.637333 272.896-36.906666z m-275.605333 206.314667c-37.397333 37.418667-37.269333 98.197333 0.298667 135.765333 37.568 37.568 98.346667 37.696 135.765333 0.298667 37.397333-37.418667 37.269333-98.197333-0.298667-135.765333-37.568-37.568-98.346667-37.696-135.765333-0.298667z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M725.333333 128a170.666667 170.666667 0 0 1 170.666667 170.666667v426.666666a170.666667 170.666667 0 0 1-170.666667 170.666667H298.666667a170.666667 170.666667 0 0 1-170.666667-170.666667V298.666667a170.666667 170.666667 0 0 1 170.666667-170.666667h426.666666z m-366.613333 149.845333s-16.725333-5.546667-21.653333 20.138667c-1.92 9.962667-4.565333 28.309333-7.082667 47.061333l-1.258667 9.386667c-2.048 15.530667-3.925333 30.442667-5.12 40.106667l-0.832 6.826666-0.32 2.56-0.170666 1.514667H277.333333v70.08l32.853334 5.76s-2.496 27.797333-2.496 51.946667v225.045333s0.981333 9.728 11.818666 9.728h37.12s10.624-0.576 10.624-9.92v-11.008h289.514667v11.008c0 9.344 10.602667 9.92 10.602667 9.92h37.141333a11.157333 11.157333 0 0 0 11.797333-9.728V533.226667c0-24.149333-2.517333-51.968-2.517333-51.968L746.666667 475.52h-0.042667v-70.058667h-44.906667l-0.213333-1.514666-0.512-4.266667-0.64-5.12a5114.24 5114.24 0 0 0-5.12-40.106667l-1.237333-9.386666c-2.538667-18.773333-5.184-37.12-7.082667-47.061334-4.949333-25.706667-21.674667-20.138667-21.674667-20.138666z m219.264 408.789334v39.296h-129.152v-39.296h129.152z m19.690667-103.168v18.218666h-172.458667v-18.218666h172.458667z m-207.146667-38.4c7.210667 0 7.189333 7.253333 7.189333 7.253333v35.904c0 7.744-8.277333 7.744-8.277333 7.744h-50.752c-9.685333 0-9.685333-7.893333-9.685333-7.893333v-35.477334c0-7.573333 9.685333-7.146667 9.685333-7.146666h1.386667c7.616-0.085333 44.053333-0.362667 50.474666-0.362667z m300.48 0c7.168 0 7.168 7.253333 7.168 7.253333v35.904c0 7.744-8.256 7.744-8.256 7.744h-50.773333c-9.706667 0-9.706667-7.893333-9.706667-7.893333v-35.477334c0-7.573333 9.706667-7.146667 9.706667-7.146666h1.386666c7.594667-0.085333 44.032-0.362667 50.474667-0.362667z m-93.333333 7.253333v18.218667h-172.458667v-18.218667h172.458667zM667.306667 296.533333l18.56 160.384H337.856l9.28-160.405333H667.306667z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M652.949333 865.706667c11.690667 11.946667 30.613333 11.946667 42.282667 0a31.146667 31.146667 0 0 0 0-43.306667l-295.765333-302.933333a10.666667 10.666667 0 0 1 0-14.933334l295.765333-302.933333a31.146667 31.146667 0 0 0 0-43.306667 29.397333 29.397333 0 0 0-42.282667 0L328.768 490.346667a31.146667 31.146667 0 0 0 0 43.306666L652.949333 865.706667z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 85.333333c235.648 0 426.666667 191.018667 426.666667 426.666667s-191.018667 426.666667-426.666667 426.666667S85.333333 747.648 85.333333 512 276.352 85.333333 512 85.333333z m0 64C311.701333 149.333333 149.333333 311.701333 149.333333 512s162.368 362.666667 362.666667 362.666667 362.666667-162.368 362.666667-362.666667S712.298667 149.333333 512 149.333333z m0 128a32 32 0 0 1 32 32v170.645334l170.666667 0.021333a32 32 0 0 1 0 64l-170.688-0.021333 0.021333 170.688a32 32 0 0 1-64 0l-0.021333-170.688-170.645334 0.021333a32 32 0 0 1 0-64l170.666667-0.021333V309.333333A32 32 0 0 1 512 277.333333z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 85.333333c235.648 0 426.666667 191.018667 426.666667 426.666667s-191.018667 426.666667-426.666667 426.666667S85.333333 747.648 85.333333 512 276.352 85.333333 512 85.333333z m0 192a32 32 0 0 0-32 32v170.645334l-170.666667 0.021333a32 32 0 0 0 0 64l170.645334-0.021333 0.021333 170.688a32 32 0 0 0 64 0l-0.021333-170.688 170.688 0.021333a32 32 0 0 0 0-64l-170.666667-0.021333V309.333333A32 32 0 0 0 512 277.333333z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 85.333333c235.648 0 426.666667 191.018667 426.666667 426.666667s-191.018667 426.666667-426.666667 426.666667S85.333333 747.648 85.333333 512 276.352 85.333333 512 85.333333z m0 64C311.701333 149.333333 149.333333 311.701333 149.333333 512s162.368 362.666667 362.666667 362.666667 362.666667-162.368 362.666667-362.666667S712.298667 149.333333 512 149.333333z m202.666667 330.666667a32 32 0 0 1 0 64h-405.333334a32 32 0 0 1 0-64h405.333334z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 85.333333c235.648 0 426.666667 191.018667 426.666667 426.666667s-191.018667 426.666667-426.666667 426.666667S85.333333 747.648 85.333333 512 276.352 85.333333 512 85.333333z m202.666667 394.666667h-405.333334a32 32 0 0 0 0 64h405.333334a32 32 0 0 0 0-64z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 85.333333c235.648 0 426.666667 191.018667 426.666667 426.666667s-191.018667 426.666667-426.666667 426.666667S85.333333 747.648 85.333333 512 276.352 85.333333 512 85.333333z m0 64C311.701333 149.333333 149.333333 311.701333 149.333333 512s162.368 362.666667 362.666667 362.666667 362.666667-162.368 362.666667-362.666667S712.298667 149.333333 512 149.333333z m160 490.666667a32 32 0 0 1 0 64h-320a32 32 0 0 1 0-64h320zM298.666667 490.666667a21.333333 21.333333 0 0 1 21.333333 21.333333v21.333333a21.333333 21.333333 0 0 1-21.333333 21.333334h-21.333334a21.333333 21.333333 0 0 1-21.333333-21.333334v-21.333333a21.333333 21.333333 0 0 1 21.333333-21.333333h21.333334z m149.333333 0a21.333333 21.333333 0 0 1 21.333333 21.333333v21.333333a21.333333 21.333333 0 0 1-21.333333 21.333334h-21.333333a21.333333 21.333333 0 0 1-21.333334-21.333334v-21.333333a21.333333 21.333333 0 0 1 21.333334-21.333333h21.333333z m149.333333 0a21.333333 21.333333 0 0 1 21.333334 21.333333v21.333333a21.333333 21.333333 0 0 1-21.333334 21.333334h-21.333333a21.333333 21.333333 0 0 1-21.333333-21.333334v-21.333333a21.333333 21.333333 0 0 1 21.333333-21.333333h21.333333z m149.333334 0a21.333333 21.333333 0 0 1 21.333333 21.333333v21.333333a21.333333 21.333333 0 0 1-21.333333 21.333334h-21.333334a21.333333 21.333333 0 0 1-21.333333-21.333334v-21.333333a21.333333 21.333333 0 0 1 21.333333-21.333333h21.333334z m-448-149.333334a21.333333 21.333333 0 0 1 21.333333 21.333334v21.333333a21.333333 21.333333 0 0 1-21.333333 21.333333h-21.333334a21.333333 21.333333 0 0 1-21.333333-21.333333v-21.333333a21.333333 21.333333 0 0 1 21.333333-21.333334h21.333334z m149.333333 0a21.333333 21.333333 0 0 1 21.333333 21.333334v21.333333a21.333333 21.333333 0 0 1-21.333333 21.333333h-21.333333a21.333333 21.333333 0 0 1-21.333334-21.333333v-21.333333a21.333333 21.333333 0 0 1 21.333334-21.333334h21.333333z m149.333333 0a21.333333 21.333333 0 0 1 21.333334 21.333334v21.333333a21.333333 21.333333 0 0 1-21.333334 21.333333h-21.333333a21.333333 21.333333 0 0 1-21.333333-21.333333v-21.333333a21.333333 21.333333 0 0 1 21.333333-21.333334h21.333333z m149.333334 0a21.333333 21.333333 0 0 1 21.333333 21.333334v21.333333a21.333333 21.333333 0 0 1-21.333333 21.333333h-21.333334a21.333333 21.333333 0 0 1-21.333333-21.333333v-21.333333a21.333333 21.333333 0 0 1 21.333333-21.333334h21.333334z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M820.522667 234.666667C885.76 234.666667 938.666667 289.28 938.666667 356.693333v310.613334c0 67.413333-52.906667 122.026667-118.144 122.026666H336.170667c-36.672 0-71.253333-17.578667-93.610667-47.573333l-146.069333-195.925333a56.917333 56.917333 0 0 1 0-67.669334l146.069333-195.925333c22.357333-29.994667 56.96-47.573333 93.610667-47.573333z m0.149333 66.56H333.909333c-16.746667 0-32.554667 7.978667-42.773333 21.632L149.333333 511.978667l141.802667 189.162666c9.429333 12.586667 23.616 20.373333 38.933333 21.482667l3.84 0.149333H820.693333c29.824 0 53.994667-24.832 53.994667-55.466666V356.693333c0-30.634667-24.170667-55.466667-53.994667-55.466666z m-125.653333 91.776a30.72 30.72 0 0 1 0 43.456l-75.562667 75.52 75.541333 75.562666a30.72 30.72 0 1 1-43.456 43.456l-75.52-75.562666-75.562666 75.562666a30.72 30.72 0 1 1-43.456-43.456L532.565333 512l-75.562666-75.52a30.72 30.72 0 1 1 43.456-43.456L576 468.522667l75.52-75.52a30.72 30.72 0 0 1 43.456 0z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M170.666667 480m32 0l618.666666 0q32 0 32 32l0 0q0 32-32 32l-618.666666 0q-32 0-32-32l0 0q0-32 32-32Z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M298.666667 106.666667v174.229333a10.666667 10.666667 0 0 0 13.909333 10.154667l1.770667-0.746667 38.272-20.416a21.333333 21.333333 0 0 1 17.685333-1.088l2.410667 1.088 38.272 20.416a10.666667 10.666667 0 0 0 15.509333-7.488l0.170667-1.92V106.666667h384a42.666667 42.666667 0 0 1 42.666666 42.666666v512H320a106.666667 106.666667 0 0 0-4.629333 213.226667L320 874.666667h533.333333a42.666667 42.666667 0 0 1-42.666666 42.666666H256a85.333333 85.333333 0 0 1-85.333333-85.333333V192a85.333333 85.333333 0 0 1 85.333333-85.333333h42.666667z m554.666666 597.333333v128H320a64 64 0 0 1 0-128h533.333333z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M725.333333 106.666667a170.666667 170.666667 0 0 1 170.666667 170.666666v469.333334a170.666667 170.666667 0 0 1-170.666667 170.666666H298.666667a170.666667 170.666667 0 0 1-170.666667-170.666666V277.333333a170.666667 170.666667 0 0 1 170.666667-170.666666h426.666666z m-29.333333 445.973333H328.064l-3.349333 0.170667c-23.893333 2.496-35.072 31.658667-17.365334 49.002666l117.696 115.114667 2.773334 2.389333c11.52 8.768 28.16 7.936 38.698666-2.453333l2.432-2.709333a28.373333 28.373333 0 0 0-2.496-37.973334l-67.413333-65.984h296.96l3.413333-0.192A28.992 28.992 0 0 0 725.333333 581.418667c0-15.893333-13.141333-28.8-29.333333-28.8z m-99.797333-247.957333a29.738667 29.738667 0 0 0-38.72 2.453333l-2.432 2.709333a28.373333 28.373333 0 0 0 2.496 37.973334l67.413333 65.984h-296.96l-3.413333 0.192A28.992 28.992 0 0 0 298.666667 442.581333c0 15.893333 13.141333 28.8 29.333333 28.8h367.936l3.349333-0.192c23.893333-2.496 35.072-31.658667 17.365334-49.002666l-117.696-115.114667z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M725.333333 512c117.824 0 213.333333 95.509333 213.333334 213.333333s-95.509333 213.333333-213.333334 213.333334-213.333333-95.509333-213.333333-213.333334 95.509333-213.333333 213.333333-213.333333z m42.666667-405.333333a85.333333 85.333333 0 0 1 85.333333 85.333333l0.021334 311.594667A254.826667 254.826667 0 0 0 725.333333 469.333333c-141.376 0-256 114.624-256 256 0 76.458667 33.514667 145.109333 86.677334 192H256a85.333333 85.333333 0 0 1-85.333333-85.333333V192a85.333333 85.333333 0 0 1 85.333333-85.333333h512z m54.208 538.709333l-2.24 1.92-117.184 112.789333a17.344 17.344 0 0 1-22.208 1.536l-1.92-1.621333-47.957333-46.762667a26.410667 26.410667 0 0 0-36.48 0c-9.386667 9.088-10.026667 23.466667-1.877334 33.28l1.877334 2.005334 78.229333 76.16a26.453333 26.453333 0 0 0 34.218667 1.941333l2.261333-1.92 147.52-142.08a24.384 24.384 0 0 0 0-35.306667 26.453333 26.453333 0 0 0-34.24-1.941333zM650.666667 298.666667h-320a32 32 0 0 0-3.072 63.850666L330.666667 362.666667h320a32 32 0 0 0 0-64z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M938.666667 426.666667v320a85.333333 85.333333 0 0 1-85.333334 85.333333H170.666667a85.333333 85.333333 0 0 1-85.333334-85.333333V426.666667h853.333334z m-181.333334 97.450666a10.666667 10.666667 0 0 0-10.666666 10.666667v41.813333c-113.813333 6.826667-170.709333 70.613333-170.666667 191.402667 13.653333-65.877333 70.549333-101.248 170.666667-106.112v40.661333a10.666667 10.666667 0 0 0 17.493333 8.213334l90.837333-75.712a21.333333 21.333333 0 0 0 0-32.768l-90.837333-75.712a10.666667 10.666667 0 0 0-6.826667-2.453334zM853.333333 192a85.333333 85.333333 0 0 1 85.333334 85.333333v85.333334H85.333333v-85.333334a85.333333 85.333333 0 0 1 85.333334-85.333333h682.666666z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 85.333333c235.648 0 426.666667 191.018667 426.666667 426.666667s-191.018667 426.666667-426.666667 426.666667S85.333333 747.648 85.333333 512 276.352 85.333333 512 85.333333z m0 64C311.701333 149.333333 149.333333 311.701333 149.333333 512s162.368 362.666667 362.666667 362.666667 362.666667-162.368 362.666667-362.666667S712.298667 149.333333 512 149.333333z m0 512a42.666667 42.666667 0 1 1 0 85.333334 42.666667 42.666667 0 0 1 0-85.333334z m0-362.666666a32 32 0 0 1 32 32v256a32 32 0 0 1-64 0v-256A32 32 0 0 1 512 298.666667z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 85.333333c235.648 0 426.666667 191.018667 426.666667 426.666667s-191.018667 426.666667-426.666667 426.666667S85.333333 747.648 85.333333 512 276.352 85.333333 512 85.333333z m0 576a42.666667 42.666667 0 1 0 0 85.333334 42.666667 42.666667 0 0 0 0-85.333334z m0-362.666666a32 32 0 0 0-32 32v256a32 32 0 0 0 64 0v-256A32 32 0 0 0 512 298.666667z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 85.333333c235.648 0 426.666667 191.018667 426.666667 426.666667s-191.018667 426.666667-426.666667 426.666667S85.333333 747.648 85.333333 512 276.352 85.333333 512 85.333333z m0 576a42.666667 42.666667 0 1 0 0 85.333334 42.666667 42.666667 0 0 0 0-85.333334z m0-362.666666a32 32 0 0 0-32 32v256a32 32 0 0 0 64 0v-256A32 32 0 0 0 512 298.666667z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M467.626667 199.253333a116.330667 116.330667 0 0 1 165.461333 12.906667A119.68 119.68 0 0 1 661.333333 289.472V734.506667C661.333333 800.149333 608.810667 853.333333 544 853.333333a116.48 116.48 0 0 1-76.373333-28.586666l-148.8-129.152H224c-63.210667 0-114.773333-50.624-117.248-114.026667L106.666667 576.789333v-129.578666c0-65.621333 52.522667-118.805333 117.333333-118.805334h94.805333z m116.864 55.061334a52.885333 52.885333 0 0 0-75.2-5.845334l-166.784 144.746667H224c-29.44 0-53.333333 24.170667-53.333333 53.973333v129.6c0 29.824 23.893333 54.016 53.333333 54.016h118.506667l166.784 144.725334c9.664 8.384 21.973333 13.013333 34.709333 13.013333 29.44 0 53.333333-24.192 53.333333-54.016V289.493333a54.4 54.4 0 0 0-12.842666-35.157333z m345.472 159.722666a29.696 29.696 0 0 1 0 41.984L873.984 512l55.978667 55.957333a29.696 29.696 0 1 1-41.984 41.984L832 554.026667l-55.957333 55.957333a29.696 29.696 0 1 1-41.984-41.984l55.957333-55.957333-55.957333-56a29.696 29.696 0 1 1 41.984-41.984l55.957333 55.978666 56-55.978666a29.696 29.696 0 0 1 41.984 0z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M467.626667 199.253333a116.330667 116.330667 0 0 1 165.461333 12.906667A119.68 119.68 0 0 1 661.333333 289.472V734.506667C661.333333 800.149333 608.810667 853.333333 544 853.333333a116.48 116.48 0 0 1-76.373333-28.586666l-148.8-129.152H224c-63.210667 0-114.773333-50.624-117.248-114.026667L106.666667 576.789333v-129.578666c0-65.621333 52.522667-118.805333 117.333333-118.805334h94.805333z m462.336 214.784a29.696 29.696 0 0 1 0 41.984L873.984 512l55.978667 55.957333a29.696 29.696 0 1 1-41.984 41.984L832 554.026667l-55.957333 55.957333a29.696 29.696 0 1 1-41.984-41.984l55.957333-55.957333-55.957333-56a29.696 29.696 0 1 1 41.984-41.984l55.957333 55.978666 56-55.978666a29.696 29.696 0 0 1 41.984 0z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M736 853.333333a32 32 0 0 1 0 64h-448a32 32 0 0 1 0-64h448z m106.666667-746.666666A96 96 0 0 1 938.666667 202.666667v469.333333a96 96 0 0 1-96 96h-661.333334A96 96 0 0 1 85.333333 672v-469.333333A96 96 0 0 1 181.333333 106.666667z m0 64h-661.333334A32 32 0 0 0 149.333333 202.666667v469.333333A32 32 0 0 0 181.333333 704h661.333334a32 32 0 0 0 32-32v-469.333333A32 32 0 0 0 842.666667 170.666667z m-84.053334 179.968a31.786667 31.786667 0 0 1 2.24 42.666666l-2.197333 2.410667-149.888 149.589333c-11.754667 11.733333-30.378667 12.437333-42.965333 2.133334l-2.410667-2.197334-126.464-126.848-126.293333 126.037334a32.106667 32.106667 0 0 1-42.794667 2.24l-2.453333-2.197334a31.786667 31.786667 0 0 1-2.24-42.645333l2.197333-2.410667 149.013333-148.714666a32.106667 32.106667 0 0 1 42.944-2.133334l2.432 2.197334 126.442667 126.826666 127.168-126.890666a32.085333 32.085333 0 0 1 45.269333-0.064z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M736 853.333333a32 32 0 0 1 0 64h-448a32 32 0 0 1 0-64h448z m106.666667-746.666666A96 96 0 0 1 938.666667 202.666667v469.333333a96 96 0 0 1-96 96h-661.333334A96 96 0 0 1 85.333333 672v-469.333333A96 96 0 0 1 181.333333 106.666667z m-84.053334 243.968a32.085333 32.085333 0 0 0-45.269333 0.064l-127.168 126.890666-126.442667-126.826666-2.432-2.197334a32.106667 32.106667 0 0 0-42.944 2.133334l-149.013333 148.693333-2.197333 2.432a31.786667 31.786667 0 0 0 2.24 42.666667l2.453333 2.176c12.586667 10.197333 31.104 9.429333 42.816-2.24l126.272-126.037334 126.464 126.848 2.410667 2.197334c12.586667 10.304 31.210667 9.6 42.965333-2.133334l149.888-149.589333 2.197333-2.432a31.786667 31.786667 0 0 0-2.24-42.645333z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M618.666667 259.562667a10.666667 10.666667 0 0 0 15.68 9.386666l38.272-20.394666a21.333333 21.333333 0 0 1 20.096 0l38.272 20.416a10.666667 10.666667 0 0 0 15.68-9.408V106.666667h42.666666a85.333333 85.333333 0 0 1 85.333334 85.333333v640a85.333333 85.333333 0 0 1-85.333334 85.333333H234.666667a85.333333 85.333333 0 0 1-85.333334-85.333333V192a85.333333 85.333333 0 0 1 85.333334-85.333333h384zM277.333333 106.666667h42.666667v810.666666h-42.666667V106.666667z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 106.666667c60.010667 0 116.970667 13.034667 168.213333 36.437333L615.893333 204.181333a63.232 63.232 0 0 0-16.533333 60.48l1.173333 4.010667 9.685334 30.144A233.792 233.792 0 0 0 512 277.333333c-129.6 0-234.666667 105.066667-234.666667 234.666667s105.066667 234.666667 234.666667 234.666667 234.666667-105.066667 234.666667-234.666667c0-28.8-5.184-56.405333-14.698667-81.92l54.528 15.466667c21.525333 7.189333 41.813333-7.573333 58.282667-23.552l2.709333-2.688 45.226667-46.784A404.544 404.544 0 0 1 917.333333 512c0 223.850667-181.482667 405.333333-405.333333 405.333333S106.666667 735.850667 106.666667 512 288.149333 106.666667 512 106.666667z m0 234.666666c27.306667 0 53.098667 6.4 75.989333 17.813334l-104.597333 109.781333c-18.517333 18.517333-12.714667 60.650667 10.709333 82.88 22.485333 21.333333 69.717333 19.285333 89.834667 2.688l2.368-2.133333 89.770667-87.509334A170.666667 170.666667 0 1 1 512 341.333333zM800.554667 112.746667a20.757333 20.757333 0 0 1 5.013333 8.128l29.653333 89.28 89.216 29.610666a20.757333 20.757333 0 0 1 8.149334 34.346667l-120 120.021333a41.493333 41.493333 0 0 1-42.496 10.026667l-63.616-21.290667-141.354667 141.354667a31.125333 31.125333 0 1 1-44.010667-44.010667l141.056-141.056-21.12-64a41.493333 41.493333 0 0 1 10.090667-42.325333l120.085333-120.106667a20.757333 20.757333 0 0 1 29.333334 0z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M896 384v426.666667a85.333333 85.333333 0 0 1-85.333333 85.333333H213.333333a85.333333 85.333333 0 0 1-85.333333-85.333333V384h768zM490.666667 128v213.333333H128l103.146667-171.904A85.333333 85.333333 0 0 1 304.32 128H490.666667z m229.013333 0a85.333333 85.333333 0 0 1 73.173333 41.429333L896 341.333333H533.333333V128z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M405.333333 704a106.666667 106.666667 0 0 1 0 213.333333h-170.666666a106.666667 106.666667 0 0 1 0-213.333333h170.666666z m114.901334-597.226667h-13.866667l13.909333 0.106667c182.357333 3.754667 339.754667 129.024 384.725334 306.133333H542.293333a127.658667 127.658667 0 0 0-90.538666 37.205334 128.213333 128.213333 0 0 0-37.717334 90.453333 122.453333 122.453333 0 0 0 91.413334 118.250667L917.333333 773.76v0.938667a121.386667 121.386667 0 0 1-47.317333 96.213333 120.874667 120.874667 0 0 1-104.96 20.992l-212.373333-56.768a149.333333 149.333333 0 0 0-142.208-173.717333L405.333333 661.333333h-170.666666a148.650667 148.650667 0 0 0-86.293334 27.456 138.624 138.624 0 0 1-12.288-23.701333A404.266667 404.266667 0 0 1 106.666667 512.341333 405.781333 405.781333 0 0 1 228.266667 222.357333a404.053333 404.053333 0 0 1 291.989333-115.562666zM405.333333 746.666667a64 64 0 1 0 0 128 64 64 0 0 0 0-128z m509.098667-282.752c1.92 16.128 2.901333 32.490667 2.901333 49.066666v207.786667l-398.613333-111.210667a71.509333 71.509333 0 0 1-53.333333-69.056 76.970667 76.970667 0 0 1 76.906666-76.586666h372.138667z m-387.968 52.928a29.077333 29.077333 0 0 0 28.970667 50.410666 29.141333 29.141333 0 0 0 0-50.474666 28.949333 28.949333 0 0 0-28.970667 0.064z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M761.2 639.7c-10.6 0-21.1-4-29.2-12.1-16.1-16.1-16.1-42.3 0-58.4l97.5-97.5c5.6-5.6 7.1-13.9 7.3-19.9l8.6-242.5c0.1-3.9-2.8-11.2-9.5-17.9-6.7-6.7-14.7-9.5-17.9-9.5l-242.5 8.6c-6 0.2-14.2 1.7-19.9 7.3l-102 102.1c-16.1 16.1-42.3 16.1-58.4 0s-16.1-42.3 0-58.4l102.1-102.1c19.2-19.2 46-30.4 75.3-31.4l242.5-8.6c27.9-1 56.9 11.2 79.2 33.6 22.4 22.4 34.6 51.2 33.6 79.3l-8.6 242.5c-1.1 29.4-12.2 56.1-31.4 75.3l-97.5 97.5c-8.1 8.1-18.7 12.1-29.2 12.1zM444.4 925.3c-40.6 0-84.7-18.5-120.4-54.3L156.4 703.4C93.9 640.9 84 552.8 133.8 502.9l88.3-88.3c16.1-16.1 42.3-16.1 58.4 0s16.1 42.3 0 58.4l-88.3 88.3c-14.4 14.4-7.8 53.3 22.6 83.7l167.6 167.6c30.4 30.4 69.3 37 83.7 22.6l83.7-83.7c16.1-16.1 42.3-16.1 58.4 0s16.1 42.3 0 58.4l-83.7 83.7c-21.4 21.3-49.8 31.7-80.1 31.7z" /><path d="M705.8 326.3m-45.8 0a45.8 45.8 0 1 0 91.6 0 45.8 45.8 0 1 0-91.6 0Z" /><path d="M829.9 885.7c-10.6 0-21.1-4-29.2-12.1l-642-642c-16.1-16.1-16.1-42.3 0-58.4s42.3-16.1 58.4 0l642 642c16.1 16.1 16.1 42.3 0 58.4-8.1 8.1-18.6 12.1-29.2 12.1z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M511.914667 106.666667c202.325333 0 369.088 165.376 383.445333 375.850666l0.469333 8.746667c0.085333 2.901333 0.128 8.533333 0.149334 17.066667l0.021333 9.472v20.16l-0.064 23.04 0.064 2.965333v83.136c0 2.282667-0.064 4.522667-0.213333 6.762667 0.149333 1.194667 0.213333 2.410667 0.213333 3.626666 0 112.448-84.906667 205.034667-194.026667 216.96C689.130667 899.733333 660.48 917.333333 627.2 917.333333h-23.424c-45.269333 0-81.984-32.576-81.984-72.746666v-20.8c0-40.170667 36.714667-72.746667 81.984-72.746667H627.2c40.192 0 73.6 25.642667 80.64 59.52a155.605333 155.605333 0 0 0 95.189333-60.074667 103.850667 103.850667 0 0 1-114.602666-103.36v-83.157333a103.850667 103.850667 0 0 1 142.997333-96.256c-20.48-169.28-156.8-298.666667-319.509333-298.666667-170.026667 0-305.92 127.082667-320.362667 299.093334a103.850667 103.850667 0 0 1 144.021333 95.829333v83.136a103.850667 103.850667 0 0 1-103.786666 103.936A103.850667 103.850667 0 0 1 128 647.104v-83.136-1.066667l0.085333-72.277333C132.138667 272.853333 300.16 106.666667 511.914667 106.666667z m124.629333 706.730666h-42.090667a10.389333 10.389333 0 0 0-10.389333 10.389334v20.8c0 5.738667 4.650667 10.389333 10.389333 10.389333h42.090667a10.389333 10.389333 0 0 0 10.368-10.389333v-20.8a10.389333 10.389333 0 0 0-10.368-10.389334z m-404.757333-290.986666a41.536 41.536 0 0 0-41.514667 41.557333l0.064-1.877333-0.085333 32.938666v52.074667c0 21.930667 16.96 39.893333 38.442666 41.472l3.093334 0.106667a41.536 41.536 0 0 0 41.514666-41.578667v-83.136a41.536 41.536 0 0 0-41.514666-41.578667z m560.426666 0a41.536 41.536 0 0 0-41.514666 41.557333v83.136c0 22.976 18.581333 41.6 41.514666 41.6a41.536 41.536 0 0 0 41.514667-41.6v-48.832a31.573333 31.573333 0 0 1-0.170667-3.242667l0.021334-34.624a41.536 41.536 0 0 0-41.365334-38.016z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512.042667 213.333333c148.992 0 283.733333 78.186667 403.2 231.317334 31.253333 40.021333 31.253333 94.698667-0.106667 134.869333l-6.826667 8.64C790.570667 735.466667 658.133333 810.666667 512.042667 810.666667 363.008 810.666667 228.266667 732.437333 108.736 579.264c-31.189333-40-31.232-94.592 0.042667-134.762667l6.805333-8.64C233.045333 288.533333 365.546667 213.333333 512.042667 213.333333z m0 61.802667c-123.904 0-238.378667 64.96-344.32 197.845333l-6.613334 8.341334a49.344 49.344 0 0 0 0.064 61.205333c108.16 138.645333 224.810667 206.336 350.869334 206.336 123.52 0 237.952-64.96 344.192-197.888l6.613333-8.341333a49.344 49.344 0 0 0 0-61.226667c-108.16-138.602667-224.768-206.293333-350.805333-206.293333zM512 384a128 128 0 1 1 0 256 128 128 0 0 1 0-256z m0 59.093333a68.906667 68.906667 0 1 0 0 137.813334 68.906667 68.906667 0 0 0 0-137.813334z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512.042667 213.333333c148.992 0 283.733333 78.186667 403.2 231.317334 31.253333 40.021333 31.253333 94.698667-0.106667 134.869333l-6.826667 8.64C790.570667 735.466667 658.133333 810.666667 512.042667 810.666667 363.008 810.666667 228.266667 732.437333 108.736 579.264c-31.189333-40-31.232-94.592 0.042667-134.762667l6.805333-8.64C233.045333 288.533333 365.546667 213.333333 512.042667 213.333333zM512 384a128 128 0 1 0 0 256 128 128 0 0 0 0-256z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M490.666667 576c14.08 0 28.16 0.341333 42.24 1.002667a244.906667 244.906667 0 0 0-30.698667 63.082666A821.546667 821.546667 0 0 0 490.666667 640c-77.333333 0-154.752 10.816-232.405334 32.490667a119.829333 119.829333 0 0 0-87.466666 110.229333L170.666667 787.904V832a21.333333 21.333333 0 0 0 18.837333 21.184L192 853.333333h341.589333a246.698667 246.698667 0 0 0 64.149334 64.021334L192 917.333333a85.333333 85.333333 0 0 1-85.333333-85.333333v-44.096a183.829333 183.829333 0 0 1 134.4-177.066667C324.266667 587.648 407.466667 576 490.666667 576z m245.333333-64a202.666667 202.666667 0 1 1 0 405.333333 202.666667 202.666667 0 0 1 0-405.333333z m0 64a138.666667 138.666667 0 1 0 0 277.333333 138.666667 138.666667 0 0 0 0-277.333333z m0 21.333333a21.333333 21.333333 0 0 1 21.333333 21.333334v91.626666l57.472 57.472a21.333333 21.333333 0 0 1 1.770667 28.16l-1.770667 2.005334a21.333333 21.333333 0 0 1-28.16 1.770666l-2.005333-1.770666-51.477333-51.456A21.333333 21.333333 0 0 1 714.666667 725.333333v-106.666666a21.333333 21.333333 0 0 1 21.333333-21.333334zM490.666667 106.666667c117.824 0 213.333333 95.509333 213.333333 213.333333s-95.509333 213.333333-213.333333 213.333333-213.333333-95.509333-213.333334-213.333333S372.842667 106.666667 490.666667 106.666667z m0 64a149.333333 149.333333 0 1 0 0 298.666666 149.333333 149.333333 0 0 0 0-298.666666z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M444.629333 149.333333c99.221333 0 179.648 94.549333 179.648 211.2 0 83.84-41.557333 156.288-101.802666 190.4-1.216 6.698667-1.002667 13.482667 0.64 20.309334 6.229333 26.090667 27.968 43.413333 65.194666 51.946666l59.925334 19.072c9.984 3.093333 19.968 6.08 29.952 8.853334l11.264 3.2 10.858666 3.306666c62.229333 19.626667 103.616 46.08 103.616 114.965334C803.456 826.410667 770.197333 853.333333 704.128 853.333333H185.130667c-64.853333 0-98.133333-26.922667-99.797334-80.746666 0-66.922667 39.061333-93.802667 98.346667-113.28l10.666667-3.349334 11.050666-3.242666 5.674667-1.6c28.970667-8.064 57.941333-17.856 86.912-26.986667 39.722667-11.349333 62.421333-28.906667 68.117333-52.650667 1.642667-6.848 1.770667-13.76 0.426667-20.736-60.096-34.133333-101.546667-106.474667-101.546667-190.208 0-116.650667 80.426667-211.2 179.648-211.2z m202.112 23.466667c80.618667 0 145.962667 75.648 145.962667 168.96 0 67.072-33.770667 125.013333-82.688 152.298667-1.024 5.354667-0.853333 10.794667 0.490667 16.256 8.277333 34.069333 48.896 40.298667 59.029333 43.456l33.493333 10.56c11.157333 3.477333 22.314667 6.826667 33.493334 9.898666l10.752 3.029334 10.325333 3.157333c48.810667 15.616 81.066667 37.013333 81.066667 90.986667-0.384 43.072-27.413333 64.597333-81.088 64.597333h-9.536c-4.992-38.613333-19.690667-65.834667-44.117334-81.706667a374.570667 374.570667 0 0 0-58.154666-30.698666l-11.861334-4.906667a643.072 643.072 0 0 0-6.186666-2.432l-12.842667-4.864-13.653333-4.906667-14.506667-5.013333-32-10.602667-70.762667-22.741333 4.864-3.797333c48.426667-39.381333 84.970667-104.917333 84.970667-195.050667l0.106667-8.341333c-0.106667-94.272-26.965333-138.730667-64.64-181.76 12.501333-4.032 23.893333-6.378667 37.482666-6.378667z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M793.6 128a102.4 102.4 0 0 1 102.4 102.4v563.2a102.4 102.4 0 0 1-102.4 102.4H230.4A102.4 102.4 0 0 1 128 793.6V230.4A102.4 102.4 0 0 1 230.4 128h563.2z m-76.864 179.2H307.904A52.885333 52.885333 0 0 0 256 360.682667v103.616a276.757333 276.757333 0 0 0 41.450667 146.496l4.650666 7.253333a252.266667 252.266667 0 0 0 112.042667 94.421333v32a20.48 20.48 0 0 0 18.048 22.634667l1.578667 0.128c5.482667 0.512 10.666667 0.682667 15.978666 0.746667l8.064 0.021333a317.397333 317.397333 0 0 0 206.421334-79.018667l6.250666-5.674666A295.850667 295.850667 0 0 0 768 463.530667v-102.848a51.989333 51.989333 0 0 0-50.474667-53.461334l-0.768-0.021333z m-361.429333 111.04c14.506667 0 26.666667 10.517333 29.013333 24.533333l0.341333 2.837334c0.768 17.194667 4.416 34.090667 10.773334 50.048l2.901333 6.762666a139.797333 139.797333 0 0 0 83.52 76.522667l5.653333 1.770667a137.770667 137.770667 0 0 0 41.6 1.066666l6.869334-1.066666a108.864 108.864 0 0 0 78.144-51.541334l2.709333-4.757333a29.312 29.312 0 0 1 36.117333-12.202667l2.624 1.216c6.272 3.349333 11.029333 8.896 13.44 15.509334l0.853334 2.901333c2.026667 8.384 0.384 17.216-4.522667 24.32h-0.064a167.082667 167.082667 0 0 1-115.733333 83.157333l-6.165334 1.002667a170.24 170.24 0 0 1-23.296 2.645333l-7.808 0.170667a177.962667 177.962667 0 0 1-38.976-4.096l-2.133333-0.256a199.893333 199.893333 0 0 1-124.053333-106.090667l-2.709334-5.973333a220.16 220.16 0 0 1-17.92-69.76l-0.64-9.045333a30.293333 30.293333 0 0 1 26.645334-29.461334l2.816-0.213333z m312.32-1.28a36.245333 36.245333 0 0 1 37.376 35.072v1.28a35.84 35.84 0 0 1-35.050667 36.053333h-0.064a36.245333 36.245333 0 1 1-2.261333-72.426666z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 85.333333c235.648 0 426.666667 191.018667 426.666667 426.666667s-191.018667 426.666667-426.666667 426.666667S85.333333 747.648 85.333333 512 276.352 85.333333 512 85.333333z m0 64C311.701333 149.333333 149.333333 311.701333 149.333333 512s162.368 362.666667 362.666667 362.666667 362.666667-162.368 362.666667-362.666667S712.298667 149.333333 512 149.333333z m-202.666667 469.333334a32 32 0 1 1 0 64 32 32 0 0 1 0-64z m405.333334 0a32 32 0 0 1 0 64h-277.333334a32 32 0 0 1 0-64h277.333334z m-405.333334-149.333334a32 32 0 1 1 0 64 32 32 0 0 1 0-64z m405.333334 0a32 32 0 0 1 0 64h-277.333334a32 32 0 0 1 0-64h277.333334z m-405.333334-149.333333a32 32 0 1 1 0 64 32 32 0 0 1 0-64z m405.333334 0a32 32 0 0 1 0 64h-277.333334a32 32 0 0 1 0-64h277.333334z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M671.829333 676.053333c-53.610667-78.933333-97.685333-174.741333-144.789333-292.053333l-21.930667-55.061333c-37.845333-93.653333-71.573333-155.797333-167.936-129.024l-21.504-48.917334-4.8-10.837333c-4.842667-10.922667-27.712-16.106667-43.050666-8.661333-15.36 7.466667-30.08 25.386667-25.024 37.461333l26.816 63.744c-75.818667 43.306667-69.888 98.538667-12.8 208.064l14.869333 28.074667c58.453333 109.546667 130.816 234.794667 260.096 328.512 51.072 37.034667 110.165333 65.386667 177.28 85.056l14.506667 4.074666a52.16 52.16 0 0 0 63.957333-36.458666c4.693333-17.216 0.170667-35.626667-11.989333-48.746667l-16.917334-18.453333c-38.144-42.133333-67.072-77.717333-86.784-106.752z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 85.333333c200.298667 0 362.666667 191.018667 362.666667 426.666667s-162.368 426.666667-362.666667 426.666667S149.333333 747.648 149.333333 512 311.701333 85.333333 512 85.333333z m23.722667 217.066667a25.194667 25.194667 0 0 0-25.408-0.576 24.106667 24.106667 0 0 0-12.522667 21.674667l0.042667 141.781333-96.64-66.816-1.045334-0.704a24.618667 24.618667 0 0 0-33.130666 7.146667l-0.64 1.066666c-6.954667 11.306667-3.882667 25.92 7.04 33.642667l106.645333 73.941333-106.901333 76.117334-1.002667 0.746666a25.088 25.088 0 0 0-4.970667 34.005334l0.725334 1.024a24.64 24.64 0 0 0 33.514666 5.034666l96.533334-68.437333v139.626667c0.170667 8.874667 5.333333 16.938667 13.397333 20.992 8.085333 4.053333 17.770667 3.456 25.237333-1.578667l135.082667-94.229333 0.981333-0.746667c6.336-4.949333 9.92-12.522667 9.728-20.458667a25.194667 25.194667 0 0 0-10.773333-19.925333l-104.917333-72.704 105.472-74.88 1.002666-0.704a25.173333 25.173333 0 0 0 9.472-20.394667 25.258667 25.258667 0 0 0-10.688-19.84l-135.36-94.208z m11.754666 257.642667l66.773334 46.592-66.773334 46.4v-92.992z m0-189.205334l67.370667 47.424-67.370667 47.829334v-95.253334z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M313.26 811.73h646.72v-99.49H313.26v99.49z m0-298.48h646.72v-99.49H313.26v99.49z m0-397.98v99.49h646.72v-99.49H313.26zM64.53 811.73h149.24v-99.49H64.53v99.49z m0-298.48h149.24v-99.49H64.53v99.49z m0-298.49h149.24v-99.49H64.53v99.49z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M343.402667 701.098667l135.04 20.586666 56.597333 98.005334a53.333333 53.333333 0 1 1-92.373333 53.333333l-99.264-171.946667z m549.312-481.237334a85.333333 85.333333 0 0 1 3.285333 23.466667V664.32a85.333333 85.333333 0 0 1-114.154667 80.32C698.325333 714.645333 622.592 693.973333 554.666667 682.666667a13093.546667 13093.546667 0 0 0-234.624-36.330667v-398.506667A19907.733333 19907.733333 0 0 1 554.666667 213.333333c65.706667-9.130667 143.189333-26.453333 232.533333-52.032a85.333333 85.333333 0 0 1 105.514667 58.56zM256 257.578667v379.392l-54.784-7.893334A85.333333 85.333333 0 0 1 128 544.597333v-194.133333a85.333333 85.333333 0 0 1 72.32-84.330667c19.157333-2.944 37.717333-5.802667 55.68-8.533333z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M224 938.666667A96 96 0 0 1 128 842.666667V469.333333c0-212.074667 171.925333-384 384-384s384 171.925333 384 384v373.333334a96 96 0 0 1-96 96zM512 149.333333C335.274667 149.333333 192 292.608 192 469.333333v373.333334a32 32 0 0 0 32 32H320V522.666667a117.333333 117.333333 0 0 1 112.618667-117.248L437.333333 405.333333h149.333334a117.333333 117.333333 0 0 1 117.333333 117.333334V874.666667h96a32 32 0 0 0 31.850667-28.928L832 842.666667V469.333333c0-176.725333-143.274667-320-320-320z m74.666667 320h-149.333334a53.333333 53.333333 0 0 0-53.333333 53.333334V874.666667h256V522.666667a53.333333 53.333333 0 0 0-49.834667-53.226667L586.666667 469.333333zM512 618.666667a42.666667 42.666667 0 0 1 21.354667 79.616L533.333333 746.666667a21.333333 21.333333 0 0 1-42.666666 0v-48.384A42.666667 42.666667 0 0 1 512 618.666667z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 85.333333c212.074667 0 384 171.925333 384 384v373.333334a96 96 0 0 1-96 96H704V522.666667a117.333333 117.333333 0 0 0-117.333333-117.333334h-149.333334a117.333333 117.333333 0 0 0-117.333333 117.333334V938.666667h-96A96 96 0 0 1 128 842.666667V469.333333c0-212.074667 171.925333-384 384-384z m74.666667 384l3.498666 0.128C617.984 471.552 640 498.346667 640 531.093333V938.666667H384V531.093333C384 496.981333 407.893333 469.333333 437.333333 469.333333h149.333334zM512 618.666667a42.666667 42.666667 0 0 0-21.333333 79.616V746.666667a21.333333 21.333333 0 0 0 42.666666 0l0.021334-48.384A42.666667 42.666667 0 0 0 512 618.666667z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M573 421c-23.1 0-41 17.9-41 40s17.9 40 41 40c21.1 0 39-17.9 39-40s-17.9-40-39-40zM293 421c-23.1 0-41 17.9-41 40s17.9 40 41 40c21.1 0 39-17.9 39-40s-17.9-40-39-40z" /><path d="M894 345c-48.1-66-115.3-110.1-189-130v0.1c-17.1-19-36.4-36.5-58-52.1-163.7-119-393.5-82.7-513 81-96.3 133-92.2 311.9 6 439l0.8 132.6c0 3.2 0.5 6.4 1.5 9.4 5.3 16.9 23.3 26.2 40.1 20.9L309 806c33.5 11.9 68.1 18.7 102.5 20.6l-0.5 0.4c89.1 64.9 205.9 84.4 313 49l127.1 41.4c3.2 1 6.5 1.6 9.9 1.6 17.7 0 32-14.3 32-32V753c88.1-119.6 90.4-284.9 1-408zM323 735l-12-5-99 31-1-104-8-9c-84.6-103.2-90.2-251.9-11-361 96.4-132.2 281.2-161.4 413-66 132.2 96.1 161.5 280.6 66 412-80.1 109.9-223.5 150.5-348 102z m505-17l-8 10 1 104-98-33-12 5c-56 20.8-115.7 22.5-171 7l-0.2-0.1C613.7 788.2 680.7 742.2 729 676c76.4-105.3 88.8-237.6 44.4-350.4l0.6 0.4c23 16.5 44.1 37.1 62 62 72.6 99.6 68.5 235.2-8 330z" /><path d="M433 421c-23.1 0-41 17.9-41 40s17.9 40 41 40c21.1 0 39-17.9 39-40s-17.9-40-39-40z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M853.333333 714.666667v64H170.666667v-64h682.666666zM320 405.333333v213.333334l-149.333333-106.666667 149.333333-106.666667z m533.333333 85.333334v64H405.333333v-64h448z m0-234.666667v64H170.666667v-64h682.666666z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M768 384v490.666667a42.666667 42.666667 0 0 1-42.666667 42.666666H298.666667a42.666667 42.666667 0 0 1-42.666667-42.666666V384h512z m-345.152 128c-36.949333 0-66.666667 18.645333-75.797333 51.669333-3.306667 10.88-5.546667 25.728-5.717334 83.029334v6.293333c0 59.050667 2.282667 73.408 5.717334 84.288 9.514667 33.024 38.848 52.053333 75.797333 52.053333 36.586667 0 65.92-18.645333 75.818667-52.053333 2.944-10.453333 4.8-24.192 4.949333-77.909333v-6.378667c0-62.528-1.92-78.08-4.949333-89.322667-9.898667-33.024-39.253333-51.669333-75.818667-51.669333zM661.333333 515.882667h-41.152L570.666667 551.253333v48.938667l44.949333-31.850667v217.130667H661.333333V515.882667zM422.848 555.52c15.637333 0 28.970667 8.170667 32 23.317333 1.770667 6.784 2.858667 18.176 3.029333 61.994667v23.658667c-0.170667 41.130667-1.28 50.901333-3.413333 58.048-4.181333 15.146667-16 22.528-31.616 22.528-16.362667 0-29.333333-7.381333-32.362667-22.528-1.536-7.765333-3.434667-18.645333-3.434666-69.525334 0-53.973333 1.130667-66.794667 3.413333-74.176 4.202667-15.146667 16-23.317333 32.384-23.317333zM853.333333 128a85.333333 85.333333 0 0 1 85.333334 85.333333v298.666667a85.333333 85.333333 0 0 1-85.333334 85.333333h-42.666666v-192h10.666666a32 32 0 0 0 0-64h-618.666666a32 32 0 0 0-3.072 63.850667L202.666667 405.333333h10.666666v192H170.666667a85.333333 85.333333 0 0 1-85.333334-85.333333V213.333333a85.333333 85.333333 0 0 1 85.333334-85.333333h682.666666z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M501.333333 874.666667a32 32 0 0 1 0 64h-320a32 32 0 0 1 0-64h320zM134.250667 605.034667l282.325333 165.269333c15.573333 9.130667 20.928 29.354667 11.946667 45.162667a32.362667 32.362667 0 0 1-44.544 12.096L101.632 662.293333a33.301333 33.301333 0 0 1-11.925333-45.162666 32.362667 32.362667 0 0 1 44.544-12.096z m278.165333-422.4l225.877333 132.224a44.416 44.416 0 0 1 15.893334 60.202666L578.133333 508.650667l338.773334 198.314666a44.416 44.416 0 0 1 15.936 60.202667 43.136 43.136 0 0 1-59.392 16.149333L534.656 584.96l-76.074667 133.589333a43.136 43.136 0 0 1-59.370666 16.128L173.333333 602.474667a44.416 44.416 0 0 1-15.893333-60.202667l195.605333-343.509333a43.136 43.136 0 0 1 59.370667-16.128z m15.232-92.864l282.346667 165.269333c15.573333 9.130667 20.906667 29.354667 11.925333 45.162667a32.362667 32.362667 0 0 1-44.544 12.096L395.050667 147.029333a33.301333 33.301333 0 0 1-11.946667-45.162666 32.362667 32.362667 0 0 1 44.544-12.096z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M701.041778 455.111111a56.888889 56.888889 0 0 1 56.888889 56.888889 56.888889 56.888889 0 0 1-56.888889 56.888889 56.888889 56.888889 0 0 1-56.888889-56.888889 56.888889 56.888889 0 0 1 56.888889-56.888889z" /><path d="M359.708444 455.111111a56.888889 56.888889 0 0 1 56.888889 56.888889 56.888889 56.888889 0 0 1-56.888889 56.888889 56.888889 56.888889 0 0 1-56.888888-56.888889 56.888889 56.888889 0 0 1 56.888888-56.888889z" /><path d="M530.375111 910.165333H134.314667l-2.218667-36.352V512a398.222222 398.222222 0 1 1 398.222222 398.222222z m-329.955555-68.266666h329.955555a329.955556 329.955556 0 1 0-329.955555-329.955556z" /><path d="M530.375111 455.111111a56.888889 56.888889 0 0 1 56.888889 56.888889 56.888889 56.888889 0 0 1-56.888889 56.888889 56.888889 56.888889 0 0 1-56.888889-56.888889 56.888889 56.888889 0 0 1 56.888889-56.888889z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M768 384v533.333333a42.666667 42.666667 0 0 1-42.56-39.466666L725.333333 874.666667a42.666667 42.666667 0 0 0-85.226666-3.2L640 874.666667a42.666667 42.666667 0 0 1-85.226667 3.2L554.666667 874.666667a42.666667 42.666667 0 0 0-85.226667-3.2L469.333333 874.666667a42.666667 42.666667 0 0 1-85.226666 3.2L384 874.666667a42.666667 42.666667 0 0 0-85.226667-3.2L298.666667 874.666667a42.666667 42.666667 0 0 1-39.466667 42.56L256 917.333333V384h512z m-106.666667 277.333333H362.666667a21.333333 21.333333 0 0 0-2.496 42.517334L362.666667 704h298.666666a21.333333 21.333333 0 0 0 0-42.666667z m192-533.333333a85.333333 85.333333 0 0 1 85.333334 85.333333v256a85.333333 85.333333 0 0 1-85.333334 85.333334h-42.666666v-170.666667h10.666666a32 32 0 0 0 0-64h-618.666666a32 32 0 0 0-3.072 63.850667L202.666667 384h10.666666v170.666667H170.666667a85.333333 85.333333 0 0 1-85.333334-85.333334V213.333333a85.333333 85.333333 0 0 1 85.333334-85.333333h682.666666z m-192 384H362.666667a21.333333 21.333333 0 0 0-2.496 42.517333L362.666667 554.666667h298.666666a21.333333 21.333333 0 0 0 0-42.666667z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M531.626667 915.228444a66.616889 66.616889 0 0 1-51.598223-24.462222L120.092444 484.181333a66.503111 66.503111 0 0 1-4.835555-74.296889l130.844444-269.027555a66.673778 66.673778 0 0 1 56.888889-32.142222h456.362667a66.787556 66.787556 0 0 1 57.173333 32.312889l1.308445 2.503111 130.844444 266.524444a66.673778 66.673778 0 0 1-5.688889 74.296889l-1.194666 1.479111-358.741334 404.935111a66.787556 66.787556 0 0 1-51.655111 24.462222z m-359.253334-472.177777l359.253334 405.731555 1.194666-1.479111 358.115556-404.252444-1.365333-2.503111-129.877334-264.988445H303.616z" /><path d="M531.626667 668.16a53.930667 53.930667 0 0 1-41.472-20.195556L270.165333 400.156444l49.948445-44.316444 211.512889 238.933333 211.740444-238.933333 49.948445 44.316444-220.216889 247.808a53.930667 53.930667 0 0 1-41.472 20.195556z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M701.64898 117.446531l2.194285 3.552653L778.741551 250.77551H815.020408a114.938776 114.938776 0 0 1 114.855184 110.320327L929.959184 365.714286v355.265306a114.938776 114.938776 0 0 1-110.320327 114.855184L815.020408 835.918367h-606.040816a114.938776 114.938776 0 0 1-114.855184-110.320326L94.040816 720.979592v-355.265306a114.938776 114.938776 0 0 1 110.320327-114.855184L208.979592 250.77551h123.109877l271.67347-156.839183a73.289143 73.289143 0 0 1 97.886041 23.531102zM815.020408 313.469388h-606.040816a52.244898 52.244898 0 0 0-52.140408 48.817632L156.734694 365.714286v355.265306a52.244898 52.244898 0 0 0 48.817633 52.140408L208.979592 773.22449h606.040816a52.244898 52.244898 0 0 0 52.140408-48.817633L867.265306 720.979592V668.734694h-177.632653a114.938776 114.938776 0 0 1-114.855184-110.320327L574.693878 553.795918a114.938776 114.938776 0 0 1 114.938775-114.938775H867.265306v-73.142857a52.244898 52.244898 0 0 0-52.244898-52.244898z m52.244898 188.081632h-177.632653a52.244898 52.244898 0 0 0-52.140408 48.817633L637.387755 553.795918a52.244898 52.244898 0 0 0 52.244898 52.244898H867.265306v-104.489796z m-156.734694 20.89796a31.346939 31.346939 0 1 1 0 62.693877 31.346939 31.346939 0 0 1 0-62.693877zM636.969796 147.706776l-1.734531 0.794122L458.041469 250.77551H706.35102l-56.821551-98.429388a10.490776 10.490776 0 0 0-12.580571-4.639346z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M256 319.402667V320h576a117.162667 117.162667 0 0 1 106.581333 112.021333l0.085334 4.714667V512h-25.92l-2.986667-0.426667-3.093333-0.170666h-213.333334l-4.714666 0.106666a117.333333 117.333333 0 0 0-112.512 112.384l-0.106667 4.842667 0.085333 4.714667a117.333333 117.333333 0 0 0 112.426667 112.533333l4.821333 0.085333H874.666667V746.666667h64v52.736a117.333333 117.333333 0 0 1-112.618667 117.248l-4.714667 0.085333h-618.666666a117.333333 117.333333 0 0 1-117.248-112.618667L85.333333 799.424v-362.666667a117.333333 117.333333 0 0 1 112.618667-117.248l4.714667-0.106666H256z m682.666667 256v106.666666H693.333333l-3.498666-0.106666a53.333333 53.333333 0 0 1-49.706667-49.706667L640 628.736l0.106667-3.498667 0.341333-3.456a53.333333 53.333333 0 0 1 49.386667-46.250666l3.498666-0.128H938.666667z m-224 21.333333a32 32 0 1 0 0 64 32 32 0 0 0 0-64z m-9.066667-413.418667l2.24 3.626667 52.16 90.368h-73.898667l-33.706666-58.368a10.709333 10.709333 0 0 0-12.842667-4.757333l-1.749333 0.810666-107.968 62.314667h-128.597334l204.416-117.994667a74.816 74.816 0 0 1 99.946667 24zM512 213.333333h192v64h-192v-64z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M885.824 597.333333c17.408 0 31.509333 14.336 31.509333 32 0 16.64-12.501333 30.293333-28.458666 31.850667L184.533333 661.333333l135.317334 137.365334c11.52 11.712 12.266667 30.250667 2.176 42.816l-2.154667 2.432a31.146667 31.146667 0 0 1-42.154667 2.218666l-2.410666-2.197333-153.258667-155.584a53.930667 53.930667 0 0 1 0-75.413333 52.16 52.16 0 0 1 32.96-15.466667L159.168 597.333333h726.656zM745.6 177.834667l2.389333 2.197333 153.898667 155.584a53.76 53.76 0 0 1 0 75.413333 52.458667 52.458667 0 0 1-33.088 15.466667l-4.181333 0.170667-729.386667-0.149334c-17.450667 0-28.565333-14.314667-28.565333-32C106.666667 377.877333 119.36 362.666667 135.253333 362.666667h703.893334l-135.872-137.365334a32.277333 32.277333 0 0 1-2.176-42.816l2.154666-2.432a31.36 31.36 0 0 1 42.346667-2.218666z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 85.333333c235.648 0 426.666667 191.018667 426.666667 426.666667s-191.018667 426.666667-426.666667 426.666667S85.333333 747.648 85.333333 512 276.352 85.333333 512 85.333333z m0 64C311.701333 149.333333 149.333333 311.701333 149.333333 512s162.368 362.666667 362.666667 362.666667 362.666667-162.368 362.666667-362.666667S712.298667 149.333333 512 149.333333z m182.997333 179.669334a30.72 30.72 0 0 1 0 43.456l-139.52 139.52 139.52 139.562666a30.72 30.72 0 1 1-43.456 43.456l-139.52-139.562666-139.562666 139.562666a30.72 30.72 0 1 1-43.456-43.456L468.565333 512l-139.562666-139.52a30.72 30.72 0 1 1 43.456-43.456L512 468.522667l139.52-139.52a30.72 30.72 0 0 1 43.456 0z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 85.333333c235.648 0 426.666667 191.018667 426.666667 426.666667s-191.018667 426.666667-426.666667 426.666667S85.333333 747.648 85.333333 512 276.352 85.333333 512 85.333333z m182.997333 243.669334a30.72 30.72 0 0 0-43.456 0l-139.52 139.52-139.562666-139.52a30.72 30.72 0 1 0-43.456 43.456l139.562666 139.52-139.562666 139.562666a30.72 30.72 0 1 0 43.456 43.456L512 555.434667l139.52 139.562666a30.72 30.72 0 1 0 43.456-43.456L555.477333 512l139.52-139.52a30.72 30.72 0 0 0 0-43.456z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M506.389333 106.773333l13.888 0.106667c182.357333 3.754667 339.754667 129.024 384.725334 306.133333H542.293333a127.658667 127.658667 0 0 0-90.538666 37.205334 128.213333 128.213333 0 0 0-37.717334 90.453333 122.453333 122.453333 0 0 0 91.413334 118.250667L917.333333 773.76v-52.970667l-398.613333-111.232a71.509333 71.509333 0 0 1-53.333333-69.056 76.970667 76.970667 0 0 1 76.906666-76.586666h372.138667c1.92 16.128 2.901333 32.490667 2.901333 49.066666v261.717334a121.386667 121.386667 0 0 1-47.317333 96.213333 120.874667 120.874667 0 0 1-104.96 20.992L230.826667 749.098667c-43.008-11.52-78.08-42.666667-94.72-84.010667A404.266667 404.266667 0 0 1 106.666667 512.341333 405.781333 405.781333 0 0 1 228.266667 222.357333a404.053333 404.053333 0 0 1 291.989333-115.562666h-13.866667z m49.045334 410.005334A28.949333 28.949333 0 0 0 512 542.016c0 10.368 5.504 19.946667 14.464 25.173333a28.949333 28.949333 0 0 0 43.52-25.173333c0-10.432-5.546667-20.053333-14.549333-25.237333z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M565.888 174.784c5.824 12.8 9.194667 26.56 9.941333 40.533333l0.170667 6.016v105.258667l253.013333 137.024 2.624 1.216a113.941333 113.941333 0 0 1 64.256 97.152l0.106667 4.992v236.330667l-0.085333 4.586666c-2.389333 59.306667-50.752 106.944-110.933334 109.354667L780.16 917.333333 576 917.312V917.333333H245.333333c-63.210667 0-114.773333-48.853333-117.248-110.037333L128 802.688V313.962667c0-43.626667 25.322667-83.306667 65.024-102.613334l4.650667-2.133333 213.333333-92.650667c59.221333-25.706667 128.554667 0.362667 154.88 58.218667zM576 397.589333v222.890667c3.349333-1.173333 6.933333-1.813333 10.666667-1.813333h128a32 32 0 0 1 0 64h-128c-3.733333 0-7.317333-0.64-10.666667-1.813334v174.272h204.181333l3.456-0.085333c26.325333-1.706667 47.36-22.4 49.066667-48.32l0.128-3.413333V566.976l-0.149333-3.818667a51.797333 51.797333 0 0 0-27.626667-41.856l-3.498667-1.685333-2.389333-1.173333L576 397.589333z m-135.616-223.786666l-3.370667 1.344-213.333333 92.224a51.946667 51.946667 0 0 0-31.530667 43.584L192 314.773333v486.698667c0 27.498667 22.016 50.005333 49.834667 51.754667L245.333333 853.333333H512V222.549333c0-4.352-0.554667-8.682667-1.664-12.885333l-1.28-4.138667-1.642667-4.053333c-11.477333-25.066667-40.896-36.949333-67.029333-27.648zM416 618.666667a32 32 0 0 1 0 64h-128a32 32 0 0 1 0-64h128z m0-170.666667a32 32 0 0 1 0 64h-128a32 32 0 0 1 0-64h128z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M576 917.333333h42.666667V349.696l210.346666 113.92 2.624 1.216a113.941333 113.941333 0 0 1 64.256 97.152l0.106667 4.992v236.330667l-0.085333 4.586666c-2.389333 59.306667-50.752 106.944-110.933334 109.354667L780.16 917.333333 576 917.312V917.333333H245.333333c-63.210667 0-114.773333-48.853333-117.248-110.037333L128 802.688V313.962667c0-43.626667 25.322667-83.306667 65.024-102.613334l4.650667-2.133333 213.333333-92.650667c59.221333-25.706667 128.554667 0.362667 154.88 58.218667 5.824 12.8 9.194667 26.56 9.941333 40.533333l0.170667 6.016V917.333333z m-160-298.666666h-128a32 32 0 0 0-3.072 63.850666L288 682.666667h128a32 32 0 0 0 0-64z m362.666667 0H682.666667v64h96a32 32 0 0 0 0-64z m-362.666667-170.666667h-128a32 32 0 0 0-3.072 63.850667L288 512h128a32 32 0 0 0 0-64z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M421.333333 542.229333a60.437333 60.437333 0 0 1 60.437334 60.437334v211.562666A60.437333 60.437333 0 0 1 421.333333 874.666667H209.770667A60.437333 60.437333 0 0 1 149.333333 814.229333V602.666667a60.437333 60.437333 0 0 1 60.437334-60.437334h211.562666z m392.896 0A60.437333 60.437333 0 0 1 874.666667 602.666667v211.562666A60.437333 60.437333 0 0 1 814.229333 874.666667H602.666667a60.437333 60.437333 0 0 1-60.437334-60.437334V602.666667a60.437333 60.437333 0 0 1 60.437334-60.437334h211.562666zM421.333333 149.333333a60.437333 60.437333 0 0 1 60.437334 60.437334v211.562666a60.437333 60.437333 0 0 1-60.437334 60.437334H209.770667A60.437333 60.437333 0 0 1 149.333333 421.333333V209.770667A60.437333 60.437333 0 0 1 209.770667 149.333333h211.562666z m287.104 0a166.229333 166.229333 0 1 1 0 332.437334 166.229333 166.229333 0 0 1 0-332.437334z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M395.733333 583.189333a32.042667 32.042667 0 0 1 42.88 47.509334L237.333333 832H394.666667l3.072 0.149333A32 32 0 0 1 394.666667 896h-234.666667l-3.072-0.149333A32 32 0 0 1 128 864v-234.666667l0.149333-3.072A32 32 0 0 1 160 597.333333l3.072 0.149334A32 32 0 0 1 192 629.333333v157.333334l201.301333-201.28z m189.653334 2.197334c11.733333-11.733333 30.293333-12.458667 42.88-2.197334l2.432 2.197334L832 786.666667V629.333333l0.149333-3.072a32 32 0 0 1 28.778667-28.8L864 597.333333l3.072 0.149334a32 32 0 0 1 28.8 28.778666L896 629.333333v234.666667l-0.149333 3.072a32 32 0 0 1-28.778667 28.8L864 896h-234.666667l-3.072-0.149333a32 32 0 0 1 0-63.701334L629.333333 832h157.333334l-201.28-201.301333-2.197334-2.432a32.042667 32.042667 0 0 1 2.197334-42.88zM394.666667 128a32 32 0 0 1 3.072 63.850667L394.666667 192h-157.333334l201.28 201.301333a32.042667 32.042667 0 0 1-42.88 47.509334l-2.432-2.197334L192 237.333333V394.666667a32 32 0 0 1-28.928 31.850666L160 426.666667a32 32 0 0 1-31.850667-28.928L128 394.666667v-234.666667a32 32 0 0 1 28.928-31.850667L160 128h234.666667z m469.333333 0l3.072 0.149333a32 32 0 0 1 28.8 28.778667L896 160v234.666667l-0.149333 3.072a32 32 0 0 1-28.778667 28.8L864 426.666667l-3.072-0.149334a32 32 0 0 1-28.8-28.778666L832 394.666667v-157.333334l-201.301333 201.28-2.432 2.197334a32.042667 32.042667 0 0 1-45.077334-45.077334l2.197334-2.432L786.666667 192H629.333333l-3.072-0.149333a32 32 0 0 1 0-63.701334L629.333333 128h234.666667z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M289.5 613.5a128 128 0 1 0 0 181 127.5 127.5 0 0 0 0-181z m-50.9 130.1a56 56 0 0 1-79.2 0 56.1 56.1 0 0 1 0-79.2 56 56 0 0 1 79.2 0 56.1 56.1 0 0 1 0 79.2zM515 338a128 128 0 1 0-90.5-37.5A127.5 127.5 0 0 0 515 338z m-39.6-167.6a56 56 0 0 1 79.2 0 56.1 56.1 0 0 1 0 79.2 56 56 0 0 1-79.2 0 56.1 56.1 0 0 1 0-79.2z m439.1 456.1a128 128 0 1 0 0 181 127.5 127.5 0 0 0 0-181z m-50.9 130.1a56 56 0 0 1-79.2 0 56.1 56.1 0 0 1 0-79.2 56 56 0 0 1 79.2 0 56.1 56.1 0 0 1 0 79.2zM136.2 514.2a201.1 201.1 0 0 1 63.3-10.2h1.8a4 4 0 0 0 3.9-3.3 311.5 311.5 0 0 1 86.2-163.3 314.5 314.5 0 0 1 42.1-35.4 3.9 3.9 0 0 0 1.3-5 200.9 200.9 0 0 1-18.3-62.9 4.1 4.1 0 0 0-6.1-3c-96.6 59.7-164.7 161-179.4 278.8a3.9 3.9 0 0 0 5.2 4.3z m573.4 366.5a198.2 198.2 0 0 1-26.5-22.3 208.3 208.3 0 0 1-20.1-23.3 3.8 3.8 0 0 0-5.1-1.2c-8 4.2-16.1 8.1-24.5 11.6a313 313 0 0 1-242.8 0 287.6 287.6 0 0 1-31.5-15.5 4.1 4.1 0 0 0-5.1 1 177.3 177.3 0 0 1-13.1 14.4 195.7 195.7 0 0 1-36.5 28.9 4 4 0 0 0 0 6.8 384.5 384.5 0 0 0 405 6.4 4.1 4.1 0 0 0 0.2-6.8z m-14.3-575.2a314 314 0 0 1 104.2 131.1 306.2 306.2 0 0 1 21.4 77.3 3.7 3.7 0 0 0 3.6 3.1 199.7 199.7 0 0 1 65.3 10.9 3.6 3.6 0 0 0 4.7-3.7c-10.6-121.5-77.7-226.7-174.9-289.3a3.6 3.6 0 0 0-5.5 2.6 200.7 200.7 0 0 1-19.8 63.4 3.6 3.6 0 0 0 1 4.6z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 967.68c251.668 0 455.68-204.012 455.68-455.68S763.668 56.32 512 56.32 56.32 260.332 56.32 512 260.332 967.68 512 967.68z m0-71.68c-212.07 0-384-171.93-384-384s171.93-384 384-384 384 171.93 384 384-171.93 384-384 384z" /><path d="M544.297 405.279a77.599 77.599 0 1 1 77.599 77.578 30.72 30.72 0 0 0 0 61.44c76.78 0 139.028-62.249 139.028-139.029S698.675 266.24 621.896 266.24s-139.039 62.249-139.039 139.028a30.72 30.72 0 0 0 61.44 0z m-61.44 213.217a77.588 77.588 0 0 1-155.177 0 77.588 77.588 0 0 1 77.588-77.599 30.72 30.72 0 0 0 0-61.44c-76.769 0-139.028 62.239-139.028 139.039 0 76.78 62.249 139.028 139.028 139.028 76.79 0 139.029-62.248 139.029-139.028a30.72 30.72 0 0 0-61.44 0z" /><path d="M482.857 402.156V619.93h61.44V402.156z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 554.666667c83.2 0 166.4 11.626667 249.6 34.858666a183.829333 183.829333 0 0 1 134.4 177.066667V810.666667a85.333333 85.333333 0 0 1-85.333333 85.333333H213.333333a85.333333 85.333333 0 0 1-85.333333-85.333333v-44.096a183.829333 183.829333 0 0 1 134.4-177.066667C345.6 566.314667 428.8 554.666667 512 554.666667z m-0.064 42.666666c-20.245333 0-30.698667 7.104-31.36 21.333334L450.133333 776.704a21.333333 21.333333 0 0 0 5.674667 18.944l40.938667 42.026667a21.333333 21.333333 0 0 0 30.549333 0l40.96-42.026667a21.333333 21.333333 0 0 0 5.653333-18.944L543.402667 618.666667c-0.725333-14.229333-11.221333-21.333333-31.466667-21.333334zM512 106.666667c117.824 0 213.333333 95.509333 213.333333 213.333333s-95.509333 213.333333-213.333333 213.333333-213.333333-95.509333-213.333333-213.333333S394.176 106.666667 512 106.666667z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M693.333333 128A32 32 0 0 1 725.333333 160V192h74.666667a117.333333 117.333333 0 0 1 117.248 112.618667L917.333333 309.333333v448a117.333333 117.333333 0 0 1-117.333333 117.333334h-576A117.333333 117.333333 0 0 1 106.666667 757.333333v-448A117.333333 117.333333 0 0 1 224 192H298.666667V160a32 32 0 0 1 64 0V192h298.666666V160A32 32 0 0 1 693.333333 128zM298.666667 256h-74.666667A53.333333 53.333333 0 0 0 170.666667 309.333333v448a53.333333 53.333333 0 0 0 53.333333 53.333334h576a53.333333 53.333333 0 0 0 53.333333-53.333334v-448a53.333333 53.333333 0 0 0-53.333333-53.333333H725.333333v10.666667a32 32 0 0 1-64 0V256H362.666667v10.666667a32 32 0 0 1-64 0V256z m32 362.666667a32 32 0 0 1 0 64h-64a32 32 0 0 1 0-64h64z m213.333333 0a32 32 0 0 1 0 64h-64a32 32 0 0 1 0-64h64z m213.333333 0a32 32 0 0 1 0 64h-64a32 32 0 0 1 0-64h64z m-426.666666-192a32 32 0 0 1 0 64h-64a32 32 0 0 1 0-64h64z m213.333333 0a32 32 0 0 1 0 64h-64a32 32 0 0 1 0-64h64z m213.333333 0a32 32 0 0 1 0 64h-64a32 32 0 0 1 0-64h64z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M693.333333 128A32 32 0 0 1 725.333333 160V192h74.666667a117.333333 117.333333 0 0 1 117.248 112.618667L917.333333 309.333333v448a117.333333 117.333333 0 0 1-112.618666 117.248L800 874.666667h-576a117.333333 117.333333 0 0 1-117.248-112.618667L106.666667 757.333333v-448a117.333333 117.333333 0 0 1 112.618666-117.248L224 192H298.666667V160a32 32 0 0 1 64 0V192h298.666666V160A32 32 0 0 1 693.333333 128zM853.333333 426.666667H170.666667v330.666666a53.333333 53.333333 0 0 0 49.834666 53.226667L224 810.666667h576a53.333333 53.333333 0 0 0 53.226667-49.834667L853.333333 757.333333V426.666667z m-554.666666-170.666667h-74.666667a53.333333 53.333333 0 0 0-53.226667 49.834667L170.666667 309.333333V362.666667h682.666666v-53.333334a53.333333 53.333333 0 0 0-49.834666-53.226666L800 256H725.333333v10.666667a32 32 0 0 1-64 0V256H362.666667v10.666667a32 32 0 0 1-64 0V256z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M693.333333 128A32 32 0 0 1 725.333333 160V192h74.666667a117.333333 117.333333 0 0 1 117.248 112.618667L917.333333 309.333333v448a117.333333 117.333333 0 0 1-112.618666 117.248L800 874.666667h-576a117.333333 117.333333 0 0 1-117.248-112.618667L106.666667 757.333333v-448a117.333333 117.333333 0 0 1 112.618666-117.248L224 192H298.666667V160a32 32 0 0 1 64 0V192h298.666666V160A32 32 0 0 1 693.333333 128zM853.333333 426.666667H170.666667v330.666666a53.333333 53.333333 0 0 0 49.834666 53.226667L224 810.666667h576a53.333333 53.333333 0 0 0 53.226667-49.834667L853.333333 757.333333V426.666667z m-138.666666 234.666666a32 32 0 0 1 0 64h-426.666667a32 32 0 0 1 0-64h426.666667z m-277.333334-149.333333a32 32 0 0 1 0 64h-149.333333a32 32 0 0 1 0-64h149.333333zM298.666667 256h-74.666667a53.333333 53.333333 0 0 0-53.226667 49.834667L170.666667 309.333333V362.666667h682.666666v-53.333334a53.333333 53.333333 0 0 0-49.834666-53.226666L800 256H725.333333v10.666667a32 32 0 0 1-64 0V256H362.666667v10.666667a32 32 0 0 1-64 0V256z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M160 640a32 32 0 0 1 31.850667 28.928L192 672v118.848l0.128 3.221333a41.152 41.152 0 0 0 37.632 37.802667l3.392 0.128H352l3.072 0.149333a32 32 0 0 1 0 63.701334L352 896h-118.848l-4.565333-0.106667a105.152 105.152 0 0 1-100.48-100.352L128 790.848V672l0.149333-3.072A32 32 0 0 1 160 640z m704 0a32 32 0 0 1 31.850667 28.928L896 672v118.848a105.152 105.152 0 0 1-100.586667 105.045333l-4.565333 0.106667H672a32 32 0 0 1-3.072-63.850667L672 832h118.848a41.152 41.152 0 0 0 41.024-37.930667l0.128-3.2V672a32 32 0 0 1 32-32z m0-160a32 32 0 0 1 0 64h-704a32 32 0 0 1 0-64h704zM352 128a32 32 0 0 1 3.072 63.850667L352 192h-118.848a41.152 41.152 0 0 0-41.024 37.930667l-0.128 3.2V352a32 32 0 0 1-63.850667 3.072L128 352v-118.848a105.152 105.152 0 0 1 100.586667-105.045333L233.152 128H352z m438.848 0l4.565333 0.106667a105.152 105.152 0 0 1 100.48 100.352l0.106667 4.693333V352l-0.149333 3.072a32 32 0 0 1-63.701334 0L832 352v-118.848l-0.128-3.221333a41.152 41.152 0 0 0-37.632-37.802667L790.848 192H672l-3.072-0.149333a32 32 0 0 1 0-63.701334L672 128h118.848z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M552 593.8a44 44 0 1 0 44-44 44 44 0 0 0-44 44z m368-140h-88v-140a40 40 0 0 0-40-40H569.2l-82.9-143.6a40.2 40.2 0 0 0-54.7-14.7L150.8 277.7a39.9 39.9 0 0 0-22.8 36.1v560a40 40 0 0 0 40 40h624a40 40 0 0 0 40-40v-140h88a40 40 0 0 0 40-40v-200a40 40 0 0 0-40-40zM439.9 193.9l46.2 79.9H301.5zM760 841.8H200v-496h560v108H588a140 140 0 0 0 0 280h172z m136-172H588a76 76 0 0 1 0-152h308z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M744 251.1a40.1 40.1 0 0 0-31.3-15.1H640v-68a40 40 0 0 0-40-40H104a40 40 0 0 0-40 40v560a40 40 0 0 0 40 40h88a128 128 0 0 0 256 0h188a128 128 0 0 0 256 0h28a40 40 0 0 0 40-40V536.5a39.9 39.9 0 0 0-8.7-24.9zM697.3 308l95.5 120H640V308zM320 824a56 56 0 1 1 56-56 56 56 0 0 1-56 56z m248-128H425.8a127.9 127.9 0 0 0-211.6 0H136V200h432v496z m-120.1 67.6z m-0.3-5.5z m-0.4-4.4c0-0.3-0.1-0.6-0.1-1s0.1 0.7 0.1 1z m-0.7-5.3z m-0.7-4.3a2.9 2.9 0 0 1-0.2-0.9 2.9 2.9 0 0 0 0.2 0.9z m-1.1-5.2a0.1 0.1 0 0 0-0.1-0.1 0.1 0.1 0 0 1 0.1 0.1z m-1.1-4.2c-0.1-0.3-0.1-0.5-0.2-0.8s0.1 0.5 0.2 0.8z m-1.4-5a0.1 0.1 0 0 0-0.1-0.1 0.1 0.1 0 0 1 0.1 0.1z m-1.4-4.1a2.5 2.5 0 0 1-0.2-0.7 2.5 2.5 0 0 0 0.2 0.7z m-1.8-4.8z m-1.7-4.1l-0.2-0.5z m-4.1-8.5c-0.1-0.1-0.1-0.3-0.2-0.4s0.1 0.3 0.2 0.4z m-4.7-8.1l-0.2-0.3z m-236.4 63.5z m0.3-5.5z m0.4-4.4c0-0.3 0.1-0.6 0.1-1s-0.1 0.7-0.1 1z m0.7-5.3z m0.7-4.3a2.9 2.9 0 0 0 0.2-0.9 2.9 2.9 0 0 1-0.2 0.9z m1.1-5.2a0.1 0.1 0 0 1 0.1-0.1 0.1 0.1 0 0 0-0.1 0.1z m1.1-4.2c0.1-0.3 0.1-0.5 0.2-0.8s-0.1 0.5-0.2 0.8z m1.4-5a0.1 0.1 0 0 1 0.1-0.1 0.1 0.1 0 0 0-0.1 0.1z m1.4-4.1a2.5 2.5 0 0 0 0.2-0.7 2.5 2.5 0 0 1-0.2 0.7z m1.8-4.8z m1.7-4.1l0.2-0.5z m4.1-8.5c0.1-0.1 0.1-0.3 0.2-0.4s-0.1 0.3-0.2 0.4z m4.7-8.1l0.2-0.3zM764 824a56 56 0 1 1 56-56 56 56 0 0 1-56 56z m0-184a127.7 127.7 0 0 0-105.8 56H640V492h203.7l44.3 55.7V696h-18.2A127.7 127.7 0 0 0 764 640z m-123.6 94.7c0.1-0.3 0.1-0.5 0.2-0.8s-0.1 0.5-0.2 0.8z m1.4-5a0.1 0.1 0 0 1 0.1-0.1 0.1 0.1 0 0 0-0.1 0.1z m1.4-4.1a2.5 2.5 0 0 0 0.2-0.7 2.5 2.5 0 0 1-0.2 0.7z m1.8-4.8z m1.7-4.1l0.2-0.5z m4.1-8.5c0.1-0.1 0.1-0.3 0.2-0.4s-0.1 0.3-0.2 0.4z m4.7-8.1l0.2-0.3z m232.1 34.6c-0.1-0.3-0.1-0.5-0.2-0.8s0.1 0.5 0.2 0.8z m-1.4-5a0.1 0.1 0 0 0-0.1-0.1 0.1 0.1 0 0 1 0.1 0.1z m-1.4-4.1a2.5 2.5 0 0 1-0.2-0.7 2.5 2.5 0 0 0 0.2 0.7z m-1.8-4.8z m-1.7-4.1l-0.2-0.5z m-4.1-8.5c-0.1-0.1-0.1-0.3-0.2-0.4s0.1 0.3 0.2 0.4z m-4.7-8.1l-0.2-0.3z m19.4 62.4z m-3.3-23.7a0.1 0.1 0 0 1 0.1 0.1 0.1 0.1 0 0 0-0.1-0.1z m1 4.4a2.9 2.9 0 0 0 0.2 0.9 2.9 2.9 0 0 1-0.2-0.9z m0.9 5.1z m0.6 4.4c0 0.4 0.1 0.7 0.1 1s-0.1-0.6-0.1-1z m0.5 5.3z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M947.6 575.6l-74.3-74.4a42.9 42.9 0 0 0-30.5-12.3 49.4 49.4 0 0 0-34.8 14.7l-279 279a50.1 50.1 0 0 0-13.8 25.5L488 942a16 16 0 0 0 15.6 19.2 12.4 12.4 0 0 0 3.3-0.4l133.9-27.1a50.9 50.9 0 0 0 25.4-13.8l279.1-279.1c18.6-18.6 19.7-47.9 2.3-65.2zM623.8 871.8l-58.7 11.9 11.9-58.6 184.2-184.2 46.8 46.7zM847.6 648l-46.8-46.7 41-41 46.8 46.7zM512 604c144.7 0 262-117.3 262-262S656.7 80 512 80 250 197.3 250 342a261.7 261.7 0 0 0 117.4 218.5c-140 57.4-239.3 195.4-239.3 355.5v25.5a4 4 0 0 0 4 4h64a4 4 0 0 0 4-4V916a307.1 307.1 0 0 1 24.6-120.9 315.1 315.1 0 0 1 166.4-166.5A307.9 307.9 0 0 1 512 604zM377.6 476.4A190.2 190.2 0 1 1 512 532a189.1 189.1 0 0 1-134.4-55.6z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M860 760H296.3a88 88 0 1 0 0 72H860a4 4 0 0 0 4-4v-64a4 4 0 0 0-4-4zM216 316a87.8 87.8 0 0 0 80.3-52H860a4 4 0 0 0 4-4v-64a4 4 0 0 0-4-4H296.3A88 88 0 1 0 216 316z m592 108a87.8 87.8 0 0 0-80.3 52H164a4 4 0 0 0-4 4v64a4 4 0 0 0 4 4h563.7A88 88 0 1 0 808 424z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 106.666667a106.666667 106.666667 0 0 1 106.581333 102.378666L618.666667 213.333333h245.333333a32 32 0 0 1 0 64H789.333333v522.666667a117.333333 117.333333 0 0 1-112.618666 117.248L672 917.333333h-341.333333a117.333333 117.333333 0 0 1-117.248-112.618666L213.333333 800V277.333333H160a32 32 0 0 1 0-64H405.333333a106.666667 106.666667 0 0 1 106.666667-106.666666z m213.333333 170.666666H277.333333v522.666667a53.333333 53.333333 0 0 0 49.834667 53.226667L330.666667 853.333333h341.333333a53.333333 53.333333 0 0 0 53.226667-49.834666L725.333333 800V277.333333z m-309.333333 149.333334a32 32 0 0 1 32 32v234.666666a32 32 0 0 1-64 0v-234.666666a32 32 0 0 1 32-32z m170.666667 0a32 32 0 0 1 32 32v234.666666a32 32 0 0 1-64 0v-234.666666a32 32 0 0 1 32-32zM512 164.842667c-25.706667 0-46.72 20.010667-48.384 45.312l-0.106667 3.178666h96.981334A48.490667 48.490667 0 0 0 512 164.842667z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 106.666667a106.666667 106.666667 0 0 1 106.581333 102.378666L618.666667 213.333333h245.333333a32 32 0 0 1 0 64H789.333333v522.666667a117.333333 117.333333 0 0 1-112.618666 117.248L672 917.333333h-341.333333a117.333333 117.333333 0 0 1-117.248-112.618666L213.333333 800V277.333333H160a32 32 0 0 1 0-64H405.333333a106.666667 106.666667 0 0 1 106.666667-106.666666z m-96 320a32 32 0 0 0-32 32v234.666666a32 32 0 0 0 64 0v-234.666666a32 32 0 0 0-32-32z m170.666667 0a32 32 0 0 0-32 32v234.666666a32 32 0 0 0 64 0v-234.666666a32 32 0 0 0-32-32z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M864 704a32 32 0 0 1 31.850667 28.928L896 736v21.333333a117.333333 117.333333 0 0 1-112.618667 117.248L778.666667 874.666667h-533.333334a117.333333 117.333333 0 0 1-117.248-112.618667L128 757.333333v-21.333333a32 32 0 0 1 63.850667-3.072L192 736v21.333333a53.333333 53.333333 0 0 0 49.834667 53.226667L245.333333 810.666667h533.333334a53.333333 53.333333 0 0 0 53.226666-49.834667L832 757.333333v-21.333333a32 32 0 0 1 32-32zM512 149.333333c4.16 0 8.128 0.789333 11.776 2.24l0.32 0.106667c3.861333 1.514667 7.488 3.797333 10.624 6.826667L779.946667 394.88c12.544 12.16 12.544 31.893333 0 44.053333a32.853333 32.853333 0 0 1-45.44 0L544 255.424V714.666667a32 32 0 0 1-64 0V255.424l-190.464 183.509333a32.853333 32.853333 0 0 1-45.44 0 30.485333 30.485333 0 0 1 0-44.053333L489.258667 158.506667c3.157333-3.029333 6.805333-5.333333 10.688-6.848A32.213333 32.213333 0 0 1 512 149.333333z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M618.666667 170.666667a32 32 0 0 1 3.072 63.850666L618.666667 234.666667H202.666667a53.333333 53.333333 0 0 0-53.226667 49.834666L149.333333 288.021333v448c0 8.533333 2.005333 16.64 5.589334 23.808l174.442666-174.442666a32 32 0 0 1 42.837334-2.197334l2.432 2.197334 85.312 85.333333 169.450666-150.613333a32 32 0 0 1 40.170667-1.92l2.474667 2.005333 2.304 2.304 199.936 219.946667 0.277333-3.2 0.106667-3.221334V490.666667l0.149333-3.072a32 32 0 0 1 63.701333 0L938.666667 490.666667v245.333333a117.333333 117.333333 0 0 1-112.618667 117.248l-4.714667 0.106667h-618.666666a117.333333 117.333333 0 0 1-117.248-112.64L85.333333 736.042667v-448a117.333333 117.333333 0 0 1 112.618667-117.248l4.714667-0.085334L618.666667 170.666667z m29.610666 418.282666l-142.997333 127.104 61.354667 61.333334c3.477333 3.498667 5.994667 7.594667 7.552 11.968H821.333333c2.88 0 5.717333-0.234667 8.490667-0.682667l-181.546667-199.722667zM352 653.269333L215.893333 789.333333h272.192L352 653.226667zM341.333333 298.666667a106.666667 106.666667 0 1 1 0 213.333333 106.666667 106.666667 0 0 1 0-213.333333zM789.333333 170.666667a32 32 0 0 1 32 32v85.312l85.333334 0.021333a32 32 0 0 1 0 64l-85.354667-0.021333 0.021333 85.354666a32 32 0 0 1-64 0l-0.021333-85.354666-85.312 0.021333a32 32 0 0 1 0-64l85.333333-0.021333V202.666667A32 32 0 0 1 789.333333 170.666667z m-448 192a42.666667 42.666667 0 1 0 0 85.333333 42.666667 42.666667 0 0 0 0-85.333333z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M853.333333 576a85.333333 85.333333 0 0 1 85.333334 85.333333v106.666667a85.333333 85.333333 0 0 1-85.333334 85.333333H170.666667a85.333333 85.333333 0 0 1-85.333334-85.333333v-106.666667a85.333333 85.333333 0 0 1 85.333334-85.333333h682.666666z m-288 106.666667h-106.666666a32 32 0 0 0-3.072 63.850666L458.666667 746.666667h106.666666a32 32 0 0 0 0-64zM853.333333 256a85.333333 85.333333 0 0 1 85.333334 85.333333v106.666667a85.333333 85.333333 0 0 1-85.333334 85.333333H170.666667a85.333333 85.333333 0 0 1-85.333334-85.333333v-106.666667a85.333333 85.333333 0 0 1 85.333334-85.333333h682.666666z m-288 106.666667h-106.666666a32 32 0 0 0-3.072 63.850666L458.666667 426.666667h106.666666a32 32 0 0 0 0-64z m167.317334-234.666667a85.333333 85.333333 0 0 1 60.352 25.002667L853.333333 213.333333H170.666667l60.330666-60.330666A85.333333 85.333333 0 0 1 291.349333 128h441.301334z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M640 213.333333a42.666667 42.666667 0 0 0-39.466667-42.56L597.333333 170.666667h-170.666666a42.666667 42.666667 0 0 0-42.56 39.466666L384 213.333333v21.333334h-64v-21.333334a106.666667 106.666667 0 0 1 102.037333-106.56L426.666667 106.666667h170.666666a106.666667 106.666667 0 0 1 106.56 102.037333L704 213.333333v21.333334h149.333333a85.333333 85.333333 0 0 1 85.333334 85.333333v469.333333a85.333333 85.333333 0 0 1-85.333334 85.333334H170.666667a85.333333 85.333333 0 0 1-85.333334-85.333334V320a85.333333 85.333333 0 0 1 85.333334-85.333333h469.333333v-21.333334z m213.333333 170.666667H170.666667a21.333333 21.333333 0 0 0-2.496 42.517333L170.666667 426.666667h256v21.333333a42.666667 42.666667 0 0 0 39.466666 42.56L469.333333 490.666667h85.333334a42.666667 42.666667 0 0 0 42.56-39.466667L597.333333 448v-21.333333h256a21.333333 21.333333 0 0 0 2.496-42.517334L853.333333 384z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 234.666667l320 170.666666v405.333334a85.333333 85.333333 0 0 1-85.333333 85.333333H277.333333a85.333333 85.333333 0 0 1-85.333333-85.333333V405.333333l320-170.666666z m0 149.333333a32 32 0 0 0-32 32v213.333333A32 32 0 0 0 512 661.333333h192a32 32 0 0 0 0-64h-160.021333l0.021333-181.333333a32 32 0 0 0-28.928-31.850667z m12.16-253.76l3.285333 1.493333 372.458667 209.408c16.021333 8.234667 22.101333 27.477333 13.568 42.944-8.021333 14.570667-26.133333 20.629333-41.6 14.421334l-2.858667-1.301334-356.992-201.450666-356.992 201.365333a33.557333 33.557333 0 0 1-42.837333-10.389333l-1.642667-2.645334a31.146667 31.146667 0 0 1 10.773334-41.386666l2.709333-1.578667 372.48-209.365333a33.898667 33.898667 0 0 1 27.648-1.493334z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M853.333333 170.666667a85.333333 85.333333 0 0 1 85.333334 85.333333v208.32a63.744 63.744 0 0 0-37.781334-16.128L896 448h-128a64 64 0 0 0-63.893333 60.245333L704 512v256h-128v42.666667h74.666667a32 32 0 0 1 0 64h-277.333334a32 32 0 0 1 0-64H448v-42.666667H170.666667a85.333333 85.333333 0 0 1-85.333334-85.333333V256a85.333333 85.333333 0 0 1 85.333334-85.333333h682.666666z m21.333334 320a42.666667 42.666667 0 0 1 42.666666 42.666666v298.666667a42.666667 42.666667 0 0 1-42.666666 42.666667h-85.333334a42.666667 42.666667 0 0 1-42.666666-42.666667V533.333333a42.666667 42.666667 0 0 1 42.666666-42.666666h85.333334z m-21.333334 277.333333h-42.666666a21.333333 21.333333 0 0 0-2.496 42.517333L810.666667 810.666667h42.666666a21.333333 21.333333 0 0 0 0-42.666667z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 85.333333c145.984 0 265.642667 112.810667 276.522667 256H906.666667a32 32 0 0 1 0 64H896l-54.656 437.248A85.333333 85.333333 0 0 1 756.650667 917.333333H267.349333a85.333333 85.333333 0 0 1-84.672-74.752L128 405.333333h-10.666667a32 32 0 0 1 0-64h118.144C246.357333 198.144 366.016 85.333333 512 85.333333z m-96 469.333334a32 32 0 0 0-32 32v149.333333a32 32 0 0 0 64 0v-149.333333a32 32 0 0 0-32-32z m192 0a32 32 0 0 0-32 32v149.333333a32 32 0 0 0 64 0v-149.333333a32 32 0 0 0-32-32zM512 146.965333c-111.936 0-203.946667 85.248-214.656 194.368h429.312C715.946667 232.213333 623.936 146.986667 512 146.986667z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M467.626667 199.253333a116.330667 116.330667 0 0 1 165.461333 12.906667A119.68 119.68 0 0 1 661.333333 289.472V734.506667C661.333333 800.149333 608.810667 853.333333 544 853.333333a116.48 116.48 0 0 1-76.373333-28.586666l-148.8-129.152H224c-63.210667 0-114.773333-50.624-117.248-114.026667L106.666667 576.789333v-129.578666c0-65.621333 52.522667-118.805333 117.333333-118.805334h94.805333z m335.274666 43.712C873.813333 304.832 917.333333 405.205333 917.333333 512c0 108.437333-42.944 207.936-114.709333 269.269333-14.890667 12.736-36.586667 10.090667-48.448-5.909333-11.861333-16-9.386667-39.317333 5.504-52.053333 54.997333-47.018667 88.682667-125.013333 88.682667-211.306667 0-84.693333-34.346667-163.882667-88.96-211.541333-14.784-12.906667-17.024-36.224-5.013334-52.117334 12.010667-15.872 33.728-18.282667 48.512-5.376z m-218.410666 11.349334a52.885333 52.885333 0 0 0-75.2-5.845334l-166.784 144.746667H224c-29.44 0-53.333333 24.170667-53.333333 53.973333v129.6c0 29.824 23.893333 54.016 53.333333 54.016h118.506667l166.784 144.725334c9.664 8.384 21.973333 13.013333 34.709333 13.013333 29.44 0 53.333333-24.192 53.333333-54.016V289.493333a54.4 54.4 0 0 0-12.842666-35.157333z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M467.626667 199.253333a116.330667 116.330667 0 0 1 165.461333 12.906667A119.68 119.68 0 0 1 661.333333 289.472V734.506667C661.333333 800.149333 608.810667 853.333333 544 853.333333a116.48 116.48 0 0 1-76.373333-28.586666l-148.8-129.152H224c-63.210667 0-114.773333-50.624-117.248-114.026667L106.666667 576.789333v-129.578666c0-65.621333 52.522667-118.805333 117.333333-118.805334h94.805333z m335.274666 43.712C873.813333 304.832 917.333333 405.205333 917.333333 512c0 108.437333-42.944 207.936-114.709333 269.269333-14.890667 12.736-36.586667 10.090667-48.448-5.909333-11.861333-16-9.386667-39.317333 5.504-52.053333 54.997333-47.018667 88.682667-125.013333 88.682667-211.306667 0-84.693333-34.346667-163.882667-88.96-211.541333-14.784-12.906667-17.024-36.224-5.013334-52.117334 12.010667-15.872 33.728-18.282667 48.512-5.376z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M666.325333 128a118.101333 118.101333 0 0 1 102.208 58.816l154.325334 266.368a117.290667 117.290667 0 0 1 0 117.632l-154.325334 266.368A118.101333 118.101333 0 0 1 666.325333 896H357.674667a118.101333 118.101333 0 0 1-102.208-58.816L101.12 570.816a117.290667 117.290667 0 0 1 0-117.632l154.325333-266.368A118.101333 118.101333 0 0 1 357.674667 128z m0 64.170667H357.674667c-19.157333 0-36.864 10.176-46.464 26.730666L156.906667 485.269333c-9.6 16.533333-9.6 36.906667 0 53.461334l154.304 266.368a53.696 53.696 0 0 0 46.464 26.730666h308.650666c19.157333 0 36.864-10.176 46.464-26.730666l154.304-266.368c9.6-16.533333 9.6-36.906667 0-53.461334L712.789333 218.88a53.696 53.696 0 0 0-46.464-26.730667zM512 362.666667a149.333333 149.333333 0 1 1 0 298.666666 149.333333 149.333333 0 0 1 0-298.666666z m0 64a85.333333 85.333333 0 1 0 0 170.666666 85.333333 85.333333 0 0 0 0-170.666666z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M666.325333 128a118.101333 118.101333 0 0 1 102.208 58.816l154.325334 266.368a117.290667 117.290667 0 0 1 0 117.632l-154.325334 266.368A118.101333 118.101333 0 0 1 666.325333 896H357.674667a118.101333 118.101333 0 0 1-102.208-58.816L101.12 570.816a117.290667 117.290667 0 0 1 0-117.632l154.325333-266.368A118.101333 118.101333 0 0 1 357.674667 128zM512 362.666667a149.333333 149.333333 0 1 0 0 298.666666 149.333333 149.333333 0 0 0 0-298.666666z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 106.666667c87.978667 0 161.130667 64.469333 176 149.376 58.218667 1.066667 106.453333 45.888 112.832 104.32l0.426667 4.906666 30.464 426.666667c4.394667 64.64-43.712 120.661333-107.456 125.12l-3.968 0.213333-3.989334 0.064H307.669333C243.797333 917.333333 192 864.810667 192 800l0.064-4.053333 0.213333-4.010667 30.464-426.666667c4.053333-59.904 51.968-106.752 110.613334-109.162666l2.624-0.064 1.045333-5.397334C353.984 168.426667 425.877333 106.666667 512 106.666667z m173.866667 213.333333h-347.733334c-26.474667 0-48.64 19.925333-52.096 46.208l-0.362666 3.456-30.549334 428.501333-0.021333 1.834667c0 28.266667 21.696 51.413333 49.109333 53.226667l3.456 0.106666h408.64l3.626667-0.128c27.818667-1.941333 49.066667-25.493333 48.96-53.376l-0.128-3.498666-30.464-426.666667C736.426667 341.717333 713.493333 320 685.866667 320zM437.333333 405.333333a32 32 0 1 1 0 64 32 32 0 0 1 0-64z m149.333334 0a32 32 0 1 1 0 64 32 32 0 0 1 0-64zM512 170.666667c-52.949333 0-97.6 36.096-111.317333 85.333333h222.634666C609.6 206.784 564.949333 170.666667 512 170.666667z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 106.666667c87.978667 0 161.130667 64.469333 176 149.376 58.218667 1.066667 106.453333 45.888 112.832 104.32l0.426667 4.906666 30.464 426.666667c4.394667 64.64-43.712 120.661333-107.456 125.12l-3.968 0.213333-3.989334 0.064H307.669333C243.797333 917.333333 192 864.810667 192 800l0.064-4.053333 0.213333-4.010667 30.464-426.666667c4.053333-59.904 51.968-106.752 110.613334-109.162666l2.624-0.064 1.045333-5.397334C353.984 168.426667 425.877333 106.666667 512 106.666667z m-74.666667 298.666666a32 32 0 1 0 0 64 32 32 0 0 0 0-64z m149.333334 0a32 32 0 1 0 0 64 32 32 0 0 0 0-64zM512 170.666667c-52.949333 0-97.6 36.096-111.317333 85.333333h222.634666C609.6 206.784 564.949333 170.666667 512 170.666667z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 85.333333c235.648 0 426.666667 191.018667 426.666667 426.666667s-191.018667 426.666667-426.666667 426.666667S85.333333 747.648 85.333333 512 276.352 85.333333 512 85.333333z m0 64C311.701333 149.333333 149.333333 311.701333 149.333333 512s162.368 362.666667 362.666667 362.666667 362.666667-162.368 362.666667-362.666667S712.298667 149.333333 512 149.333333z m0 394.666667a32 32 0 0 1-32-32V256a32 32 0 0 1 64 0l-0.021333 224H746.666667a32 32 0 0 1 0 64H512z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 85.333333c235.648 0 426.666667 191.018667 426.666667 426.666667s-191.018667 426.666667-426.666667 426.666667S85.333333 747.648 85.333333 512 276.352 85.333333 512 85.333333z m234.666667 458.666667a32 32 0 0 0 0-64h-202.688L544 256a32 32 0 0 0-28.928-31.850667L512 224a32 32 0 0 0-32 32v256a32 32 0 0 0 32 32z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M706.986667 106.666667a85.333333 85.333333 0 0 1 85.333333 85.333333l-0.021333 355.626667h59.562666a42.666667 42.666667 0 0 1 29.461334 11.84l2.56 2.624a42.666667 42.666667 0 0 1-1.173334 57.685333l-2.645333 2.56-311.658667 274.56a85.333333 85.333333 0 0 1-109.312 2.944l-3.498666-2.944-311.658667-274.56a42.666667 42.666667 0 0 1 25.024-74.581333l3.2-0.128h59.52V192a85.333333 85.333333 0 0 1 85.333333-85.333333h389.973334z m-96.490667 215.786666a32 32 0 0 0-41.685333 2.069334l-59.221334 56.234666-59.178666-56.234666a32 32 0 0 0-44.074667 0l-0.853333 0.789333a29.952 29.952 0 0 0 0 43.456l40.106666 38.08h-32.234666a30.72 30.72 0 0 0 0 61.44h66.304v40.96h-44.757334a30.72 30.72 0 0 0 0 61.44h44.736v49.941333a32 32 0 0 0 32 32h0.704a32 32 0 0 0 32-32v-49.92h44.757334a30.72 30.72 0 0 0 0-61.44l-44.778667-0.021333 0.021333-40.96h66.304a30.72 30.72 0 1 0 0-61.44h-37.034666l40.106666-38.08 2.133334-2.218667a29.973333 29.973333 0 0 0-2.133334-41.237333l-0.832-0.789333z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M158.293333 652.949333a29.397333 29.397333 0 0 0 0 42.282667 31.146667 31.146667 0 0 0 43.306667 0l302.933333-295.765333a10.666667 10.666667 0 0 1 14.933334 0l302.933333 295.765333a31.146667 31.146667 0 0 0 43.306667 0c11.946667-11.669333 11.946667-30.592 0-42.282667L533.653333 328.768a31.146667 31.146667 0 0 0-43.306666 0L158.293333 652.949333z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M465.472 347.946667L183.317333 646.656A21.333333 21.333333 0 0 0 198.826667 682.666667h626.346666a21.333333 21.333333 0 0 0 15.509334-35.989334L558.528 347.946667a64 64 0 0 0-93.056 0z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M437.482667 134.784a112.810667 112.810667 0 0 1 149.034666 0l256.021334 205.717333A94.613333 94.613333 0 0 1 874.666667 411.648v390.613333C874.666667 865.813333 823.722667 917.333333 760.896 917.333333H263.104C200.277333 917.333333 149.333333 865.813333 149.333333 802.261333v-390.613333c0-27.306667 11.733333-53.269333 32.128-71.146667z m108.373333 47.424a51.285333 51.285333 0 0 0-67.733333 0l-256.021334 205.717333c-6.805333 5.973333-10.709333 14.613333-10.709333 23.722667v390.613333c0 28.885333 23.146667 52.309333 51.712 52.309334h497.792c28.565333 0 51.712-23.424 51.712-52.309334v-390.613333c0-9.109333-3.904-17.749333-10.709333-23.722667zM608 640a32 32 0 0 1 0 64h-192a32 32 0 0 1 0-64h192z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M437.482667 134.784a112.810667 112.810667 0 0 1 149.034666 0l256.021334 205.717333A94.613333 94.613333 0 0 1 874.666667 411.648v390.613333C874.666667 865.813333 823.722667 917.333333 760.896 917.333333H263.104C200.277333 917.333333 149.333333 865.813333 149.333333 802.261333v-390.613333c0-27.306667 11.733333-53.269333 32.128-71.146667zM608 640h-192a32 32 0 0 0 0 64h192a32 32 0 0 0 0-64z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M631.936 584.042667c43.242667 5.802667 86.464 14.741333 129.685333 26.816a183.829333 183.829333 0 0 1 134.378667 177.066666V832a85.333333 85.333333 0 0 1-85.333333 85.333333H213.333333a85.333333 85.333333 0 0 1-85.333333-85.333333v-44.096a183.829333 183.829333 0 0 1 134.4-177.066667 958.506667 958.506667 0 0 1 111.146667-24.106666l18.538666-2.688 89.749334 89.792c7.893333 7.893333 18.112 12.032 28.437333 12.458666h3.456l3.434667-0.277333a42.474667 42.474667 0 0 0 25.002666-12.181333l89.770667-89.792z m22.336 68.16l-66.837333 66.88a106.666667 106.666667 0 0 1-147.008 3.669333l-3.84-3.669333-66.88-66.88-3.648 0.64c-23.04 4.032-46.08 9.024-69.162667 14.997333l-17.28 4.650667a119.829333 119.829333 0 0 0-87.509333 110.229333L192 787.904V832a21.333333 21.333333 0 0 0 18.837333 21.184L213.333333 853.333333h597.333334a21.333333 21.333333 0 0 0 21.184-18.837333L832 832v-44.096a119.829333 119.829333 0 0 0-87.594667-115.413333 900.629333 900.629333 0 0 0-86.442666-19.669334l-3.690667-0.618666zM512 128c117.824 0 213.333333 95.509333 213.333333 213.333333 0 115.84-92.309333 210.090667-207.36 213.248L512 554.666667c-117.824 0-213.333333-95.509333-213.333333-213.333334 0-115.84 92.309333-210.090667 207.36-213.248L512 128z m0 64a149.333333 149.333333 0 1 0 0 298.666667 149.333333 149.333333 0 0 0 0-298.666667z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M956.8 502.4C918.9 452.3 734.2 224 512 224S105.1 452.3 67.2 502.4a15.9 15.9 0 0 0 0 19.2C105.1 571.7 289.8 800 512 800s406.9-228.3 444.8-278.4a15.9 15.9 0 0 0 0-19.2zM758.4 623.5c-39.7 31.9-79.4 57-118.1 74.4-44.2 20-87.4 30.1-128.3 30.1s-84.1-10.1-128.3-30.1c-38.7-17.4-78.4-42.5-118.1-74.4-48.7-39.2-88.3-81.7-113.7-111.5 25.4-29.8 65-72.3 113.7-111.5 39.7-31.9 79.4-57 118.1-74.4 44.2-20 87.4-30.1 128.3-30.1s84.1 10.1 128.3 30.1c38.7 17.4 78.4 42.5 118.1 74.4 48.7 39.2 88.3 81.7 113.7 111.5-25.4 29.8-65 72.3-113.7 111.5zM513 384a128 128 0 1 0 128 128 128 128 0 0 0-128-128z m0 192a64 64 0 1 1 64-64 64.1 64.1 0 0 1-64 64z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M563.050667 865.706667c-11.690667 11.946667-30.613333 11.946667-42.282667 0a31.146667 31.146667 0 0 1 0-43.306667l295.765333-302.933333a10.666667 10.666667 0 0 0 0-14.933334L520.768 201.6a31.146667 31.146667 0 0 1 0-43.306667 29.397333 29.397333 0 0 1 42.282667 0l324.181333 332.053334a31.146667 31.146667 0 0 1 0 43.306666L563.050667 865.706667z" /><path d="M179.050667 865.706667c-11.690667 11.946667-30.613333 11.946667-42.282667 0a31.146667 31.146667 0 0 1 0-43.306667l295.765333-302.933333a10.666667 10.666667 0 0 0 0-14.933334L136.768 201.6a31.146667 31.146667 0 0 1 0-43.306667 29.397333 29.397333 0 0 1 42.282667 0l324.181333 332.053334a31.146667 31.146667 0 0 1 0 43.306666L179.050667 865.706667z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M460.949333 865.706667c11.690667 11.946667 30.613333 11.946667 42.282667 0a31.146667 31.146667 0 0 0 0-43.306667L207.466667 519.466667a10.666667 10.666667 0 0 1 0-14.933334l295.765333-302.933333a31.146667 31.146667 0 0 0 0-43.306667 29.397333 29.397333 0 0 0-42.282667 0L136.768 490.346667a31.146667 31.146667 0 0 0 0 43.306666L460.949333 865.706667z" /><path d="M844.949333 865.706667c11.690667 11.946667 30.613333 11.946667 42.282667 0a31.146667 31.146667 0 0 0 0-43.306667l-295.765333-302.933333a10.666667 10.666667 0 0 1 0-14.933334l295.765333-302.933333a31.146667 31.146667 0 0 0 0-43.306667 29.397333 29.397333 0 0 0-42.282667 0L520.768 490.346667a31.146667 31.146667 0 0 0 0 43.306666L844.949333 865.706667z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M882.688 395.690667l42.133333-11.306667a10.986667 10.986667 0 0 1 13.056 14.762667l-36.864 92.096a32.96 32.96 0 0 1-50.986666 13.696l-77.824-61.290667a11.050667 11.050667 0 0 1 3.946666-19.306667l46.336-12.458666c-49.706667-161.664-223.552-256.533333-392.746666-212.608-172.16 44.693333-274.325333 216.170667-228.181334 382.997333 46.122667 166.826667 223.082667 265.813333 395.221334 221.12 16.661333-4.330667 33.792 5.248 38.250666 21.397333 4.48 16.149333-5.418667 32.746667-22.08 37.077334C407.466667 915.2 196.266667 797.056 141.226667 597.930667 86.165333 398.826667 208.106667 194.154667 413.568 140.8c202.346667-52.522667 410.24 61.269333 469.12 254.890667z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M583.2 64a4.1 4.1 0 0 0-4.2 4.1V444a4 4 0 0 0 4 4h375.8a4.2 4.2 0 0 0 4.2-4.2C960.8 235 792 66.2 583.2 64zM643 384V134.4a310.4 310.4 0 0 1 62.1 19.4 320.7 320.7 0 0 1 168.1 168.1 312.5 312.5 0 0 1 19.4 62.1z m310 128h-64a4 4 0 0 0-4 4c-1.1 103.2-43.5 199.9-119.5 270.9A375.7 375.7 0 0 1 505.7 888c-98.1-0.9-190.3-39-260.2-107.8A376.2 376.2 0 0 1 133.2 525c-3.5-105.3 35.9-204.8 109.9-278.9A373.4 373.4 0 0 1 505 136a4 4 0 0 0 4-4V68a4 4 0 0 0-4-4 448.3 448.3 0 1 0 452 452 4 4 0 0 0-4-4z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M746.666667 128a170.666667 170.666667 0 0 1 170.666666 170.666667v426.666666a170.666667 170.666667 0 0 1-170.666666 170.666667H277.333333a170.666667 170.666667 0 0 1-170.666666-170.666667V298.666667a170.666667 170.666667 0 0 1 170.666666-170.666667h469.333334zM320 426.666667a32 32 0 0 0-32 32v277.333333a32 32 0 0 0 64 0v-277.333333A32 32 0 0 0 320 426.666667z m384 85.333333a32 32 0 0 0-32 32v192a32 32 0 0 0 64 0v-192A32 32 0 0 0 704 512z m-192-256a32 32 0 0 0-32 32v448a32 32 0 0 0 64 0v-448A32 32 0 0 0 512 256z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M309.8 595.7a4.1 4.1 0 0 0 5.7-0.3l86.9-96.9a4 4 0 0 1 5.8-0.2L520.4 611a16.2 16.2 0 0 0 22.7 0l221.7-222.6a3.9 3.9 0 0 0 0-5.6l-39.6-39.6a4.2 4.2 0 0 0-5.7 0L534.6 528.8a4 4 0 0 1-5.7 0L405.8 405.2a4.1 4.1 0 0 0-5.9 0.1L267.8 552.7a4 4 0 0 0 0.4 5.6zM732 688H292a4 4 0 0 0-4 4v56a4 4 0 0 0 4 4h440a4 4 0 0 0 4-4v-56a4 4 0 0 0-4-4z m124-560H168a40 40 0 0 0-40 40v688a40 40 0 0 0 40 40h688a40 40 0 0 0 40-40V168a40 40 0 0 0-40-40z m-32 696H200V200h624z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M490.666667 170.666667a21.333333 21.333333 0 0 1 21.333333 21.333333v298.794667c0 23.488 19.093333 42.538667 42.538667 42.538666H853.333333a21.333333 21.333333 0 0 1 21.333334 21.333334c0 212.074667-171.925333 384-384 384S106.666667 766.741333 106.666667 554.666667 278.592 170.666667 490.666667 170.666667z m103.296-42.666667C772.565333 128 917.333333 272.768 917.333333 451.370667a17.962667 17.962667 0 0 1-18.005333 17.962666H618.666667a42.666667 42.666667 0 0 1-42.666667-42.666666V145.962667c0-9.92 8.042667-17.962667 17.962667-17.962667z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M435.825778 486.684444H284.273778a186.595556 186.595556 0 1 1 186.652444-186.595555v185.685333zM284.273778 181.703111a118.385778 118.385778 0 0 0 0 236.714667h118.328889v-118.328889A118.499556 118.499556 0 0 0 284.444444 181.987556z" /><path d="M284.444444 910.165333A186.595556 186.595556 0 0 1 284.444444 537.031111h185.514667l0.967111 34.986667v151.552A186.88 186.88 0 0 1 284.444444 910.165333z m0-304.924444a118.328889 118.328889 0 1 0 118.328889 118.328889v-118.328889z" /><path d="M707.697778 486.684444H522.069333l-0.967111-35.043555V300.088889a186.652444 186.652444 0 1 1 186.595556 186.595555z m-118.272-68.266666h118.272a118.385778 118.385778 0 1 0-118.272-118.328889z" /><path d="M707.754667 910.165333a186.88 186.88 0 0 1-186.652445-186.595555V537.884444l35.100445-0.853333h151.552a186.595556 186.595556 0 0 1 0 373.134222z m-118.328889-304.924444v118.328889a118.272 118.272 0 1 0 118.328889-118.328889z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M428.309333 149.333333c154.048 0 278.954667 124.885333 278.954667 278.954667a277.76 277.76 0 0 1-60.245333 173.184l175.68 175.722667a32 32 0 0 1 2.197333 42.816l-2.197333 2.432-0.256 0.256a32 32 0 0 1-45.248 0l-175.722667-175.68a277.781333 277.781333 0 0 1-173.162667 60.224C274.24 707.242667 149.333333 582.357333 149.333333 428.288S274.24 149.333333 428.309333 149.333333z m0 64.384c-118.528 0-214.613333 96.064-214.613333 214.570667s96.085333 214.592 214.613333 214.592c57.749333 0 110.165333-22.826667 148.736-59.925333 0.768-1.066667 1.664-2.069333 2.602667-3.029334l0.277333-0.256c0.981333-0.981333 1.984-1.877333 3.050667-2.688a213.674667 213.674667 0 0 0 59.904-148.693333c0-118.506667-96.064-214.570667-214.570667-214.570667z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M821.610667 302.293333l-199.658667 116.053334a218.730667 218.730667 0 0 1-219.904 0l-199.68-116.053334a21.333333 21.333333 0 0 1 0-36.885333L469.12 110.293333a85.333333 85.333333 0 0 1 85.802667 0l266.709333 155.114667a21.333333 21.333333 0 0 1 0 36.906667zM191.786667 764.224l266.922666 155.733333a21.333333 21.333333 0 0 0 32.085334-18.432V668.672c0-79.402667-41.941333-152.682667-109.930667-192.426667l-199.338667-116.202666a21.333333 21.333333 0 0 0-32.064 18.410666v312.064a85.333333 85.333333 0 0 0 42.325334 73.706667zM533.333333 668.714667V901.546667a21.333333 21.333333 0 0 0 32.085334 18.410666l266.922666-155.733333A85.333333 85.333333 0 0 0 874.666667 690.474667V378.453333a21.333333 21.333333 0 0 0-32.085334-18.410666l-199.296 116.288c-68.096 39.68-109.952 113.066667-109.952 192.362666z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 170.666667a32 32 0 0 1 32 32v277.312l277.333333 0.021333a32 32 0 0 1 0 64l-277.354666-0.021333L544 821.333333a32 32 0 0 1-64 0l-0.021333-277.354666L202.666667 544a32 32 0 0 1 0-64l277.333333-0.021333V202.666667A32 32 0 0 1 512 170.666667z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 85.333333c235.648 0 426.666667 191.018667 426.666667 426.666667s-191.018667 426.666667-426.666667 426.666667S85.333333 747.648 85.333333 512 276.352 85.333333 512 85.333333z m0 64C311.701333 149.333333 149.333333 311.701333 149.333333 512s162.368 362.666667 362.666667 362.666667 362.666667-162.368 362.666667-362.666667S712.298667 149.333333 512 149.333333z m0 256a32 32 0 0 1 32 32V661.333333H576a32 32 0 0 1 0 64h-128a32 32 0 0 1 0-64h32v-192H448a32 32 0 0 1 0-64h64z m0-128a42.666667 42.666667 0 1 1 0 85.333334 42.666667 42.666667 0 0 1 0-85.333334z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 85.333333c235.648 0 426.666667 191.018667 426.666667 426.666667s-191.018667 426.666667-426.666667 426.666667S85.333333 747.648 85.333333 512 276.352 85.333333 512 85.333333z m0 320h-64a32 32 0 0 0 0 64h32v192H448a32 32 0 0 0 0 64h128a32 32 0 0 0 0-64h-32V437.333333A32 32 0 0 0 512 405.333333z m0-128a42.666667 42.666667 0 1 0 0 85.333334 42.666667 42.666667 0 0 0 0-85.333334z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M768 106.666667a85.333333 85.333333 0 0 1 85.333333 85.333333v640a85.333333 85.333333 0 0 1-85.333333 85.333333H256a85.333333 85.333333 0 0 1-85.333333-85.333333v-106.666667h53.333333a32 32 0 0 0 31.850667-28.928L256 693.333333a32 32 0 0 0-28.928-31.850666L224 661.333333H170.666667v-106.666666h53.333333a32 32 0 0 0 31.850667-28.928L256 522.666667a32 32 0 0 0-28.928-31.850667L224 490.666667H170.666667v-106.666667h53.333333a32 32 0 0 0 31.850667-28.928L256 352a32 32 0 0 0-28.928-31.850667L224 320H170.666667V192a85.333333 85.333333 0 0 1 85.333333-85.333333h512zM554.666667 551.296c-36.970667 0-73.962667 5.205333-110.933334 15.594667a82.154667 82.154667 0 0 0-59.733333 79.210666v19.733334c0 21.077333 16.981333 38.165333 37.930667 38.165333h265.472c20.949333 0 37.930667-17.088 37.930666-38.186667v-19.712a82.154667 82.154667 0 0 0-59.733333-79.210666 408.298667 408.298667 0 0 0-110.933333-15.573334zM554.666667 341.333333c-52.373333 0-94.805333 42.730667-94.805334 95.445334 0 52.693333 42.453333 95.424 94.805334 95.424 52.373333 0 94.805333-42.730667 94.805333-95.424C649.472 384.064 607.018667 341.333333 554.666667 341.333333z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 85.333333c58.901333 0 106.666667 49.322667 106.666667 110.165334 0 5.610667-0.426667 11.178667-1.216 16.64 114.133333 45.44 195.050667 162.496 195.050666 299.136v119.296l2.325334 0.853333a92.8 92.8 0 0 1 59.733333 82.197333l0.106667 4.352c0 51.2-41.749333 92.693333-93.248 92.693334h-141.802667c-5.013333 71.594667-60.245333 128-127.616 128-67.370667 0-122.602667-56.405333-127.616-128H242.56C191.082667 810.666667 149.333333 769.173333 149.333333 717.973333a92.736 92.736 0 0 1 59.84-86.570666l2.346667-0.832v-119.616l0.064-6.762667c2.730667-133.76 82.901333-247.424 195.008-292.010667A108.266667 108.266667 0 0 1 405.333333 195.498667C405.333333 134.656 453.098667 85.333333 512 85.333333z m68.224 725.333334h-136.448c4.778667 36.202667 33.493333 64 68.224 64 34.709333 0 63.445333-27.797333 68.224-64zM512 253.824c-129.088 0-235.392 111.445333-238.250667 251.328l-0.064 6.144v144.917333c0 17.066667-13.930667 30.890667-31.104 30.890667l-2.986666 0.149333a30.976 30.976 0 0 0-28.096 30.741334c0 17.066667 13.930667 30.890667 31.082666 30.890666H781.44c17.152 0 31.082667-13.824 31.082667-30.890666 0-17.066667-13.930667-30.890667-31.082667-30.890667l-2.986667-0.149333a30.976 30.976 0 0 1-28.117333-30.741334v-144.917333c0-142.698667-107.221333-257.493333-238.314667-257.493333z m0-95.04c-19.2 0-34.88 15.744-35.541333 35.434667a288.021333 288.021333 0 0 1 71.04 0l0.064 1.28c0-20.266667-15.936-36.693333-35.562667-36.693334z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 106.666667c58.901333 0 106.666667 49.322667 106.666667 110.165333 0 5.610667-0.426667 11.178667-1.216 16.64 114.133333 45.44 195.050667 162.496 195.050666 299.136v119.296l2.325334 0.853333a92.8 92.8 0 0 1 59.733333 82.197334l0.106667 4.352c0 51.2-41.749333 92.693333-93.248 92.693333h-141.802667c-5.013333 71.594667-60.245333 128-127.616 128-67.370667 0-122.602667-56.405333-127.616-128H242.56C191.082667 832 149.333333 790.506667 149.333333 739.306667a92.736 92.736 0 0 1 59.84-86.570667l2.346667-0.832v-119.616l0.064-6.762667c2.730667-133.76 82.901333-247.424 195.008-292.010666a108.266667 108.266667 0 0 1-1.258667-16.682667C405.333333 155.989333 453.098667 106.666667 512 106.666667z m0 73.429333c-19.2 0-34.88 15.744-35.541333 35.434667a288.021333 288.021333 0 0 1 71.04 0l0.064 1.28c0-20.266667-15.936-36.693333-35.562667-36.693334z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M394.666667 597.333333l3.072 0.149334A32 32 0 0 1 426.666667 629.333333v234.666667l-0.149334 3.072A32 32 0 0 1 394.666667 896l-3.072-0.149333A32 32 0 0 1 362.666667 864V661.333333H160l-3.072-0.149333A32 32 0 0 1 160 597.333333h234.666667z m469.333333 0l3.072 0.149334a32 32 0 0 1 0 63.701333L864 661.333333H661.333333v202.666667l-0.149333 3.072a32 32 0 0 1-28.778667 28.8L629.333333 896a32 32 0 0 1-31.850666-28.928L597.333333 864v-234.666667l0.149334-3.072a32 32 0 0 1 28.778666-28.8L629.333333 597.333333h234.666667z m-469.333333-469.333333a32 32 0 0 1 31.850666 28.928L426.666667 160v234.666667a32 32 0 0 1-28.928 31.850666L394.666667 426.666667h-234.666667a32 32 0 0 1-3.072-63.850667L160 362.666667H362.666667V160a32 32 0 0 1 28.928-31.850667L394.666667 128z m234.666666 0l3.072 0.149333a32 32 0 0 1 28.8 28.778667L661.333333 160V362.666667h202.666667l3.072 0.149333a32 32 0 0 1 0 63.701333L864 426.666667h-234.666667l-3.072-0.149334a32 32 0 0 1-28.8-28.778666L597.333333 394.666667v-234.666667l0.149334-3.072A32 32 0 0 1 629.333333 128z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M822.848 152.234667c19.52-5.632 40.533333-2.986667 58.026667 7.253333a73.216 73.216 0 0 1 28.266666 96.896l-2.026666 3.648-323.562667 546.752a94.570667 94.570667 0 0 1-19.925333 23.701333 95.424 95.424 0 0 1-130.709334-6.4l-3.285333-3.605333-29.141333-33.664-38.314667 35.946667a74.112 74.112 0 0 1-46.016 19.882666l-4.693333 0.149334c-39.466667 0-71.68-30.72-73.813334-69.418667l-0.106666-4.032v-99.157333c0-34.773333 15.786667-67.626667 42.773333-89.472l4.352-3.370667L616.469333 333.653333a31.786667 31.786667 0 0 1 44.288 6.613334 31.36 31.36 0 0 1-4.266666 42.090666l-2.389334 1.92-331.797333 243.712a52.394667 52.394667 0 0 0-21.269333 38.378667l-0.128 3.818667v99.157333a10.517333 10.517333 0 0 0 16.213333 8.853333l1.578667-1.216 62.442666-58.581333a31.808 31.808 0 0 1 43.584 0.106667l2.176 2.261333 50.773334 58.666667a31.786667 31.786667 0 0 0 49.365333-1.706667l1.92-2.88 323.562667-546.730667a10.453333 10.453333 0 0 0-10.346667-15.744l-1.706667 0.341334-647.573333 186.517333a31.445333 31.445333 0 0 0-17.237333 48.170667l2.090666 2.666666 44.266667 50.837334a31.36 31.36 0 0 1-3.221333 44.394666c-12.394667 10.666667-30.762667 10.069333-42.453334-0.853333l-2.218666-2.346667-44.266667-50.816a94.272 94.272 0 0 1-19.413333-35.52c-14.165333-48.64 12.757333-99.413333 60.416-115.626666l4.394666-1.365334 647.594667-186.538666z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M880.896 180.8a73.216 73.216 0 0 1 28.245333 96.917333l-2.026666 3.648-323.562667 546.752a94.570667 94.570667 0 0 1-19.925333 23.701334 95.424 95.424 0 0 1-130.709334-6.4l-3.285333-3.605334-29.141333-33.664-38.314667 35.946667a74.112 74.112 0 0 1-46.016 19.882667l-4.693333 0.149333c-39.466667 0-71.68-30.72-73.813334-69.418667l-0.106666-4.032v-97.642666l312.746666-253.717334a10.666667 10.666667 0 0 0-11.562666-17.770666l-337.493334 172.416-31.936-35.904-0.064-0.213334-39.381333-45.226666a94.272 94.272 0 0 1-19.413333-35.52c-14.165333-48.64 12.757333-99.413333 60.416-115.626667l4.394666-1.365333 647.594667-186.538667c19.52-5.632 40.533333-2.986667 58.026667 7.253333z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M938.666667 553.92V768c0 64.8-52.533333 117.333333-117.333334 117.333333H202.666667c-64.8 0-117.333333-52.533333-117.333334-117.333333V256c0-64.8 52.533333-117.333333 117.333334-117.333333h618.666666c64.8 0 117.333333 52.533333 117.333334 117.333333v297.92z m-64-74.624V256a53.333333 53.333333 0 0 0-53.333334-53.333333H202.666667a53.333333 53.333333 0 0 0-53.333334 53.333333v344.48A290.090667 290.090667 0 0 1 192 597.333333a286.88 286.88 0 0 1 183.296 65.845334C427.029333 528.384 556.906667 437.333333 704 437.333333c65.706667 0 126.997333 16.778667 170.666667 41.962667z m0 82.24c-5.333333-8.32-21.130667-21.653333-43.648-32.917333C796.768 511.488 753.045333 501.333333 704 501.333333c-121.770667 0-229.130667 76.266667-270.432 188.693334-2.730667 7.445333-7.402667 20.32-13.994667 38.581333-7.68 21.301333-34.453333 28.106667-51.370666 13.056-16.437333-14.634667-28.554667-25.066667-36.138667-31.146667A222.890667 222.890667 0 0 0 192 661.333333c-14.464 0-28.725333 1.365333-42.666667 4.053334V768a53.333333 53.333333 0 0 0 53.333334 53.333333h618.666666a53.333333 53.333333 0 0 0 53.333334-53.333333V561.525333zM320 480a96 96 0 1 1 0-192 96 96 0 0 1 0 192z m0-64a32 32 0 1 0 0-64 32 32 0 0 0 0 64z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M352 653.248L552.085333 853.333333H202.666667a117.034667 117.034667 0 0 1-42.730667-8.021333L352 653.226667z m296.277333-64.32l230.528 249.386667A116.8 116.8 0 0 1 821.333333 853.333333h-178.752l-137.301333-137.301333 142.997333-127.104zM821.333333 170.666667a117.333333 117.333333 0 0 1 117.333334 117.333333v448c0 20.650667-5.333333 40.064-14.72 56.917333L674.346667 522.453333l-2.304-2.282666-2.474667-2.026667a32 32 0 0 0-40.170667 1.92l-169.450666 150.613333-85.333334-85.333333-2.410666-2.197333a32 32 0 0 0-42.837334 2.197333L108.586667 806.144A116.821333 116.821333 0 0 1 85.333333 736v-448A117.333333 117.333333 0 0 1 202.666667 170.666667zM341.333333 298.666667a106.666667 106.666667 0 1 0 0 213.333333 106.666667 106.666667 0 0 0 0-213.333333z m0 64a42.666667 42.666667 0 1 1 0 85.333333 42.666667 42.666667 0 0 1 0-85.333333z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M956.1 320H739.9a4 4 0 0 0-3.9 3.9v56.2a4 4 0 0 0 3.9 3.9h216.2a4 4 0 0 0 3.9-3.9v-56.2a4 4 0 0 0-3.9-3.9zM676 256h280a4 4 0 0 0 4-4v-56a4 4 0 0 0-4-4H676a4 4 0 0 0-4 4v56a4 4 0 0 0 4 4z m280 192H676a4 4 0 0 0-4 4v56a4 4 0 0 0 4 4h280a4 4 0 0 0 4-4v-56a4 4 0 0 0-4-4z m-408.4 57.6A209.6 209.6 0 0 0 626 342c0-116-94-210-210-210s-210 94-210 210a209.3 209.3 0 0 0 78.2 163.7C155.4 558.1 64 684.9 64 831.9V888a4 4 0 0 0 4 4h64a4 4 0 0 0 4-4v-56.1a276.2 276.2 0 0 1 22-108.5 283.5 283.5 0 0 1 60.3-89.2 279.3 279.3 0 0 1 89.2-60.2 273.8 273.8 0 0 1 104.9-22h7.2a273.8 273.8 0 0 1 104.9 22 279.3 279.3 0 0 1 89.2 60.2 283.5 283.5 0 0 1 60.3 89.2 276.2 276.2 0 0 1 22 108.5V888a4 4 0 0 0 4 4h64a4 4 0 0 0 4-4v-56.1c0-147.1-91.5-273.9-220.4-326.3z m-34-66a137 137 0 0 1-93.6 40.3h-8a137.9 137.9 0 1 1 101.6-40.3z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M892 824H200V132a4 4 0 0 0-4-4h-64a4 4 0 0 0-4 4v760a4 4 0 0 0 4 4h760a4 4 0 0 0 4-4v-64a4 4 0 0 0-4-4z m-616-72h64a4 4 0 0 0 4-4V636a4 4 0 0 0-4-4h-64a4 4 0 0 0-4 4v112a4 4 0 0 0 4 4z m160-240a4 4 0 0 0-4 4v232a4 4 0 0 0 4 4h64a4 4 0 0 0 4-4V516a4 4 0 0 0-4-4z m160 80a4 4 0 0 0-4 4v152a4 4 0 0 0 4 4h64a4 4 0 0 0 4-4V596a4 4 0 0 0-4-4z m160-160a4 4 0 0 0-4 4v312a4 4 0 0 0 4 4h64a4 4 0 0 0 4-4V436a4 4 0 0 0-4-4z m-427.4 52a4 4 0 0 0 5.6-0.2l135.5-146.5 130.5 121.6a40.1 40.1 0 0 0 57-2.5l139.2-153.9 37.1 28.3a4.2 4.2 0 0 0 6.8-2.9l16.3-156.6a4.2 4.2 0 0 0-5.7-4.4l-146.7 57.2a4.2 4.2 0 0 0-1 7.3l42.1 32.1L626 395.4 495.7 274.1a39.9 39.9 0 0 0-56.6 2.1L287.2 440.3a4.1 4.1 0 0 0 0.2 5.7z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M511 604c144.7 0 262-117.3 262-262S655.7 80 511 80 249 197.3 249 342c0 91.2 46.6 171.5 117.4 218.5C226.3 617.9 127 755.9 127 916v25.5a4 4 0 0 0 4 4h64a3.9 3.9 0 0 0 4-4V916a307.1 307.1 0 0 1 24.6-120.9 315.8 315.8 0 0 1 166.5-166.5A307.1 307.1 0 0 1 511 604zM376.6 476.4A190.2 190.2 0 1 1 511 532a189.1 189.1 0 0 1-134.4-55.6zM892 864H644a4 4 0 0 0-4 4v56a4 4 0 0 0 4 4h248a4 4 0 0 0 4-4v-56a4 4 0 0 0-4-4z m-356-32a64 64 0 1 0 64 64 64.1 64.1 0 0 0-64-64z m0 80a16 16 0 1 1 16-16 16 16 0 0 1-16 16z m356-240H644a4 4 0 0 0-4 4v56a4 4 0 0 0 4 4h248a4 4 0 0 0 4-4v-56a4 4 0 0 0-4-4z m-356-32a64 64 0 1 0 64 64 64.1 64.1 0 0 0-64-64z m0 80a16 16 0 1 1 16-16 16 16 0 0 1-16 16z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 234.666667l320 170.666666v405.333334a85.333333 85.333333 0 0 1-85.333333 85.333333H277.333333a85.333333 85.333333 0 0 1-85.333333-85.333333V405.333333l320-170.666666z m161.173333 244.245333a32.256 32.256 0 0 0-45.866666 0l-149.077334 151.957333-0.341333 0.341334a21.333333 21.333333 0 0 1-30.165333-0.405334l-51.029334-52.416a32.256 32.256 0 0 0-45.866666 0 32.853333 32.853333 0 0 0 0 46.208l89.194666 91.157334a32.256 32.256 0 0 0 45.866667 0l187.285333-190.656a32.853333 32.853333 0 0 0 0-46.186667zM524.16 130.24l3.285333 1.493333 372.458667 209.408c16.021333 8.234667 22.101333 27.477333 13.568 42.944-8.021333 14.570667-26.133333 20.629333-41.6 14.421334l-2.858667-1.301334-356.992-201.450666-356.992 201.365333a33.557333 33.557333 0 0 1-42.837333-10.389333l-1.642667-2.645334a31.146667 31.146667 0 0 1 10.773334-41.386666l2.709333-1.578667 372.48-209.365333a33.898667 33.898667 0 0 1 27.648-1.493334z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M408.064 149.333333c115.989333 0 217.088 59.946667 267.434667 148.117334C813.098667 322.645333 917.333333 433.493333 917.333333 567.317333c0 72.746667-31.061333 140.8-84.864 191.509334l-2.090666 1.877333 13.610666 49.792c7.125333 26.112-7.744 52.906667-33.493333 61.461333l-3.264 0.981334a52.842667 52.842667 0 0 1-39.424-5.098667l-65.130667-36.906667-5.76 1.578667c-22.869333 5.824-46.528 9.173333-70.613333 9.898667l-10.368 0.170666c-115.989333 0-217.088-59.946667-267.456-148.138666a228.48 228.48 0 0 1-7.168-1.365334l-9.770667-2.176-7.466666-1.941333-65.066667 36.864a52.650667 52.650667 0 0 1-66.944-12.778667l-2.133333-2.922666-1.898667-2.965334a50.133333 50.133333 0 0 1-6.101333-34.730666l0.917333-3.925334 13.162667-48.32-1.642667-1.450666c-51.733333-47.466667-83.221333-110.784-87.253333-179.136l-0.341334-7.616L106.666667 424.597333C106.666667 272 242.133333 149.333333 408.064 149.333333z m207.872 203.904c-132.565333 0-239.04 96.426667-239.04 214.08 0 117.674667 106.474667 214.08 239.04 214.08 27.946667 0 55.210667-4.266667 80.938667-12.586666l13.226666-4.266667 67.157334 38.016-17.301334-63.36 15.573334-12.522667c50.346667-40.469333 79.445333-97.877333 79.445333-159.36 0-117.674667-106.496-214.08-239.04-214.08z m-207.872-142.72c-132.544 0-239.04 96.405333-239.04 214.08 0 60.16 27.882667 116.416 76.202667 156.693334l5.44 4.394666 15.914666 12.501334-17.024 62.357333 66.773334-37.802667 4.629333 1.450667a253.824 253.824 0 0 1-6.421333-56.874667c0-146.496 124.864-265.429333 281.685333-274.688-43.626667-49.92-111.530667-82.133333-188.16-82.133333z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M615.936 374.570667c132.544 0 239.04 96.426667 239.04 214.08 0 61.482667-29.12 118.890667-79.466667 159.36l-15.573333 12.501333 17.322667 63.36-67.136-37.973333-13.248 4.266666c-25.728 8.277333-52.970667 12.586667-80.938667 12.586667-132.565333 0-239.04-96.426667-239.04-214.101333s106.474667-214.08 239.04-214.08zM408.064 170.666667c115.989333 0 217.088 59.946667 267.434667 148.117333a328.96 328.96 0 0 0-59.562667-5.397333c-165.930667 0-301.397333 122.666667-301.397333 275.264 0 45.930667 12.266667 89.152 33.941333 127.146666a228.48 228.48 0 0 1-7.168-1.386666l-9.770667-2.176-7.466666-1.941334-65.066667 36.864a52.650667 52.650667 0 0 1-66.944-12.778666l-2.133333-2.922667-1.898667-2.965333a50.133333 50.133333 0 0 1-6.101333-34.730667l0.917333-3.925333 13.162667-48.32-1.642667-1.450667c-51.733333-47.466667-83.221333-110.784-87.253333-179.136l-0.341334-7.616L106.666667 445.930667C106.666667 293.333333 242.133333 170.666667 408.064 170.666667z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 576c83.2 0 166.4 11.626667 249.6 34.858667a183.829333 183.829333 0 0 1 134.4 177.066666V832a85.333333 85.333333 0 0 1-85.333333 85.333333H213.333333a85.333333 85.333333 0 0 1-85.333333-85.333333v-44.096a183.829333 183.829333 0 0 1 134.4-177.066667C345.6 587.648 428.8 576 512 576z m0 64c-77.333333 0-154.752 10.816-232.405333 32.490667a119.829333 119.829333 0 0 0-87.466667 110.229333L192 787.904V832a21.333333 21.333333 0 0 0 18.837333 21.184L213.333333 853.333333h597.333334a21.333333 21.333333 0 0 0 21.184-18.837333L832 832v-44.096a119.829333 119.829333 0 0 0-87.594667-115.413333C666.752 650.816 589.312 640 512 640z m0-533.333333c117.824 0 213.333333 95.509333 213.333333 213.333333s-95.509333 213.333333-213.333333 213.333333-213.333333-95.509333-213.333333-213.333333S394.176 106.666667 512 106.666667z m0 64a149.333333 149.333333 0 1 0 0 298.666666 149.333333 149.333333 0 0 0 0-298.666666z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 576c83.2 0 166.4 11.626667 249.6 34.858667a183.829333 183.829333 0 0 1 134.4 177.066666V832a85.333333 85.333333 0 0 1-85.333333 85.333333H213.333333a85.333333 85.333333 0 0 1-85.333333-85.333333v-44.096a183.829333 183.829333 0 0 1 134.4-177.066667C345.6 587.648 428.8 576 512 576z m0-469.333333c117.824 0 213.333333 95.509333 213.333333 213.333333s-95.509333 213.333333-213.333333 213.333333-213.333333-95.509333-213.333333-213.333333S394.176 106.666667 512 106.666667z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M589.162667 170.666667a117.333333 117.333333 0 0 1 111.317333 80.234666l3.925333 11.84a21.333333 21.333333 0 0 0 20.266667 14.592H800a117.333333 117.333333 0 0 1 117.248 112.618667L917.333333 394.666667v341.333333a117.333333 117.333333 0 0 1-117.333333 117.333333h-576A117.333333 117.333333 0 0 1 106.666667 736v-341.333333a117.333333 117.333333 0 0 1 117.333333-117.333334h75.328a21.333333 21.333333 0 0 0 20.245333-14.592l3.946667-11.84a117.333333 117.333333 0 0 1 106.282667-80.128L434.837333 170.666667z m0 64h-154.325334a53.333333 53.333333 0 0 0-50.602666 36.48l-13.674667 41.024A42.666667 42.666667 0 0 1 330.090667 341.333333H224A53.333333 53.333333 0 0 0 170.666667 394.666667v341.333333a53.333333 53.333333 0 0 0 53.333333 53.333333h576a53.333333 53.333333 0 0 0 53.333333-53.333333v-341.333333a53.333333 53.333333 0 0 0-53.333333-53.333334h-106.112a42.666667 42.666667 0 0 1-40.469333-29.184l-13.653334-41.024A53.333333 53.333333 0 0 0 589.162667 234.666667zM512 405.333333a149.333333 149.333333 0 1 1 0 298.666667 149.333333 149.333333 0 0 1 0-298.666667z m0 64a85.333333 85.333333 0 1 0 0 170.666667 85.333333 85.333333 0 0 0 0-170.666667z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 85.333333c235.648 0 426.666667 191.018667 426.666667 426.666667s-191.018667 426.666667-426.666667 426.666667c-7.146667 0-14.250667-0.170667-21.333333-0.533334V938.666667H170.666667a85.333333 85.333333 0 0 1-85.333334-85.333334V533.333333h0.533334A433.749333 433.749333 0 0 1 85.333333 512C85.333333 276.352 276.352 85.333333 512 85.333333z m0 64C311.701333 149.333333 149.333333 311.701333 149.333333 512c0 6.08 0.149333 12.16 0.426667 18.197333 0.149333 2.538667 0.128 5.034667-0.042667 7.509334l-0.384 3.84V853.333333a21.333333 21.333333 0 0 0 18.837334 21.184L170.666667 874.666667h311.722666a65.706667 65.706667 0 0 1 7.616-0.512l3.84 0.064c6.016 0.298667 12.074667 0.448 18.154667 0.448 200.298667 0 362.666667-162.368 362.666667-362.666667 0-197.973333-158.656-358.933333-355.776-362.602667L512 149.333333z m-192 341.333334a42.666667 42.666667 0 1 1 0 85.333333 42.666667 42.666667 0 0 1 0-85.333333z m192 0a42.666667 42.666667 0 1 1 0 85.333333 42.666667 42.666667 0 0 1 0-85.333333z m192 0a42.666667 42.666667 0 1 1 0 85.333333 42.666667 42.666667 0 0 1 0-85.333333z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M864 704a32 32 0 0 1 31.850667 28.928L896 736v21.333333a117.333333 117.333333 0 0 1-112.618667 117.248L778.666667 874.666667h-533.333334a117.333333 117.333333 0 0 1-117.248-112.618667L128 757.333333v-21.333333a32 32 0 0 1 63.850667-3.072L192 736v21.333333a53.333333 53.333333 0 0 0 49.834667 53.226667L245.333333 810.666667h533.333334a53.333333 53.333333 0 0 0 53.226666-49.834667L832 757.333333v-21.333333a32 32 0 0 1 32-32zM512 149.333333a32 32 0 0 1 32 32v459.242667l190.464-183.509333a32.853333 32.853333 0 0 1 45.44 0c12.586667 12.16 12.586667 31.872 0 44.053333L534.741333 737.493333c-3.157333 3.029333-6.805333 5.333333-10.688 6.848a32.213333 32.213333 0 0 1-23.808 0.085334l-0.32-0.106667a32.128 32.128 0 0 1-10.624-6.826667L244.053333 501.12a30.485333 30.485333 0 0 1 0-44.053333 32.853333 32.853333 0 0 1 45.44 0l190.485334 183.509333V181.333333A32 32 0 0 1 512 149.333333z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M486.570667 97.216a33.130667 33.130667 0 0 1 51.264 0.512c34.709333 43.328 152.064 98.261333 307.776 117.034667 16.576 2.005333 29.056 16 29.056 32.64v372.629333a167.04 167.04 0 0 1-20.096 79.402667C761.813333 871.146667 633.770667 938.666667 511.530667 938.666667l-6.528-0.106667c-118.954667-3.413333-244.586667-70.741333-335.573334-239.125333a167.808 167.808 0 0 1-19.925333-71.914667L149.333333 620.032V247.402667c0-16.64 12.48-30.634667 29.056-32.64 152.426667-18.368 269.077333-72.277333 305.237334-114.005334z m25.408 67.178667l-1.792 1.450666c-52.693333 41.813333-163.456 91.882667-290.389334 109.802667l-4.416 0.597333v342.976l0.149334 5.866667c0.746667 15.104 4.864 29.866667 12.074666 43.221333 80.96 149.845333 188.714667 201.962667 278.826667 204.544l5.568 0.085334c92.522667 0 201.92-51.989333 284.373333-204.629334a101.546667 101.546667 0 0 0 12.224-48.277333V276.245333l-16.277333-2.325333c-120.938667-18.048-227.904-67.690667-278.954667-108.416l-1.386666-1.109333zM512 341.333333a74.666667 74.666667 0 0 1 32.021333 142.144L544 597.333333h21.333333a32 32 0 0 1 0 64h-21.333333v32a32 32 0 0 1-64 0v-209.856A74.666667 74.666667 0 0 1 512 341.333333z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64z m265.9 713.9a377.2 377.2 0 0 1-119.6 80.6 377.5 377.5 0 0 1-292.6 0 377.1 377.1 0 0 1-200.2-200.2 377.5 377.5 0 0 1 0-292.6 377.1 377.1 0 0 1 200.2-200.2 377.5 377.5 0 0 1 292.6 0 377.1 377.1 0 0 1 200.2 200.2 377.5 377.5 0 0 1 0 292.6 377.2 377.2 0 0 1-80.6 119.6zM312 454a58 58 0 1 0 58 58 58 58 0 0 0-58-58z m200 0a58 58 0 1 0 58 58 58 58 0 0 0-58-58z m200 0a58 58 0 1 0 58 58 58 58 0 0 0-58-58z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M821.333333 170.666667a117.333333 117.333333 0 0 1 117.333334 117.333333v448a117.333333 117.333333 0 0 1-117.333334 117.333333h-618.666666A117.333333 117.333333 0 0 1 85.333333 736v-448A117.333333 117.333333 0 0 1 202.666667 170.666667z m0 64h-618.666666A53.333333 53.333333 0 0 0 149.333333 288v448A53.333333 53.333333 0 0 0 202.666667 789.333333h618.666666a53.333333 53.333333 0 0 0 53.333334-53.333333v-448a53.333333 53.333333 0 0 0-53.333334-53.333333z m-469.333333 64a160 160 0 0 1 128 256v99.413333c0 21.12-13.738667 39.893333-34.24 47.36l-3.690667 1.194667-68.48 19.669333a78.357333 78.357333 0 0 1-38.442666 1.194667l-4.714667-1.194667-68.501333-19.669333c-21.269333-6.101333-36.202667-24.042667-37.781334-44.864l-0.149333-3.690667V554.666667l-2.261333-3.072A160 160 0 0 1 352 298.666667z m64 306.688a159.466667 159.466667 0 0 1-64 13.312 159.466667 159.466667 0 0 1-64-13.312v41.173333l60.928 17.493333c1.322667 0.384 2.730667 0.512 4.117333 0.384l2.026667-0.384 60.928-17.493333v-41.173333zM757.333333 554.666667a32 32 0 0 1 0 64h-149.333333a32 32 0 0 1 0-64h149.333333z m-405.333333-192a96 96 0 1 0 0 192 96 96 0 0 0 0-192z m405.333333 42.666666a32 32 0 0 1 0 64h-149.333333a32 32 0 0 1 0-64h149.333333z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M821.333333 192a117.333333 117.333333 0 0 1 117.333334 117.333333v405.333334a117.333333 117.333333 0 0 1-117.333334 117.333333h-618.666666A117.333333 117.333333 0 0 1 85.333333 714.666667v-405.333334A117.333333 117.333333 0 0 1 202.666667 192zM874.666667 426.666667H149.333333v288A53.333333 53.333333 0 0 0 202.666667 768h618.666666a53.333333 53.333333 0 0 0 53.333334-53.333333V426.666667z m-96 64a32 32 0 0 1 0 64h-64a32 32 0 0 1 0-64h64z m42.666666-234.666667h-618.666666A53.333333 53.333333 0 0 0 149.333333 309.333333V362.666667h725.333334v-53.333334a53.333333 53.333333 0 0 0-53.333334-53.333333z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 85.333333c235.648 0 426.666667 191.018667 426.666667 426.666667s-191.018667 426.666667-426.666667 426.666667S85.333333 747.648 85.333333 512 276.352 85.333333 512 85.333333z m0 64C311.701333 149.333333 149.333333 311.701333 149.333333 512s162.368 362.666667 362.666667 362.666667 362.666667-162.368 362.666667-362.666667S712.298667 149.333333 512 149.333333z m0 533.333334a42.666667 42.666667 0 1 1 0 85.333333 42.666667 42.666667 0 0 1 0-85.333333z m0-426.666667c88.362667 0 160 67.861333 160 151.573333 0 75.029333-43.157333 135.189333-125.248 178.688l-2.752 1.408v22.016c0 15.765333-12.693333 28.714667-28.928 30.165334L512 640c-16.64 0-30.293333-12.032-31.850667-27.392l-0.149333-2.922667v-40.426666c0-11.584 6.976-22.186667 17.984-27.242667 75.136-34.688 110.016-78.762667 110.016-134.442667 0-50.218667-42.986667-90.944-96-90.944s-96 40.725333-96 90.944c0 16.746667-14.336 30.314667-32 30.314667s-32-13.568-32-30.293333C352 323.84 423.637333 256 512 256z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M532.053333 138.069333c43.861333-43.861333 117.312-41.493333 164.074667 5.290667l184.768 184.746667c46.762667 46.784 49.130667 120.234667 5.290667 164.096L568.234667 810.154667a108.16 108.16 0 0 1-70.677334 31.210666l-196.8 11.2c-63.637333 3.626667-121.514667-45.333333-129.237333-109.354666a116.266667 116.266667 0 0 1-0.64-20.992l11.904-195.84a108.117333 108.117333 0 0 1 31.189333-70.229334z m120.768 48.597334c-21.248-21.269333-54.634667-22.336-74.581333-2.410667l-318.08 318.08c-8.405333 8.426667-13.44 19.712-14.165333 31.914667l-11.904 195.84c-0.213333 3.178667-0.106667 6.357333 0.277333 9.557333 3.52 29.098667 29.824 51.349333 58.752 49.706667l196.8-11.221334a49.152 49.152 0 0 0 32.128-14.186666l317.952-317.952c19.925333-19.925333 18.837333-53.333333-2.410667-74.581334z m-205.568 300.970666a93.802667 93.802667 0 0 1 93.696 93.888 93.802667 93.802667 0 0 1-93.696 93.909334 93.802667 93.802667 0 0 1-93.696-93.909334 93.802667 93.802667 0 0 1 93.696-93.888z m0 62.592c-17.237333 0-31.232 14.016-31.232 31.296s13.994667 31.317333 31.232 31.317334c17.237333 0 31.232-14.016 31.232-31.317334 0-17.28-13.994667-31.296-31.232-31.296z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M821.333333 170.666667a117.333333 117.333333 0 0 1 117.333334 117.333333v448a117.333333 117.333333 0 0 1-117.333334 117.333333h-618.666666A117.333333 117.333333 0 0 1 85.333333 736v-448A117.333333 117.333333 0 0 1 202.666667 170.666667z m52.842667 110.058666L576 571.072a91.093333 91.093333 0 0 1-124.373333 3.370667l-3.669334-3.370667-298.154666-290.346667A53.802667 53.802667 0 0 0 149.333333 288v448A53.333333 53.333333 0 0 0 202.666667 789.333333h618.666666a53.333333 53.333333 0 0 0 53.333334-53.333333v-448c0-2.474667-0.170667-4.906667-0.490667-7.274667zM821.333333 234.666667h-618.666666c-2.922667 0-5.76 0.213333-8.554667 0.682666l296.533333 288.789334c11.2 10.901333 28.245333 11.626667 40.213334 2.197333l2.474666-2.197333 296.554667-288.789334A53.717333 53.717333 0 0 0 821.333333 234.666667z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M371.050667 865.706667c-11.690667 11.946667-30.613333 11.946667-42.282667 0a31.146667 31.146667 0 0 1 0-43.306667l295.765333-302.933333a10.666667 10.666667 0 0 0 0-14.933334L328.768 201.6a31.146667 31.146667 0 0 1 0-43.306667 29.397333 29.397333 0 0 1 42.282667 0l324.181333 332.053334a31.146667 31.146667 0 0 1 0 43.306666L371.050667 865.706667z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M347.392 116.693333C275.2 140.032 196.693333 209.152 148.266667 288.426667a427.605333 427.605333 0 0 0 19.754666 476.053333c102.698667 140.053333 276.074667 202.24 446.122667 162.325333 11.242667-2.645333 17.408-9.045333 23.744-18.474666 55.978667-83.413333 33.066667-198.442667-51.114667-253.546667-34.773333-22.762667-73.6-31.893333-114.304-34.176-39.296-2.197333-78.592-3.925333-116.224-17.194667-59.669333-21.056-85.802667-59.84-81.941333-123.221333 3.52-57.664 29.866667-106.858667 58.517333-155.093333 4.672-7.829333 12.992-14.208 7.509334-25.813334-28.16-59.648-25.386667-119.082667 7.04-182.570666m526.08 619.797333c138.602667-225.728 46.634667-511.04-184.682667-616.533333-32.362667-14.762667-145.813333-48.938667-271.36-28.010667-19.114667 3.2-30.144 13.866667-39.232 29.76-52.928 92.586667-14.954667 212.266667 81.877333 256.810667 35.498667 16.341333 73.216 21.866667 111.786667 22.826666 38.656 0.981333 76.373333 6.421333 111.978667 22.528 47.658667 21.589333 72.32 67.669333 65.813333 119.808-6.848 54.848-29.056 103.552-58.133333 149.333334-8.682667 13.696-9.088 24.597333-3.946667 39.957333 9.92 29.610667 17.002667 60.8 12.202667 92.245333-4.117333 26.922667-10.837333 53.653333-24.106667 78.997334 78.677333-35.541333 145.408-84.117333 189.973333-159.445334 2.624-2.752 5.888-5.12 7.829334-8.277333z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 85.333333c235.648 0 426.666667 191.018667 426.666667 426.666667s-191.018667 426.666667-426.666667 426.666667S85.333333 747.648 85.333333 512 276.352 85.333333 512 85.333333z m0 64C311.701333 149.333333 149.333333 311.701333 149.333333 512s162.368 362.666667 362.666667 362.666667 362.666667-162.368 362.666667-362.666667S712.298667 149.333333 512 149.333333z m191.232 321.237334c16.192 4.864 25.557333 22.570667 20.928 39.552-27.648 101.632-89.173333 159.914667-180.138667 170.709333L544 757.333333a32 32 0 0 1-64 0v-76.501333c-90.965333-10.794667-152.512-69.077333-180.16-170.709333-4.608-16.981333 4.757333-34.688 20.928-39.552 16.213333-4.842667 33.066667 4.992 37.696 21.973333C381.845333 578.56 430.997333 618.666667 512 618.666667c81.024 0 130.154667-40.106667 153.557333-126.122667 4.629333-16.981333 21.504-26.816 37.674667-21.973333zM512 234.666667c57.386667 0 104.213333 46.933333 106.581333 105.770666l0.085334 4.650667v120.490667C618.666667 526.549333 570.901333 576 512 576c-57.386667 0-104.213333-46.933333-106.581333-105.770667L405.333333 465.578667v-120.490667C405.333333 284.117333 453.098667 234.666667 512 234.666667z m0 60.245333c-25.664 0-46.677333 20.629333-48.362667 46.741333l-0.128 3.434667v120.490667c0 27.712 21.717333 50.176 48.490667 50.176 25.664 0 46.677333-20.629333 48.362667-46.741334l0.128-3.434666v-120.490667c0-27.712-21.717333-50.176-48.490667-50.176z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M693.333333 106.666667A32 32 0 0 1 725.333333 138.666667V170.666667h74.666667a117.333333 117.333333 0 0 1 117.248 112.618666L917.333333 288v448a117.333333 117.333333 0 0 1-112.618666 117.248L800 853.333333h-576a117.333333 117.333333 0 0 1-117.248-112.618666L106.666667 736v-448a117.333333 117.333333 0 0 1 112.618666-117.248L224 170.666667H298.666667V138.666667a32 32 0 0 1 64 0V170.666667h298.666666V138.666667A32 32 0 0 1 693.333333 106.666667z m-20.16 286.912a32.256 32.256 0 0 0-45.866666 0l-149.077334 151.957333-0.341333 0.341333a21.333333 21.333333 0 0 1-30.165333-0.405333l-51.029334-52.416a32.256 32.256 0 0 0-45.866666 0 32.853333 32.853333 0 0 0 0 46.208l89.194666 91.157333a32.256 32.256 0 0 0 45.866667 0l187.285333-190.656a32.853333 32.853333 0 0 0 0-46.186666z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M815.253333 573.866667c17.493333 0 33.749333 8.789333 43.456 23.274666l1.984 3.2 68.565334 119.850667c8.704 15.210667 9.322667 33.706667 1.877333 49.386667l-1.877333 3.562666-68.565334 119.850667a52.416 52.416 0 0 1-41.706666 26.346667l-3.733334 0.128h-137.173333c-17.493333 0-33.749333-8.789333-43.456-23.274667l-1.984-3.2-68.565333-119.850667a53.354667 53.354667 0 0 1-1.877334-49.386666l1.877334-3.562667 68.565333-119.850667a52.416 52.416 0 0 1 41.706667-26.346666l3.733333-0.128h137.173333zM693.333333 106.666667A32 32 0 0 1 725.333333 138.666667V170.666667h74.666667a117.333333 117.333333 0 0 1 117.248 112.618666L917.333333 288v280.128l-11.882666-20.352a68.949333 68.949333 0 0 0-59.605334-34.048h-198.357333a68.949333 68.949333 0 0 0-59.605333 34.048l-89.984 154.176a67.456 67.456 0 0 0 0 68.096L546.496 853.333333H224a117.333333 117.333333 0 0 1-117.248-112.618666L106.666667 736v-448a117.333333 117.333333 0 0 1 112.618666-117.248L224 170.666667H298.666667V138.666667a32 32 0 0 1 64 0V170.666667h298.666666V138.666667A32 32 0 0 1 693.333333 106.666667zM746.666667 689.770667c-31.808 0-57.6 25.472-57.6 56.896 0 31.424 25.792 56.896 57.6 56.896s57.6-25.472 57.6-56.896c0-31.424-25.792-56.896-57.6-56.896z m-116.906667-298.453334l-2.453333 2.261334-149.077334 151.957333-0.341333 0.341333a21.333333 21.333333 0 0 1-28.16 1.408l-2.005333-1.813333-51.029334-52.416a32.256 32.256 0 0 0-45.866666 0 32.853333 32.853333 0 0 0-2.218667 43.733333l2.218667 2.474667 89.194666 91.157333c11.882667 11.968 30.656 12.714667 43.392 2.261334l2.474667-2.261334 187.285333-190.656a32.853333 32.853333 0 0 0 0-46.186666 32.256 32.256 0 0 0-43.392-2.261334z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M158.293333 371.050667a29.397333 29.397333 0 0 1 0-42.282667 31.146667 31.146667 0 0 1 43.306667 0l302.933333 295.765333a10.666667 10.666667 0 0 0 14.933334 0l302.933333-295.765333a31.146667 31.146667 0 0 1 43.306667 0c11.946667 11.669333 11.946667 30.592 0 42.282667L533.653333 695.232a31.146667 31.146667 0 0 1-43.306666 0L158.293333 371.050667z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M558.528 676.053333l282.154667-298.730666A21.333333 21.333333 0 0 0 825.173333 341.333333H198.826667a21.333333 21.333333 0 0 0-15.509334 35.989334L465.472 676.053333a64 64 0 0 0 93.056 0z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M650.048 135.424a33.066667 33.066667 0 0 1 44.266667 49.045333L644.053333 234.666667H778.666667a117.333333 117.333333 0 0 1 117.248 112.618666L896 352v384a117.333333 117.333333 0 0 1-117.333333 117.333333h-533.333334A117.333333 117.333333 0 0 1 128 736v-384a117.333333 117.333333 0 0 1 117.333333-117.333333h113.237334l-50.218667-50.197334a33.066667 33.066667 0 0 1 44.266667-49.066666l2.517333 2.282666L452.096 234.666667h98.453333l96.981334-96.981334zM778.666667 298.666667h-533.333334A53.333333 53.333333 0 0 0 192 352v384a53.333333 53.333333 0 0 0 53.333333 53.333333h533.333334a53.333333 53.333333 0 0 0 53.333333-53.333333v-384a53.333333 53.333333 0 0 0-53.333333-53.333333z m-352.064 138.709333c0-26.026667 29.44-41.152 50.602666-26.026667l149.333334 106.624a31.978667 31.978667 0 0 1 0 52.053334l-149.333334 106.624c-21.184 15.125333-50.602667 0-50.602666-26.026667z m64.021333 62.144v88.96l62.293333-44.48-62.293333-44.48z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M650.048 135.424a33.066667 33.066667 0 0 1 44.266667 49.045333L644.053333 234.666667H778.666667a117.333333 117.333333 0 0 1 117.248 112.618666L896 352v384a117.333333 117.333333 0 0 1-117.333333 117.333333h-533.333334A117.333333 117.333333 0 0 1 128 736v-384a117.333333 117.333333 0 0 1 117.333333-117.333333h113.237334l-50.218667-50.197334a33.066667 33.066667 0 0 1 44.266667-49.066666l2.517333 2.282666L452.096 234.666667h98.453333l96.981334-96.981334zM426.602667 437.376v213.248c0 26.026667 29.44 41.152 50.602666 26.026667l149.333334-106.624a31.978667 31.978667 0 0 0 0-52.053334l-149.333334-106.624c-21.184-15.125333-50.602667 0-50.602666 26.026667z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M469.568 127.530667c28.16-28.16 74.154667-27.776 102.762667 0.853333l2.986666 3.157333 2.816 3.370667 251.093334 318.293333c34.986667 44.373333 32.896 106.773333-4.224 147.477334l-3.584 3.733333-42.986667 42.986667 110.997333 110.976c34.56 34.581333 37.077333 88.938667 7.189334 125.376l-3.093334 3.584-3.029333 3.157333c-35.050667 35.072-91.648 35.712-128.597333 2.282667l-3.498667-3.349334-111.018667-110.976-42.944 42.965334c-38.186667 38.186667-98.005333 43.370667-143.04 13.696l-4.330666-2.986667-3.84-2.901333L134.912 578.133333c-31.765333-25.045333-37.610667-70.762667-13.077333-102.122666l2.752-3.306667 2.944-3.136L469.568 127.530667z m300.586667 350.570666l-292.053334 292.053334 13.205334 10.410666c19.882667 15.68 47.744 14.976 66.261333-1.237333l2.453333-2.304 86.656-86.656 155.392 155.392a31.146667 31.146667 0 0 0 44.032 0.341333c11.306667-11.306667 11.882667-29.333333 1.813334-41.642666l-2.154667-2.389334-155.413333-155.370666 86.677333-86.677334c17.493333-17.493333 19.754667-45.013333 5.866667-65.536l-2.325334-3.2-10.410666-13.184z m-449.408-112.96l-55.744 55.765334 72.021333 54.250666c13.034667 9.813333 16.256 27.84 7.893333 41.472l-1.706666 2.496c-9.813333 13.013333-27.84 16.256-41.472 7.893334l-2.496-1.706667-79.061334-59.584-48.661333 48.682667-0.405333 0.469333a10.389333 10.389333 0 0 0 0.490666 13.312l1.386667 1.28 255.466667 201.536 302.528-302.528-201.514667-255.488-0.832-0.938667a10.432 10.432 0 0 0-13.226667-1.322666l-1.450666 1.194666-48.256 48.277334 59.584 79.04a31.402667 31.402667 0 0 1-50.133334 37.802666l-54.272-72.021333-55.744 55.722667 81.408 81.408a31.402667 31.402667 0 0 1-44.416 44.373333l-81.386666-81.386667z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M814.058667 433.984l15.168 19.242667c34.986667 44.352 32.896 106.752-4.224 147.456l-3.584 3.733333-42.986667 42.986667 110.997333 110.976c34.56 34.581333 37.077333 88.938667 7.189334 125.376l-3.093334 3.584-3.029333 3.157333c-35.050667 35.072-91.648 35.712-128.597333 2.282667l-3.498667-3.349334-111.018667-110.976-42.944 42.965334c-38.186667 38.186667-98.005333 43.370667-143.04 13.696l-4.330666-2.986667-3.84-2.901333-19.242667-15.168 380.074667-380.074667zM572.330667 128.362667l2.986666 3.2 2.816 3.349333L774.186667 383.36 383.402667 774.144 134.912 578.133333c-31.765333-25.045333-37.610667-70.762667-13.077333-102.122666l2.752-3.306667 2.944-3.136 43.221333-43.221333 100.736 59.52 1.728 0.853333a10.666667 10.666667 0 0 0 11.946667-16.789333l-71.253334-86.741334 57.728-57.728 101.674667 66.026667 1.706667 0.896a10.666667 10.666667 0 0 0 13.013333-15.701333l-66.346667-101.269334 52.117334-52.117333 72.042666 68.117333 1.493334 1.194667a10.666667 10.666667 0 0 0 15.317333-13.845333l-49.173333-95.146667 56.106666-56.085333c28.138667-28.16 74.133333-27.776 102.741334 0.853333z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M519.04 575.978667H512h5.781333l4.501334-0.064h3.776l6.186666-0.128c89.92-1.664 173.12-14.528 234.922667-35.626667 21.973333-7.530667 39.978667-15.658667 53.845333-23.744 30.208-14.293333 55.594667-30.677333 74.965334-48.618667L896 490.666667l0.021333 45.162666-0.042666 0.021334L896 885.333333a32 32 0 0 1-64 0V582.528c-21.717333 10.688-46.976 20.053333-75.093333 27.925333l-10.24 2.730667V800a32 32 0 0 1-64 0v-173.312l-5.205334 0.917333-18.730666 2.773334-15.317334 2.005333-23.488 2.56-24.085333 2.048-16.341333 1.066667-8.256 0.448-16.682667 0.725333c-8.405333 0.298667-16.853333 0.512-25.386667 0.64L512 640l-17.152-0.128c-8.533333-0.128-17.002667-0.341333-25.386667-0.64l-20.842666-0.938667-20.48-1.301333-24.064-2.048-23.488-2.56-15.317334-1.984-15.018666-2.218667-8.938667-1.472L341.333333 800a32 32 0 0 1-64 0v-186.816l-10.24-2.730667c-28.138667-7.893333-53.397333-17.237333-75.114666-27.946666L192 864a32 32 0 0 1-64 0l-0.021333-328.170667L128 490.666667v-22.890667c19.370667 17.962667 44.778667 34.346667 75.029333 48.64 13.845333 8.085333 31.829333 16.213333 53.802667 23.722667 61.824 21.12 145.066667 33.984 234.986667 35.669333l6.08 0.085333 2.56 0.042667 5.76 0.042667H512l10.133333-0.064-3.093333 0.064zM512 106.666667c235.648 0 426.666667 95.509333 426.666667 213.333333s-191.018667 213.333333-426.666667 213.333333S85.333333 437.824 85.333333 320 276.352 106.666667 512 106.666667z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 234.666667l320 170.666666v405.333334a85.333333 85.333333 0 0 1-85.333333 85.333333H277.333333a85.333333 85.333333 0 0 1-85.333333-85.333333V405.333333l320-170.666666z m149.376 384h-298.666667l-2.432 0.128c-17.365333 1.856-25.514667 23.466667-12.629333 36.309333l85.610667 85.333333 2.005333 1.770667a21.333333 21.333333 0 0 0 28.16-1.813333l1.770667-2.005334a21.333333 21.333333 0 0 0-1.813334-28.16L414.336 661.333333h247.04l2.496-0.149333A21.333333 21.333333 0 0 0 661.376 618.666667z m-72.597333-166.208a21.333333 21.333333 0 0 0-28.16 1.813333l-1.770667 2.005333a21.333333 21.333333 0 0 0 1.813333 28.16L609.706667 533.333333H362.666667l-2.496 0.149334A21.333333 21.333333 0 0 0 362.666667 576h298.666666l2.432-0.128c17.365333-1.856 25.514667-23.466667 12.629334-36.309333l-85.610667-85.333334z m-64.64-322.218667l3.306666 1.493333 372.458667 209.408c16.021333 8.234667 22.101333 27.477333 13.568 42.944-8.021333 14.570667-26.133333 20.629333-41.6 14.421334l-2.858667-1.301334-356.992-201.450666-356.992 201.365333a33.557333 33.557333 0 0 1-42.837333-10.389333l-1.642667-2.645334a31.146667 31.146667 0 0 1 10.773334-41.386666l2.709333-1.578667 372.48-209.365333a33.898667 33.898667 0 0 1 27.648-1.493334z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M296.704 517.546667v-3.584l0.32-4.394667 0.704-6.549333 0.938667-6.186667 0.853333-4.736 1.066667-5.12 1.28-5.546667 1.536-5.952 1.834666-6.293333 2.133334-6.613333 2.453333-6.954667 2.816-7.210667 1.536-3.733333 3.370667-7.594667c21.461333-46.421333 64.96-105.173333 153.130666-153.258666 97.472-53.141333 170.176-12.416 220.117334 43.52l6.122666 7.061333c2.005333 2.389333 3.968 4.778667 5.888 7.189333l5.653334 7.274667 2.730666 3.669333 5.312 7.338667 5.056 7.36 4.842667 7.338667 4.608 7.253333 4.373333 7.168 4.138667 7.04 5.802667 10.218667 5.269333 9.728 9.024 17.557333 8 16.170667c9.365333 18.965333 25.130667 34.688 42.88 50.538666l21.952 19.285334c27.946667 24.725333 56.405333 52.736 70.528 95.36 27.285333 82.410667 14.101333 150.912-26.112 191.872l-9.984 10.069333-6.656 6.485333-7.168 6.613334-5.034667 4.458666-5.269333 4.416-5.461333 4.330667-5.674667 4.224-5.888 4.053333c-43.946667 29.184-104.448 42.624-177.706667-31.978666-36.864-37.546667-45.866667-63.658667-49.813333-86.144l-1.066667-6.634667-1.728-12.821333-0.96-6.272c-2.837333-16.661333-8.234667-33.002667-27.904-53.056-23.189333-23.616-36.394667-27.029333-52.416-25.408l-4.650666 0.576-18.474667 3.050666-6.186667 0.853334-3.264 0.362666-6.954666 0.576c-16.96 1.045333-38.954667-0.192-69.76-8.149333-62.208-16.106667-88.64-50.304-99.882667-76.373333l-2.048-5.098667a110.976 110.976 0 0 1-0.874667-2.453333l-1.514666-4.672-1.194667-4.352-1.28-5.781334-0.597333-3.328-0.682667-5.973333a52.544 52.544 0 0 1-0.064-0.768z m-165.888-106.730667c32.405333-32.981333 85.12-32.789333 117.76 0.469333 32.64 33.237333 32.832 86.933333 0.426667 119.893334-32.362667 33.002667-85.077333 32.789333-117.717334-0.426667-32.64-33.28-32.853333-86.954667-0.469333-119.936z m365.013333-270.506667a41.088 41.088 0 0 1 58.858667 0.213334c16.32 16.64 16.426667 43.477333 0.213333 59.968a41.088 41.088 0 0 1-58.88-0.213334 42.965333 42.965333 0 0 1-0.213333-59.968zM365.013333 190.997333a51.968 51.968 0 0 1 36.650667-37.333333c17.941333-4.821333 37.12 0.469333 50.325333 13.909333 20.394667 20.778667 20.522667 54.336 0.277334 74.965334a51.370667 51.370667 0 0 1-73.6-0.298667 53.973333 53.973333 0 0 1-13.653334-51.242667z m-124.608 66.794667a61.653333 61.653333 0 0 1 88.32 0.362667c24.469333 24.917333 24.618667 65.194667 0.32 89.941333a61.653333 61.653333 0 0 1-88.298666-0.362667c-24.469333-24.917333-24.64-65.194667-0.341334-89.941333z" /></svg>
\ No newline at end of file
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="32px" height="32.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M444.096 264.597333c99.733333-58.069333 199.381333-27.306667 259.477333 54.976 14.72 20.16 25.984 38.229333 38.698667 61.226667l21.056 38.613333 8.32 14.72 5.098667 8.64 4.992 8.128 5.12 8.021334 5.546666 8.32 6.122667 8.96c5.312 7.658667 10.88 15.210667 16.853333 22.826666l2.069334 2.56 7.978666 9.493334 33.024 38.485333 15.146667 17.898667 12.864 15.530666 8.192 10.24 4.48 5.909334 3.562667 4.949333 1.386666 2.090667c4.8 7.466667 8.832 14.848 12.16 22.314666 39.530667 88.789333 24.810667 194.773333-28.586666 252.885334-63.616 69.226667-200.085333 83.2-276.544 0-35.84-39.018667-51.541333-70.976-57.685334-108.394667l-0.896-5.141333c-4.928-26.688-12.586667-41.493333-31.253333-53.653334-9.770667-6.357333-28.266667-11.413333-55.445333-15.296l-4.544-0.64-9.856-1.258666-35.584-4.138667-8.853334-1.216-7.530666-1.216a175.146667 175.146667 0 0 1-3.413334-0.64l-6.208-1.408-2.922666-0.768c-62.570667-17.28-101.632-53.824-120.64-100.906667l-2.282667-6.122666-3.221333-10.325334-1.557334-6.186666-1.557333-7.637334-0.810667-5.290666-0.853333-8.405334v-8.490666l0.405333-5.973334 0.853334-8.170666 1.066666-7.509334 0.981334-5.76 1.216-6.250666 1.472-6.677334 1.749333-7.125333 2.048-7.530667 2.389333-7.893333 2.773334-8.234667 3.413333-9.386666 4.949333-12.074667c29.376-67.84 82.624-129.216 164.778667-177.066667z m203.989333 88.298667c-41.813333-54.336-104.96-72.469333-172.309333-32.96-70.165333 41.194667-114.069333 92.16-137.728 147.242667l-3.157333 7.637333-3.626667 9.770667-2.133333 6.464-1.856 6.186666-1.578667 5.824-1.344 5.461334-1.109333 5.098666-0.896 4.672-0.704 4.053334-0.768 5.333333-0.597334 5.610667-0.213333 2.517333-0.064 1.834667 0.341333 3.477333 0.277334 1.984 0.896 4.565333 0.810666 3.242667 1.578667 5.226667 1.792 4.821333c11.050667 27.648 34.368 49.6 77.013333 61.504l3.626667 0.853333 4.650667 0.896 5.802666 0.896 7.125334 0.96 39.936 4.736 10.24 1.386667c36.202667 5.226667 62.101333 12.373333 82.218666 25.557333 39.509333 25.92 54.613333 58.645333 62.4 106.517334l0.768 4.266666c4.416 22.464 14.506667 41.770667 40.042667 69.76 48.512 53.205333 142.293333 43.52 181.973333 0 34.688-38.037333 45.333333-115.328 16.64-180.352a101.696 101.696 0 0 0-7.317333-13.397333 84.458667 84.458667 0 0 0-3.370667-4.821333l-5.077333-6.570667-6.464-8.021333-15.829333-19.008-45.269334-53.290667-7.850666-9.536-1.792-2.282667a574.762667 574.762667 0 0 1-19.264-26.325333l-6.805334-10.005333-6.122666-9.258667-5.674667-8.938667-5.482667-9.002666-5.546666-9.472-5.845334-10.346667-6.4-11.626667-18.517333-34.261333a485.610667 485.610667 0 0 0-34.24-54.613333zM194.410667 381.589333c25.088 25.088 25.258667 65.6 0.341333 90.496-24.896 24.917333-65.408 24.746667-90.496-0.341333-25.088-25.088-25.258667-65.6-0.341333-90.496 24.896-24.917333 65.408-24.746667 90.496 0.341333z m88.490666-173.824a53.333333 53.333333 0 0 1 0.298667 75.434667 53.333333 53.333333 0 0 1-75.434667-0.298667 53.333333 53.333333 0 0 1-0.298666-75.434666 53.333333 53.333333 0 0 1 75.434666 0.298666z m131.157334-88.490666a42.666667 42.666667 0 0 1 0.213333 60.352 42.666667 42.666667 0 0 1-60.330667-0.234667 42.88 42.88 0 0 1-11.2-41.258667c3.882667-14.72 15.36-26.176 30.058667-30.058666a42.88 42.88 0 0 1 41.258667 11.2z m131.157333-24.490667a32 32 0 0 1 0.170667 45.269333 32 32 0 0 1-45.269334-0.170666 32 32 0 0 1-0.170666-45.269334 32 32 0 0 1 45.269333 0.170667z" /></svg>
\ No newline at end of file
<template>
<component :is="type" v-bind="linkProps">
<slot />
</component>
</template>
<script lang="ts" setup>
/**
* @description 兼容第三方页面的跳转
*/
import { isExternal } from '@/utils/validate'
interface Props {
to: string | Record<string, string>
replace?: boolean
}
const props = defineProps<Props>()
const isExternalLink = computed(() => {
return typeof props.to !== 'object' && isExternal(props.to)
})
const type = computed(() => {
if (isExternalLink.value) {
return 'a'
}
return 'router-link'
})
const linkProps = computed(() => {
if (isExternalLink.value) {
return {
href: props.to,
target: '_blank'
}
}
return props
})
</script>
<template>
<div class="color-picker flex flex-1">
<el-color-picker v-model="color" :predefine="predefineColors" />
<el-input v-model="color" class="mx-[10px] flex-1" type="text" readonly />
<el-button type="text" @click="reset">重置</el-button>
</div>
</template>
<script lang="ts" setup>
const props = defineProps({
modelValue: {
type: String
},
defaultColor: {
type: String
}
})
const emit = defineEmits<{
(event: 'update:modelValue', value: any): void
}>()
const color = computed({
get() {
return props.modelValue
},
set(value) {
emit('update:modelValue', value)
}
})
const predefineColors = ['#409EFF', '#28C76F', '#EA5455', '#FF9F43', '#01CFE8', '#4A5DFF']
const reset = () => {
color.value = props.defaultColor
}
</script>
<template>
<el-date-picker
v-model="content"
type="datetimerange"
range-separator="-"
start-placeholder="开始时间"
end-placeholder="结束时间"
value-format="YYYY-MM-DD HH:mm:ss"
clearable
></el-date-picker>
</template>
<script lang="ts" setup>
import { withDefaults, computed } from 'vue'
/* Props S */
const props = withDefaults(
defineProps<{
startTime?: string
endTime?: string
}>(),
{
startTime: '',
endTime: ''
}
)
const emit = defineEmits(['update:startTime', 'update:endTime'])
const content = computed<any>({
get: () => {
return [props.startTime, props.endTime]
},
set: (value: Event | any) => {
if (value === null) {
emit('update:startTime', '')
emit('update:endTime', '')
} else {
emit('update:startTime', value[0])
emit('update:endTime', value[1])
}
}
})
</script>
<template>
<div class="del-wrap">
<slot></slot>
<div v-if="showClose" class="icon-close" @click.stop="handleClose">
<icon :size="12" name="el-icon-CloseBold" />
</div>
</div>
</template>
<script lang="ts">
export default defineComponent({
props: {
showClose: {
type: Boolean,
default: true
}
},
emits: ['close'],
setup(props, { emit }) {
const handleClose = () => {
emit('close')
}
return {
handleClose
}
}
})
</script>
<style scoped lang="scss">
.del-wrap {
position: relative;
&:hover > .icon-close {
display: flex;
}
.icon-close {
display: none;
position: absolute;
top: -8px;
right: -8px;
width: 16px;
height: 16px;
background-color: rgba(0, 0, 0, 0.3);
justify-content: center;
align-items: center;
border-radius: 50%;
color: #fff;
cursor: pointer;
}
}
</style>
<template>
<div>
<template v-for="(item, index) in getOptions" :key="index">
<span>{{ index != 0 ? '、' : '' }}{{ item[config.label] }}</span>
</template>
</div>
</template>
<script lang="ts" setup>
const props = withDefaults(
defineProps<{
options: any[]
value: any
config: Record<string, string>
}>(),
{
options: () => [],
config: () => ({
label: 'name',
value: 'value'
})
}
)
const values = computed(() => {
if (props.value !== null && typeof props.value !== 'undefined') {
return Array.isArray(props.value) ? props.value : String(props.value).split(',')
} else {
return []
}
})
const getOptions = computed(() => {
return props.options.filter((item) => values.value.includes(item[props.config.value]))
})
</script>
<template>
<div class="border border-br flex flex-col" :style="styles">
<toolbar class="border-b border-br" :editor="editorRef" :defaultConfig="toolbarConfig" :mode="mode" />
<w-editor class="overflow-y-auto flex-1" v-model="valueHtml" :defaultConfig="editorConfig" :mode="mode"
@onCreated="handleCreated" />
<material-picker ref="materialPickerRef" :type="fileType" :limit="-1" hidden-upload @change="selectChange" />
</div>
</template>
<script setup lang="ts">
import '@wangeditor/editor/dist/css/style.css' // 引入 css
import { Editor as WEditor, Toolbar } from '@wangeditor/editor-for-vue'
import type { IEditorConfig, IToolbarConfig } from '@wangeditor/editor'
import MaterialPicker from '@/components/material/picker.vue'
import { addUnit } from '@/utils/util'
import type { CSSProperties } from 'vue'
import { getToken } from '@/utils/auth'
const props = withDefaults(
defineProps<{
modelValue?: string
mode?: 'default' | 'simple'
height?: string | number
width?: string | number
toolbarConfig?: Partial<IToolbarConfig>
}>(),
{
modelValue: '',
mode: 'default',
height: '100%',
width: 'auto',
toolbarConfig: () => ({})
}
)
const emit = defineEmits<{
(event: 'update:modelValue', value: string): void
}>()
// 编辑器实例,必须用 shallowRef
const editorRef = shallowRef()
const materialPickerRef = shallowRef<InstanceType<typeof MaterialPicker>>()
const fileType = ref('')
let insertFn: any
const editorConfig: Partial<IEditorConfig> = {
MENU_CONF: {
uploadImage: {
customBrowseAndUpload(insert: any) {
fileType.value = 'image'
materialPickerRef.value?.showPopup(-1)
insertFn = insert
}
},
uploadVideo: {
fieldName: 'image',
server: 'https://foxpsd.com/xcxapi/shop/uploadImg',
meta: {
token: getToken()
},
metaWithUrl: true,
customInsert(res: any, insertFn: any) {
insertFn(res.img_url)
}
}
}
}
const styles = computed<CSSProperties>(() => ({
height: addUnit(props.height),
width: addUnit(props.width)
}))
const valueHtml = computed({
get() {
return props.modelValue
},
set(value) {
emit('update:modelValue', value)
}
})
const selectChange = (fileUrl: string[]) => {
fileUrl.forEach((url) => {
insertFn(url)
})
}
// 组件销毁时,也及时销毁编辑器
onBeforeUnmount(() => {
const editor = editorRef.value
if (editor == null) return
editor.destroy()
})
const handleCreated = (editor: any) => {
editorRef.value = editor // 记录 editor 实例,重要!
}
</script>
<style lang="scss">
.w-e-full-screen-container {
z-index: 999;
}
.w-e-text-container [data-slate-editor] ul {
list-style: disc;
}
.w-e-text-container [data-slate-editor] ol {
list-style: decimal;
}
h1 {
font-size: 2em;
}
h2 {
font-size: 1.5em;
}
h3 {
font-size: 1.17em;
}
h4 {
font-size: 1em;
}
h5 {
font-size: 0.83em;
}
h1,
h2,
h3,
h4,
h5 {
font-weight: bold;
}
</style>
<template>
<div class="export-data">
<popup ref="popupRef" title="导出设置" width="500px" confirm-button-text="确认导出" @confirm="handleConfirm" :async="true"
@open="getData">
<template #trigger>
<el-button>导出</el-button>
</template>
<div>
<el-form ref="formRef" :model="formData" label-width="120px" :rules="formRules">
<el-form-item label="数据量:">
预计导出{{ exportData.count }}条数据, 共{{ exportData.sum_page }}页,每页{{
exportData.page_size
}}条数据
</el-form-item>
<el-form-item label="导出限制:">
每次导出最大允许{{ exportData.max_page }}页,共{{
exportData.all_max_size
}}条数据
</el-form-item>
<el-form-item prop="page_type" label="导出范围:" required>
<el-radio-group v-model="formData.page_type">
<el-radio :label="0">全部导出</el-radio>
<el-radio :label="1">分页导出</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="分页范围:" v-if="formData.page_type == 1">
<div class="flex">
<el-form-item prop="page_start">
<el-input style="width: 140px" v-model.number="formData.page_start"
placeholder=""></el-input>
</el-form-item>
<span class="flex-none ml-2 mr-2">页,至</span>
<el-form-item prop="page_end">
<el-input style="width: 140px" v-model.number="formData.page_end" placeholder=""></el-input>
</el-form-item>
</div>
</el-form-item>
<el-form-item label="导出文件名称:" prop="file_name">
<el-input v-model="formData.file_name" placeholder="请输入导出文件名称"></el-input>
</el-form-item>
</el-form>
</div>
</popup>
</div>
</template>
<script lang="ts" setup>
import feedback from '@/utils/feedback'
import Popup from '@/components/popup/index.vue'
import type { FormInstance } from 'element-plus'
const formRef = shallowRef<FormInstance>()
const props = defineProps({
params: {
type: Object,
default: () => ({})
},
pageSize: {
type: Number,
default: 25
},
fetchFun: {
type: Function,
required: true
}
})
const popupRef = shallowRef<InstanceType<typeof Popup>>()
const formData = reactive({
page_type: 0,
page_start: 1,
page_end: 200,
file_name: ''
})
const formRules: any = {
page_start: [
{ required: true, message: '请输入起始页码' },
{ type: 'number', message: '页码必须是整数' },
{
validator: (rule: any, value: any, callback: any) => {
if (value <= 0) return callback(new Error('页码必须大于0'))
callback()
}
}
],
page_end: [
{ required: true, message: '请输入结束页码' },
{ type: 'number', message: '页码必须是整数' },
{
validator: (rule: any, value: any, callback: any) => {
if (value <= 0) return callback(new Error('页码必须大于0'))
callback()
}
}
]
}
const exportData = reactive({
count: 0,
sum_page: 0,
page_size: 0,
max_page: 0,
all_max_size: 0
})
const getData = async () => {
const res = await props.fetchFun({
...props.params,
page_size: props.pageSize,
export: 1
})
Object.assign(exportData, res)
formData.file_name = res.file_name
formData.page_end = res.page_end
formData.page_start = res.page_start
}
const handleConfirm = async () => {
await formRef.value?.validate()
feedback.loading('正在导出中...')
try {
await props.fetchFun({
...props.params,
...formData,
page_size: props.pageSize,
export: 2
})
popupRef.value?.close()
feedback.closeLoading()
} catch (error) {
feedback.closeLoading()
}
}
getData()
</script>
<template>
<div class="footer-btns">
<div class="footer-btns__content" :style="fixed ? 'position: fixed' : ''">
<slot></slot>
</div>
</div>
</template>
<script lang="ts" setup>
defineProps({
fixed: {
type: Boolean,
default: true
}
})
</script>
<style scoped lang="scss">
.footer-btns {
height: 60px;
&__content {
bottom: 0;
height: 60px;
right: 0;
left: 0;
z-index: 99;
@apply flex justify-center items-center shadow bg-body;
}
}
</style>
<template>
<div class="foxpsd-template-choose-select">
<popup ref="popupRef" width="1000px" custom-class="body-padding" title="选择foxpsd模板" @confirm="handleConfirm"
@close="handleClose">
<div class="foxpsd_choose_wrap">
<div class="foxpsd_choose_search">
<el-form ref="formRef" class="mb-[-16px]" @submit.native.prevent :model="fileParams" :inline="true">
<el-form-item>
<el-input placeholder="搜索模板标题/SKU" class="w-[280px]" v-model="fileParams.content" clearable
/>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="resetPage">查询</el-button>
<el-button @click="resetParams">重置</el-button>
</el-form-item>
</el-form>
</div>
<div class="foxpsd_choose flex flex-col flex-1 mb-1 min-h-0 mt-2">
<el-scrollbar v-if="pager.lists.length">
<ul class="file-list flex flex-wrap">
<li class="file-item-wrap" v-for="item in pager.lists" :key="item.id"
:style="{ width: '100px' }">
<file-item :uri="item.img_url" file-size="100px" type="image" @click="selectFile(item)">
<div class="item-selected" v-if="isSelect(item.id)">
<icon :size="24" name="el-icon-Check" color="#fff" />
</div>
</file-item>
<overflow-tooltip class="mt-1" :content="item.title" />
</li>
</ul>
</el-scrollbar>
</div>
<div class="flex flex-1 justify-center items-center" v-if="!pager.loading && !pager.lists.length">
暂无数据~
</div>
<div class="flex justify-between items-center mt-2">
<pagination v-model="pager" @change="getLists" layout="total, prev, pager, next, jumper" />
</div>
</div>
</popup>
<div class="flex">
<el-input placeholder="请选择模板" disabled :value="modelValue" v-if="haveInput"/>
<el-button @click="showPopup()" type="primary" class="ml-2">选择模板</el-button>
</div>
</div>
</template>
<script lang="ts" setup>
import Popup from '@/components/popup/index.vue'
import { useThrottleFn } from '@vueuse/core'
import { usePaging } from '@/hooks/usePaging'
import FileItem from './../material/file.vue'
import { foxpsdDiyTemplateListFindAndCountAll } from "@/api/product"
const popupRef = ref<InstanceType<typeof Popup>>()
const select = ref<any[]>([])
const limit = ref(1)
const emit = defineEmits<{
(event: 'update:modelValue', value: string): void
(event: 'change', value: any): void
}>()
defineProps(['modelValue','haveInput']);
const handleClose = () => {
nextTick(() => { })
}
const fileParams = reactive({
content: '',
status: 1
})
const { pager, getLists, resetPage, resetParams } = usePaging({
fetchFun: foxpsdDiyTemplateListFindAndCountAll,
params: fileParams,
firstLoading: true
})
const selectFile = (item: any) => {
const index = select.value.findIndex((items: any) => items.id == item.id)
if (index != -1) {
select.value.splice(index, 1)
return
}
if (select.value.length == limit.value) {
if (limit.value == 1) {
select.value = []
select.value.push(item)
return
}
}
select.value.push(item)
}
const isSelect = (id: number) => {
return !!select.value.find((item: any) => item.id == id)
}
const showPopup = () => {
popupRef.value?.open()
}
const handleConfirm = useThrottleFn(
() => {
emit('update:modelValue', select.value[0].sku);
emit('change', select.value[0]);
},
1000,
false
)
getLists();
</script>
<style scoped lang="scss">
.foxpsd_choose_wrap {
padding: 20px;
.foxpsd_choose {
max-height: 400px;
min-height: 200px;
}
}
.file-list {
.file-item-wrap {
margin-right: 16px;
line-height: 1.3;
cursor: pointer;
.item-selected {
display: flex;
align-items: center;
justify-content: center;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border-radius: 4px;
background-color: rgba(0, 0, 0, 0.5);
box-sizing: border-box;
}
.operation-btns {
height: 28px;
visibility: hidden;
}
&:hover .operation-btns {
visibility: visible;
}
}
}
</style>
\ No newline at end of file
import * as ElementPlusIcons from '@element-plus/icons-vue'
//@ts-ignore
import localIconsName from 'virtual:svg-icons-names'
export const LOCAL_ICON_PREFIX = 'local-icon-'
export const EL_ICON_PREFIX = 'el-icon-'
const elIconsName: string[] = []
for (const [, component] of Object.entries(ElementPlusIcons)) {
elIconsName.push(`${EL_ICON_PREFIX}${component.name}`)
}
export function getElementPlusIconNames() {
return elIconsName
}
export function getLocalIconNames() {
return localIconsName
}
<script lang="ts">
import { createVNode } from 'vue'
import { ElIcon } from 'element-plus'
import { EL_ICON_PREFIX, LOCAL_ICON_PREFIX } from './index'
import svgIcon from './svg-icon.vue'
export default defineComponent({
name: 'Icon',
props: {
name: {
type: String,
required: true
},
size: {
type: [String, Number],
default: '14px'
},
color: {
type: String,
default: 'inherit'
}
},
setup(props) {
if (props.name.indexOf(EL_ICON_PREFIX) === 0) {
// el-icon
return () =>
createVNode(
ElIcon,
{
size: props.size,
color: props.color
},
() => [createVNode(resolveComponent(props.name.replace(EL_ICON_PREFIX, '')))]
)
}
if (props.name.indexOf(LOCAL_ICON_PREFIX) === 0) {
// 本地icon
return () =>
h(
'i',
{
class: ['local-icon']
},
createVNode(svgIcon, { ...props })
)
}
}
})
</script>
<template>
<div class="icon-select">
<el-popover
trigger="contextmenu"
v-model:visible="state.popoverVisible"
:width="state.popoverWidth"
>
<div
@mouseover.stop="state.mouseoverSelect = true"
@mouseout.stop="state.mouseoverSelect = false"
>
<div>
<div class="flex justify-between">
<div class="mb-3">请选择图标</div>
<div>
<span
v-for="(item, index) in iconTabsMap"
:key="index"
class="cursor-pointer text-sm ml-2"
:class="{
'text-primary': index == tabIndex
}"
@click="tabIndex = index"
>
{{ item.name }}
</span>
</div>
</div>
<div class="h-[280px]">
<el-scrollbar>
<div class="flex flex-wrap">
<div v-for="item in iconNamesFliter" :key="item" class="m-1">
<el-button @click="handleSelect(item)">
<icon :name="item" :size="18" />
</el-button>
</div>
</div>
</el-scrollbar>
</div>
</div>
</div>
<template #reference>
<el-input
ref="inputRef"
v-model.trim="state.inputValue"
placeholder="搜索图标"
:autofocus="false"
:disabled="disabled"
@focus="handleFocus"
@blur="handleBlur"
clearable
>
<template #prepend>
<div class="flex items-center" v-if="modelValue">
<el-tooltip class="flex-1 w-20" :content="modelValue" placement="top">
<icon
class="mr-1"
:key="modelValue"
:name="modelValue"
:size="16"
/>
</el-tooltip>
</div>
<template v-else></template>
</template>
<template #append>
<el-button>
<icon name="el-icon-Close" :size="18" @click="handleClear" />
</el-button>
</template>
</el-input>
</template>
</el-popover>
</div>
</template>
<script lang="ts" setup>
import { computed, nextTick, onMounted, reactive, shallowRef, watch } from 'vue'
import { useEventListener } from '@vueuse/core'
import { ElInput } from 'element-plus'
import { getElementPlusIconNames, getLocalIconNames } from './index'
interface Props {
modelValue: string
disabled?: boolean
}
withDefaults(defineProps<Props>(), {
modelValue: '',
disabled: false
})
const emits = defineEmits<{
(e: 'update:modelValue', value: string): void
(e: 'change', value: string): void
}>()
const tabIndex = ref(0)
const iconTabsMap = [
{
name: 'element图标',
icons: getElementPlusIconNames()
},
{
name: '本地图标',
icons: getLocalIconNames()
}
]
const inputRef = shallowRef<InstanceType<typeof ElInput>>()
const state = reactive({
inputValue: '',
popoverVisible: false,
popoverWidth: 0,
mouseoverSelect: false,
inputFocus: false
})
// input 框聚焦
const handleFocus = () => {
state.inputFocus = state.popoverVisible = true
}
// input 框失去焦点
const handleBlur = () => {
state.inputFocus = false
state.popoverVisible = state.mouseoverSelect
}
// 选中图标
const handleSelect = (icon: string) => {
state.mouseoverSelect = state.popoverVisible = false
emits('update:modelValue', icon)
emits('change', icon)
}
//取消选中
const handleClear = () => {
emits('update:modelValue', '')
emits('change', '')
}
//根据输入框内容塞选
const iconNamesFliter = computed(() => {
const iconNames = iconTabsMap[tabIndex.value]?.icons ?? []
if (!state.inputValue) {
return iconNames
}
const inputValue = state.inputValue.toLowerCase()
return iconNames.filter((icon: string) => {
if (icon.toLowerCase().indexOf(inputValue) !== -1) {
return icon
}
})
})
// 获取 input 的宽度
const getInputWidth = () => {
nextTick(() => {
const inputWidth = inputRef.value?.$el.offsetWidth
state.popoverWidth = inputWidth < 300 ? 300 : inputWidth
})
}
//监听body点击事件
useEventListener(document.body, 'click', () => {
state.popoverVisible = state.inputFocus || state.mouseoverSelect ? true : false
})
watch(
() => state.popoverVisible,
async (value) => {
await nextTick()
if (value) {
inputRef.value?.focus()
} else {
inputRef.value?.blur()
}
}
)
onMounted(() => {
getInputWidth()
})
</script>
<template>
<svg aria-hidden="true" :style="styles">
<use :xlink:href="symbolId" fill="currentColor" />
</svg>
</template>
<script lang="ts">
import { addUnit } from '@/utils/util'
import type { CSSProperties } from 'vue'
export default defineComponent({
props: {
name: {
type: String,
required: true
},
size: {
type: [Number, String],
default: 16
},
color: {
type: String,
default: 'inherit'
}
},
setup(props) {
const symbolId = computed(() => `#${props.name}`)
const styles = computed<CSSProperties>(() => {
return {
width: addUnit(props.size),
height: addUnit(props.size),
color: props.color
}
})
return { symbolId, styles }
}
})
</script>
<template>
<el-image :style="styles" v-bind="props"> </el-image>
</template>
<script lang="ts" setup>
import { computed } from 'vue'
import type { CSSProperties } from 'vue'
import { addUnit } from '@/utils/util'
import { imageProps } from 'element-plus'
const props = defineProps({
width: {
type: [String, Number],
default: 'auto'
},
height: {
type: [String, Number],
default: 'auto'
},
radius: {
type: [String, Number],
default: 0
},
...imageProps
})
const styles = computed<CSSProperties>(() => {
return {
width: addUnit(props.width),
height: addUnit(props.height),
borderRadius: addUnit(props.radius)
}
})
</script>
<style lang="scss" scoped>
.el-image {
display: block;
.el-image__error {
@apply text-xs;
}
}
</style>
<template>
<el-menu :default-active="modelValue" class="w-[160px] min-h-[668px] pages-menu" @select="handleSelect">
<el-menu-item v-for="item in menus" :index="item.id + ''" :key="item.id">
<span>{{ item.name }}</span>
</el-menu-item>
</el-menu>
</template>
<script lang="ts" setup>
import type { PropType } from 'vue'
const props = defineProps({
menus: {
type: Array as PropType<Record<string, any>>,
default: () => ([])
},
modelValue: {
type: String,
default: '1'
}
})
const router = useRouter();
const emit = defineEmits<{
(event: 'update:modelValue', value: string): void
(event: 'change', value: string, obj: any, index: number): void
}>()
const handleSelect = (id: string) => {
emit('update:modelValue', id);
let index: number = props.menus.findIndex((item: any) => item.id == id);
let menuItem = props.menus[index];
emit('change', id, menuItem, index);
if (menuItem.path) {
router.push(menuItem.path)
}
}
</script>
<style lang="scss" scoped>
.pages-menu {
:deep(.el-menu-item) {
border-color: transparent;
&.is-active {
border-right-width: 2px;
border-color: var(--el-color-primary);
background-color: var(--el-color-primary-light-9);
}
}
}
</style>
<template>
<div class="custom-link mt-[30px]">
<div class="flex flex-wrap items-center">
自定义链接
<div class="ml-4 flex-1 min-w-[100px]">
<el-input :model-value="modelValue.path" placeholder="请输入链接地址" @input="handleInput" />
</div>
</div>
<div class="form-tips">
请填写完整的带有“https://”或“http://”的链接地址
</div>
</div>
</template>
<script lang="ts" setup>
import type { PropType } from 'vue'
import { LinkTypeEnum, type Link } from '.'
defineProps({
modelValue: {
type: Object as PropType<Link>,
default: () => ({})
}
})
const emit = defineEmits<{
(event: 'update:modelValue', value: Link): void
}>()
const handleInput = (value: string) => {
emit('update:modelValue', {
path: value,
type: LinkTypeEnum.CUSTOM_LINK
})
}
</script>
export enum LinkTypeEnum {
'SHOP_PAGES' = 'shop',
'CUSTOM_LINK' = 'custom'
}
export interface Link {
path: string
name?: string
type: string
query?: Record<string, any>
}
<template>
<div class="link flex">
<el-menu :default-active="activeMenu" class="w-[160px] min-h-[350px] link-menu" @select="handleSelect">
<el-menu-item v-for="(item, index) in menus" :index="item.type" :key="index">
<span>{{ item.name }}</span>
</el-menu-item>
</el-menu>
<div class="flex-1 pl-4">
<shop-pages v-model="activeLink" v-if="LinkTypeEnum.SHOP_PAGES == activeMenu" />
<custom-link v-model="activeLink" v-if="LinkTypeEnum.CUSTOM_LINK == activeMenu" />
</div>
</div>
</template>
<script lang="ts" setup>
import type { PropType } from 'vue'
import { LinkTypeEnum, type Link } from '.'
import ShopPages from './shop-pages.vue'
import CustomLink from './custom-link.vue'
const props = defineProps({
modelValue: {
type: Object as PropType<Link>,
required: true
}
})
const emit = defineEmits<{
(event: 'update:modelValue', value: any): void
}>()
const menus = ref([
{
name: '商城页面',
type: LinkTypeEnum.SHOP_PAGES,
link: {}
},
{
name: '自定义链接',
type: LinkTypeEnum.CUSTOM_LINK,
link: {}
}
])
const activeLink = computed({
get() {
return menus.value.find((item) => item.type == activeMenu.value)?.link as Link
},
set(value) {
menus.value.forEach((item) => {
if (item.type == activeMenu.value) {
item.link = value
}
})
}
})
const activeMenu = ref<string>(LinkTypeEnum.SHOP_PAGES)
const handleSelect = (index: string) => {
activeMenu.value = index
}
watch(activeLink, (value) => {
if (!value.type) return
emit('update:modelValue', value)
})
watch(
() => props.modelValue,
(value) => {
activeMenu.value = value.type
activeLink.value = value
},
{
immediate: true
}
)
</script>
<style lang="scss" scoped>
.link-menu {
--el-menu-item-height: 40px;
:deep(.el-menu-item) {
border-color: transparent;
&.is-active {
border-right-width: 2px;
border-color: var(--el-color-primary);
background-color: var(--el-color-primary-light-9);
}
}
}
</style>
<template>
<div class="link-picker flex-1" @click="!disabled && popupRef?.open()">
<el-input :model-value="getLink" placeholder="请选择链接" readonly :disabled="disabled">
<template #suffix>
<icon v-if="!modelValue" name="el-icon-ArrowRight" />
<icon v-else name="el-icon-Close" @click.stop="!disabled && emit('update:modelValue', '')" />
</template>
</el-input>
<popup ref="popupRef" width="700px" title="链接选择" @confirm="handleConfirm">
<link-content v-model="activeLink" />
</popup>
</div>
</template>
<script lang="ts" setup>
import { LinkTypeEnum, type Link } from '.'
import LinkContent from './index.vue'
import Popup from '@/components/popup/index.vue'
const props = defineProps({
modelValue: {
type: String
},
disabled: {
type: Boolean,
default: false
}
})
const emit = defineEmits<{
(event: 'update:modelValue', value: any): void
}>()
const popupRef = shallowRef<InstanceType<typeof Popup>>()
const activeLink = ref({ path: '', type: LinkTypeEnum.SHOP_PAGES })
const handleConfirm = () => {
emit('update:modelValue', activeLink.value.path)
}
const getLink = computed(() => {
return props.modelValue;
})
watch(
() => props.modelValue,
(value: any) => {
activeLink.value.path = value
},
{
immediate: true
}
)
</script>
<style scoped lang="scss">
.link-picker {
:deep(.el-input) {
&.is-disabled {
.el-input__inner {
cursor: not-allowed;
}
.el-input__suffix {
cursor: not-allowed;
}
}
.el-input__inner {
cursor: pointer;
}
.el-input__suffix {
cursor: pointer;
}
}
}
</style>
<template>
<div class="shop-pages">
<div class="link-list flex flex-wrap">
<div class="link-item border border-br px-5 py-[5px] rounded-[3px] cursor-pointer mr-[10px] mb-[10px]"
v-for="(item, index) in linkList" :class="{
'border-primary text-primary':
modelValue.path == item.path && modelValue.name == item.name
}" :key="index" @click="handleSelect(item)">
{{ item.name }}
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import type { PropType } from 'vue'
import { LinkTypeEnum, type Link } from '.'
defineProps({
modelValue: {
type: Object as PropType<Link>,
default: () => ({})
}
})
const emit = defineEmits<{
(event: 'update:modelValue', value: Link): void
}>()
const linkList = ref([
{
path: '/pages/index/index',
name: '商城首页',
type: LinkTypeEnum.SHOP_PAGES
}
])
const handleSelect = (value: Link) => {
emit('update:modelValue', value)
}
</script>
<template>
<div>
<div class="file-item relative" :style="{ height: fileSize, width: fileSize }">
<el-image class="image" v-if="type == 'image'" fit="contain" :src="uri"></el-image>
<video class="video" v-else-if="type == 'video'" :src="uri"></video>
<div v-if="type == 'video'"
class="absolute left-1/2 top-1/2 translate-x-[-50%] translate-y-[-50%] rounded-full w-5 h-5 flex justify-center items-center bg-[rgba(0,0,0,0.3)]">
<icon name="el-icon-CaretRight" :size="18" color="#fff" />
</div>
<slot></slot>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
export default defineComponent({
props: {
// 图片地址
uri: {
type: String
},
// 图片尺寸
fileSize: {
type: String,
default: '100px'
},
// 文件类型
type: {
type: String,
default: 'image'
}
},
emits: ['close']
})
</script>
<style scoped lang="scss">
.file-item {
box-sizing: border-box;
position: relative;
border-radius: 4px;
overflow: hidden;
@apply bg-br-extra-light border border-br-extra-light;
.image,
.video {
display: block;
box-sizing: border-box;
width: 100%;
height: 100%;
}
}
</style>
import {
fileCateAdd,
fileCateDelete,
fileCateEdit,
fileCateLists,
fileDelete,
fileList,
fileMove,
fileRename
} from '@/api/file'
import { usePaging } from '@/hooks/usePaging'
import feedback from '@/utils/feedback'
import { ElMessage, ElTree, type CheckboxValueType } from 'element-plus'
import { shallowRef, type Ref } from 'vue'
import useUserStore from '@/stores/modules/user/user'
const { userInfo } = useUserStore()
// 左侧分组的钩子函数
export function useCate(type: number) {
const treeRef = shallowRef<InstanceType<typeof ElTree>>()
// 分组列表
const cateLists = ref<any[]>([])
// 选中的分组id
const cateId = ref<number | string>('')
// 获取分组列表
const getCateLists = async () => {
const res = await fileCateLists({
user_sku: userInfo.shop.default_user_sku
})
const item: any[] = [
{
title: '全部',
id: ''
}
]
cateLists.value = res.data.list;
cateLists.value.unshift(...item)
setTimeout(() => {
treeRef.value?.setCurrentKey(cateId.value)
}, 0)
}
// 添加分组
const handleAddCate = async (value: string) => {
await fileCateAdd({
title: value,
user_sku: userInfo.shop.default_user_sku,
idx: 1
})
getCateLists()
}
// 编辑分组
const handleEditCate = async (value: string, id: number) => {
await fileCateEdit({
id,
title: value,
user_sku: userInfo.shop.default_user_sku
})
getCateLists()
}
// 删除分组
const handleDeleteCate = async (id: number) => {
await feedback.confirm('确定要删除?')
await fileCateDelete({ id })
cateId.value = ''
getCateLists()
}
//选中分类
const handleCatSelect = (item: any) => {
cateId.value = item.id;
}
return {
treeRef,
cateId,
cateLists,
handleAddCate,
handleEditCate,
handleDeleteCate,
getCateLists,
handleCatSelect
}
}
// 处理文件的钩子函数
export function useFile(
cateId: Ref<string | number>,
type: Ref<number>,
limit: Ref<number>,
size: number
) {
const tableRef = shallowRef()
const listShowType = ref('normal')
const moveId = ref(0)
const select = ref<any[]>([])
const isCheckAll = ref(false)
const isIndeterminate = ref(false)
const fileParams = reactive({
content: '',
tid: cateId.value == 'all' ? '' : cateId,
proxy: 1,
user_sku: userInfo.shop.default_user_sku
})
const { pager, getLists, resetPage } = usePaging({
fetchFun: fileList,
params: fileParams,
firstLoading: true,
size
})
const getFileList = () => {
getLists()
}
const refresh = () => {
resetPage()
}
const isSelect = (id: number) => {
return !!select.value.find((item: any) => item.id == id)
}
const batchFileDelete = async (id?: number[]) => {
await feedback.confirm(
'确认删除后,本地或云存储文件也将同步删除,如文件已被使用,请谨慎操作!'
)
const ids = id ? id : select.value.map((item: any) => item.id)
await fileDelete({ ids: ids.join(',') })
getFileList()
clearSelect()
}
const batchFileMove = async () => {
const ids = select.value.map((item: any) => item.id)
await fileMove({ ids, cid: moveId.value })
moveId.value = 0
getFileList()
clearSelect()
}
const selectFile = (item: any) => {
const index = select.value.findIndex((items: any) => items.id == item.id)
if (index != -1) {
select.value.splice(index, 1)
return
}
if (select.value.length == limit.value) {
if (limit.value == 1) {
select.value = []
select.value.push(item)
return
}
ElMessage.warning('已达到选择上限')
return
}
select.value.push(item)
}
const clearSelect = () => {
select.value = []
}
const cancelSelete = (id: number) => {
select.value = select.value.filter((item: any) => item.id != id)
}
const selectAll = (value: CheckboxValueType) => {
isIndeterminate.value = false
tableRef.value?.toggleAllSelection()
if (value) {
select.value = [...pager.lists]
return
}
clearSelect()
}
const handleFileRename = async (name: string, id: number) => {
await fileRename({
id,
name
})
getFileList()
}
return {
listShowType,
tableRef,
moveId,
pager,
fileParams,
select,
isCheckAll,
isIndeterminate,
getFileList,
refresh,
batchFileDelete,
batchFileMove,
selectFile,
isSelect,
clearSelect,
cancelSelete,
selectAll,
handleFileRename
}
}
<template>
<div class="material" v-loading="pager.loading">
<div class="material__left">
<div class="flex-1 min-h-0">
<el-scrollbar>
<div class="material-left__content pt-4 p-b-4">
<el-tree ref="treeRef" node-key="id" :data="cateLists" empty-text="''" :highlight-current="true"
:expand-on-click-node="false" :current-node-key="cateId" @node-click="handleCatSelect">
<template v-slot="{ data }">
<div class="flex flex-1 items-center min-w-0 pr-4">
<img class="w-[20px] h-[16px] mr-3" src="@/assets/images/icon_folder.png" />
<span class="flex-1 truncate mr-2">
<overflow-tooltip :content="data.title" />
</span>
<el-dropdown v-if="data.id > 0" :hide-on-click="false">
<span class="muted m-r-10">···</span>
<template #dropdown>
<el-dropdown-menu>
<popover-input @confirm="handleEditCate($event, data.id)" size="default"
:value="data.title" width="400px" :limit="20" show-limit teleported>
<div>
<el-dropdown-item>
命名分组
</el-dropdown-item>
</div>
</popover-input>
<div @click="handleDeleteCate(data.id)">
<el-dropdown-item>删除分组</el-dropdown-item>
</div>
</el-dropdown-menu>
</template>
</el-dropdown>
</div>
</template>
</el-tree>
</div>
</el-scrollbar>
</div>
<div class="flex justify-center p-2 border-t border-br">
<popover-input @confirm="handleAddCate" size="default" width="400px" :limit="20" show-limit teleported>
<el-button> 添加分组 </el-button>
</popover-input>
</div>
</div>
<div class="material__center flex flex-col">
<div class="operate-btn flex">
<div class="flex-1 flex">
<upload v-if="type == 'image'" class="mr-3" :data="{ type_id: cateId }" :type="type"
:show-progress="true" @success="refresh" :limit="50">
<el-button type="primary">本地上传</el-button>
</upload>
<upload v-if="type == 'video'" class="mr-3" :data="{ type_id: cateId }" :type="type"
:show-progress="true" @success="refresh">
<el-button type="primary">本地上传</el-button>
</upload>
<el-button v-if="mode == 'page'" :disabled="!select.length" @click.stop="batchFileDelete()">
删除
</el-button>
<popup v-if="mode == 'page'" class="ml-3" @confirm="batchFileMove" :disabled="!select.length"
title="移动文件">
<template #trigger>
<el-button :disabled="!select.length">移动</el-button>
</template>
<div>
<span class="mr-5">移动文件至</span>
<el-select v-model="moveId" placeholder="请选择">
<template v-for="item in cateLists" :key="item.id">
<el-option v-if="item.id !== ''" :label="item.name" :value="item.id"></el-option>
</template>
</el-select>
</div>
</popup>
</div>
<el-input class="w-60" placeholder="请输入名称" v-model="fileParams.content" @keyup.enter="refresh">
<template #append>
<el-button @click="refresh">
<template #icon>
<icon name="el-icon-Search" />
</template>
</el-button>
</template>
</el-input>
<div class="flex items-center ml-2">
<el-tooltip content="列表视图" placement="top">
<div class="list-icon" :class="{
select: listShowType == 'table'
}" @click="listShowType = 'table'">
<icon name="local-icon-list-2" :size="18" />
</div>
</el-tooltip>
<el-tooltip content="平铺视图" placement="top">
<div class="list-icon" :class="{
select: listShowType == 'normal'
}" @click="listShowType = 'normal'">
<icon name="el-icon-Menu" :size="18" />
</div>
</el-tooltip>
</div>
</div>
<div class="mt-3" v-if="mode == 'page'">
<el-checkbox :disabled="!pager.lists.length" v-model="isCheckAll" @change="selectAll"
:indeterminate="isIndeterminate">
当页全选
</el-checkbox>
</div>
<div class="material-center__content flex flex-col flex-1 mb-1 min-h-0">
<el-scrollbar v-if="pager.lists.length" v-show="listShowType == 'normal'">
<ul class="file-list flex flex-wrap mt-4">
<li class="file-item-wrap" v-for="item in pager.lists" :key="item.id" :style="{ width: fileSize }">
<del-wrap @close="batchFileDelete([item.id])">
<file-item :uri="item.img_url" :file-size="fileSize" :type="type" @click="selectFile(item)">
<div class="item-selected" v-if="isSelect(item.id)">
<icon :size="24" name="el-icon-Check" color="#fff" />
</div>
</file-item>
</del-wrap>
<overflow-tooltip class="mt-1" :content="item.title" />
<div class="operation-btns flex items-center">
<el-button type="primary" link @click.stop="batchFileDelete([item.id])"> 删除</el-button>
<el-button type="primary" link @click="handlePreview(item.img_url)">
查看
</el-button>
</div>
</li>
</ul>
</el-scrollbar>
<el-table ref="tableRef" class="mt-4" v-show="listShowType == 'table'" :data="pager.lists" width="100%"
height="100%" size="large" @row-click="selectFile">
<el-table-column width="55">
<template #default="{ row }">
<el-checkbox :modelValue="isSelect(row.id)" @change="selectFile(row)" />
</template>
</el-table-column>
<el-table-column label="图片" width="100">
<template #default="{ row }">
<file-item :uri="row.img_url" file-size="50px" :type="type"></file-item>
</template>
</el-table-column>
<el-table-column label="名称" min-width="100" show-overflow-tooltip>
<template #default="{ row }">
<el-link @click.stop="handlePreview(row.img_url)" :underline="false">
{{ row.title }}
</el-link>
</template>
</el-table-column>
<el-table-column prop="create_date" label="上传时间" min-width="100" />
<el-table-column label="操作" width="150" fixed="right">
<template #default="{ row }">
<div class="inline-block">
<el-button type="primary" link @click.stop="handlePreview(row.img_url)">
查看
</el-button>
</div>
<div class="inline-block">
<el-button type="primary" link @click.stop="batchFileDelete([row.id])">
删除
</el-button>
</div>
</template>
</el-table-column>
</el-table>
<div class="flex flex-1 justify-center items-center" v-if="!pager.loading && !pager.lists.length">
暂无数据~
</div>
</div>
<div class="material-center__footer flex justify-between items-center mt-2">
<div class="flex">
<template v-if="mode == 'page'">
<span class="mr-3">
<el-checkbox :disabled="!pager.lists.length" v-model="isCheckAll" @change="selectAll"
:indeterminate="isIndeterminate">
当页全选
</el-checkbox>
</span>
<el-button :disabled="!select.length" @click="batchFileDelete()">
删除
</el-button>
<popup class="ml-3 inline" @confirm="batchFileMove" :disabled="!select.length" title="移动文件">
<template #trigger>
<el-button :disabled="!select.length">移动</el-button>
</template>
<div>
<span class="mr-5">移动文件至</span>
<el-select v-model="moveId" placeholder="请选择">
<template v-for="item in cateLists" :key="item.id">
<el-option v-if="item.id !== ''" :label="item.title" :value="item.id"></el-option>
</template>
</el-select>
</div>
</popup>
</template>
</div>
<pagination v-model="pager" @change="getFileList" layout="total, prev, pager, next, jumper" />
</div>
</div>
<div class="material__right" v-if="mode == 'picker'">
<div class="flex justify-between p-2 flex-wrap">
<div class="sm flex items-center">
已选择 {{ select.length }}
<span v-if="limit">/{{ limit }}</span>
</div>
<el-button type="primary" link @click="clearSelect">清空</el-button>
</div>
<div class="flex-1 min-h-0">
<el-scrollbar class="ls-scrollbar">
<ul class="select-lists flex flex-col p-t-3">
<li class="mb-4" v-for="item in select" :key="item.id">
<div class="select-item">
<del-wrap @close="cancelSelete(item.id)">
<file-item :uri="item.img_url" file-size="100px" :type="type"></file-item>
</del-wrap>
</div>
</li>
</ul>
</el-scrollbar>
</div>
</div>
<preview v-model="showPreview" :url="previewUrl" :type="type" />
</div>
</template>
<script lang="ts" setup>
import { useCate, useFile } from './hook'
import FileItem from './file.vue'
import Preview from './preview.vue'
import type { Ref } from 'vue'
const props = defineProps({
fileSize: {
type: String,
default: '100px'
},
limit: {
type: Number,
default: 1
},
type: {
type: String,
default: 'image'
},
mode: {
type: String,
default: 'picker'
},
pageSize: {
type: Number,
default: 15
}
})
const emit = defineEmits(['change'])
const { limit } = toRefs(props)
const typeValue = computed<number>(() => {
switch (props.type) {
case 'image':
return 10
case 'video':
return 20
case 'file':
return 30
default:
return 0
}
})
const visible: Ref<boolean> = inject('visible')!
const previewUrl = ref('')
const showPreview = ref(false)
const {
treeRef,
cateId,
cateLists,
handleAddCate,
handleEditCate,
handleDeleteCate,
getCateLists,
handleCatSelect
} = useCate(typeValue.value)
const {
tableRef,
listShowType,
moveId,
pager,
fileParams,
select,
isCheckAll,
isIndeterminate,
getFileList,
refresh,
batchFileDelete,
batchFileMove,
selectFile,
isSelect,
clearSelect,
cancelSelete,
selectAll
} = useFile(cateId, typeValue, limit, props.pageSize)
const getData = async () => {
await getCateLists()
treeRef.value?.setCurrentKey(cateId.value)
console.log(cateId.value)
getFileList()
}
const handlePreview = (url: string) => {
previewUrl.value = url
showPreview.value = true
}
watch(
visible,
async (val: boolean) => {
if (val) {
getData()
}
},
{
immediate: true
}
)
watch(cateId, () => {
fileParams.content = ''
refresh()
})
watch(
select,
(val: any[]) => {
emit('change', val)
if (val.length == pager.lists.length && val.length !== 0) {
isIndeterminate.value = false
isCheckAll.value = true
return
}
if (val.length > 0) {
isIndeterminate.value = true
} else {
isCheckAll.value = false
isIndeterminate.value = false
}
},
{
deep: true
}
)
onMounted(() => {
props.mode == 'page' && getData()
})
defineExpose({
clearSelect
})
</script>
<style scoped lang="scss">
.material {
@apply h-full min-h-0 flex flex-1;
&__left {
@apply border-r border-br flex flex-col w-[200px];
:deep(.el-tree-node__content) {
height: 36px;
.el-tree-node__label {
display: flex;
flex: 1;
min-width: 0;
}
}
}
&__center {
flex: 1;
min-width: 0;
min-height: 0;
padding: 16px 16px 0;
.list-icon {
border-radius: 3px;
display: flex;
padding: 5px;
cursor: pointer;
&.select {
@apply text-primary bg-primary-light-8;
}
}
.file-list {
.file-item-wrap {
margin-right: 16px;
line-height: 1.3;
cursor: pointer;
.item-selected {
display: flex;
align-items: center;
justify-content: center;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border-radius: 4px;
background-color: rgba(0, 0, 0, 0.5);
box-sizing: border-box;
}
.operation-btns {
height: 28px;
visibility: hidden;
}
&:hover .operation-btns {
visibility: visible;
}
}
}
}
&__right {
@apply border-l border-br flex flex-col;
width: 130px;
.select-lists {
padding: 10px;
.select-item {
width: 100px;
height: 100px;
}
}
}
}
</style>
<template>
<div class="material-select">
<popup ref="popupRef" width="830px" custom-class="body-padding" :title="`选择${tipsText}`" @confirm="handleConfirm"
@close="handleClose">
<template v-if="!hiddenUpload" #trigger>
<div class="material-select__trigger clearfix" @click.stop>
<draggable class="draggable" v-model="fileList" animation="300" item-key="id">
<template v-slot:item="{ element, index }">
<div class="material-preview" :class="{
'is-disabled': disabled,
'is-one': limit == 1
}" @click="showPopup(index)">
<div class="material-preview-body">
<del-wrap @close="deleteImg(index)">
<file-item :uri="excludeDomain ? getImageUrl(element) : element" :file-size="size"
:type="type"></file-item>
</del-wrap>
<div class="operation-btns text-xs text-center">
<span>修改</span>
|
<span @click.stop="handlePreview(element)">查看</span>
</div>
</div>
<slot name="imgItem" v-bind="{ element, index }"></slot>
</div>
</template>
</draggable>
<div class="material-upload" @click="showPopup(-1)" v-show="showUpload" :class="{
'is-disabled': disabled,
'is-one': limit == 1,
[uploadClass]: true
}">
<slot name="upload">
<div class="upload-btn" :style="{
width: size,
height: size
}">
<icon :size="25" name="el-icon-Plus" />
<span>添加</span>
</div>
</slot>
</div>
</div>
</template>
<el-scrollbar>
<div class="material-wrap">
<material ref="materialRef" :type="type" :file-size="fileSize" :limit="meterialLimit"
@change="selectChange" />
</div>
</el-scrollbar>
</popup>
<preview v-model="showPreview" :url="getImageUrl(previewUrl)" :type="type" />
</div>
</template>
<script lang="ts">
import Draggable from 'vuedraggable'
import Popup from '@/components/popup/index.vue'
import FileItem from './file.vue'
import Material from './index.vue'
import Preview from './preview.vue'
import useAppStore from '@/stores/modules/app'
import { useThrottleFn } from '@vueuse/core'
export default defineComponent({
components: {
Popup,
Draggable,
FileItem,
Material,
Preview
},
props: {
modelValue: {
type: [String, Array],
default: () => []
},
// 文件类型
type: {
type: String,
default: 'image'
},
// 选择器尺寸
size: {
type: String,
default: '100px'
},
// 文件尺寸
fileSize: {
type: String,
default: '100px'
},
// 选择数量限制
limit: {
type: Number,
default: 1
},
// 禁用选择
disabled: {
type: Boolean,
default: false
},
// 隐藏上传框*(目前在富文本中使用到)
hiddenUpload: {
type: Boolean,
default: false
},
uploadClass: {
type: String,
default: ''
},
//选择的url排出域名
excludeDomain: {
type: Boolean,
default: false
}
},
emits: ['change', 'update:modelValue'],
setup(props, { emit }) {
const popupRef = ref<InstanceType<typeof Popup>>()
const materialRef = ref<InstanceType<typeof Material>>()
const previewUrl = ref('')
const showPreview = ref(false)
const fileList = ref<any[]>([])
const select = ref<any[]>([])
const isAdd = ref(true)
const currentIndex = ref(-1)
const { disabled, limit, modelValue } = toRefs(props)
const { getImageUrl } = useAppStore()
const tipsText = computed(() => {
switch (props.type) {
case 'image':
return '图片'
case 'video':
return '视频'
default:
return ''
}
})
const showUpload = computed(() => {
return props.limit - fileList.value.length > 0
})
const meterialLimit: any = computed(() => {
if (!isAdd.value) {
return 1
}
if (limit.value == -1) return null
return limit.value - fileList.value.length
})
const handleConfirm = useThrottleFn(
() => {
const selectUri = select.value.map((item) =>
props.excludeDomain ? item.img_url : item.img_url
)
if (!isAdd.value) {
fileList.value.splice(currentIndex.value, 1, selectUri.shift())
} else {
fileList.value = [...fileList.value, ...selectUri]
}
handleChange()
},
1000,
false
)
const showPopup = (index: number) => {
if (disabled.value) return
if (index >= 0) {
isAdd.value = false
currentIndex.value = index
} else {
isAdd.value = true
}
popupRef.value?.open()
}
const selectChange = (val: any[]) => {
select.value = val
}
const handleChange = () => {
const valueImg = limit.value != 1 ? fileList.value : fileList.value[0] || ''
emit('update:modelValue', valueImg)
emit('change', valueImg)
handleClose()
}
const deleteImg = (index: number) => {
fileList.value.splice(index, 1)
handleChange()
}
const handlePreview = (url: string) => {
previewUrl.value = url
showPreview.value = true
}
const handleClose = () => {
nextTick(() => {
if (props.hiddenUpload) fileList.value = []
materialRef.value?.clearSelect()
})
}
watch(
modelValue,
(val: any[] | string) => {
fileList.value = Array.isArray(val) ? val : (val == '' || val == null) ? [] : [val]
},
{
immediate: true
}
)
provide('limit', props.limit)
provide('hiddenUpload', props.hiddenUpload)
return {
popupRef,
materialRef,
fileList,
tipsText,
handleConfirm,
meterialLimit,
showUpload,
showPopup,
selectChange,
deleteImg,
previewUrl,
showPreview,
handlePreview,
handleClose,
getImageUrl
}
}
})
</script>
<style scoped lang="scss">
.material-select {
.material-upload,
.material-preview {
position: relative;
border-radius: 4px;
cursor: pointer;
margin-right: 8px;
margin-bottom: 8px;
box-sizing: border-box;
float: left;
&.is-disabled {
cursor: not-allowed;
}
&.is-one {
margin-bottom: 0;
}
&:hover {
.operation-btns {
display: block;
}
}
.operation-btns {
display: none;
position: absolute;
bottom: 0;
border-radius: 4px;
width: 100%;
line-height: 2;
color: #fff;
background-color: rgba(0, 0, 0, 0.3);
}
}
.material-upload {
:deep(.upload-btn) {
@apply text-tx-secondary box-border rounded border-br border-dashed border flex flex-col justify-center items-center;
}
}
}
.material-preview-body {
position: relative;
}
.material-wrap {
min-width: 720px;
height: 430px;
@apply border-t border-b border-br;
}
</style>
<template>
<div v-show="modelValue">
<div v-if="type == 'image'">
<el-image-viewer
v-if="previewLists.length"
:url-list="previewLists"
hide-on-click-modal
@close="handleClose"
/>
</div>
<div v-if="type == 'video'">
<el-dialog v-model="visible" width="740px" title="视频预览" :before-close="handleClose">
<video-player ref="playerRef" :src="url" width="100%" height="450px" />
</el-dialog>
</div>
</div>
</template>
<script lang="ts" setup>
const props = defineProps({
modelValue: {
type: Boolean,
default: false
},
url: {
type: String,
default: ''
},
type: {
type: String,
default: 'image'
}
})
const emit = defineEmits<{
(event: 'update:modelValue', value: boolean): void
}>()
const playerRef = shallowRef()
const visible = computed({
get() {
return props.modelValue
},
set(value) {
emit('update:modelValue', value)
}
})
const handleClose = () => {
emit('update:modelValue', false)
}
const previewLists = ref<any[]>([])
watch(
() => props.modelValue,
(value) => {
if (value) {
nextTick(() => {
previewLists.value = [props.url]
playerRef.value?.play()
})
} else {
nextTick(() => {
previewLists.value = []
playerRef.value?.pause()
})
}
}
)
</script>
<template>
<div>
<el-tooltip v-bind="props" :disabled="disabled">
<div
ref="textRef"
class="overflow-text truncate"
:style="{ textOverflow: overfloType }"
>
{{ content }}
</div>
</el-tooltip>
</div>
</template>
<script lang="ts" setup>
import { useEventListener } from '@vueuse/core'
import { useTooltipContentProps, type Placement } from 'element-plus'
import type { PropType } from 'vue'
const props = defineProps({
...useTooltipContentProps,
teleported: {
type: Boolean,
default: false
},
placement: {
type: String as PropType<Placement>,
default: 'top'
},
overfloType: {
type: String as PropType<'ellipsis' | 'unset' | 'clip'>,
default: 'ellipsis'
}
})
const textRef = shallowRef<HTMLElement>()
const disabled = ref(false)
useEventListener(textRef, 'mouseenter', () => {
if (textRef.value?.scrollWidth! > textRef.value?.offsetWidth!) {
disabled.value = false
} else {
disabled.value = true
}
})
</script>
<style></style>
<template>
<div class="pagination">
<el-pagination v-bind="props" :pager-count="5" v-model:currentPage="pager.page" v-model:pageSize="pager.size"
:page-sizes="pageSizes" :layout="layout" :total="pager.count" :hide-on-single-page="false"
@size-change="sizeChange" @current-change="pageChange"></el-pagination>
</div>
</template>
<script lang="ts" setup>
interface Props {
modelValue?: Record<string, any>
pageSizes?: number[]
layout?: string
}
const props = withDefaults(defineProps<Props>(), {
modelValue: () => ({}),
pageSizes: () => [15, 20, 30, 40],
layout: 'total, sizes, prev, pager, next, jumper'
})
const emit = defineEmits<{
(event: 'change'): void
(event: 'update:modelValue', value: any): void
}>()
const pager = computed({
get() {
return props.modelValue
},
set(value) {
emit('update:modelValue', value)
}
})
const sizeChange = () => {
pager.value.page = 1
emit('change')
}
const pageChange = () => {
emit('change')
}
</script>
<template>
<div @mouseenter="inPopover = true" @mouseleave="inPopover = false">
<el-popover placement="top" v-model:visible="visible" :width="width" trigger="contextmenu" class="popover-input"
:teleported="teleported" :persistent="false" popper-class="!p-0">
<div class="flex p-3" @click.stop="">
<div class="popover-input__input mr-[10px] flex-1">
<el-select class="flex-1" :size="size" v-if="type == 'select'" v-model="inputValue"
:teleported="teleported">
<el-option v-for="item in options" :key="item.value" :label="item.label"
:value="item.value"></el-option>
</el-select>
<el-input-number :min="1" :max="100" v-model="inputValue"
v-else-if="type == 'number'"></el-input-number>
<el-input v-else v-model.trim="inputValue" :maxlength="limit" :show-word-limit="showLimit" :type="type"
:size="size" clearable :placeholder="placeholder" />
</div>
<div class="popover-input__btns flex-none">
<el-button link @click="close">取消</el-button>
<el-button type="primary" :size="size" @click="handleConfirm">确定</el-button>
</div>
</div>
<template #reference>
<div class="inline" @click.stop="handleOpen">
<slot></slot>
</div>
</template>
</el-popover>
</div>
</template>
<script lang="ts" setup>
import { useEventListener } from '@vueuse/core'
import type { PropType } from 'vue'
const props = defineProps({
value: {
type: String
},
type: {
type: String,
default: 'text'
},
width: {
type: [Number, String],
default: '300px'
},
placeholder: String,
disabled: {
type: Boolean,
default: false
},
options: {
type: Array as PropType<any[]>,
default: () => []
},
size: {
type: String as PropType<'default' | 'small' | 'large'>,
default: 'default'
},
limit: {
type: Number,
default: 200
},
showLimit: {
type: Boolean,
default: false
},
teleported: {
type: Boolean,
default: true
}
})
const emit = defineEmits(['confirm'])
const visible = ref(false)
const inPopover = ref(false)
const inputValue = ref()
const handleConfirm = () => {
close()
emit('confirm', inputValue.value)
}
const handleOpen = () => {
if (props.disabled) {
return
}
visible.value = true
}
const close = () => {
visible.value = false
}
watch(
() => props.value,
(value) => {
inputValue.value = value
},
{
immediate: true
}
)
// useEventListener(document.documentElement, 'click', () => {
// if (inPopover.value) return
// close()
// })
</script>
<style scoped lang="scss"></style>
<template>
<div class="dialog">
<div class="dialog__trigger" @click="open">
<!-- 触发弹窗 -->
<slot name="trigger"></slot>
</div>
<el-dialog v-model="visible" :custom-class="customClass" :center="center" :append-to-body="true" :width="width"
:close-on-click-modal="clickModalClose" @closed="close">
<!-- 弹窗内容 -->
<template v-if="title" #header>{{ title }}</template>
<!-- 自定义内容 -->
<slot>{{ content }}</slot>
<!-- 底部弹窗页脚 -->
<template #footer>
<div class="dialog-footer">
<el-button v-if="cancelButtonText" @click="handleEvent('cancel')">
{{ cancelButtonText }}
</el-button>
<el-button :loading="buttonLoading" v-if="confirmButtonText" type="primary"
@click="handleEvent('confirm')">
{{ confirmButtonText }}
</el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<script lang="ts">
export default defineComponent({
props: {
title: {
// 弹窗标题
type: String,
default: ''
},
content: {
// 弹窗内容
type: String,
default: ''
},
confirmButtonText: {
// 确认按钮内容
type: [String, Boolean],
default: '确定'
},
cancelButtonText: {
// 取消按钮内容
type: [String, Boolean],
default: '取消'
},
buttonLoading: {
type: Boolean,
default: false
},
width: {
// 弹窗的宽度
type: String,
default: '400px'
},
disabled: {
// 是否禁用
type: Boolean,
default: false
},
async: {
// 是否开启异步关闭
type: Boolean,
default: false
},
clickModalClose: {
// 点击遮罩层关闭对话窗口
type: Boolean,
default: false
},
center: {
// 是否居中布局
type: Boolean,
default: false
},
customClass: {
type: String,
default: ''
}
},
emits: ['confirm', 'cancel', 'close', 'open'],
setup(props, { emit }) {
const visible = ref(false)
const handleEvent = (type: 'confirm' | 'cancel') => {
emit(type)
if (!props.async || type === 'cancel') {
close()
}
}
const close = () => {
visible.value = false
nextTick(() => {
emit('close')
})
}
const open = () => {
if (props.disabled) {
return
}
emit('open')
visible.value = true
}
provide('visible', visible)
return {
visible,
handleEvent,
close,
open
}
}
})
</script>
<style scoped lang="scss">
.dialog-body {
white-space: pre-line;
}
</style>
<template>
<div>
<div class="file-item relative" :style="{ height: fileSize, width: fileSize }">
<el-image class="image" v-if="type == 'image'" fit="contain" :src="uri"></el-image>
<video class="video" v-else-if="type == 'video'" :src="uri"></video>
<div
v-if="type == 'video'"
class="absolute left-1/2 top-1/2 translate-x-[-50%] translate-y-[-50%] rounded-full w-5 h-5 flex justify-center items-center bg-[rgba(0,0,0,0.3)]"
>
<icon name="el-icon-CaretRight" :size="18" color="#fff" />
</div>
<slot></slot>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
export default defineComponent({
props: {
// 图片地址
uri: {
type: String
},
// 图片尺寸
fileSize: {
type: String,
default: '100px'
},
// 文件类型
type: {
type: String,
default: 'image'
}
},
emits: ['close']
})
</script>
<style scoped lang="scss">
.file-item {
box-sizing: border-box;
position: relative;
border-radius: 4px;
overflow: hidden;
@apply bg-br-extra-light border border-br-extra-light;
.image,
.video {
display: block;
box-sizing: border-box;
width: 100%;
height: 100%;
}
}
</style>
import {
shopTypeList,
shopDiy
} from '@/api/product'
import { usePaging } from '@/hooks/usePaging'
import feedback from '@/utils/feedback'
import { ElMessage, ElTree, type CheckboxValueType } from 'element-plus'
import { shallowRef, type Ref } from 'vue'
import useAppStore from '@/stores/modules/app'
const appStore = useAppStore()
// 左侧分组的钩子函数
export function useCate(type: number) {
const treeRef = shallowRef<InstanceType<typeof ElTree>>()
// 分组列表
const cateLists = ref<any[]>([])
// 选中的分组id
const cateId = ref<number | string>('')
// 获取分组列表
const getCateLists = async () => {
const res = await shopTypeList({ type: 1 })
const item: any[] = [
{
title: '全部',
id: ''
}
]
cateLists.value = res.data.list;
cateLists.value.unshift(...item)
setTimeout(() => {
treeRef.value?.setCurrentKey(cateId.value)
}, 0)
}
//选中分类
const handleCatSelect = (item: any) => {
cateId.value = item.id
}
return {
treeRef,
cateId,
cateLists,
getCateLists,
handleCatSelect
}
}
// 处理文件的钩子函数
export function useFile(
cateId: Ref<string | number>,
type: Ref<number>,
limit: Ref<number>,
size: number
) {
const tableRef = shallowRef()
const listShowType = ref('normal')
const moveId = ref(0)
const select = ref<any[]>([])
const isCheckAll = ref(false)
const isIndeterminate = ref(false)
const fileParams = reactive({
content: '',
tid: cateId
})
const { pager, getLists, resetPage } = usePaging({
fetchFun: shopDiy,
params: fileParams,
firstLoading: true,
size
})
const getFileList = () => {
getLists()
}
const refresh = () => {
resetPage()
}
const isSelect = (id: number) => {
return !!select.value.find((item: any) => item.id == id)
}
const selectFile = (item: any) => {
const index = select.value.findIndex((items: any) => items.id == item.id)
if (index != -1) {
select.value.splice(index, 1)
return
}
if (select.value.length == limit.value) {
if (limit.value == 1) {
select.value = []
select.value.push(item)
return
}
ElMessage.warning('已达到选择上限')
return
}
select.value.push(item)
}
const clearSelect = () => {
select.value = []
}
const cancelSelete = (id: number) => {
select.value = select.value.filter((item: any) => item.id != id)
}
const selectAll = (value: CheckboxValueType) => {
isIndeterminate.value = false
tableRef.value?.toggleAllSelection()
if (value) {
select.value = [...pager.lists]
return
}
clearSelect()
}
return {
listShowType,
tableRef,
moveId,
pager,
fileParams,
select,
isCheckAll,
isIndeterminate,
getFileList,
refresh,
selectFile,
isSelect,
clearSelect,
cancelSelete,
selectAll
}
}
<template>
<div class="material-select">
<popup ref="popupRef" width="830px" custom-class="body-padding" :title="`选择产品`" @confirm="handleConfirm"
@close="handleClose">
<template v-if="!hiddenUpload" #trigger>
<div class="material-select__trigger clearfix" @click.stop>
<div>
<el-tag class="mr-1" :key="item.id" v-for="(item, index) in fileList" closable
@close="deleteImg(index)">{{ item.title
}}</el-tag>
</div>
<el-button class="mt-2" @click="showPopup(-1)" type="primary">添加</el-button>
</div>
</template>
<el-scrollbar>
<div class="material-wrap">
<product ref="prouctRef" mode="page" :type="type" :file-size="fileSize" :limit="meterialLimit"
@change="selectChange" />
</div>
</el-scrollbar>
</popup>
<preview v-model="showPreview" :url="previewUrl" :type="type" />
</div>
</template>
<script lang="ts">
import Draggable from 'vuedraggable'
import Popup from '@/components/popup/index.vue'
import FileItem from './file.vue'
import Product from './product.vue'
import Preview from './preview.vue'
import useAppStore from '@/stores/modules/app'
import { useThrottleFn } from '@vueuse/core'
import { shopDiyDids } from "@/api/product"
export default defineComponent({
components: {
Popup,
Draggable,
FileItem,
Product,
Preview
},
props: {
modelValue: {
type: Array,
default: () => []
},
// 文件类型
type: {
type: String,
default: 'image'
},
// 选择器尺寸
size: {
type: String,
default: '100px'
},
// 文件尺寸
fileSize: {
type: String,
default: '100px'
},
// 选择数量限制
limit: {
type: Number,
default: 1
},
// 禁用选择
disabled: {
type: Boolean,
default: false
},
// 隐藏上传框*(目前在富文本中使用到)
hiddenUpload: {
type: Boolean,
default: false
},
uploadClass: {
type: String,
default: ''
}
},
emits: ['change', 'update:modelValue'],
setup(props, { emit }) {
const popupRef = ref<InstanceType<typeof Popup>>()
const prouctRef = ref<InstanceType<typeof Product>>()
const previewUrl = ref('')
const showPreview = ref(false)
const fileList = ref<any[]>([])
const select = ref<any[]>([])
const isAdd = ref(true)
const currentIndex = ref(-1)
const { disabled, limit, modelValue } = toRefs(props)
const { getImageUrl } = useAppStore()
const showUpload = computed(() => {
return props.limit - fileList.value.length > 0
})
const meterialLimit: any = computed(() => {
if (!isAdd.value) {
return 1
}
if (limit.value == -1) return null
return limit.value - fileList.value.length
})
const handleConfirm = useThrottleFn(
() => {
select.value.forEach((item: any) => {
let flage: boolean = fileList.value.some((fileItem) => fileItem.id == item.id);
if (!flage) {
fileList.value.push(item);
}
})
handleChange()
},
1000,
false
)
const showPopup = (index: number) => {
if (disabled.value) return
if (index >= 0) {
isAdd.value = false
currentIndex.value = index
} else {
isAdd.value = true
}
popupRef.value?.open()
}
const selectChange = (val: any[]) => {
select.value = val
}
const handleChange = () => {
let arr: any[] = fileList.value.map((item) => item.id);
emit('update:modelValue', arr)
emit('change', arr)
handleClose()
}
const deleteImg = (index: number) => {
fileList.value.splice(index, 1)
handleChange()
}
const handlePreview = (url: string) => {
previewUrl.value = url
showPreview.value = true
}
const handleClose = () => {
nextTick(() => {
if (props.hiddenUpload) fileList.value = []
prouctRef.value?.clearSelect()
})
}
const getData = async (ids: string) => {
let res: any = await shopDiyDids({ ids });
fileList.value = res.data.list;
}
watch(
modelValue,
(val: any) => {
getData(val.join(","));
},
{
immediate: true
}
)
provide('limit', props.limit)
provide('hiddenUpload', props.hiddenUpload)
return {
popupRef,
prouctRef,
fileList,
handleConfirm,
meterialLimit,
showUpload,
showPopup,
selectChange,
deleteImg,
previewUrl,
showPreview,
handlePreview,
handleClose,
getImageUrl
}
}
})
</script>
<style scoped lang="scss">
.material-select {
.material-upload,
.material-preview {
position: relative;
border-radius: 4px;
cursor: pointer;
margin-right: 8px;
margin-bottom: 8px;
box-sizing: border-box;
float: left;
&.is-disabled {
cursor: not-allowed;
}
&.is-one {
margin-bottom: 0;
}
&:hover {
.operation-btns {
display: block;
}
}
.operation-btns {
display: none;
position: absolute;
bottom: 0;
border-radius: 4px;
width: 100%;
line-height: 2;
color: #fff;
background-color: rgba(0, 0, 0, 0.3);
}
}
.material-upload {
:deep(.upload-btn) {
@apply text-tx-secondary box-border rounded border-br border-dashed border flex flex-col justify-center items-center;
}
}
}
.material-wrap {
min-width: 720px;
height: 430px;
@apply border-t border-b border-br;
}
</style>
<template>
<div v-show="modelValue">
<div v-if="type == 'image'">
<el-image-viewer v-if="previewLists.length" :url-list="previewLists" hide-on-click-modal @close="handleClose" />
</div>
<div v-if="type == 'video'">
<el-dialog v-model="visible" width="740px" title="视频预览" :before-close="handleClose">
<video-player ref="playerRef" :src="url" width="100%" height="450px" />
</el-dialog>
</div>
</div>
</template>
<script lang="ts" setup>
const props = defineProps({
modelValue: {
type: Boolean,
default: false
},
url: {
type: String,
default: ''
},
type: {
type: String,
default: 'image'
}
})
const emit = defineEmits<{
(event: 'update:modelValue', value: boolean): void
}>()
const playerRef = shallowRef()
const visible = computed({
get() {
return props.modelValue
},
set(value) {
emit('update:modelValue', value)
}
})
const handleClose = () => {
emit('update:modelValue', false)
}
const previewLists = ref<any[]>([])
watch(
() => props.modelValue,
(value) => {
if (value) {
nextTick(() => {
previewLists.value = [props.url]
playerRef.value?.play()
})
} else {
nextTick(() => {
previewLists.value = []
playerRef.value?.pause()
})
}
}
)
</script>
<template>
<div class="material" v-loading="pager.loading">
<div class="material__left">
<div class="flex-1 min-h-0">
<el-scrollbar>
<div class="material-left__content pt-4 p-b-4">
<el-tree ref="treeRef" node-key="id" :data="cateLists" empty-text="''" :highlight-current="true"
:expand-on-click-node="false" :current-node-key="cateId" @node-click="handleCatSelect">
<template v-slot="{ data }">
<div class="flex flex-1 items-center min-w-0 pr-4">
<img class="w-[20px] h-[16px] mr-3" src="@/assets/images/icon_folder.png" />
<span class="flex-1 truncate mr-2">
<overflow-tooltip :content="data.title" />
</span>
</div>
</template>
</el-tree>
</div>
</el-scrollbar>
</div>
</div>
<div class="material__center flex flex-col">
<div class="operate-btn flex">
<el-input class="w-60" placeholder="请输入名称" v-model="fileParams.content" @keyup.enter="refresh">
<template #append>
<el-button @click="refresh">
<template #icon>
<icon name="el-icon-Search" />
</template>
</el-button>
</template>
</el-input>
</div>
<div class="mt-3" v-if="mode == 'page'">
<el-checkbox :disabled="!pager.lists.length" v-model="isCheckAll" @change="selectAll"
:indeterminate="isIndeterminate">
当页全选
</el-checkbox>
</div>
<div class="material-center__content flex flex-col flex-1 mb-1 min-h-0">
<el-scrollbar v-if="pager.lists.length" v-show="listShowType == 'normal'">
<ul class="file-list flex flex-wrap mt-4">
<li class="file-item-wrap" v-for="item in pager.lists" :key="item.id" :style="{ width: fileSize }">
<file-item :uri="item.img_url" :file-size="fileSize" :type="type" @click="selectFile(item)">
<div class="item-selected" v-if="isSelect(item.id)">
<icon :size="24" name="el-icon-Check" color="#fff" />
</div>
</file-item>
<overflow-tooltip class="mt-1" :content="item.title" />
<div class="operation-btns flex items-center">
<el-button type="primary" link @click="handlePreview(item.img_url)">
查看
</el-button>
</div>
</li>
</ul>
</el-scrollbar>
<div class="flex flex-1 justify-center items-center" v-if="!pager.loading && !pager.lists.length">
暂无数据~
</div>
</div>
<div class="material-center__footer flex justify-between items-center mt-2">
<div class="flex">
<template v-if="mode == 'page'">
<span class="mr-3">
<el-checkbox :disabled="!pager.lists.length" v-model="isCheckAll" @change="selectAll"
:indeterminate="isIndeterminate">
当页全选
</el-checkbox>
</span>
</template>
</div>
<pagination v-model="pager" @change="getFileList" layout="total, prev, pager, next, jumper" />
</div>
</div>
<div class="material__right" v-if="mode == 'picker'">
<div class="flex justify-between p-2 flex-wrap">
<div class="sm flex items-center">
已选择 {{ select.length }}
<span v-if="limit">/{{ limit }}</span>
</div>
<el-button type="primary" link @click="clearSelect">清空</el-button>
</div>
<div class="flex-1 min-h-0">
<el-scrollbar class="ls-scrollbar">
<ul class="select-lists flex flex-col p-t-3">
<li class="mb-4" v-for="item in select" :key="item.id">
<div class="select-item">
<del-wrap @close="cancelSelete(item.id)">
<file-item :uri="item.img_url" file-size="100px" :type="type"></file-item>
</del-wrap>
</div>
</li>
</ul>
</el-scrollbar>
</div>
</div>
<preview v-model="showPreview" :url="previewUrl" :type="type" />
</div>
</template>
<script lang="ts" setup>
import { useCate, useFile } from './hook'
import FileItem from './file.vue'
import Preview from './preview.vue'
import type { Ref } from 'vue'
const props = defineProps({
fileSize: {
type: String,
default: '100px'
},
limit: {
type: Number,
default: 1
},
type: {
type: String,
default: 'image'
},
mode: {
type: String,
default: 'picker'
},
pageSize: {
type: Number,
default: 15
}
})
const emit = defineEmits(['change'])
const { limit } = toRefs(props)
const typeValue = computed<number>(() => {
switch (props.type) {
case 'image':
return 10
case 'video':
return 20
case 'file':
return 30
default:
return 0
}
})
const visible: Ref<boolean> = inject('visible')!
const previewUrl = ref('')
const showPreview = ref(false)
const {
treeRef,
cateId,
cateLists,
getCateLists,
handleCatSelect
} = useCate(typeValue.value)
const {
listShowType,
pager,
fileParams,
select,
isCheckAll,
isIndeterminate,
getFileList,
refresh,
selectFile,
isSelect,
clearSelect,
cancelSelete,
selectAll
} = useFile(cateId, typeValue, limit, props.pageSize)
const getData = async () => {
await getCateLists()
treeRef.value?.setCurrentKey(cateId.value)
getFileList()
}
const handlePreview = (url: string) => {
previewUrl.value = url
showPreview.value = true
}
watch(
visible,
async (val: boolean) => {
if (val) {
getData()
}
},
{
immediate: true
}
)
watch(cateId, () => {
fileParams.content = ''
refresh()
})
watch(
select,
(val: any[]) => {
emit('change', val)
if (val.length == pager.lists.length && val.length !== 0) {
isIndeterminate.value = false
isCheckAll.value = true
return
}
if (val.length > 0) {
isIndeterminate.value = true
} else {
isCheckAll.value = false
isIndeterminate.value = false
}
},
{
deep: true
}
)
onMounted(() => {
props.mode == 'page' && getData()
})
defineExpose({
clearSelect
})
</script>
<style scoped lang="scss">
.material {
@apply h-full min-h-0 flex flex-1;
&__left {
@apply border-r border-br flex flex-col w-[200px];
:deep(.el-tree-node__content) {
height: 36px;
.el-tree-node__label {
display: flex;
flex: 1;
min-width: 0;
}
}
}
&__center {
flex: 1;
min-width: 0;
min-height: 0;
padding: 16px 16px 0;
.list-icon {
border-radius: 3px;
display: flex;
padding: 5px;
cursor: pointer;
&.select {
@apply text-primary bg-primary-light-8;
}
}
.file-list {
.file-item-wrap {
margin-right: 16px;
line-height: 1.3;
cursor: pointer;
.item-selected {
display: flex;
align-items: center;
justify-content: center;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border-radius: 4px;
background-color: rgba(0, 0, 0, 0.5);
box-sizing: border-box;
}
.operation-btns {
height: 28px;
visibility: hidden;
}
&:hover .operation-btns {
visibility: visible;
}
}
}
}
&__right {
@apply border-l border-br flex flex-col;
width: 130px;
.select-lists {
padding: 10px;
.select-item {
width: 100px;
height: 100px;
}
}
}
}
</style>
<template>
<div class="upload">
<el-upload ref="uploadRefs" :headers="headers" :name="name" :action="action" :multiple="multiple" :limit="limit"
:show-file-list="false" :data="data" :on-progress="handleProgress" :on-success="handleSuccess"
:on-exceed="handleExceed" :on-error="handleError" :accept="getAccept">
<slot></slot>
</el-upload>
<el-dialog v-if="showProgress && fileList.length" v-model="visible" title="上传进度" :close-on-click-modal="false"
width="500px" :modal="false" @close="handleClose">
<div class="file-list p-4">
<template v-for="(item, index) in fileList" :key="index">
<div class="mb-5">
<div>{{ item.name }}</div>
<div class="flex-1">
<el-progress :percentage="parseInt(item.percentage)"></el-progress>
</div>
</div>
</template>
</div>
</el-dialog>
</div>
</template>
<script lang="ts">
import { computed, defineComponent, ref, reactive, shallowRef } from 'vue'
import config from '@/config'
import feedback from '@/utils/feedback'
import type { ElUpload } from 'element-plus'
import useUserStore from '@/stores/modules/user/user'
import {apiDiyImageSave} from '@/api/file'
export default defineComponent({
components: {},
props: {
// 上传文件类型
type: {
type: String,
default: 'file'
},
saveFoxpsd: {
type: Boolean,
default: true
},
action: {
type: String,
default: `${config.baseUrl}/api/v1/uploadOss`
},
name: {
type: String,
default: `image`
},
// 是否支持多选
multiple: {
type: Boolean,
default: true
},
// 多选时最多选择几条
limit: {
type: Number,
default: 10
},
// 上传时的额外参数
data: {
type: Object,
default: () => ({})
},
// 是否显示上传进度
showProgress: {
type: Boolean,
default: false
}
},
emits: ['change', 'error', 'success'],
setup(props: any, { emit }) {
const uploadRefs = shallowRef<InstanceType<typeof ElUpload>>();
const userstore = useUserStore();
const data = reactive({
...props.data
})
const headers = {
'Authorization':userstore.token
}
const visible = ref(false)
const fileList = ref<any[]>([])
const handleProgress = (event: any, file: any, fileLists: any[]) => {
visible.value = true
fileList.value = toRaw(fileLists)
}
const handleSuccess = async (response: any, file: any, fileLists: any[]) => {
emit('change', file)
console.log(file)
//图片上传到图库
if (props.saveFoxpsd && props.type == 'image') {
let data = response.data;
let obj = {
data: [{
img_url: data.url,
title: file.name,
width: data.width || 1000,
height: data.height || 1000,
size: file.size || 1000
}],
user_sku: userstore.userInfo.shop.default_user_sku,
...props.data
}
await apiDiyImageSave(obj);
}
const allSuccess = fileLists.every((item) => item.status == 'success');
if (allSuccess) {
uploadRefs.value?.clearFiles();
visible.value = false;
emit('success', response)
}
if (response.code && response.code == 10001) {
feedback.msgError(response.msg)
}
}
const handleError = (event: any, file: any) => {
feedback.msgError(`${file.name}文件上传失败`)
uploadRefs.value?.abort(file)
visible.value = false
emit('change', file)
emit('error', file)
}
const handleExceed = () => {
feedback.msgError(`超出上传上限${props.limit},请重新上传`)
}
const handleClose = () => {
uploadRefs.value?.clearFiles()
visible.value = false
}
const getAccept = computed(() => {
switch (props.type) {
case 'image':
return '.jpg,.png,.gif,.jpeg'
case 'video':
return '.wmv,.avi,.mpg,.mpeg,.3gp,.mov,.mp4,.flv,.rmvb,.mkv'
case 'psd':
return '.psd'
case 'svg':
return '.svg,.xml'
default:
return '*'
}
})
return {
uploadRefs,
visible,
fileList,
getAccept,
data,
handleProgress,
handleSuccess,
handleError,
handleExceed,
handleClose,
headers
}
}
})
</script>
<style lang="scss"></style>
<template>
<div>
<video-play
ref="playerRef"
v-bind="options"
:src="src"
@play="onPlay"
@pause="onPause"
@timeupdate="onTimeupdate"
@canplay="onCanplay"
/>
</div>
</template>
<script setup lang="ts">
import { reactive, shallowRef } from 'vue'
import 'vue3-video-play/dist/style.css'
import VideoPlay from 'vue3-video-play'
const props = defineProps({
src: {
type: String,
required: true
},
width: String,
height: String,
poster: String
})
const playerRef = shallowRef()
const options = reactive({
color: 'var(--el-color-primary)', //主题色
muted: false, //静音
webFullScreen: false,
speedRate: ['0.75', '1.0', '1.25', '1.5', '2.0'], //播放倍速
autoPlay: true, //自动播放
loop: false, //循环播放
mirror: false, //镜像画面
ligthOff: false, //关灯模式
volume: 0.3, //默认音量大小
control: true, //是否显示控制器
title: '', //视频名称
poster: '', //封面
...props
})
const play = () => {
playerRef.value.play()
}
const pause = () => {
playerRef.value.pause()
}
const onPlay = (event: any) => {
console.log(event, '播放')
}
const onPause = (event: any) => {
console.log(event, '暂停')
}
const onTimeupdate = (event: any) => {
console.log(event, '时间更新')
}
const onCanplay = (event: any) => {
console.log(event, '可以播放')
}
defineExpose({
play,
pause
})
</script>
console.log(process.env.NODE_ENV)
const config = {
terminal: 1, //终端
title: 'FOXPSD 模板管理系统', //网站默认标题
version: '1.6.0', //版本号
baseUrl: process.env.NODE_ENV == 'development' ? 'http://localhost:7001' : ``, //请求接口域名 http://139.129.227.83:8095
business: {
default_user_sku: '6cec01ec-0a4d-40e9-a396-8da8b094876d',
foxpsd_appid: '1676529074812884611'
},
urlPrefix: '', //请求默认前缀
timeout: 60 * 1000, //请求超时时长
oss_domain: "",
web_name: "FOXPSD 模板管理系统",
web_favicon: "https://foxpsd.com/www/images/icon.png",
web_logo: "https://img.foxpsd.com/lt_logo.jpg",
login_image: "https://img.foxpsd.com/login_image.png",
copyright_config: [
{
"key": "",
"value": "https://beian.miit.gov.cn"
}
]
}
export default config
const defaultSetting = {
showCrumb: true, // 是否显示面包屑
showLogo: true, // 是否显示logo
isUniqueOpened: false, //只展开一个一级菜单
sideWidth: 200, //侧边栏宽度
sideTheme: 'light', //侧边栏主题
sideDarkColor: '#1d2124', //侧边栏深色主题颜色
openMultipleTabs: true, // 是否开启多标签tab栏
theme: '#4A5DFF', //主题色
successTheme: '#67c23a', //成功主题色
warningTheme: '#e6a23c', //警告主题色
dangerTheme: '#f56c6c', //危险主题色
errorTheme: '#f56c6c', //错误主题色
infoTheme: '#909399' //信息主题色
}
export default defaultSetting
//菜单主题类型
export enum ThemeEnum {
LIGHT = 'light',
DARK = 'dark'
}
// 菜单类型
export enum MenuEnum {
CATALOGUE = 'M',
MENU = 'C',
BUTTON = 'A'
}
// 屏幕
export enum ScreenEnum {
SM = 640,
MD = 768,
LG = 1024,
XL = 1280,
'2XL' = 1536
}
// 客户端类型
export enum ClientEnum {
MP_WEIXIN = 1, // 微信-小程序
OA_WEIXIN = 2, // 微信-公众号
H5 = 3, // H5
PC = 4, // PC
IOS = 5, //苹果
ANDROID = 6 //安卓
}
export const ClientMap = {
[ClientEnum.MP_WEIXIN]: '微信小程序',
[ClientEnum.OA_WEIXIN]: '微信公众号',
[ClientEnum.H5]: '手机H5',
[ClientEnum.PC]: '电脑PC',
[ClientEnum.IOS]: '苹果APP',
[ClientEnum.ANDROID]: '安卓APP'
}
// 本地缓冲key
//token
export const TOKEN_KEY = 'token'
//账号
export const ACCOUNT_KEY = 'account'
//设置
export const SETTING_KEY = 'setting'
export enum PageEnum {
//登录页面
LOGIN = '/login',
//无权限页面
ERROR_403 = '/403',
INDEX = '/'
}
export enum ContentTypeEnum {
// json
JSON = 'application/json;charset=UTF-8',
// form-data 上传资源(图片,视频)
FORM_DATA = 'multipart/form-data;charset=UTF-8',
FORM_URL = 'application/json'
}
export enum RequestMethodsEnum {
GET = 'GET',
POST = 'POST'
}
export enum RequestCodeEnum {
SUCCESS = true,
FAIL = 0,
LOGIN_FAILURE = -1,
OPEN_NEW_PAGE = 2
}
import { getDictData } from '@/api/app'
import { reactive, toRaw } from 'vue'
interface Options {
[propName: string]: {
api: PromiseFun
params?: Record<string, any>
transformData?(data: any): any
}
}
// {
// dict: {
// api: dictData,
// params: { name: 'user' },
// transformData(data: any) {
// return data.list
// }
// }
// }
export function useDictOptions<T = any>(options: Options) {
const optionsData: any = reactive({})
const optionsKey = Object.keys(options)
const apiLists = optionsKey.map((key) => {
const value = options[key]
optionsData[key] = []
return () => value.api(toRaw(value.params) || {})
})
const refresh = async () => {
const res = await Promise.allSettled<Promise<any>>(apiLists.map((api) => api()))
res.forEach((item, index) => {
const key = optionsKey[index]
if (item.status == 'fulfilled') {
const { transformData } = options[key]
const data = transformData ? transformData(item.value) : item.value
optionsData[key] = data
}
})
}
refresh()
return {
optionsData: optionsData as T,
refresh
}
}
// useDictData<{
// dict: any[]
// }>(['dict'])
export function useDictData<T = any>(dict: string) {
const dictData: any = reactive({})
const refresh = async () => {
const data = await getDictData({
type: dict
})
Object.assign(dictData, data)
}
refresh()
return {
dictData: dictData as T,
refresh
}
}
import { ref } from 'vue'
export function useLockFn(fn: (...args: any[]) => Promise<any>) {
const isLock = ref(false)
const lockFn = async (...args: any[]) => {
if (isLock.value) return
isLock.value = true
try {
const res = await fn(...args)
isLock.value = false
return res
} catch (e) {
isLock.value = false
throw e
}
}
return {
isLock,
lockFn
}
}
import useTabsStore from '@/stores/modules/multipleTabs'
import useSettingStore from '@/stores/modules/setting'
export default function useMultipleTabs() {
const router = useRouter()
const route = useRoute()
const tabsStore = useTabsStore()
const settingStore = useSettingStore()
const tabsLists = computed(() => {
return tabsStore.getTabList
})
const currentTab = computed(() => {
return route.fullPath
})
const addTab = () => {
if (!settingStore.openMultipleTabs) return
tabsStore.addTab(router)
}
const removeTab = (fullPath?: any) => {
if (!settingStore.openMultipleTabs) return
fullPath = fullPath ?? route.fullPath
tabsStore.removeTab(fullPath, router)
}
const removeOtherTab = () => {
if (!settingStore.openMultipleTabs) return
tabsStore.removeOtherTab(route)
}
const removeAllTab = () => {
if (!settingStore.openMultipleTabs) return
tabsStore.removeAllTab(router)
}
return {
tabsLists,
currentTab,
addTab,
removeTab,
removeOtherTab,
removeAllTab
}
}
import { reactive, toRaw } from 'vue'
// 分页钩子函数
interface Options {
page?: number
size?: number
fetchFun: (_arg: any) => Promise<any>
params?: Record<any, any>
firstLoading?: boolean
}
function guolvParams(params: any) {
let p: any = {};
for (let key in params) {
if (params[key] && params[key] != 'all' || params[key] === 0) {
p[key] = params[key];
}
}
return p
}
export function usePaging(options: Options) {
let { page = 1, size = 15, fetchFun, params = {}, firstLoading = false } = options
// 记录分页初始参数
const paramsInit: Record<any, any> = Object.assign({}, toRaw(params))
// 分页数据
const pager = reactive({
page,
size,
loading: firstLoading,
count: 0,
lists: [] as any[],
extend: {} as Record<string, any>
})
if (params.rows) {
pager.size = params.rows
}
// 请求分页接口
const getLists = (_params = {}) => {
pager.loading = true;
if (JSON.stringify(_params) != '{}') {
params = { ...params, ..._params }
}
// console.log(params)
return fetchFun({
page: pager.page,
rows: pager.size,
...guolvParams(params)
})
.then((res: any) => {
if (params.proxy) {
pager.count = res.data.rowCount || res.data.totalRow;
pager.lists = res?.data.list;
} else {
if (res?.data.results) {
pager.count = res?.data.results.totalRow;
pager.lists = res?.data.results.list;
} else {
pager.lists = res?.data.list;
if (res?.data.totalRow) {
pager.count = Number(res?.data.totalRow);
} else {
pager.count = res?.data.list.length;
}
}
pager.extend = res?.data;
return Promise.resolve(res?.data)
}
})
.catch((err: any) => {
return Promise.reject(err)
})
.finally(() => {
pager.loading = false
})
}
// 重置为第一页
const resetPage = () => {
pager.page = 1
getLists()
}
// 重置参数
const resetParams = () => {
Object.keys(paramsInit).forEach((item) => {
params[item] = paramsInit[item]
})
getLists()
}
return {
pager,
getLists,
resetParams,
resetPage
}
}
import type { RouteLocationNormalizedLoaded } from 'vue-router'
export function useWatchRoute(callback: (route: RouteLocationNormalizedLoaded) => void) {
const route = useRoute()
watch(
route,
() => {
callback(route)
},
{
immediate: true
}
)
return {
route
}
}
/**
* perm 操作权限处理
* 指令用法:
* <el-button v-perms="['auth.menu/edit']">编辑</el-button>
*/
import feedback from '@/utils/feedback'
import useClipboard from 'vue-clipboard3'
const clipboard = 'data-clipboard-text'
export default {
mounted: (el: HTMLElement, binding: any) => {
el.setAttribute(clipboard, binding.value)
const { toClipboard } = useClipboard()
el.onclick = () => {
toClipboard(el.getAttribute(clipboard)!)
.then(() => {
feedback.msgSuccess('复制成功')
})
.catch(() => {
feedback.msgError('复制失败')
})
}
},
updated: (el: HTMLElement, binding: any) => {
el.setAttribute(clipboard, binding.value)
}
}
/**
* perm 操作权限处理
* 指令用法:
* <el-button v-perms="['auth.menu/edit']">编辑</el-button>
*/
import useUserStore from '@/stores/modules/user/user'
export default {
mounted: (el: HTMLElement, binding: any) => {
const { value } = binding
const userStore = useUserStore()
const permissions = userStore.perms
const all_permission = '*'
if (Array.isArray(value)) {
if (value.length > 0) {
const hasPermission = permissions.some((key: string) => {
return all_permission == key || value.includes(key)
})
if (!hasPermission) {
el.parentNode && el.parentNode.removeChild(el)
}
}
} else {
throw new Error('like v-perms="[\'auth.menu/edit\']"')
}
}
}
import type { App } from 'vue'
const modules = import.meta.glob('./**/*', { eager: true })
// 安装方法,执行某一类相同操作
function install(app: App<Element>) {
Object.keys(modules).forEach((key) => {
const name = key.replace(/(.*\/)*([^.]+).*/gi, '$2')
const type = key.replace(/^\.\/([\w-]+).*/gi, '$1')
const module: any = modules[key]
if (module.default) {
switch (type) {
// 用于注册全局指令
case 'directives':
app.directive(name, module.default)
break
// 使用插件
case 'plugins':
typeof module.default === 'function' && module.default(app)
break
}
}
})
}
export default {
install
}
//引入 echarts 核心模块,核心模块提供了 echarts 使用必须要的接口。
import * as echarts from 'echarts/core'
//引入柱状图图表,图表后缀都为 Chart
import {
BarChart,
LineChart,
PieChart,
MapChart,
PictorialBarChart,
RadarChart,
ScatterChart
} from 'echarts/charts'
// 引入提示框,标题,直角坐标系,数据集,内置数据转换器组件,组件后缀都为 Component
import {
TitleComponent,
TooltipComponent,
GridComponent,
PolarComponent,
AriaComponent,
ParallelComponent,
LegendComponent,
RadarComponent,
ToolboxComponent,
DataZoomComponent,
VisualMapComponent,
TimelineComponent,
CalendarComponent,
GraphicComponent
} from 'echarts/components'
//引入 Canvas 渲染器,注意引入 CanvasRenderer 或者 SVGRenderer 是必须的一步
import { CanvasRenderer } from 'echarts/renderers'
//标签自动布局,全局过渡动画等特性
import { LabelLayout, UniversalTransition } from 'echarts/features'
// 注册必须的组件
echarts.use([
LegendComponent,
TitleComponent,
TooltipComponent,
GridComponent,
PolarComponent,
AriaComponent,
ParallelComponent,
BarChart,
LineChart,
PieChart,
MapChart,
RadarChart,
PictorialBarChart,
RadarComponent,
ToolboxComponent,
DataZoomComponent,
VisualMapComponent,
TimelineComponent,
CalendarComponent,
GraphicComponent,
ScatterChart,
CanvasRenderer,
LabelLayout,
UniversalTransition
])
import * as ElementPlusIcons from '@element-plus/icons-vue'
import type { App } from 'vue'
//https://github.com/element-plus/element-plus/issues/7293
import 'element-plus/es/components/dialog/style/css'
export default (app: App<Element>) => {
// 全局注册ElementPlus图标
for (const [key, component] of Object.entries(ElementPlusIcons)) {
app.component(key, component)
}
}
import type { App } from 'vue'
import 'highlight.js/styles/github.css'
import hljs from 'highlight.js/lib/common'
import hljsVuePlugin from '@highlightjs/vue-plugin'
console.log(hljs)
export default (app: App<Element>) => {
app.use(hljsVuePlugin)
}
import store from '@/stores'
import type { App } from 'vue'
export default (app: App<Element>) => {
app.use(store)
}
import router from '@/router'
import type { App } from 'vue'
export default (app: App<Element>) => {
app.use(router)
}
<template>
<footer class="layout-footer">
<div class="text-center p-2 text-xs text-tx-secondary max-w-[900px] mx-auto">
<a
class="mx-1 hover:underline"
:href="item.value"
target="_blank"
v-for="item in copyright"
:key="item.key"
>
{{ item.key }}
</a>
</div>
</footer>
</template>
<script setup lang="ts">
import useAppStore from '@/stores/modules/app'
const appStore = useAppStore()
const copyright = computed(() => appStore.config.copyright_config || [])
</script>
<template>
<el-breadcrumb class="app-breadcrumb">
<el-breadcrumb-item v-for="item in breadcrumbs" :key="item.path">
{{ item.meta.title }}
</el-breadcrumb-item>
</el-breadcrumb>
</template>
<script setup lang="ts">
import { useWatchRoute } from '@/hooks/useWatchRoute'
import type { RouteLocationMatched, RouteLocationNormalizedLoaded } from 'vue-router'
const breadcrumbs = ref<RouteLocationMatched[]>([])
const getBreadcrumb = (route: RouteLocationNormalizedLoaded) => {
const matched = route.matched.filter((item) => item.meta && item.meta.title)
breadcrumbs.value = matched
}
useWatchRoute((route) => {
getBreadcrumb(route)
})
</script>
<template>
<div class="fold h-full cursor-pointer flex items-center px-2" @click="toggleCollapsed">
<icon :name="`local-icon-${isCollapsed ? 'close' : 'open'}`" :size="20" />
</div>
</template>
<script setup lang="ts">
import useAppStore from '@/stores/modules/app'
const appStore = useAppStore()
const isCollapsed = computed(() => appStore.isCollapsed)
// 折叠展开菜单
const toggleCollapsed = () => {
appStore.toggleCollapsed()
}
</script>
<template>
<div class="full-screen h-full cursor-pointer flex items-center px-2" @click="toggleFullscreen">
<icon :size="16" :name="`local-icon-${isFullscreen ? 'fullscreen-exit' : 'fullscreen'}`" />
</div>
</template>
<script setup lang="ts">
import { useFullscreen } from '@vueuse/core'
const { toggle: toggleFullscreen, isFullscreen } = useFullscreen()
</script>
<template>
<header class="header">
<div class="navbar">
<div class="flex-1 flex">
<div class="navbar-item">
<fold />
</div>
<div class="navbar-item">
<refresh />
</div>
<div class="flex items-center px-2" v-if="!isMobile && settingStore.showCrumb">
<breadcrumb />
</div>
</div>
<div class="flex">
<div class="navbar-item" v-if="!isMobile">
<full-screen />
</div>
<div class="navbar-item">
<user-drop-down />
</div>
<div class="navbar-item">
<setting />
</div>
</div>
</div>
<multiple-tabs v-if="settingStore.openMultipleTabs" />
</header>
</template>
<script setup lang="ts">
import useAppStore from '@/stores/modules/app'
import Fold from './fold.vue'
import Refresh from './refresh.vue'
import Breadcrumb from './breadcrumb.vue'
import FullScreen from './full-screen.vue'
import UserDropDown from './user-drop-down.vue'
import Setting from '../setting/index.vue'
import MultipleTabs from './multiple-tabs.vue'
import useSettingStore from '@/stores/modules/setting'
const appStore = useAppStore()
const isMobile = computed(() => appStore.isMobile)
const settingStore = useSettingStore()
</script>
<style lang="scss">
.navbar {
height: var(--navbar-height);
@apply flex px-2 bg-body;
.navbar-item {
@apply h-full flex justify-center items-center hover:bg-page;
}
}
</style>
<template>
<div class="app-tabs pl-4 flex bg-body">
<div class="flex-1 min-w-0">
<el-tabs
:model-value="currentTab"
:closable="tabsLists.length > 1"
@tab-change="handleChange"
@tab-remove="removeTab($event)"
>
<template v-for="item in tabsLists" :key="item.fullPath">
<el-tab-pane :label="item.title" :name="item.fullPath"></el-tab-pane>
</template>
</el-tabs>
</div>
<el-dropdown @command="handleCommand">
<span class="flex items-center px-3">
<icon :size="16" name="el-icon-arrow-down" />
</span>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item command="closeCurrent"> 关闭当前 </el-dropdown-item>
<el-dropdown-item command="closeOther"> 关闭其他 </el-dropdown-item>
<el-dropdown-item command="closeAll"> 关闭全部 </el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</div>
</template>
<script setup lang="ts">
import useMultipleTabs from '@/hooks/useMultipleTabs'
import { useWatchRoute } from '@/hooks/useWatchRoute'
import useTabsStore, { getRouteParams } from '@/stores/modules/multipleTabs'
const router = useRouter()
const tabsStore = useTabsStore()
const { removeOtherTab, addTab, removeAllTab, removeTab, tabsLists, currentTab } = useMultipleTabs()
useWatchRoute(() => {
addTab()
})
const handleChange = (fullPath: any) => {
const tabItem = tabsStore.tasMap[fullPath]
router.push(getRouteParams(tabItem))
}
const handleCommand = (command: any) => {
switch (command) {
case 'closeCurrent':
removeTab()
break
case 'closeOther':
removeOtherTab()
break
case 'closeAll':
removeAllTab()
break
}
}
</script>
<style lang="scss" scoped>
.app-tabs {
@apply border-t border-br;
:deep(.el-tabs) {
height: 40px;
.el-tabs {
&__header {
margin-bottom: 0;
}
&__content {
display: none;
}
&__nav-next,
&__nav-prev {
@apply text-xl;
}
&__nav-wrap::after {
height: 0;
}
&__item {
font-weight: normal;
padding: 0 15px !important;
box-sizing: border-box;
&.is-active {
background-color: var(--el-color-primary-light-9);
&::before {
content: '';
display: inline-block;
width: 6px;
height: 6px;
background-color: var(--el-color-primary);
margin-right: 6px;
border-radius: 50%;
vertical-align: 2px;
}
&::after {
position: absolute;
content: '';
display: block;
top: 0;
height: 2px;
left: 0;
width: 100%;
background-color: var(--el-color-primary);
}
}
.is-icon-close {
color: var(--el-text-color-regular);
vertical-align: -2px;
&:hover {
color: var(--color-white);
background-color: var(--el-color-danger);
}
}
}
&__active-bar {
display: none;
}
}
}
}
</style>
<template>
<div class="refresh cursor-pointer h-full flex items-center px-2" @click="refreshView">
<icon name="el-icon-RefreshRight" :size="18" />
</div>
</template>
<script setup lang="ts">
import useAppStore from '@/stores/modules/app'
const appStore = useAppStore()
// 刷新页面
const refreshView = () => {
appStore.refreshView()
}
</script>
<template>
<el-dropdown class="px-2" @command="handleCommand">
<div class="flex items-center">
<el-avatar :size="34" src="https://img.foxpsd.com/avatar.png" />
<div class="ml-3 mr-1">{{ userInfo.name}}</div>
<icon name="el-icon-ArrowDown" />
</div>
<template #dropdown>
<el-dropdown-menu>
<!-- <router-link to="/user/setting">
<el-dropdown-item>个人设置</el-dropdown-item>
</router-link> -->
<el-dropdown-item command="logout">退出登录</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</template>
<script setup lang="ts">
import useUserStore from '@/stores/modules/user/user'
import feedback from '@/utils/feedback'
const userStore = useUserStore()
const userInfo = computed(() => userStore.userInfo)
const handleCommand = async (command: string) => {
switch (command) {
case 'logout':
await feedback.confirm('确定退出登录吗?')
userStore.logout()
}
}
</script>
<template>
<main class="main-wrap h-full bg-page">
<el-scrollbar>
<div class="p-4">
<router-view v-if="isRouteShow" v-slot="{ Component, route }">
<keep-alive :include="includeList" :max="20">
<component :is="Component" :key="route.fullPath" />
</keep-alive>
</router-view>
</div>
</el-scrollbar>
</main>
</template>
<script setup lang="ts">
import useAppStore from '@/stores/modules/app'
import useTabsStore from '@/stores/modules/multipleTabs'
import useSettingStore from '@/stores/modules/setting'
const appStore = useAppStore()
const tabsStore = useTabsStore()
const settingStore = useSettingStore()
const isRouteShow = computed(() => appStore.isRouteShow)
const includeList = computed(() => (settingStore.openMultipleTabs ? tabsStore.getCacheTabList : []))
</script>
<style></style>
<template>
<div class="setting-drawer">
<el-drawer
v-model="showSetting"
append-to-body
direction="rtl"
size="250px"
title="主题设置"
>
<div class="setting-item mb-5">
<span class="text-tx-secondary">风格设置</span>
<div class="flex mt-4 cursor-pointer">
<div
class="mr-4 flex relative text-primary"
v-for="item in sideThemeList"
:key="item.type"
@click="sideTheme = item.type"
>
<img :src="item.image" width="52" height="36" />
<icon
v-if="sideTheme == item.type"
class="icon-select"
name="el-icon-Select"
/>
</div>
</div>
</div>
<div class="setting-item mb-5 flex justify-between items-center">
<span class="text-tx-secondary">主题颜色</span>
<div>
<el-color-picker v-model="theme" :predefine="predefineColors" />
</div>
</div>
<div class="setting-item mb-5 flex justify-between items-center">
<span class="text-tx-secondary">开启黑暗模式</span>
<div>
<el-switch :model-value="isDark" @change="toggleDark" />
</div>
</div>
<div class="setting-item mb-5 flex justify-between items-center">
<span class="text-tx-secondary">开启多页签栏</span>
<div>
<el-switch
v-model="openMultipleTabs"
:active-value="true"
:inactive-value="false"
/>
</div>
</div>
<div class="setting-item mb-5 flex justify-between items-center">
<span class="text-tx-secondary">只展开一个一级菜单</span>
<div>
<el-switch
v-model="isUniqueOpened"
:active-value="true"
:inactive-value="false"
/>
</div>
</div>
<div class="setting-item mb-5 flex justify-between items-center">
<div class="text-tx-secondary flex-none mr-3">菜单栏宽度</div>
<div>
<el-input-number v-model="sideWidth" :min="180" :max="250" />
</div>
</div>
<div class="setting-item mb-5 flex justify-between items-center">
<div class="text-tx-secondary flex-none mr-3">显示LOGO</div>
<div>
<el-switch v-model="showLogo" :active-value="true" :inactive-value="false" />
</div>
</div>
<div class="setting-item mb-5 flex justify-between items-center">
<div class="text-tx-secondary flex-none mr-3">显示面包屑</div>
<div>
<el-switch v-model="showCrumb" :active-value="true" :inactive-value="false" />
</div>
</div>
<div class="setting-item mb-5 flex justify-between items-center">
<el-button @click="resetTheme">重置主题</el-button>
</div>
</el-drawer>
</div>
</template>
<script setup lang="ts">
import useSettingStore from '@/stores/modules/setting'
import { useDark, useToggle } from '@vueuse/core'
import theme_light from '@/assets/images/theme_white.png'
import theme_dark from '@/assets/images/theme_black.png'
const settingStore = useSettingStore()
const predefineColors = ref(['#409EFF', '#28C76F', '#EA5455', '#FF9F43', '#01CFE8', '#4A5DFF'])
const sideThemeList = [
{
type: 'dark',
image: theme_dark
},
{
type: 'light',
image: theme_light
}
]
const sideTheme = computed({
get() {
return settingStore.sideTheme
},
set(value) {
settingStore.setSetting({
key: 'sideTheme',
value
})
}
})
const openMultipleTabs = computed({
get() {
return settingStore.openMultipleTabs
},
set(value) {
settingStore.setSetting({
key: 'openMultipleTabs',
value
})
}
})
const isUniqueOpened = computed({
get() {
return settingStore.isUniqueOpened
},
set(value) {
settingStore.setSetting({
key: 'isUniqueOpened',
value
})
}
})
const sideWidth = computed({
get() {
return settingStore.sideWidth
},
set(value) {
settingStore.setSetting({
key: 'sideWidth',
value
})
}
})
const showSetting = computed({
get() {
return settingStore.showDrawer
},
set(value) {
settingStore.setSetting({
key: 'showDrawer',
value
})
}
})
const theme = computed({
get() {
return settingStore.theme
},
set(value) {
settingStore.setSetting({
key: 'theme',
value
})
themeChange()
}
})
const showLogo = computed({
get() {
return settingStore.showLogo
},
set(value) {
settingStore.setSetting({
key: 'showLogo',
value
})
}
})
const showCrumb = computed({
get() {
return settingStore.showCrumb
},
set(value) {
settingStore.setSetting({
key: 'showCrumb',
value
})
}
})
const isDark = useDark()
const themeChange = () => {
settingStore.setTheme(isDark.value)
}
const toggleDark = () => {
useToggle(isDark)()
themeChange()
}
const resetTheme = () => {
isDark.value = false
settingStore.resetTheme()
themeChange()
}
</script>
<style lang="scss" scoped>
.icon-select {
@apply absolute left-1/2 top-1/2;
transform: translate(-50%, -50%);
}
</style>
<template>
<div class="setting flex cursor-pointer h-full items-center px-2" @click="openSetting">
<icon :size="16" name="el-icon-Setting" />
<layout-setting />
</div>
</template>
<script setup lang="ts">
import useSettingStore from '@/stores/modules/setting'
import LayoutSetting from './drawer.vue'
const settingStore = useSettingStore()
const openSetting = () => {
settingStore.setSetting({
key: 'showDrawer',
value: true
})
}
</script>
<template>
<aside class="sidebar h-full">
<el-drawer
v-model="showMenuDrawer"
direction="ltr"
:size="drawderSize"
title="主题设置"
:with-header="false"
>
<side />
</el-drawer>
<side v-show="!isMobile" />
</aside>
</template>
<script setup lang="ts">
import Side from './side.vue'
import useAppStore from '@/stores/modules/app'
import useSettingStore from '@/stores/modules/setting'
const appStore = useAppStore()
const settingStore = useSettingStore()
const isMobile = computed(() => appStore.isMobile)
const showMenuDrawer = computed({
get() {
return !appStore.isCollapsed && isMobile.value
},
set(value) {
appStore.toggleCollapsed(!value)
}
})
const drawderSize = computed(() => {
return `${settingStore.sideWidth + 1}px`
})
</script>
<style lang="scss" scoped>
.sidebar {
:deep(.el-drawer__body) {
padding: 0;
}
}
</style>
<template>
<div class="logo">
<image-contain fit="contain" :width="szie" :height="szie" radius="1000px" :src="config.web_logo" />
<transition name="title-width">
<div v-show="showTitle" class="logo-title overflow-hidden whitespace-nowrap"
:class="{ 'text-white': theme == ThemeEnum.DARK }" :style="{ left: `${szie + 16}px` }">
<overflow-tooltip :content="title || config.web_name" :teleported="true" placement="bottom"
overflo-type="unset">
</overflow-tooltip>
</div>
</transition>
</div>
</template>
<script setup lang="ts">
import useAppStore from '@/stores/modules/app'
import { ThemeEnum } from '@/enums/appEnums'
defineProps({
szie: { type: Number, default: 30 },
title: { type: String },
theme: { type: String },
showTitle: { type: Boolean, default: true }
})
const appStore = useAppStore()
const config = computed(() => appStore.config)
</script>
<style lang="scss" scoped>
.logo {
height: var(--navbar-height);
overflow: hidden;
@apply flex items-center p-2 relative;
.logo-title {
width: 70%;
position: absolute;
font-size: 14px;
}
.title-width-enter-active {
opacity: 0;
transition: all 0.3s ease-out;
}
.title-width-leave-active {
transition: all 0.3s cubic-bezier(1, 0.5, 0.8, 1);
}
.title-width-enter-from,
.title-width-leave-to {
width: 0;
opacity: 0;
}
}
</style>
<template>
<template v-if="!route.meta?.hidden">
<app-link v-if="!hasShowChild" :to="`${routePath}?${queryStr}`">
<el-menu-item :index="routePath">
<icon
class="menu-item-icon"
:size="16"
v-if="routeMeta?.icon"
:name="routeMeta?.icon"
/>
<template #title>
<span>{{ routeMeta?.title }}</span>
</template>
</el-menu-item>
</app-link>
<el-sub-menu v-else :index="routePath" :popper-class="popperClass">
<template #title>
<icon
class="menu-item-icon"
:size="16"
v-if="routeMeta?.icon"
:name="routeMeta?.icon"
/>
<span>{{ routeMeta?.title }}</span>
</template>
<menu-item
v-for="item in route?.children"
:key="resolvePath(item.path)"
:route="item"
:route-path="resolvePath(item.path)"
:popper-class="popperClass"
/>
</el-sub-menu>
</template>
</template>
<script lang="ts" setup>
import { getNormalPath, objectToQuery } from '@/utils/util'
import { isExternal } from '@/utils/validate'
import type { RouteRecordRaw } from 'vue-router'
interface Props {
route: RouteRecordRaw
routePath: string
popperClass: string
}
const props = defineProps<Props>()
const hasShowChild = computed(() => {
const children: RouteRecordRaw[] = props.route.children ?? []
return !!children.filter((item) => !item.meta?.hidden).length
})
const routeMeta = computed(() => {
return props.route.meta
})
const resolvePath = (path: string) => {
if (isExternal(path)) {
return path
}
const newPath = getNormalPath(`${props.routePath}/${path}`)
return newPath
}
const queryStr = computed<string>(() => {
const query = props.route.meta?.query as string
try {
const queryObj = JSON.parse(query)
return objectToQuery(queryObj)
} catch (error) {
// console.log(error)
return query
}
})
</script>
<style lang="scss" scoped>
.el-menu-item,
.el-sub-menu__title {
.menu-item-icon {
margin-right: 8px;
width: var(--el-menu-icon-width);
text-align: center;
vertical-align: middle;
}
}
</style>
<template>
<div class="menu flex-1 min-h-0" :class="themeClass" :style="isCollapsed ? '' : `--aside-width: ${width}px`">
<el-scrollbar>
<el-menu v-bind="config" :default-active="activeMenu" :collapse="isCollapsed" mode="vertical"
:unique-opened="uniqueOpened" @select="$emit('select')">
<menu-item v-for="route in routes" :key="route.path" :route="route" :route-path="route.path"
:popper-class="themeClass" />
</el-menu>
</el-scrollbar>
</div>
</template>
<script setup lang="ts">
import type { PropType } from 'vue'
import MenuItem from './menu-item.vue'
import type { RouteRecordRaw } from 'vue-router'
const props = defineProps({
routes: {
type: Object as PropType<RouteRecordRaw[]>
},
config: {
type: Object
},
uniqueOpened: {
type: Boolean,
default: false
},
isCollapsed: {
type: Boolean,
default: false
},
theme: {
type: String
},
width: {
type: Number,
default: 200
}
})
defineEmits(['select'])
const route = useRoute()
const activeMenu = computed<string>(() => route.meta?.activeMenu || route.path)
const themeClass = computed(() => `theme-${props.theme}`)
</script>
<style lang="scss" scoped>
.menu {
&.theme-dark {
.el-menu {
:deep(.el-menu-item) {
&.is-active {
@apply bg-primary border-primary;
}
}
}
:deep(.el-menu--collapse) {
.el-sub-menu.is-active .el-sub-menu__title {
@apply bg-primary #{!important};
}
}
}
&.theme-light {
:deep(.el-menu) {
.el-menu-item {
border-color: transparent;
&.is-active {
@apply bg-primary-light-9 border-r-2 border-primary;
}
}
.el-menu-item:hover,
.el-sub-menu__title:hover {
color: var(--el-color-primary);
}
}
}
.el-menu {
border-right: none;
&:not(.el-menu--collapse) {
width: var(--aside-width);
}
}
}
</style>
<template>
<div class="side" :style="sideStyle">
<side-logo v-if="settingStore.showLogo" :show-title="!isCollapsed" :theme="sideTheme" />
<side-menu :routes="routes" :is-collapsed="isCollapsed" :width="settingStore.sideWidth"
:unique-opened="settingStore.isUniqueOpened" :config="menuProp" :theme="sideTheme" @select="handleSelect" />
</div>
</template>
<script setup lang="ts">
import useAppStore from '@/stores/modules/app'
import useSettingStore from '@/stores/modules/setting'
import useUserStore from '@/stores/modules/user/user'
import SideLogo from './logo.vue'
import SideMenu from './menu.vue'
const appStore = useAppStore()
const isCollapsed = computed(() => {
if (appStore.isMobile) {
return false
} else {
return appStore.isCollapsed
}
})
const settingStore = useSettingStore()
const sideTheme = computed(() => settingStore.sideTheme)
const userStore = useUserStore()
const routes = computed(() => userStore.routes)
const sideStyle = computed(() => {
return sideTheme.value == 'dark'
? {
'--side-dark-color': settingStore.sideDarkColor
}
: ''
})
const menuProp = computed(() => {
return {
backgroundColor: sideTheme.value == 'dark' ? settingStore.sideDarkColor : '',
textColor: sideTheme.value == 'dark' ? 'var(--el-color-white)' : '',
activeTextColor: sideTheme.value == 'dark' ? 'var(--el-color-white)' : ''
}
})
const handleSelect = () => {
if (appStore.isMobile) {
appStore.toggleCollapsed(true)
}
}
</script>
<style lang="scss" scoped>
.side {
position: relative;
z-index: 999;
@apply border-r border-br-light h-full flex flex-col;
background-color: var(--side-dark-color, var(--el-bg-color));
}
</style>
<template>
<div class="layout-default flex h-screen w-full">
<div class="app-aside">
<layout-sidebar />
</div>
<div class="flex-1 flex flex-col min-w-0">
<div class="app-header">
<layout-header />
</div>
<div class="app-main flex-1 min-h-0">
<layout-main />
</div>
</div>
</div>
</template>
<script setup lang="ts">
import LayoutMain from './components/main.vue'
import LayoutSidebar from './components/sidebar/index.vue'
import LayoutHeader from './components/header/index.vue'
</script>
"use strict";
var resvg = (() => {
var I = Object.defineProperty;
var S = Object.getOwnPropertyDescriptor;
var U = Object.getOwnPropertyNames;
var E = Object.prototype.hasOwnProperty;
var T = (e, t) => {
for (var n in t)
I(e, n, {
get: t[n],
enumerable: !0
})
}
, L = (e, t, n, i) => {
if (t && typeof t == "object" || typeof t == "function")
for (let o of U(t))
!E.call(e, o) && o !== n && I(e, o, {
get: () => t[o],
enumerable: !(i = S(t, o)) || i.enumerable
});
return e
}
;
var C = e => L(I({}, "__esModule", {
value: !0
}), e);
var V = {};
T(V, {
Resvg: () => J,
initWasm: () => H
});
var r, w = new Array(128).fill(void 0);
w.push(void 0, null, !0, !1);
var y = w.length;
function g(e) {
y === w.length && w.push(w.length + 1);
let t = y;
return y = w[t],
w[t] = e,
t
}
function c(e) {
return w[e]
}
function z(e) {
e < 132 || (w[e] = y,
y = e)
}
function u(e) {
let t = c(e);
return z(e),
t
}
var m = 0
, l = null;
function x() {
return (l === null || l.byteLength === 0) && (l = new Uint8Array(r.memory.buffer)),
l
}
var A = new TextEncoder("utf-8")
, P = typeof A.encodeInto == "function" ? function (e, t) {
return A.encodeInto(e, t)
}
: function (e, t) {
let n = A.encode(e);
return t.set(n),
{
read: e.length,
written: n.length
}
}
;
function k(e, t, n) {
if (n === void 0) {
let a = A.encode(e)
, f = t(a.length);
return x().subarray(f, f + a.length).set(a),
m = a.length,
f
}
let i = e.length
, o = t(i)
, b = x()
, _ = 0;
for (; _ < i; _++) {
let a = e.charCodeAt(_);
if (a > 127)
break;
b[o + _] = a
}
if (_ !== i) {
_ !== 0 && (e = e.slice(_)),
o = n(o, i, i = _ + e.length * 3);
let a = x().subarray(o + _, o + i)
, f = P(e, a);
_ += f.written
}
return m = _,
o
}
function j(e) {
return e == null
}
var h = null;
function s() {
return (h === null || h.byteLength === 0) && (h = new Int32Array(r.memory.buffer)),
h
}
var B = new TextDecoder("utf-8", {
ignoreBOM: !0,
fatal: !0
});
B.decode();
function W(e, t) {
return B.decode(x().subarray(e, e + t))
}
function F(e, t) {
if (!(e instanceof t))
throw new Error(`expected instance of ${t.name}`);
return e.ptr
}
var d = class {
static __wrap(t) {
let n = Object.create(d.prototype);
return n.ptr = t,
n
}
__destroy_into_raw() {
let t = this.ptr;
return this.ptr = 0,
t
}
free() {
let t = this.__destroy_into_raw();
r.__wbg_bbox_free(t)
}
get x() {
return r.__wbg_get_bbox_x(this.ptr)
}
set x(t) {
r.__wbg_set_bbox_x(this.ptr, t)
}
get y() {
return r.__wbg_get_bbox_y(this.ptr)
}
set y(t) {
r.__wbg_set_bbox_y(this.ptr, t)
}
get width() {
return r.__wbg_get_bbox_width(this.ptr)
}
set width(t) {
r.__wbg_set_bbox_width(this.ptr, t)
}
get height() {
return r.__wbg_get_bbox_height(this.ptr)
}
set height(t) {
r.__wbg_set_bbox_height(this.ptr, t)
}
}
, v = class {
static __wrap(t) {
let n = Object.create(v.prototype);
return n.ptr = t,
n
}
__destroy_into_raw() {
let t = this.ptr;
return this.ptr = 0,
t
}
free() {
let t = this.__destroy_into_raw();
r.__wbg_renderedimage_free(t)
}
get width() {
return r.renderedimage_width(this.ptr) >>> 0
}
get height() {
return r.renderedimage_height(this.ptr) >>> 0
}
asPng() {
try {
let o = r.__wbindgen_add_to_stack_pointer(-16);
r.renderedimage_asPng(o, this.ptr);
var t = s()[o / 4 + 0]
, n = s()[o / 4 + 1]
, i = s()[o / 4 + 2];
if (i)
throw u(n);
return u(t)
} finally {
r.__wbindgen_add_to_stack_pointer(16)
}
}
get pixels() {
let t = r.renderedimage_pixels(this.ptr);
return u(t)
}
}
, p = class {
static __wrap(t) {
let n = Object.create(p.prototype);
return n.ptr = t,
n
}
__destroy_into_raw() {
let t = this.ptr;
return this.ptr = 0,
t
}
free() {
let t = this.__destroy_into_raw();
r.__wbg_resvg_free(t)
}
constructor(t, n) {
try {
let f = r.__wbindgen_add_to_stack_pointer(-16);
var i = j(n) ? 0 : k(n, r.__wbindgen_malloc, r.__wbindgen_realloc)
, o = m;
r.resvg_new(f, g(t), i, o);
var b = s()[f / 4 + 0]
, _ = s()[f / 4 + 1]
, a = s()[f / 4 + 2];
if (a)
throw u(_);
return p.__wrap(b)
} finally {
r.__wbindgen_add_to_stack_pointer(16)
}
}
get width() {
return r.resvg_width(this.ptr)
}
get height() {
return r.resvg_height(this.ptr)
}
render() {
try {
let o = r.__wbindgen_add_to_stack_pointer(-16);
r.resvg_render(o, this.ptr);
var t = s()[o / 4 + 0]
, n = s()[o / 4 + 1]
, i = s()[o / 4 + 2];
if (i)
throw u(n);
return v.__wrap(t)
} finally {
r.__wbindgen_add_to_stack_pointer(16)
}
}
toString() {
try {
let i = r.__wbindgen_add_to_stack_pointer(-16);
r.resvg_toString(i, this.ptr);
var t = s()[i / 4 + 0]
, n = s()[i / 4 + 1];
return W(t, n)
} finally {
r.__wbindgen_add_to_stack_pointer(16),
r.__wbindgen_free(t, n)
}
}
innerBBox() {
let t = r.resvg_innerBBox(this.ptr);
return t === 0 ? void 0 : d.__wrap(t)
}
getBBox() {
let t = r.resvg_getBBox(this.ptr);
return t === 0 ? void 0 : d.__wrap(t)
}
cropByBBox(t) {
F(t, d),
r.resvg_cropByBBox(this.ptr, t.ptr)
}
imagesToResolve() {
try {
let o = r.__wbindgen_add_to_stack_pointer(-16);
r.resvg_imagesToResolve(o, this.ptr);
var t = s()[o / 4 + 0]
, n = s()[o / 4 + 1]
, i = s()[o / 4 + 2];
if (i)
throw u(n);
return u(t)
} finally {
r.__wbindgen_add_to_stack_pointer(16)
}
}
resolveImage(t, n) {
try {
let b = r.__wbindgen_add_to_stack_pointer(-16)
, _ = k(t, r.__wbindgen_malloc, r.__wbindgen_realloc)
, a = m;
r.resvg_resolveImage(b, this.ptr, _, a, g(n));
var i = s()[b / 4 + 0]
, o = s()[b / 4 + 1];
if (o)
throw u(i)
} finally {
r.__wbindgen_add_to_stack_pointer(16)
}
}
}
;
async function N(e, t) {
if (typeof Response == "function" && e instanceof Response) {
if (typeof WebAssembly.instantiateStreaming == "function")
try {
return await WebAssembly.instantiateStreaming(e, t)
} catch (i) {
if (e.headers.get("Content-Type") != "application/wasm")
console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n", i);
else
throw i
}
let n = await e.arrayBuffer();
return await WebAssembly.instantiate(n, t)
} else {
let n = await WebAssembly.instantiate(e, t);
return n instanceof WebAssembly.Instance ? {
instance: n,
module: e
} : n
}
}
function q() {
let e = {};
return e.wbg = {},
e.wbg.__wbg_new_15d3966e9981a196 = function (t, n) {
let i = new Error(W(t, n));
return g(i)
}
,
e.wbg.__wbindgen_memory = function () {
let t = r.memory;
return g(t)
}
,
e.wbg.__wbg_buffer_cf65c07de34b9a08 = function (t) {
let n = c(t).buffer;
return g(n)
}
,
e.wbg.__wbg_newwithbyteoffsetandlength_9fb2f11355ecadf5 = function (t, n, i) {
let o = new Uint8Array(c(t), n >>> 0, i >>> 0);
return g(o)
}
,
e.wbg.__wbindgen_object_drop_ref = function (t) {
u(t)
}
,
e.wbg.__wbg_new_537b7341ce90bb31 = function (t) {
let n = new Uint8Array(c(t));
return g(n)
}
,
e.wbg.__wbg_instanceof_Uint8Array_01cebe79ca606cca = function (t) {
let n;
try {
n = c(t) instanceof Uint8Array
} catch (o) {
n = !1
}
return n
}
,
e.wbg.__wbindgen_string_get = function (t, n) {
let i = c(n)
, o = typeof i == "string" ? i : void 0;
var b = j(o) ? 0 : k(o, r.__wbindgen_malloc, r.__wbindgen_realloc)
, _ = m;
s()[t / 4 + 1] = _,
s()[t / 4 + 0] = b
}
,
e.wbg.__wbg_new_b525de17f44a8943 = function () {
let t = new Array;
return g(t)
}
,
e.wbg.__wbindgen_string_new = function (t, n) {
let i = W(t, n);
return g(i)
}
,
e.wbg.__wbg_push_49c286f04dd3bf59 = function (t, n) {
return c(t).push(c(n))
}
,
e.wbg.__wbg_length_27a2afe8ab42b09f = function (t) {
return c(t).length
}
,
e.wbg.__wbg_set_17499e8aa4003ebd = function (t, n, i) {
c(t).set(c(n), i >>> 0)
}
,
e.wbg.__wbindgen_throw = function (t, n) {
throw new Error(W(t, n))
}
,
e
}
function D(e, t) {
return r = e.exports,
R.__wbindgen_wasm_module = t,
h = null,
l = null,
r
}
async function R(e) {
typeof e == "undefined" && (e = new URL("index_bg.wasm", void 0));
let t = q();
(typeof e == "string" || typeof Request == "function" && e instanceof Request || typeof URL == "function" && e instanceof URL) && (e = fetch(e));
let { instance: n, module: i } = await N(await e, t);
return D(n, i)
}
var M = R;
var O = !1
, H = async e => {
if (O)
throw new Error("Already initialized. The `initWasm()` function can be used only once.");
await M(await e),
O = !0
}
, J = class extends p {
constructor(e, t) {
if (!O)
throw new Error("Wasm has not been initialized. Call `initWasm()` function.");
super(e, JSON.stringify(t))
}
}
;
return C(V);
}
)();
export default {
...resvg
}
\ No newline at end of file
import { createApp } from 'vue'
import App from './App.vue'
import install from './install'
import './permission'
import './styles/index.scss'
import 'virtual:svg-icons-register'
const app = createApp(App)
app.use(install)
app.mount('#app')
/**
* 权限控制
*/
import NProgress from 'nprogress'
import router, { findFirstValidRoute } from './router'
import 'nprogress/nprogress.css'
import { isExternal } from './utils/validate'
import useUserStore from './stores/modules/user/user'
import { INDEX_ROUTE, INDEX_ROUTE_NAME } from './router/routes'
import { PageEnum } from './enums/pageEnum'
import useTabsStore from './stores/modules/multipleTabs'
import { clearAuthInfo } from './utils/auth'
import config from './config'
// NProgress配置
NProgress.configure({ showSpinner: false })
const loginPath = PageEnum.LOGIN
const defaultPath = PageEnum.INDEX
// 免登录白名单
const whiteList: string[] = [PageEnum.LOGIN, PageEnum.ERROR_403]
router.beforeEach(async (to, from, next) => {
// 开始 Progress Bar
NProgress.start()
document.title = to.meta.title ?? config.title
const userStore = useUserStore()
const tabsStore = useTabsStore()
if (whiteList.includes(to.path)) {
// 在免登录白名单,直接进入
next()
} else if (userStore.token) {
// 获取用户信息
const hasGetUserInfo = Object.keys(userStore.userInfo).length !== 0
if (hasGetUserInfo) {
if (to.path === loginPath) {
next({ path: defaultPath })
} else {
next()
}
} else {
try {
await userStore.getUserInfo()
const routes = userStore.routes
// 找到第一个有效路由
const routeName = findFirstValidRoute(routes)
// 没有有效路由跳转到403页面
if (!routeName) {
clearAuthInfo()
next(PageEnum.ERROR_403)
return
}
tabsStore.setRouteName(routeName!)
INDEX_ROUTE.redirect = { name: routeName }
// 动态添加index路由
router.addRoute(INDEX_ROUTE)
routes.forEach((route: any) => {
// https 则不插入
if (isExternal(route.path)) {
return
}
if (!route.children) {
router.addRoute(INDEX_ROUTE_NAME, route)
return
}
// 动态添加可访问路由表
router.addRoute(route)
})
next({ ...to, replace: true })
} catch (err) {
clearAuthInfo()
next({ path: loginPath, query: { redirect: to.fullPath } })
}
}
} else {
next({ path: loginPath, query: { redirect: to.fullPath } })
}
})
router.afterEach(() => {
NProgress.done()
})
import { createRouter, createWebHistory, RouterView, type RouteRecordRaw } from 'vue-router'
import { MenuEnum } from '@/enums/appEnums'
import { isExternal } from '@/utils/validate'
import { constantRoutes, INDEX_ROUTE_NAME, LAYOUT } from './routes'
import useUserStore from '@/stores/modules/user/user'
// 匹配views里面所有的.vue文件,动态引入
const modules = import.meta.glob('/src/views/**/*.vue')
//
export function getModulesKey() {
return Object.keys(modules).map((item) => item.replace('/src/views/', '').replace('.vue', ''))
}
//没有权限的menu 不显示
function pathAuth(routes: any[], perms: any[]) {
for (let i = 0; i < routes.length; i++) {
const route = routes[i];
if (route.perms) {
const index = perms.indexOf(route.perms);
if (index == -1) {
routes.splice(i, 1);
}
}
if (route.children != null && route.children && route.children.length) {
pathAuth(route.children, perms)
}
}
}
// 过滤路由所需要的数据
export function filterAsyncRoutes(routes: any[], firstRoute = true, perms: any[]) {
pathAuth(routes, perms);
return routes.map((route) => {
// if (route.perms) {
// }
const routeRecord = createRouteRecord(route, firstRoute)
if (route.children != null && route.children && route.children.length) {
routeRecord.children = filterAsyncRoutes(route.children, false, perms)
}
return routeRecord
})
}
// 创建一条路由记录
export function createRouteRecord(route: any, firstRoute: boolean): RouteRecordRaw {
//@ts-ignore
const routeRecord: RouteRecordRaw = {
path: isExternal(route.paths) ? route.paths : firstRoute ? `/${route.paths}` : route.paths,
name: Symbol(route.paths),
meta: {
hidden: !route.is_show,
keepAlive: !!route.is_cache,
title: route.name,
perms: route.perms,
query: route.params,
icon: route.icon,
type: route.type,
activeMenu: route.selected
}
}
switch (route.type) {
case MenuEnum.CATALOGUE:
routeRecord.component = firstRoute ? LAYOUT : RouterView
if (!route.children) {
routeRecord.component = RouterView
}
break
case MenuEnum.MENU:
routeRecord.component = loadRouteView(route.component)
break
}
return routeRecord
}
// 动态加载组件
export function loadRouteView(component: string) {
try {
const key = Object.keys(modules).find((key) => {
return key.includes(`${component}.vue`)
})
if (key) {
return modules[key]
}
throw Error(`找不到组件${component},请确保组件路径正确`)
} catch (error) {
console.error(error)
return RouterView
}
}
// 找到第一个有效的路由
export function findFirstValidRoute(routes: RouteRecordRaw[]): string | undefined {
for (const route of routes) {
if (route.meta?.type == MenuEnum.MENU && !route.meta?.hidden && !isExternal(route.path)) {
return route.name as string
}
if (route.children) {
const name = findFirstValidRoute(route.children)
if (name) {
return name
}
}
}
}
//通过权限字符查询路由路径
export function getRoutePath(perms: string) {
const routerObj = useRouter() || router
return routerObj.getRoutes().find((item) => item.meta?.perms == perms)?.path || ''
}
// 重置路由
export function resetRouter() {
router.removeRoute(INDEX_ROUTE_NAME)
const { routes } = useUserStore()
routes.forEach((route) => {
const name = route.name
if (name && router.hasRoute(name)) {
router.removeRoute(name)
}
})
}
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes: constantRoutes
})
export default router
const menu: any[] = [
{
"type": "C",
"name": "工作台",
"icon": "el-icon-Monitor",
"sort": 1000,
"perms": "",
"paths": "workbench",
"component": "workbench/index",
"selected": "",
"params": "",
"is_cache": 0,
"is_show": 1,
"is_disable": 0
},
{
"type": "M",
"name": "模板管理",
"icon": "el-icon-ShoppingBag",
"sort": 900,
"perms": "",
"paths": "product",
"component": "",
"selected": "",
"params": "",
"is_cache": 0,
"is_show": 1,
"is_disable": 0,
"children": [
{
"type": "C",
"name": "模板分类",
"icon": "el-icon-FolderRemove",
"sort": 0,
"perms": "",
"paths": "fenlei",
"component": "product/fenlei/index",
"selected": "",
"params": "",
"is_cache": 0,
"is_show": 1,
"is_disable": 0,
},
{
"type": "C",
"name": "模板列表",
"icon": "el-icon-DocumentCopy",
"sort": 0,
"perms": "",
"paths": "lists",
"component": "product/lists/index",
"selected": "",
"params": "",
"is_cache": 0,
"is_show": 1,
"is_disable": 0,
},
{
"type": "C",
"name": "创建层面",
"icon": "el-icon-FolderRemove",
"sort": 0,
"perms": "",
"paths": "face",
"component": "product/face/index",
"selected": "/product/lists",
"params": "",
"is_cache": 0,
"is_show": 0,
"is_disable": 0,
},
{
"type": "C",
"name": "创建效果图",
"icon": "el-icon-FolderRemove",
"sort": 0,
"perms": "",
"paths": "xiaoguotu",
"component": "product/xiaoguotu/index",
"selected": "/product/lists",
"params": "",
"is_cache": 0,
"is_show": 0,
"is_disable": 0,
},
{
"type": "C",
"name": "创建尺码",
"icon": "el-icon-FolderRemove",
"sort": 0,
"perms": "",
"paths": "chima",
"component": "product/chima/index",
"selected": "/product/lists",
"params": "",
"is_cache": 0,
"is_show": 0,
"is_disable": 0,
}
]
},
{
"type": "M",
"name": "图库管理",
"icon": "el-icon-Picture",
"sort": 900,
"perms": "",
"paths": "image",
"component": "",
"selected": "",
"params": "",
"is_cache": 0,
"is_show": 1,
"is_disable": 0,
"children": [
{
"type": "C",
"name": "图库分类",
"icon": "el-icon-FolderRemove",
"sort": 0,
"perms": "",
"paths": "fenlei",
"component": "image/fenlei/index",
"selected": "",
"params": "",
"is_cache": 0,
"is_show": 1,
"is_disable": 0,
},
{
"type": "C",
"name": "图库列表",
"icon": "el-icon-DocumentCopy",
"sort": 0,
"perms": "",
"paths": "lists",
"component": "image/lists/index",
"selected": "",
"params": "",
"is_cache": 0,
"is_show": 1,
"is_disable": 0,
}
]
},
{
"type": "C",
"name": "用户管理",
"icon": "el-icon-User",
"sort": 900,
"perms": "",
"paths": "member/lists",
"component": "member/lists/index",
"selected": "",
"params": "",
"is_cache": 0,
"is_show": 1,
"is_disable": 0
},
{
"type": "C",
"name": "用户保存记录",
"icon": "el-icon-MessageBox",
"sort": 900,
"perms": "",
"paths": "userSave/lists",
"component": "userSave/lists/index",
"selected": "",
"params": "",
"is_cache": 0,
"is_show": 1,
"is_disable": 0
},
{
"type": "C",
"name": "用户保存记录详情",
"icon": "el-icon-MessageBox",
"sort": 900,
"perms": "",
"paths": "userSave/lists/item",
"component": "userSave/item/index",
"selected": "/userSave/lists",
"params": "",
"is_cache": 0,
"is_show": 0,
"is_disable": 0
},
{
"type": "C",
"name": "下载记录",
"icon": "el-icon-Folder",
"sort": 900,
"perms": "",
"paths": "userSaveDown/lists",
"component": "userSaveDown/lists/index",
"selected": "",
"params": "",
"is_cache": 0,
"is_show": 1,
"is_disable": 0
}
]
export default menu
\ No newline at end of file
/**
* Note: 路由配置项
*
* path: '/path' // 路由路径
* name:'router-name' // 设定路由的名字,一定要填写不然使用<keep-alive>时会出现各种问题
* meta : {
title: 'title' // 设置该路由在侧边栏的名字
icon: 'icon-name' // 设置该路由的图标
activeMenu: '/system/user' // 当路由设置了该属性,则会高亮相对应的侧边栏。
query: '{"id": 1}' // 访问路由的默认传递参数
hidden: true // 当设置 true 的时候该路由不会在侧边栏出现
hideTab: true //当设置 true 的时候该路由不会在多标签tab栏出现
}
*/
import type { RouteRecordRaw } from 'vue-router'
import { PageEnum } from '@/enums/pageEnum'
import Layout from '@/layout/default/index.vue'
export const LAYOUT = () => Promise.resolve(Layout)
export const INDEX_ROUTE_NAME = Symbol()
export const constantRoutes: Array<RouteRecordRaw> = [
{
path: '/:pathMatch(.*)*',
component: () => import('@/views/error/404.vue')
},
{
path: PageEnum.ERROR_403,
component: () => import('@/views/error/403.vue')
},
{
path: PageEnum.LOGIN,
component: () => import('@/views/account/login.vue')
},
{
path: '/user',
component: LAYOUT,
children: [
{
path: 'setting',
component: () => import('@/views/user/setting.vue'),
name: Symbol(),
meta: {
title: '个人设置'
}
}
]
},
// {
// path: '/dev_tools',
// component: LAYOUT,
// children: [
// {
// path: 'code/edit',
// component: () => import('@/views/dev_tools/code/edit.vue'),
// meta: {
// title: '编辑数据表',
// activeMenu: '/dev_tools/code'
// }
// }
// ]
// },
// {
// path: '/setting',
// component: LAYOUT,
// children: [
// {
// path: 'dict/data',
// component: () => import('@/views/setting/dict/data/index.vue'),
// meta: {
// title: '数据管理',
// activeMenu: '/setting/dict'
// }
// }
// ]
// }
]
export const INDEX_ROUTE: RouteRecordRaw = {
path: PageEnum.INDEX,
component: LAYOUT,
name: INDEX_ROUTE_NAME
}
import { createPinia } from 'pinia'
const store = createPinia()
export default store
import { defineStore } from 'pinia'
import Config from "@/config/index"
import {getImageUrl} from "@/utils/getImgUrl"
interface AppSate {
config: Record<string, any>
isMobile: boolean
isCollapsed: boolean
isRouteShow: boolean
isResvg: boolean
}
const useAppStore = defineStore({
id: 'app',
state: (): AppSate => {
return {
config: {},
isMobile: true,
isCollapsed: false,
isRouteShow: true,
isResvg: false
}
},
actions: {
setResvg(val: boolean) {
this.isResvg = val;
},
getImageUrl(url: string) {
return getImageUrl(url)
},
getConfig() {
this.config = Config;
return Config;
},
setMobile(value: boolean) {
this.isMobile = value
},
toggleCollapsed(toggle?: boolean) {
this.isCollapsed = toggle ?? !this.isCollapsed
},
refreshView() {
this.isRouteShow = false
nextTick(() => {
this.isRouteShow = true
})
}
}
})
export default useAppStore
import { defineStore } from 'pinia'
import { isExternal } from '@/utils/validate'
import type {
LocationQuery,
RouteLocationNormalized,
RouteParamsRaw,
Router,
RouteRecordName
} from 'vue-router'
import { PageEnum } from '@/enums/pageEnum'
interface TabItem {
name: RouteRecordName
fullPath: string
path: string
title?: string
query?: LocationQuery
params?: RouteParamsRaw
}
interface TabsSate {
cacheTabList: Set<string>
tabList: TabItem[]
tasMap: Record<string, TabItem>
indexRouteName: RouteRecordName
}
const getHasTabIndex = (fullPath: string, tabList: TabItem[]) => {
return tabList.findIndex((item) => item.fullPath == fullPath)
}
const isCannotAddRoute = (route: RouteLocationNormalized, router: Router) => {
const { path, meta, name } = route
if (!path || isExternal(path)) return true
if (meta?.hideTab) return true
if (!router.hasRoute(name!)) return true
if (([PageEnum.LOGIN, PageEnum.ERROR_403] as string[]).includes(path)) {
return true
}
return false
}
const findTabsIndex = (fullPath: string, tabList: TabItem[]) => {
return tabList.findIndex((item) => item.fullPath === fullPath)
}
const getComponentName = (route: RouteLocationNormalized) => {
return route.matched.at(-1)?.components?.default?.name
}
export const getRouteParams = (tabItem: TabItem) => {
const { params, path, query } = tabItem
return {
params: params || {},
path,
query: query || {}
}
}
const useTabsStore = defineStore({
id: 'tabs',
state: (): TabsSate => ({
cacheTabList: new Set(),
tabList: [],
tasMap: {},
indexRouteName: ''
}),
getters: {
getTabList(): TabItem[] {
return this.tabList
},
getCacheTabList(): string[] {
return Array.from(this.cacheTabList)
}
},
actions: {
setRouteName(name: RouteRecordName) {
this.indexRouteName = name
},
addCache(componentName?: string) {
if (componentName) this.cacheTabList.add(componentName)
},
removeCache(componentName?: string) {
if (componentName && this.cacheTabList.has(componentName)) {
this.cacheTabList.delete(componentName)
}
},
clearCache() {
this.cacheTabList.clear()
},
resetState() {
this.cacheTabList = new Set()
this.tabList = []
this.tasMap = {}
this.indexRouteName = ''
},
addTab(router: Router) {
const route = unref(router.currentRoute)
const { name, query, meta, params, fullPath, path } = route
if (isCannotAddRoute(route, router)) return
const hasTabIndex = getHasTabIndex(fullPath!, this.tabList)
const componentName = getComponentName(route)
const tabItem = {
name: name!,
path,
fullPath,
title: meta?.title,
query,
params
}
this.tasMap[fullPath] = tabItem
if (meta?.keepAlive) {
console.log(componentName)
this.addCache(componentName)
}
if (hasTabIndex != -1) {
return
}
this.tabList.push(tabItem)
},
removeTab(fullPath: string, router: Router) {
const { currentRoute, push } = router
const index = findTabsIndex(fullPath, this.tabList)
// 移除tab
if (this.tabList.length > 1) {
index !== -1 && this.tabList.splice(index, 1)
}
const componentName = getComponentName(currentRoute.value)
this.removeCache(componentName)
if (fullPath !== currentRoute.value.fullPath) {
return
}
// 删除选中的tab
let toTab: TabItem | null = null
if (index === 0) {
toTab = this.tabList[index]
} else {
toTab = this.tabList[index - 1]
}
const toRoute = getRouteParams(toTab)
push(toRoute)
},
removeOtherTab(route: RouteLocationNormalized) {
this.tabList = this.tabList.filter((item) => item.fullPath == route.fullPath)
const componentName = getComponentName(route)
this.cacheTabList.forEach((name) => {
if (componentName !== name) {
this.removeCache(name)
}
})
},
removeAllTab(router: Router) {
const { push, currentRoute } = router
const { name } = unref(currentRoute)
if (name == this.indexRouteName) {
this.removeOtherTab(currentRoute.value)
return
}
this.tabList = []
this.clearCache()
push(PageEnum.INDEX)
}
}
})
export default useTabsStore
import { defineStore } from 'pinia'
import defaultSetting from '@/config/setting'
import cache from '@/utils/cache'
import { isObject } from '@vue/shared'
import { setTheme } from '@/utils/theme'
import { SETTING_KEY } from '@/enums/cacheEnums'
const storageSetting = cache.get(SETTING_KEY)
export const useSettingStore = defineStore({
id: 'setting',
state: () => {
const state = {
showDrawer: false,
...defaultSetting
}
isObject(storageSetting) && Object.assign(state, storageSetting)
return state
},
actions: {
// 设置布局设置
setSetting(data: Record<string, any>) {
const { key, value } = data
if (this.hasOwnProperty(key)) {
//@ts-ignore
this[key] = value
}
const settings: any = Object.assign({}, this.$state)
delete settings.showDrawer
cache.set(SETTING_KEY, settings)
},
// 设置主题色
setTheme(isDark: boolean) {
setTheme(
{
primary: this.theme,
success: this.successTheme,
warning: this.warningTheme,
danger: this.dangerTheme,
error: this.errorTheme,
info: this.infoTheme
},
isDark
)
},
resetTheme() {
for (const key in defaultSetting) {
//@ts-ignore
this[key] = defaultSetting[key]
}
cache.remove(SETTING_KEY)
}
}
})
export default useSettingStore
//大鹅
export const shopType1 = [
//优惠券
'marketing.coupon',
//分销商
'fenxiaoshang',
//分销商首页banner 控制显示隐藏
'fenxiaoshang.indexBanner',
//用户设计设置成产品
'shezhichanpin',
// 设计师相关权限 (申请,通过)
'shejishi',
//设计师首页banner 控制显示隐藏
'shejishi.indexBanner',
//首页广告
'indexAd',
//商品折扣功能
'zhekou'
];
// 随艺小程序
export const shopType2 = [
'marketing.huodong',
'marketing.zuopin',
//用户设计小程序显示功能
'xiaochengxuxianshi'
];
// 次元派
export const shopType3 = [
'marketing.coupon',
'fenxiaoshang',
//用户设计设置成产品
'shezhichanpin',
// 设计师相关权限 (申请,通过)
'shejishi'
];
//定制酒
export const shopType4 = [
'marketing.coupon',
'fenxiaoshang',
]
import { defineStore } from 'pinia'
import cache from '@/utils/cache'
import type { RouteRecordRaw } from 'vue-router'
import { getUserInfo, login } from '@/api/user'
import router, { filterAsyncRoutes } from '@/router'
import { TOKEN_KEY } from '@/enums/cacheEnums'
import { PageEnum } from '@/enums/pageEnum'
import { clearAuthInfo, getToken } from '@/utils/auth'
import menu from '@/router/menu'
import { shopType1, shopType2, shopType3, shopType4 } from "./auth"
export interface UserState {
token: string
userInfo: Record<string, any>
routes: RouteRecordRaw[]
perms: string[]
}
const useUserStore = defineStore({
id: 'user',
state: (): UserState => ({
token: getToken() || '',
// 用户信息
userInfo: {},
// 路由
routes: [],
// 权限
perms: []
}),
getters: {},
actions: {
resetState() {
this.token = ''
this.userInfo = {}
this.perms = []
},
login(playload: any) {
const { name, password } = playload
return new Promise((resolve, reject) => {
login({
name: name.trim(),
password: password
})
.then((res) => {
this.token = res.data.token
cache.set(TOKEN_KEY, res.data.token)
resolve(res.data)
})
.catch((error) => {
reject(error)
})
})
},
async logout() {
this.token = ''
await router.push(PageEnum.LOGIN)
clearAuthInfo()
},
getUserInfo() {
return new Promise((resolve, reject) => {
getUserInfo()
.then((res: any) => {
this.userInfo = res.data;
let perms = ['*'];
this.perms = perms;
this.routes = filterAsyncRoutes(menu, true, this.perms);
resolve({
...res.data,
permissions: [],
menu
})
})
.catch((error) => {
reject(error)
})
})
}
}
})
export default useUserStore
:root.dark {
color-scheme: dark;
--table-header-bg-color: var(--el-bg-color);
--el-bg-color-page: #0a0a0a;
--el-bg-color: #1d2124;
--el-bg-color-overlay: #1d1e1f;
--el-text-color-primary: #e5eaf3;
--el-text-color-regular: #cfd3dc;
--el-text-color-secondary: #a3a6ad;
--el-text-color-placeholder: #8d9095;
--el-text-color-disabled: #6c6e72;
--el-border-color-darker: #636466;
--el-border-color-dark: #58585b;
--el-border-color: #4c4d4f;
--el-border-color-light: #414243;
--el-border-color-lighter: #363637;
--el-border-color-extra-light: #2b2b2c;
--el-fill-color-darker: #424243;
--el-fill-color-dark: #39393a;
--el-fill-color: #303030;
--el-fill-color-light: #262727;
--el-fill-color-lighter: #1d1d1d;
--el-fill-color-extra-light: #191919;
--el-fill-color-blank: var(--el-bg-color);
--el-mask-color: rgba(0, 0, 0, 0.8);
--el-mask-color-extra-light: rgba(0, 0, 0, 0.3);
--el-box-shadow: 0px 12px 32px 4px rgba(0, 0, 0, 0.36), 0px 8px 20px rgba(0, 0, 0, 0.72);
--el-box-shadow-light: 0px 0px 12px rgba(0, 0, 0, 0.72);
--el-box-shadow-lighter: 0px 0px 6px rgba(0, 0, 0, 0.72);
--el-box-shadow-dark: 0px 16px 48px 16px rgba(0, 0, 0, 0.72), 0px 12px 32px #000000,
0px 8px 16px -8px #000000 !important;
/* wangeditor主题 */
--w-e-textarea-bg-color: var(--el-bg-color);
--w-e-textarea-color: var(--el-text-color-primary);
--w-e-textarea-border-color: var(--el-border-color);
--w-e-textarea-slight-border-color: var(--el-border-color-light);
--w-e-textarea-slight-color: var(--el-border-color);
--w-e-textarea-slight-bg-color: var(--el-bg-color-page);
/* --w-e-textarea-selected-border-color: #b4d5ff;
--w-e-textarea-handler-bg-color: #4290f7; */
--w-e-toolbar-color: var(--el-text-color-primary);
--w-e-toolbar-bg-color: var(--el-bg-color);
--w-e-toolbar-active-color: var(--el-text-color-primary);
--w-e-toolbar-active-bg-color: var(--el-bg-color);
--w-e-toolbar-disabled-color: var(--el-text-color-disabled);
--w-e-toolbar-border-color: var(--el-border-color);
--w-e-modal-button-bg-color: var(--el-bg-color);
--w-e-modal-button-border-color: var(--el-border-color);
}
:root {
// 弹窗居中
.el-overlay-dialog {
display: flex;
justify-content: center;
align-items: center;
min-height: 100%;
position: static;
.el-dialog {
--el-dialog-content-font-size: var(--el-font-size-base);
--el-dialog-margin-top: 50px;
max-width: calc(100vw - 30px);
flex: none;
display: flex;
flex-direction: column;
border-radius: 5px;
&.body-padding .el-dialog__body {
padding: 0;
}
.el-dialog__body {
flex: 1;
padding: 15px 20px;
}
.el-dialog__header {
font-size: var(--el-font-size-large);
}
}
}
.el-drawer {
--el-drawer-padding-primary: 16px;
&__header {
margin-bottom: 0;
padding: 13px 16px;
border-bottom: 1px solid var(--el-border-color-lighter);
}
&__title {
@apply text-tx-primary;
}
}
.el-table {
--el-table-header-text-color: var(--el-text-color-primary);
--el-table-header-bg-color: var(--table-header-bg-color);
font-size: var(--el-font-size-base);
thead {
th {
font-weight: 400;
}
}
}
.el-input-group__prepend {
background-color: var(--el-fill-color-blank);
}
.el-checkbox {
--el-checkbox-font-size: var(--el-font-size-base);
}
.el-menu--popup-container {
&.theme-light {
.el-menu {
.el-menu-item {
&.is-active {
@apply bg-primary-light-9 border-primary border-r-2;
}
}
.el-menu-item:hover,
.el-sub-menu__title:hover {
color: var(--el-color-primary);
}
}
}
&.theme-dark {
.el-menu {
.el-menu-item {
&.is-active {
@apply bg-primary;
}
}
}
}
}
.el-message-box {
--el-messagebox-width: 350px;
}
.el-date-editor {
--el-date-editor-datetimerange-width: 380px;
.el-range-input {
font-size: var(--el-font-size-small);
}
}
.el-button--primary {
--el-button-hover-link-text-color: var(--el-color-primary-light-3);
}
.el-button--success {
--el-button-hover-link-text-color: var(--el-color-success-light-3);
}
.el-button--info {
--el-button-hover-link-text-color: var(--el-color-info-light-3);
}
.el-button--warning {
--el-button-hover-link-text-color: var(--el-color-warning-light-3);
}
.el-button--danger {
--el-button-hover-link-text-color: var(--el-color-danger-light-3);
}
.el-image__error {
font-size: 12px;
}
.el-tabs__nav-wrap::after {
height: 1px;
}
.el-page-header {
&__breadcrumb {
margin-bottom: 0;
}
}
}
@media (max-width: 768px) {
.el-pagination > .el-pagination__jump {
display: none !important;
}
.el-pagination > .el-pagination__sizes {
display: none !important;
}
}
.el-button {
// 防止被tailwindcss默认样式覆盖
background-color: var(--el-button-bg-color, var(--el-color-white));
//覆盖el-button的点击样式
&:focus {
color: var(--el-button-text-color);
border-color: var(--el-button-border-color);
background-color: var(--el-button-bg-color);
}
&:hover {
color: var(--el-button-hover-text-color);
border-color: var(--el-button-hover-border-color);
background-color: var(--el-button-hover-bg-color);
}
}
@import 'element.scss';
@import 'dark.css';
@import 'var.css';
@import 'tailwind.css';
@import 'public.scss';
body {
@apply text-base text-tx-primary overflow-hidden min-w-[375px];
}
.form-tips {
@apply text-tx-secondary text-xs leading-6 mt-1;
}
.clearfix:after {
content: '';
display: block;
clear: both;
visibility: hidden;
}
/* NProgress */
#nprogress .bar {
@apply bg-primary #{!important};
}
.link {
color: var(--el-color-primary);
}
.table_base {
th,
td {
padding: 10px;
border: 1px #ddd solid;
}
}
.padding-none .el-card__body {
padding: 0;
}
\ No newline at end of file
@tailwind base;
@tailwind components;
@tailwind utilities;
\ No newline at end of file
:root {
--el-font-family: theme(fontFamily.sans);
--el-font-weight-primary: 400;
--el-menu-item-height: 46px;
--el-menu-sub-item-height: var(--el-menu-item-height);
--el-menu-icon-width: 18px;
--aside-width: 200px;
--navbar-height: 50px;
--color-white: #ffffff;
--table-header-bg-color: #f8f8f8;
--el-font-size-extra-large: 18px;
--el-menu-base-level-padding: 16px;
--el-menu-level-padding: 26px;
--el-font-size-large: 16px;
--el-font-size-medium: 15px;
--el-font-size-base: 14px;
--el-font-size-small: 13px;
--el-font-size-extra-small: 12px;
--el-bg-color: var(--color-white);
--el-bg-color-page: #f6f6f6;
--el-bg-color-overlay: #ffffff;
--el-text-color-primary: #333333;
--el-text-color-regular: #666666;
--el-text-color-secondary: #999999;
--el-text-color-placeholder: #a8abb2;
--el-text-color-disabled: #c0c4cc;
--el-border-color: #dcdfe6;
--el-border-color-light: #e4e7ed;
--el-border-color-lighter: #ebeef5;
--el-border-color-extra-light: #f2f2f2;
--el-border-color-dark: #d4d7de;
--el-border-color-darker: #cdd0d6;
--el-fill-color: #f0f2f5;
--el-fill-color-light: #f8f8f8;
--el-fill-color-lighter: #fafafa;
--el-fill-color-extra-light: #fafcff;
--el-fill-color-dark: #ebedf0;
--el-fill-color-darker: #e6e8eb;
--el-fill-color-blank: #ffffff;
--el-mask-color: rgba(255, 255, 255, 0.9);
--el-mask-color-extra-light: rgba(255, 255, 255, 0.3);
-el-box-shadow: 0px 12px 32px 4px rgba(0, 0, 0, 0.04), 0px 8px 20px rgba(0, 0, 0, 0.08);
--el-box-shadow-light: 0px 0px 12px rgba(0, 0, 0, 0.12);
--el-box-shadow-lighter: 0px 0px 6px rgba(0, 0, 0, 0.12);
--el-box-shadow-dark: 0px 16px 48px 16px rgba(0, 0, 0, 0.08), 0px 12px 32px rgba(0, 0, 0, 0.12),
0px 8px 16px -8px rgba(0, 0, 0, 0.16);
}
import { TOKEN_KEY } from '@/enums/cacheEnums'
import { resetRouter } from '@/router'
import useTabsStore from '@/stores/modules/multipleTabs'
import useUserStore from '@/stores/modules/user/user'
import cache from './cache'
export function getToken() {
return cache.get(TOKEN_KEY)
}
export function clearAuthInfo() {
const userStore = useUserStore()
const tabsStore = useTabsStore()
userStore.resetState()
tabsStore.resetState()
cache.remove(TOKEN_KEY)
resetRouter()
}
const cache = {
key: 'foxpsd_shopping_admin_',
//设置缓存(expire为缓存时效)
set(key: string, value: any, expire?: string) {
key = this.getKey(key)
let data: any = {
expire: expire ? this.time() + expire : '',
value
}
if (typeof data === 'object') {
data = JSON.stringify(data)
}
try {
window.localStorage.setItem(key, data)
} catch (e) {
return null
}
},
get(key: string) {
key = this.getKey(key)
try {
const data = window.localStorage.getItem(key)
if (!data) {
return null
}
const { value, expire } = JSON.parse(data)
if (expire && expire < this.time()) {
window.localStorage.removeItem(key)
return null
}
return value
} catch (e) {
return null
}
},
//获取当前时间
time() {
return Math.round(new Date().getTime() / 1000)
},
remove(key: string) {
key = this.getKey(key)
window.localStorage.removeItem(key)
},
clear() {
window.localStorage.clear()
},
getKey(key: string) {
return this.key + key
}
}
export default cache
/**
* @description: 开发模式
*/
export function isDevMode(): boolean {
return import.meta.env.DEV
}
/**
* @description: 生成模式
*/
export function isProdMode(): boolean {
return import.meta.env.PROD
}
import {
ElMessage,
ElMessageBox,
ElNotification,
ElLoading,
type ElMessageBoxOptions
} from 'element-plus'
import type { LoadingInstance } from 'element-plus/es/components/loading/src/loading'
export class Feedback {
private loadingInstance: LoadingInstance | null = null
static instance: Feedback | null = null
static getInstance() {
return this.instance ?? (this.instance = new Feedback())
}
// 消息提示
msg(msg: string) {
ElMessage.info(msg)
}
// 错误消息
msgError(msg: string) {
ElMessage.error(msg)
}
// 成功消息
msgSuccess(msg: string) {
ElMessage.success(msg)
}
// 警告消息
msgWarning(msg: string) {
ElMessage.warning(msg)
}
// 弹出提示
alert(msg: string) {
ElMessageBox.alert(msg, '系统提示')
}
// 错误提示
alertError(msg: string) {
ElMessageBox.alert(msg, '系统提示', { type: 'error' })
}
// 成功提示
alertSuccess(msg: string) {
ElMessageBox.alert(msg, '系统提示', { type: 'success' })
}
// 警告提示
alertWarning(msg: string) {
ElMessageBox.alert(msg, '系统提示', { type: 'warning' })
}
// 通知提示
notify(msg: string) {
ElNotification.info(msg)
}
// 错误通知
notifyError(msg: string) {
ElNotification.error(msg)
}
// 成功通知
notifySuccess(msg: string) {
ElNotification.success(msg)
}
// 警告通知
notifyWarning(msg: string) {
ElNotification.warning(msg)
}
// 确认窗体
confirm(msg: string) {
return ElMessageBox.confirm(msg, '温馨提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
}
// 提交内容
prompt(content: string, title: string, options?: ElMessageBoxOptions) {
return ElMessageBox.prompt(content, title, {
confirmButtonText: '确定',
cancelButtonText: '取消',
...options
})
}
// 打开全局loading
loading(msg: string) {
this.loadingInstance = ElLoading.service({
lock: true,
text: msg
})
}
// 关闭全局loading
closeLoading() {
this.loadingInstance?.close()
}
}
const feedback = Feedback.getInstance()
export default feedback
import Config from "@/config/index"
export function getImageUrl(imgUrl: string, width?: number, height?: number) {
var patt = new RegExp('http');
if (patt.test(imgUrl)) {
if(!width) return imgUrl
if (/oss/.test(imgUrl)) {
return imgUrl + '?x-oss-process=image/resize,l_' + width;
}
if (width && !height) {
return imgUrl + '?imageView2/2/w/' + width;
} else if (!width && height) {
return imgUrl + '?imageView2/2/h/' + height;
} else if (width && height) {
return imgUrl + '?imageView2/1/w/' + width + '/h/' + height;
} else {
return imgUrl;
}
} else {
return Config.baseUrl + imgUrl;
}
}
import { RequestMethodsEnum } from '@/enums/requestEnums'
import axios, {
AxiosError,
type AxiosInstance,
type AxiosRequestConfig,
type AxiosResponse
} from 'axios'
import { isFunction, merge, cloneDeep } from 'lodash'
import axiosCancel from './cancel'
import type { RequestData, RequestOptions } from './type'
export class Axios {
private axiosInstance: AxiosInstance
private readonly config: AxiosRequestConfig
private readonly options: RequestOptions
constructor(config: AxiosRequestConfig) {
this.config = config
this.options = config.requestOptions
this.axiosInstance = axios.create(config);
this.setupInterceptors()
}
/**
* @description 获取axios实例
*/
getAxiosInstance() {
return this.axiosInstance
}
/**
* @description 设置拦截器
*/
setupInterceptors() {
if (!this.config.axiosHooks) {
return
}
const {
requestInterceptorsHook,
requestInterceptorsCatchHook,
responseInterceptorsHook,
responseInterceptorsCatchHook
} = this.config.axiosHooks
this.axiosInstance.interceptors.request.use(
(config: any) => {
this.addCancelToken(config)
if (isFunction(requestInterceptorsHook)) {
config = requestInterceptorsHook(config)
}
return config
},
(err: Error) => {
if (isFunction(requestInterceptorsCatchHook)) {
requestInterceptorsCatchHook(err)
}
return err
}
)
this.axiosInstance.interceptors.response.use(
(response: AxiosResponse<RequestData>) => {
this.removeCancelToken(response.config.url!)
if (isFunction(responseInterceptorsHook)) {
response = responseInterceptorsHook(response)
}
return response
},
(err: AxiosError) => {
if (isFunction(responseInterceptorsCatchHook)) {
responseInterceptorsCatchHook(err)
}
if (err.code != AxiosError.ERR_CANCELED) {
this.removeCancelToken(err.config?.url!)
}
if (err.code == AxiosError.ECONNABORTED || err.code == AxiosError.ERR_NETWORK) {
return new Promise((resolve) => setTimeout(resolve, 500)).then(() =>
this.retryRequest(err)
)
}
return Promise.reject(err)
}
)
}
/**
* @description 添加CancelToken
*/
addCancelToken(config: AxiosRequestConfig) {
const { ignoreCancelToken } = config.requestOptions
!ignoreCancelToken && axiosCancel.add(config)
}
/**
* @description 移除CancelToken
*/
removeCancelToken(url: string) {
axiosCancel.remove(url)
}
/**
* @description 重新请求
*/
retryRequest(error: AxiosError) {
const config = error.config
const { retryCount, isOpenRetry } = config.requestOptions
if (!isOpenRetry || config.method?.toUpperCase() == RequestMethodsEnum.POST) {
return Promise.reject(error)
}
config.retryCount = config.retryCount ?? 0
if (config.retryCount >= retryCount) {
return Promise.reject(error)
}
config.retryCount++
return this.axiosInstance.request(config)
}
/**
* @description get请求
*/
get<T = any>(
config: Partial<AxiosRequestConfig>,
options?: Partial<RequestOptions>
): Promise<T> {
return this.request({ ...config, method: RequestMethodsEnum.GET }, options)
}
/**
* @description post请求
*/
post<T = any>(
config: Partial<AxiosRequestConfig>,
options?: Partial<RequestOptions>
): Promise<T> {
return this.request({ ...config, method: RequestMethodsEnum.POST }, options)
}
/**
* @description 请求函数
*/
request<T = any>(
config: Partial<AxiosRequestConfig>,
options?: Partial<RequestOptions>
): Promise<any> {
const opt: RequestOptions = merge({}, this.options, options)
const axioxConfig: AxiosRequestConfig = {
...cloneDeep(config),
requestOptions: opt
}
const { urlPrefix } = opt
// 拼接请求前缀如api
if (urlPrefix) {
axioxConfig.url = `${urlPrefix}${config.url}`
}
if (axioxConfig.requestOptions.headers) {
axioxConfig.headers = axioxConfig.requestOptions.headers;
}
return new Promise((resolve, reject) => {
this.axiosInstance
.request<any, AxiosResponse<RequestData<T>>>(axioxConfig)
.then((res) => {
resolve(res)
})
.catch((err) => {
reject(err)
})
})
}
}
import axios, { type AxiosRequestConfig, type Canceler } from 'axios'
const cancelerMap = new Map<string, Canceler>()
export class AxiosCancel {
private static instance?: AxiosCancel
static createInstance() {
return this.instance ?? (this.instance = new AxiosCancel())
}
add(config: AxiosRequestConfig) {
const url = config.url!
this.remove(url)
config.cancelToken = new axios.CancelToken((cancel) => {
if (!cancelerMap.has(url)) {
cancelerMap.set(url, cancel)
}
})
}
remove(url: string) {
if (cancelerMap.has(url)) {
const cancel = cancelerMap.get(url)
cancel && cancel(url)
cancelerMap.delete(url)
}
}
}
const axiosCancel = AxiosCancel.createInstance()
export default axiosCancel
import { merge } from 'lodash'
import configs from '@/config'
import { Axios } from './axios'
import { ContentTypeEnum, RequestMethodsEnum } from '@/enums/requestEnums'
import type { AxiosHooks } from './type'
import { clearAuthInfo, getToken } from '../auth'
import feedback from '../feedback'
import NProgress from 'nprogress'
import { AxiosError, type AxiosRequestConfig } from 'axios'
import router from '@/router'
function guolv(data:any){
let obj:any = {}
for(let key in data){
if(data[key] !=='' && data[key] !==null){
obj[key] = data[key]
}
}
return obj
}
// 处理axios的钩子函数
const axiosHooks: AxiosHooks = {
requestInterceptorsHook(config: any) {
NProgress.start()
const { withToken, isParamsToData } = config.requestOptions;
if (!config.params) config.params = {};
const params = guolv(config.params) || {};
const headers = guolv(config.headers) || {}
// POST请求下如果无data,则将params视为data
if (
isParamsToData &&
!Reflect.has(config, 'data') &&
config.method?.toUpperCase() === RequestMethodsEnum.POST
) {
config.data = params
config.params = {};
}
// 添加token
if (withToken) {
const token = getToken();
config.data = {
...config.data
}
headers['Authorization'] = token;
}
if (config.url.indexOf("/foxpsdData/") != -1) {
config.params.method = config.url.replace("/foxpsdData", "")
}
if (headers['Content-Type'] == 'application/x-www-form-urlencoded') {
const _params: any = new URLSearchParams();
for (let key in config.data) {
if (config.data[key] != null && config.data[key] != 'null') {
_params.append(key, config.data[key])
}
}
config.data = _params;
}
config.headers = headers
return config
},
requestInterceptorsCatchHook(err) {
console.log(err);
NProgress.done()
return err
},
async responseInterceptorsHook(response: any) {
NProgress.done()
const { isTransformResponse, isReturnDefaultResponse } = response.config.requestOptions
//返回默认响应,当需要获取响应头及其他数据时可使用
if (isReturnDefaultResponse) {
return response
}
// 是否需要对数据进行处理
if (!isTransformResponse) {
return response.data
}
const { msg, code } = response.data
if (code == 10001) {
feedback.msgError(msg);
if (msg == 'token已失效') {
router.push('/login');
}
return Promise.reject(response.data)
}
return response.data;
},
responseInterceptorsCatchHook(error) {
NProgress.done()
if (error.code !== AxiosError.ERR_CANCELED) {
error.message && feedback.msgError(error.message)
}
return Promise.reject(error)
}
}
const defaultOptions: AxiosRequestConfig = {
//接口超时时间
timeout: configs.timeout,
// 基础接口地址
baseURL: configs.baseUrl,
//请求头
headers: { 'Content-Type': ContentTypeEnum.FORM_URL },
// 处理 axios的钩子函数
axiosHooks: axiosHooks,
// 每个接口可以单独配置
requestOptions: {
// 是否将params视为data参数,仅限post请求
isParamsToData: true,
//是否返回默认的响应
isReturnDefaultResponse: false,
// 需要对返回数据进行处理
isTransformResponse: true,
// 接口拼接地址
urlPrefix: configs.urlPrefix,
// 忽略重复请求
ignoreCancelToken: true,
// 是否携带token
withToken: true,
// 开启请求超时重新发起请求请求机制
isOpenRetry: true,
// 重新请求次数
retryCount: 2
}
}
function createAxios(opt?: Partial<AxiosRequestConfig>) {
return new Axios(
// 深度合并
merge(defaultOptions, opt || {})
)
}
const request = createAxios()
export default request
import type { AxiosRequestConfig, AxiosResponse } from 'axios'
import 'axios'
declare module 'axios' {
// 扩展 RouteMeta
interface AxiosRequestConfig {
retryCount?: number
axiosHooks?: AxiosHooks
requestOptions: RequestOptions
}
}
export interface RequestOptions {
isParamsToData: boolean
isReturnDefaultResponse: boolean
isTransformResponse: boolean
urlPrefix: string
ignoreCancelToken: boolean
withToken: boolean
isOpenRetry: boolean
retryCount: number,
headers?: any
}
export interface AxiosHooks {
requestInterceptorsHook?: (config: AxiosRequestConfig) => AxiosRequestConfig
requestInterceptorsCatchHook?: (error: Error) => void
responseInterceptorsHook?: (
response: AxiosResponse<RequestData<T>>
) => AxiosResponse<RequestData> | RequestData | T
responseInterceptorsCatchHook?: (error: AxiosError) => void
}
export interface RequestData<T = any> {
code: number
data: T
msg: string
show: boolean
}
import colors from 'css-color-function'
const lightConfig = {
'dark-2': 'shade(20%)',
'light-3': 'tint(30%)',
'light-5': 'tint(50%)',
'light-7': 'tint(70%)',
'light-8': 'tint(80%)',
'light-9': 'tint(90%)'
}
const darkConfig = {
'light-3': 'shade(20%)',
'light-5': 'shade(30%)',
'light-7': 'shade(50%)',
'light-8': 'shade(60%)',
'light-9': 'shade(70%)',
'dark-2': 'tint(20%)'
}
const themeId = 'theme-vars'
/**
* @author Jason
* @description 用于生成elementui主题的行为变量
* 可选值有primary、success、warning、danger、error、info
*/
export const generateVars = (color: string, type = 'primary', isDark = false) => {
const colos = {
[`--el-color-${type}`]: color
}
const config: Record<string, string> = isDark ? darkConfig : lightConfig
for (const key in config) {
colos[`--el-color-${type}-${key}`] = `color(${color} ${config[key]})`
}
return colos
}
/**
* @author Jason
* @description 用于设置css变量
* @param key css变量key 如 --color-primary
* @param value css变量值 如 #f40
* @param dom dom元素
*/
export const setCssVar = (key: string, value: string, dom = document.documentElement) => {
dom.style.setProperty(key, value)
}
/**
* @author Jason
* @description 设置主题
*/
export const setTheme = (options: Record<string, string>, isDark = false) => {
const varsMap: Record<string, string> = Object.keys(options).reduce((prev, key) => {
return Object.assign(prev, generateVars(options[key], key, isDark))
}, {})
let theme = Object.keys(varsMap).reduce((prev, key) => {
const color = colors.convert(varsMap[key])
return `${prev}${key}:${color};`
}, '')
theme = `:root{${theme}}`
let style = document.getElementById(themeId)
if (style) {
style.innerHTML = theme
return
}
style = document.createElement('style')
style.setAttribute('type', 'text/css')
style.setAttribute('id', themeId)
style.innerHTML = theme
document.head.append(style)
}
import { isObject } from '@vue/shared'
import { number } from 'echarts/core'
import { cloneDeep } from 'lodash'
/**
* @description 添加单位
* @param {String | Number} value 值 100
* @param {String} unit 单位 px em rem
*/
export const addUnit = (value: string | number, unit = 'px') => {
return !Object.is(Number(value), NaN) ? `${value}${unit}` : value
}
/**
* @description 添加单位
* @param {unknown} value
* @return {Boolean}
*/
export const isEmpty = (value: unknown) => {
return value == null && typeof value == 'undefined'
}
/**
* @description 树转数组,队列实现广度优先遍历
* @param {Array} data 数据
* @param {Object} props `{ children: 'children' }`
*/
export const treeToArray = (data: any[], props = { children: 'children' }) => {
data = cloneDeep(data)
const { children } = props
const newData = []
const queue: any[] = []
data.forEach((child: any) => queue.push(child));
while (queue.length) {
const item: any = queue.shift()
if (item[children]) {
item[children].forEach((child: any) => queue.push(child))
delete item[children]
}
newData.push(item)
}
return newData
}
/**
* @description 数组转
* @param {Array} data 数据
* @param {Object} props `{ parent: 'pid', children: 'children' }`
*/
export const arrayToTree = (
data: any[],
props = { id: 'id', parentId: 'pid', children: 'children', number: 2 }
) => {
data = cloneDeep(data)
const { id, parentId, children, number } = props
const result: any[] = []
const map = new Map()
data.forEach((item) => {
map.set(item[id], item)
const parent = map.get(item[parentId])
if (parent) {
parent[children] = parent[children] ?? []
parent[children].push(item)
} else {
result.push(item)
}
})
if (number != -1) {
result.forEach((item: any) => {
if (number == 1) {
item[children] && delete item[children]
}
if (number == 2) {
if (item[children]) {
item[children].forEach((twoItem: any) => {
twoItem[children] && delete twoItem[children]
})
}
}
})
}
return result
}
/**
* @description 获取正确的路经
* @param {String} path 数据
*/
export function getNormalPath(path: string) {
if (path.length === 0 || !path || path == 'undefined') {
return path
}
const newPath = path.replace('//', '/')
const length = newPath.length
if (newPath[length - 1] === '/') {
return newPath.slice(0, length - 1)
}
return newPath
}
/**
* @description对象格式化为Query语法
* @param { Object } params
* @return {string} Query语法
*/
export function objectToQuery(params: Record<string, any>): string {
let query = ''
for (const props of Object.keys(params)) {
const value = params[props]
const part = encodeURIComponent(props) + '='
if (!isEmpty(value)) {
if (isObject(value)) {
for (const key of Object.keys(value)) {
if (!isEmpty(value[key])) {
const params = props + '[' + key + ']'
const subPart = encodeURIComponent(params) + '='
query += subPart + encodeURIComponent(value[key]) + '&'
}
}
} else {
query += part + encodeURIComponent(value) + '&'
}
}
}
return query.slice(0, -1)
}
/**
* @description 时间格式化
* @param dateTime { number } 时间戳
* @param fmt { string } 时间格式
* @return { string }
*/
// yyyy:mm:dd|yyyy:mm|yyyy年mm月dd日|yyyy年mm月dd日 hh时MM分等,可自定义组合
export const timeFormat = (dateTime: number, fmt = 'yyyy-mm-dd') => {
// 如果为null,则格式化当前时间
if (!dateTime) {
dateTime = Number(new Date())
}
// 如果dateTime长度为10或者13,则为秒和毫秒的时间戳,如果超过13位,则为其他的时间格式
if (dateTime.toString().length == 10) {
dateTime *= 1000
}
const date = new Date(dateTime)
let ret
const opt: any = {
'y+': date.getFullYear().toString(), // 年
'm+': (date.getMonth() + 1).toString(), // 月
'd+': date.getDate().toString(), // 日
'h+': date.getHours().toString(), // 时
'M+': date.getMinutes().toString(), // 分
's+': date.getSeconds().toString() // 秒
}
for (const k in opt) {
ret = new RegExp('(' + k + ')').exec(fmt)
if (ret) {
fmt = fmt.replace(
ret[1],
ret[1].length == 1 ? opt[k] : opt[k].padStart(ret[1].length, '0')
)
}
}
return fmt
}
/**
* @description 获取不重复的id
* @param length { Number } id的长度
* @return { String } id
*/
export const getNonDuplicateID = (length = 8) => {
let idStr = Date.now().toString(36)
idStr += Math.random().toString(36).substring(3, length)
return idStr
}
//加减乘除
export function numAdd(arg1: number, arg2: number): number {
var r1, r2, m, c;
try {
r1 = arg1.toString().split(".")[1].length;
}
catch (e) {
r1 = 0;
}
try {
r2 = arg2.toString().split(".")[1].length;
}
catch (e) {
r2 = 0;
}
c = Math.abs(r1 - r2);
m = Math.pow(10, Math.max(r1, r2));
if (c > 0) {
var cm = Math.pow(10, c);
if (r1 > r2) {
arg1 = Number(arg1.toString().replace(".", ""));
arg2 = Number(arg2.toString().replace(".", "")) * cm;
} else {
arg1 = Number(arg1.toString().replace(".", "")) * cm;
arg2 = Number(arg2.toString().replace(".", ""));
}
} else {
arg1 = Number(arg1.toString().replace(".", ""));
arg2 = Number(arg2.toString().replace(".", ""));
}
return (arg1 + arg2) / m;
};
/**
* 减法运算,避免数据相减小数点后产生多位数和计算精度损失。
*
* @param num1被减数 | num2减数
*/
export function numSub(num1: number, num2: number): number {
var baseNum, baseNum1, baseNum2;
var precision;// 精度
try {
baseNum1 = num1.toString().split(".")[1].length;
} catch (e) {
baseNum1 = 0;
}
try {
baseNum2 = num2.toString().split(".")[1].length;
} catch (e) {
baseNum2 = 0;
}
baseNum = Math.pow(10, Math.max(baseNum1, baseNum2));
precision = (baseNum1 >= baseNum2) ? baseNum1 : baseNum2;
return Number(((num1 * baseNum - num2 * baseNum) / baseNum).toFixed(precision));
};
/**
* 乘法运算,避免数据相乘小数点后产生多位数和计算精度损失。
*
* @param num1被乘数 | num2乘数
*/
export function numMulti(num1: number, num2: number): number {
var baseNum = 0;
try {
baseNum += num1.toString().split(".")[1].length;
} catch (e) {
}
try {
baseNum += num2.toString().split(".")[1].length;
} catch (e) {
}
return Number(num1.toString().replace(".", "")) * Number(num2.toString().replace(".", "")) / Math.pow(10, baseNum);
};
/**
* 除法运算,避免数据相除小数点后产生多位数和计算精度损失。
*
* @param num1被除数 | num2除数
*/
export function numDiv(num1: number, num2: number): number {
var baseNum1 = 0, baseNum2 = 0;
var baseNum3, baseNum4;
try {
baseNum1 = num1.toString().split(".")[1].length;
} catch (e) {
baseNum1 = 0;
}
try {
baseNum2 = num2.toString().split(".")[1].length;
} catch (e) {
baseNum2 = 0;
}
baseNum3 = Number(num1.toString().replace(".", ""));
baseNum4 = Number(num2.toString().replace(".", ""));
return (baseNum3 / baseNum4) * Math.pow(10, baseNum2 - baseNum1);
};
/**
* @param {string} path
* @returns {Boolean}
*/
export function isExternal(path: string) {
return /^(https?:|mailto:|tel:)/.test(path)
}
<template>
<div class="login flex flex-col">
<div class="flex-1 flex items-center justify-center">
<div class="login-card flex rounded-md">
<div class="flex-1 h-full hidden md:inline-block bg-[#38f]">
<image-contain
fit="cover"
:src="config.login_image"
:width="400"
height="100%"
/>
</div>
<div
class="login-form bg-body flex flex-col justify-center px-10 py-10 md:w-[400px] w-[375px] flex-none mx-auto"
>
<div class="text-center text-3xl font-medium mb-8">
{{ config.web_name }}
</div>
<el-form ref="formRef" :model="formData" size="large" :rules="rules">
<el-form-item prop="name">
<el-input
v-model="formData.name"
placeholder="请输入账号"
@keyup.enter="handleEnter"
>
<template #prepend>
<icon name="el-icon-User" />
</template>
</el-input>
</el-form-item>
<el-form-item prop="password">
<el-input
ref="passwordRef"
v-model="formData.password"
show-password
placeholder="请输入密码"
@keyup.enter="handleLogin"
>
<template #prepend>
<icon name="el-icon-Lock" />
</template>
</el-input>
</el-form-item>
</el-form>
<div class="mb-5">
<el-checkbox v-model="remAccount" label="记住账号"></el-checkbox>
</div>
<el-button
type="primary"
size="large"
:loading="isLock"
@click="lockLogin"
>
登录
</el-button>
</div>
</div>
</div>
<layout-footer />
</div>
</template>
<script lang="ts" setup>
import { computed, onMounted, reactive, ref, shallowRef } from 'vue'
import type { InputInstance, FormInstance } from 'element-plus'
import LayoutFooter from '@/layout/components/footer.vue'
import useAppStore from '@/stores/modules/app'
import useUserStore from '@/stores/modules/user/user'
import cache from '@/utils/cache'
import { ACCOUNT_KEY } from '@/enums/cacheEnums'
import { PageEnum } from '@/enums/pageEnum'
import { useLockFn } from '@/hooks/useLockFn'
const passwordRef = shallowRef<InputInstance>()
const formRef = shallowRef<FormInstance>()
const appStore = useAppStore()
const userStore = useUserStore()
const route = useRoute()
const router = useRouter()
const remAccount = ref(false)
const config = computed(() => appStore.config)
const formData = reactive({
name: '',
password: ''
})
const rules = {
name: [
{
required: true,
message: '请输入账号',
trigger: ['blur']
}
],
password: [
{
required: true,
message: '请输入密码',
trigger: ['blur']
}
]
}
// 回车按键监听
const handleEnter = () => {
if (!formData.password) {
return passwordRef.value?.focus()
}
handleLogin()
}
// 登录处理
const handleLogin = async () => {
await formRef.value?.validate()
// 记住账号,缓存
cache.set(ACCOUNT_KEY, {
remember: remAccount.value,
name: remAccount.value ? formData.name : ''
})
await userStore.login(formData)
const {
query: { redirect }
} = route
const path = typeof redirect === 'string' ? redirect : PageEnum.INDEX
router.push(path)
}
const { isLock, lockFn: lockLogin } = useLockFn(handleLogin)
onMounted(() => {
const value = cache.get(ACCOUNT_KEY)
if (value?.remember) {
remAccount.value = value.remember
formData.name = value.name
}
})
</script>
<style lang="scss" scoped>
.login {
background-image: url('./images/login_bg.png');
@apply min-h-screen bg-no-repeat bg-center bg-cover;
.login-card {
height: 400px;
}
}
</style>
<template>
<div class="error404">
<error
code="403"
title="您的账号权限不足,请联系管理员添加权限!"
:show-btn="false"
>
<template #content>
<div class="flex justify-center">
<img
class="w-[150px] h-[150px]"
src="@/assets/images/no_perms.png"
alt=""
/>
</div>
</template>
</error>
</div>
</template>
<script lang="ts" setup>
import Error from './components/error.vue'
</script>
<template>
<div class="error404">
<Error code="404" title="哎呀,出错了!您访问的页面不存在…"></Error>
</div>
</template>
<script lang="ts" setup>
import Error from './components/error.vue'
</script>
<template>
<div class="error">
<div>
<slot name="content">
<div class="error-code">{{ code }}</div>
</slot>
<div class="text-lg text-tx-secondary mt-7 mb-7">{{ title }}</div>
<el-button v-if="showBtn" type="primary" @click="router.go(-1)">
{{ second }} 秒后返回上一页
</el-button>
</div>
</div>
</template>
<script lang="ts" setup>
import { onUnmounted, ref } from 'vue'
import { useRouter } from 'vue-router'
const props = defineProps({
code: String,
title: String,
showBtn: {
type: Boolean,
default: true
}
})
let timer: any = null
const second = ref(5)
const router = useRouter()
props.showBtn &&
(timer = setInterval(() => {
if (second.value === 0) {
clearInterval(timer)
router.go(-1)
} else {
second.value--
}
}, 1000))
onUnmounted(() => {
timer && clearInterval(timer)
})
</script>
<style lang="scss" scoped>
.error {
text-align: center;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
.error-code {
@apply text-primary;
font-size: 150px;
}
.el-button {
width: 176px;
}
}
</style>
<template>
<div class="edit-popup">
<popup
ref="popupRef"
:title="popupTitle"
:async="true"
width="650px"
@confirm="handleSubmit"
@close="handleClose"
>
<el-form
ref="formRef"
:model="formData"
label-width="140px"
:rules="formRules"
>
<el-form-item label="分类名称" prop="title">
<el-input
v-model="formData.title"
placeholder="请输入分类名称"
clearable
/>
</el-form-item>
<el-form-item label="父级菜单" prop="parent_id" v-if="mode == 'add'">
<el-tree-select
class="flex-1"
v-model="formData.parent_id"
:data="menuOptions"
clearable
node-key="id"
:props="{
label: 'title'
}"
:default-expand-all="true"
placeholder="请选择父级菜单"
check-strictly
/>
</el-form-item>
<el-form-item label="排序" prop="idx">
<div>
<el-input-number v-model="formData.idx" :min="1" :max="9999" />
<div class="form-tips">默认为1, 数值越小越排前</div>
</div>
</el-form-item>
<el-form-item
label="素材是否可以缩放"
prop="image_suofang"
v-if="!formData.parent_id || formData.parent_id == 'all'"
>
<el-radio-group v-model="formData.image_suofang">
<el-radio :label="1">允许缩放</el-radio>
<el-radio :label="2">不允许缩放</el-radio>
</el-radio-group>
</el-form-item>
</el-form>
</popup>
</div>
</template>
<script lang="ts" setup>
import type { FormInstance } from 'element-plus'
import { apiDiyImageTypeUpdate, apiDiyImageTypeCreate } from '@/api/image'
import Popup from '@/components/popup/index.vue'
import { arrayToTree, treeToArray } from '@/utils/util'
const emit = defineEmits(['success', 'close'])
const formRef = shallowRef<FormInstance>()
const popupRef = shallowRef<InstanceType<typeof Popup>>()
const mode = ref('add')
const popupTitle = computed(() => {
return mode.value == 'edit' ? '编辑分类' : '新增分类'
})
const menuOptions = ref<any[]>([])
const formData = reactive({
id: '',
title: '',
idx: 1,
status: 1,
image_suofang: 1,
parent_id: ''
})
const formRules: any = reactive({
title: [
{
required: true,
message: '请输入标签名称',
trigger: 'blur'
}
],
idx: [
{
required: true,
message: '请输入排序',
trigger: 'blur'
}
]
})
const getMenu = (menuList: any[]) => {
const menu: any = { id: 'all', title: '顶级', children: [] }
menu.children = arrayToTree(treeToArray(menuList, { children: 'list' }), {
children: 'children',
id: 'id',
parentId: 'parent_id',
number: 1
})
menuOptions.value.push(menu)
}
const handleSubmit = async () => {
await formRef.value?.validate()
const obj: any = { ...toRaw(formData) }
if (obj.parent_id == 'all') {
delete obj.parent_id
}
if (obj.id === '') delete obj.id
if (obj.id && obj.parent_id) delete obj.parent_id
mode.value == 'edit'
? await apiDiyImageTypeUpdate(obj)
: await apiDiyImageTypeCreate(obj)
popupRef.value?.close()
emit('success')
}
const open = (key = 'add', pager: any) => {
mode.value = key
popupRef.value?.open()
getMenu(pager.lists)
}
const setFormData = (data: Record<any, any>) => {
for (const key in formData) {
if (data[key] != null && data[key] != undefined) {
//@ts-ignore
formData[key] = data[key]
}
}
}
const getDetail = async (row: Record<string, any>) => {
setFormData(row)
}
const handleClose = () => {
emit('close')
}
defineExpose({
open,
setFormData,
getDetail
})
</script>
<template>
<div>
<el-card class="!border-none" shadow="never" v-loading="pager.loading">
<div class="mb-4">
<el-button type="primary" @click="handleAdd()">
<template #icon>
<icon name="el-icon-Plus" />
</template>
新增
</el-button>
<el-button @click="handleExpand"> 展开/折叠 </el-button>
</div>
<div class="mt-2">
<el-table
ref="tableRef"
size="large"
v-loading="pager.loading"
:data="pager.lists"
row-key="id"
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
>
<el-table-column label="ID" prop="id" min-width="120" />
<el-table-column label="名称" prop="title" min-width="120" />
<el-table-column label="排序" prop="idx" min-width="120" />
<el-table-column label="素材是否允许缩放">
<template #default="{ row }">
<div v-if="!row.parent_id">
<el-tag v-if="row.image_suofang == 2">不允许</el-tag>
<el-tag v-else>允许</el-tag>
</div>
<div v-else>-</div>
</template>
</el-table-column>
<el-table-column
label="创建时间"
prop="create_date"
min-width="120"
/>
<el-table-column label="操作" width="120" fixed="right">
<template #default="{ row }">
<el-button type="primary" link @click="handleEdit(row)">
编辑
</el-button>
<el-button type="danger" link @click="handleDelete(row.id)">
删除
</el-button>
</template>
</el-table-column>
</el-table>
</div>
</el-card>
<edit-popup
v-if="showEdit"
ref="editRef"
@success="getLists"
@close="showEdit = false"
/>
</div>
</template>
<script lang="ts" setup name="productFenlei">
import { apiDiyImageTypeList, apiDiyImageTypeDelete } from '@/api/image'
import { usePaging } from '@/hooks/usePaging'
import feedback from '@/utils/feedback'
import EditPopup from './edit.vue'
import type { ElTable } from 'element-plus'
const editRef = shallowRef<InstanceType<typeof EditPopup>>()
const tableRef = shallowRef<InstanceType<typeof ElTable>>()
const showEdit = ref(false)
let isExpand = false
// type*==1设计产品==2成品==4系统素材
const paramsData: any = reactive({
type: 1
})
// eslint-disable-next-line vue/no-setup-props-destructure
const { type } = defineProps(['type'])
type && (paramsData.type = type)
const { pager, getLists } = usePaging({
fetchFun: apiDiyImageTypeList,
params: paramsData
})
const handleAdd = async () => {
showEdit.value = true
await nextTick()
editRef.value?.open('add', pager)
}
const handleEdit = async (data: any) => {
showEdit.value = true
await nextTick()
editRef.value?.open('edit', pager)
editRef.value?.getDetail(data)
}
const handleDelete = async (id: number) => {
await feedback.confirm('确定要删除?')
await apiDiyImageTypeDelete({ id })
getLists()
}
const handleExpand = () => {
isExpand = !isExpand
toggleExpand(pager.lists, isExpand)
}
const toggleExpand = (children: any[], unfold = true) => {
for (const key in children) {
tableRef.value?.toggleRowExpansion(children[key], unfold)
if (children[key].list) {
toggleExpand(children[key].list!, unfold)
}
}
}
getLists()
</script>
<template>
<div class="edit-popup">
<popup
ref="popupRef"
:title="popupTitle"
:async="true"
width="700px"
@confirm="handleSubmit"
@close="handleClose"
>
<el-form
ref="formRef"
:model="formData"
label-width="120px"
:rules="formRules"
>
<el-form-item label="分类" prop="type_id">
<el-cascader
v-model="formData.type_id"
:options="type_list"
:props="{ label: 'title', value: 'id' }"
/>
</el-form-item>
<el-form-item class="!mb-0">
<div>
<upload
:data="{ kuandu: 600 }"
@change="onUploadChange"
:limit="10"
@error="onError"
:saveFoxpsd="false"
:show-progress="true"
>
<el-button type="primary">上传图片</el-button>
</upload>
<div style="margin-top: 10px">
<el-image
v-for="(item, i) in formData.data"
:key="i"
style="width: 80px; height: 80px; margin: 0 5px 5px 0"
:src="getImageUrl(item.img_url, 200)"
:zoom-rate="1.2"
:preview-src-list="[getImageUrl(item.img_url, 800)]"
:initial-index="4"
fit="cover"
/>
</div>
</div>
</el-form-item>
</el-form>
</popup>
</div>
</template>
<script lang="ts" setup>
import type { FormInstance } from 'element-plus'
import Popup from '@/components/popup/index.vue'
import { apiDiyImageTypeList, apiDiyImageCreate } from '@/api/image'
import { getImageUrl } from '@/utils/getImgUrl'
const emit = defineEmits(['success', 'close'])
const formRef = shallowRef<FormInstance>()
const popupRef = shallowRef<InstanceType<typeof Popup>>()
const mode = ref('add')
const popupTitle = computed(() => {
return mode.value == 'edit' ? '编辑图库' : '新增图库'
})
const formData: any = reactive({
type_id: '',
data: []
})
const formRules: any = reactive({})
const onUploadChange = (file: any) => {
const data = file.response.data
formData.data.push({
width: data.width,
height: data.height,
img_url: data.url,
size: file.size,
title: file.name.trim()
})
}
const onError = (file: any) => {
console.log('上传文件失败', file)
}
const handleSubmit = async () => {
await formRef.value?.validate()
const obj: any = { ...toRaw(formData) }
if (obj.id === '') delete obj.id
if (obj.type_id && obj.type_id.length > 0) {
obj.type_id = obj.type_id[obj.type_id.length - 1]
}
await apiDiyImageCreate(obj)
popupRef.value?.close()
emit('success')
}
const type_list = ref([])
const getData = async () => {
const res = await apiDiyImageTypeList()
type_list.value = res.data.list
}
const open = async (key = 'add') => {
mode.value = key
popupRef.value?.open()
await getData()
}
const handleClose = () => {
emit('close')
}
defineExpose({
open
})
</script>
<template>
<div class="article-lists">
<el-card class="!border-none" shadow="never">
<el-form
ref="formRef"
class="mb-[-16px]"
@submit.native.prevent
:model="queryParams"
:inline="true"
>
<el-form-item label="标题">
<el-input
class="w-[280px]"
v-model="queryParams.content"
clearable
@keyup.enter="resetPage"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="resetPage">查询</el-button>
<el-button @click="resetParams">重置</el-button>
</el-form-item>
</el-form>
</el-card>
<el-card class="!border-none mt-4" shadow="never">
<div class="flex justify-between">
<div class="flex mb-4">
<el-button type="primary" @click="handleAdd">
<template #icon>
<icon name="el-icon-Plus" />
</template>
批量上传图片
</el-button>
<el-button
:disabled="selectData.length > 0 ? false : true"
type="primary"
@click="moveAdd"
>移动文件夹</el-button
>
<el-button
:disabled="selectData.length > 0 ? false : true"
type="danger"
@click="handleDelete(selectData.join(','))"
>批量删除</el-button
>
</div>
<pagination v-model="pager" @change="getLists" />
</div>
<el-table
class="mt20"
@selection-change="handleSelectionChange"
size="large"
v-loading="pager.loading"
:data="pager.lists"
>
<el-table-column type="selection" width="55" />
<el-table-column label="ID" prop="id" width="55" />
<el-table-column label="商品信息">
<template #default="{ row }">
<div class="flex relative">
<image-contain
v-if="row.img_url"
:src="getImageUrl(row.img_url, 200)"
:width="100"
:height="100"
:preview-src-list="[getImageUrl(row.img_url, 800)]"
preview-teleported
fit="contain"
/>
<div class="goodsInfo ml-4">
<div class="title">{{ row.title }}</div>
<div class="mt-2">
<div class="flex">
<div class="one">分类:</div>
<div class="two">
<span v-if="row.db_diy_image_type">{{
row.db_diy_image_type.title
}}</span>
</div>
</div>
</div>
</div>
</div>
</template>
</el-table-column>
<el-table-column label="尺寸">
<template #default="{ row }">
<div>{{ row.width }} X {{ row.height }} 像素</div>
</template>
</el-table-column>
<el-table-column label="创建时间" prop="create_date" />
<el-table-column label="操作" width="120" fixed="right">
<template #default="{ row }">
<div class="">
<el-button type="danger" link @click="handleDelete(row.id)">
删除
</el-button>
</div>
</template>
</el-table-column>
</el-table>
<div class="flex justify-end mt-4">
<pagination v-model="pager" @change="getLists" />
</div>
</el-card>
<edit-popup
v-if="showEdit"
ref="editRef"
@success="getLists"
@close="showEdit = false"
/>
<move-popup ref="movRef" @success="getLists" :ids="selectData.join(',')" />
</div>
</template>
<script lang="ts" setup name="productLists">
import { apiDiyImageList, apiDiyImageDelete } from '@/api/image'
import { usePaging } from '@/hooks/usePaging'
import feedback from '@/utils/feedback'
import { getImageUrl } from '@/utils/getImgUrl'
import EditPopup from './edit.vue'
import MovePopup from './move.vue'
const editRef = shallowRef<InstanceType<typeof EditPopup>>()
const movRef = shallowRef<InstanceType<typeof MovePopup>>()
const showEdit = ref(false)
const queryParams = reactive({
content: '',
type: 'all',
})
const { pager, getLists, resetPage, resetParams } = usePaging({
fetchFun: apiDiyImageList,
params: queryParams,
})
const selectData = ref<any[]>([])
const handleSelectionChange = (val: any[]) => {
selectData.value = val.map(({ id }) => id)
}
const handleAdd = async () => {
showEdit.value = true
await nextTick()
editRef.value?.open('add')
}
const moveAdd = async () => {
await nextTick()
movRef.value?.open('add')
}
const handleDelete = async (ids: string) => {
await feedback.confirm('确定要删除?')
await apiDiyImageDelete({ ids: ids + '' })
getLists()
}
onActivated(() => {
getLists()
})
onMounted(() => {
getLists()
})
</script>
<style lang="scss" scoped>
.goodsInfo {
.title {
font-weight: bold;
}
}
.foxpsd_box {
.zhutu_data {
display: flex;
align-items: flex-start;
justify-content: space-between;
.right_txt {
font-size: 16px;
font-weight: bold;
color: #333;
.ts {
color: #666;
font-weight: 400;
}
}
}
.boy_detail {
margin-bottom: 20px;
.boy_biaoti {
font-size: 16px;
color: #38f;
}
.img_list {
display: flex;
flex-wrap: wrap;
.item_xiaoguo {
text-align: center;
font-size: 14px;
margin-bottom: 5px;
margin-right: 5px;
}
}
}
}
.nav_her_btn {
display: flex;
align-items: center;
justify-content: flex-end;
font-size: 18px;
color: #38f;
cursor: pointer;
}
</style>
<template>
<div class="edit-popup">
<popup
ref="popupRef"
title="移动文件夹"
:async="true"
width="700px"
@confirm="handleSubmit"
@close="handleClose"
>
<el-form
ref="formRef"
:model="formData"
label-width="120px"
:rules="formRules"
>
<el-form-item label="分类" prop="type_id">
<el-cascader
v-model="formData.type_id"
:options="type_list"
:props="{ label: 'title', value: 'id' }"
/>
</el-form-item>
</el-form>
</popup>
</div>
</template>
<script lang="ts" setup>
import type { FormInstance } from 'element-plus'
import Popup from '@/components/popup/index.vue'
import { apiDiyImageTypeList, apiDiyImageMove } from '@/api/image'
// eslint-disable-next-line vue/no-setup-props-destructure
const { ids } = defineProps(['ids'])
const emit = defineEmits(['success', 'close'])
const formRef = shallowRef<FormInstance>()
const popupRef = shallowRef<InstanceType<typeof Popup>>()
const mode = ref('add')
const formData: any = reactive({
type_id: ''
})
const formRules: any = reactive({})
const handleSubmit = async () => {
await formRef.value?.validate()
const obj: any = {
...toRaw(formData),
ids
}
if (obj.type_id && obj.type_id.length > 0) {
obj.type_id = obj.type_id[obj.type_id.length - 1]
}
await apiDiyImageMove(obj)
popupRef.value?.close()
emit('success')
}
const type_list = ref([])
const getData = async () => {
const res = await apiDiyImageTypeList()
type_list.value = res.data.list
}
const open = async (key = 'add') => {
mode.value = key
popupRef.value?.open()
await getData()
}
const handleClose = () => {
emit('close')
}
defineExpose({
open
})
</script>
<template>
<div class="edit-popup">
<popup
ref="popupRef"
:title="popupTitle"
:async="true"
width="580px"
@confirm="handleSubmit"
@close="handleClose"
>
<el-form
ref="formRef"
:model="formData"
label-width="150px"
:rules="formRules"
>
<el-form-item label="昵称" prop="name">
<el-input
v-model="formData.name"
placeholder="请输入昵称"
clearable
/>
</el-form-item>
<el-form-item label="密码" prop="password" v-if="!formData.id">
<el-input
v-model="formData.password"
type="password"
placeholder="请输入密码"
clearable
/>
</el-form-item>
<el-form-item label="用户头像" prop="img_url">
<div>
<div>
<material-picker v-model="formData.img_url" :limit="1" />
</div>
<div class="form-tips">建议尺寸100*100px</div>
</div>
</el-form-item>
<el-form-item label="是否允许下载生产图" prop="chima_status">
<el-radio-group v-model="formData.chima_status">
<el-radio :label="1">允许</el-radio>
<el-radio :label="0">不允许</el-radio>
</el-radio-group>
</el-form-item>
</el-form>
</popup>
</div>
</template>
<script lang="ts" setup>
import type { FormInstance } from 'element-plus'
import {
shopTypeList,
apiDiyTemplateUpdate,
apiDiyTemplateCreate
} from '@/api/product'
import { apiDiyUserCreate, apiDiyUserUpdate } from '@/api/member'
import Popup from '@/components/popup/index.vue'
const emit = defineEmits(['success', 'close'])
const formRef = shallowRef<FormInstance>()
const popupRef = shallowRef<InstanceType<typeof Popup>>()
const mode = ref('add')
const popupTitle = computed(() => {
return mode.value == 'edit' ? '编辑用户' : '新增模用户'
})
const formData = reactive({
id: '',
name: '',
password: '123456',
img_url: '',
chima_status: 1
})
const formRules: any = reactive({
name: [
{
required: true,
message: '请输入昵称',
trigger: 'blur'
}
],
password: [
{
required: true,
message: '请输入密码',
trigger: 'blur'
}
]
})
const handleSubmit = async () => {
await formRef.value?.validate()
const obj: any = { ...toRaw(formData) }
if (obj.id === '') delete obj.id
if (obj.id) {
delete obj.password
}
mode.value == 'edit'
? await apiDiyUserUpdate(obj)
: await apiDiyUserCreate(obj)
popupRef.value?.close()
emit('success')
}
const type_list = ref([])
const getData = async () => {
const res = await shopTypeList()
console.log(res)
type_list.value = res.data.list
}
const open = async (key = 'add') => {
mode.value = key
popupRef.value?.open()
await getData()
}
const setFormData = (data: Record<any, any>) => {
for (const key in formData) {
if (data[key] != null && data[key] != undefined) {
//@ts-ignore
formData[key] = data[key]
}
}
}
const getDetail = async (row: Record<string, any>) => {
setFormData(row)
}
const handleClose = () => {
emit('close')
}
defineExpose({
open,
setFormData,
getDetail
})
</script>
<template>
<div class="article-lists">
<el-card class="!border-none" shadow="never">
<el-form
ref="formRef"
class="mb-[-16px]"
@submit.native.prevent
:model="queryParams"
:inline="true"
>
<el-form-item label="编号/标题">
<el-input
class="w-[280px]"
v-model="queryParams.content"
clearable
@keyup.enter="resetPage"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="resetPage">查询</el-button>
<el-button @click="resetParams">重置</el-button>
</el-form-item>
</el-form>
</el-card>
<el-card class="!border-none mt-4" shadow="never">
<div class="flex justify-between">
<div class="flex mb-4">
<el-button type="primary" @click="handleAdd">
<template #icon>
<icon name="el-icon-Plus" />
</template>
添加新用户
</el-button>
</div>
<pagination v-model="pager" @change="getLists" />
</div>
<el-table
class="mt20"
@selection-change="handleSelectionChange"
size="large"
v-loading="pager.loading"
:data="pager.lists"
>
<el-table-column type="selection" width="55" />
<el-table-column label="ID" prop="id" width="55" />
<el-table-column label="用户信息" width="450">
<template #default="{ row }">
<div class="flex relative">
<image-contain
v-if="row.img_url"
:src="getImageUrl(row.img_url, 200)"
:width="100"
:height="100"
:preview-src-list="[row.img_url]"
preview-teleported
fit="contain"
/>
<div class="goodsInfo ml-4">
<div class="title">{{ row.name }}</div>
<div class="mt-2">
<div class="flex">
<div class="one w-[50px]">SKU:</div>
<div class="two" v-copy="row.sku">
{{ row.sku }}
<icon
class="ml-2"
:size="14"
color="#38f"
name="el-icon-DocumentCopy"
/>
</div>
</div>
</div>
</div>
</div>
</template>
</el-table-column>
<el-table-column label="是否允许下载生产图">
<template #default="{ row }">
<el-tag v-if="row.chima_status == 1">允许</el-tag>
<el-tag v-else>不允许</el-tag>
</template>
</el-table-column>
<el-table-column label="创建时间" prop="create_date" />
<el-table-column label="操作" width="120" fixed="right">
<template #default="{ row }">
<div class="mt-3">
<el-button type="primary" link @click="handleEdit(row)">
编辑
</el-button>
</div>
<div class="">
<el-button type="danger" link @click="handleDelete(row.id)">
删除
</el-button>
</div>
</template>
</el-table-column>
</el-table>
<div class="flex justify-end mt-4">
<pagination v-model="pager" @change="getLists" />
</div>
</el-card>
<edit-popup
v-if="showEdit"
ref="editRef"
@success="getLists"
@close="showEdit = false"
/>
</div>
</template>
<script lang="ts" setup name="productLists">
import { apiDiyUserList, apiDiyUserDelete } from '@/api/member'
import { usePaging } from '@/hooks/usePaging'
import feedback from '@/utils/feedback'
import { getImageUrl } from '@/utils/getImgUrl'
import EditPopup from './edit.vue'
const editRef = shallowRef<InstanceType<typeof EditPopup>>()
const showEdit = ref(false)
const queryParams = reactive({
content: ''
})
const { pager, getLists, resetPage, resetParams } = usePaging({
fetchFun: apiDiyUserList,
params: queryParams
})
const selectData = ref<any[]>([])
const handleSelectionChange = (val: any[]) => {
selectData.value = val.map(({ id }) => id)
}
const handleAdd = async () => {
showEdit.value = true
await nextTick()
editRef.value?.open('add')
}
const handleEdit = async (data: any) => {
showEdit.value = true
await nextTick()
editRef.value?.open('edit')
editRef.value?.getDetail(data)
}
const handleDelete = async (id: number) => {
await feedback.confirm('确定要删除?')
await apiDiyUserDelete({ id })
getLists()
}
onActivated(() => {
getLists()
})
onMounted(() => {
getLists()
})
</script>
<style lang="scss" scoped>
.goodsInfo {
.title {
font-weight: bold;
}
}
.foxpsd_box {
.zhutu_data {
display: flex;
align-items: flex-start;
justify-content: space-between;
.right_txt {
font-size: 16px;
font-weight: bold;
color: #333;
.ts {
color: #666;
font-weight: 400;
}
}
}
.boy_detail {
margin-bottom: 20px;
.boy_biaoti {
font-size: 16px;
color: #38f;
}
.img_list {
display: flex;
flex-wrap: wrap;
.item_xiaoguo {
text-align: center;
font-size: 14px;
margin-bottom: 5px;
margin-right: 5px;
}
}
}
}
.nav_her_btn {
display: flex;
align-items: center;
justify-content: flex-end;
font-size: 18px;
color: #38f;
cursor: pointer;
}
</style>
<template>
<div class="edit-popup">
<popup
ref="popupRef"
:title="popupTitle"
:async="true"
width="800px"
@confirm="handleSubmit"
@close="handleClose"
>
<el-form
ref="formRef"
:model="formData"
label-width="80px"
:rules="formRules"
class="w-[90%]"
>
<el-row :gutter="20">
<el-col :span="16">
<el-form-item label="名称" prop="title">
<el-input
v-model="formData.title"
placeholder="请输入名称"
clearable
/>
</el-form-item>
<el-form-item label="排序" prop="idx">
<div>
<el-input-number v-model="formData.idx" :min="1" :max="9999" />
<div class="form-tips">默认为1, 数值越小越排前</div>
</div>
</el-form-item>
<el-form-item label="编码" prop="bianma">
<el-input
v-model="formData.bianma"
placeholder="请输入编码"
clearable
/>
<div class="text-xs text-[#f44]">
请输入编码英文或者数字组合,禁止输入特殊字符!
</div>
</el-form-item>
<el-form-item class="!mb-0">
<div>
<upload
:multiple="false"
:action="`${config.baseUrl}/api/v1/upload`"
@change="onPSDUploadChange"
type="psd"
:saveFoxpsd="false"
:show-progress="true"
>
<el-button :loading="uploadPsdLoading" type="primary"
>上传PSD文件</el-button
>
</upload>
<div>上传时间较长,请耐心等待</div>
</div>
</el-form-item>
<el-form-item label="PSD文件" prop="psd_url">
<el-input
v-model="formData.psd_url"
placeholder="psd 文件路径"
clearable
disabled
/>
<div class="text-xs text-[#f44]">
1.需要替换自定义sku,图层必须命名为 order_no
并且是一个文字图层,字体为默认字体 <br />
2.psd的尺寸 宽度或高度必须小于
10000像素一下,推荐控制在6000像素左右
</div>
</el-form-item>
<el-form-item class="!mb-0">
<div>
<upload
:multiple="false"
:action="`${config.baseUrl}/api/v1/upload`"
@change="onSVGUploadChange"
type="svg"
:saveFoxpsd="false"
:show-progress="true"
>
<el-button :loading="uploadPsdLoading" type="primary"
>上传SVG文件</el-button
>
</upload>
<div>上传时间较长,请耐心等待</div>
</div>
</el-form-item>
<el-form-item label="SVG文件" prop="psd_svg">
<el-input
v-model="formData.psd_svg"
placeholder="SVG文件路径"
clearable
disabled
/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="主图" prop="img_url">
<div>
<div>
<material-picker
:excludeDomain="true"
v-model="formData.img_url"
:limit="1"
/>
</div>
<div class="text-xs">非必填,预览使用</div>
</div>
</el-form-item>
</el-col>
</el-row>
</el-form>
</popup>
</div>
</template>
<script lang="ts" setup>
import config from '@/config'
import type { FormInstance } from 'element-plus'
import {
apiDiyTemplateChimaUpdate,
apiDiyTemplateChimaCreate,
apiPsdParser
} from '@/api/product'
import Popup from '@/components/popup/index.vue'
import useAppStore from '@/stores/modules/app'
// @ts-ignore
import resvg from '@/lib/resvg.min'
const { isResvg, setResvg } = useAppStore()
;(async () => {
if (!isResvg) {
await resvg.initWasm(fetch('https://foxpsd.com/webps/wasm/resvg.wasm'))
setResvg(true)
}
})()
const emit = defineEmits(['success', 'close'])
const formRef = shallowRef<FormInstance>()
const popupRef = shallowRef<InstanceType<typeof Popup>>()
const mode = ref('add')
const popupTitle = computed(() => {
return mode.value == 'edit' ? '编辑尺码' : '新增尺码'
})
const route = useRoute()
const uploadPsdLoading = ref(false)
const formData = reactive({
id: '',
title: '',
idx: 1,
bianma: '',
psd_url: '',
psd_svg: '',
dpi: 100,
width: '',
height: '',
img_url: '',
diy_id: route.query.did
})
const formRules: any = reactive({
title: [
{
required: true,
message: '请输入标签名称',
trigger: 'blur'
}
],
idx: [
{
required: true,
message: '请输入排序',
trigger: 'blur'
}
],
bianma: [
{
required: true,
message: '请输入编码',
trigger: 'blur'
}
],
psd_svg: [
{
required: true,
message: '请输入svg 文件不能为空',
trigger: 'blur'
}
]
})
const handleSubmit = async () => {
await formRef.value?.validate()
const obj: any = { ...toRaw(formData) }
if (obj.id === '') delete obj.id
if (obj.id) delete obj.diy_id
mode.value == 'edit'
? await apiDiyTemplateChimaUpdate(obj)
: await apiDiyTemplateChimaCreate(obj)
popupRef.value?.close()
emit('success')
}
const onPSDUploadChange = async (e: any) => {
console.log(e)
uploadPsdLoading.value = true
const relativePath = e.response.data.relativePath
const res = await apiPsdParser({
lianjie: relativePath,
upload: 'local'
}).finally(() => {
uploadPsdLoading.value = false
})
formData.img_url = res.data.img_url
formData.psd_url = res.data.relativePath
formData.psd_svg = res.data.svg
formData.dpi = res.data.dpi
formData.width = res.data.width
formData.height = res.data.height
}
const onSVGUploadChange = (file: any) => {
uploadPsdLoading.value = true
const relativePath = file.response.data.relativePath
formData.psd_svg = relativePath
const reader = new FileReader()
reader.readAsText(file.raw)
reader.onload = async () => {
const resvgJS = new resvg.Resvg(reader.result, {})
const svgWidth = resvgJS.width
const svgHeight = resvgJS.height
formData.width = svgWidth
formData.height = svgHeight
uploadPsdLoading.value = false
}
}
const open = (key = 'add', pager: any) => {
mode.value = key
popupRef.value?.open()
}
const setFormData = (data: Record<any, any>) => {
for (const key in formData) {
if (data[key] != null && data[key] != undefined) {
//@ts-ignore
formData[key] = data[key]
}
}
}
const getDetail = async (row: Record<string, any>) => {
setFormData(row)
}
const handleClose = () => {
emit('close')
}
defineExpose({
open,
setFormData,
getDetail
})
</script>
<template>
<div>
<el-card class="!border-none" shadow="never">
<el-page-header :content="$route.meta.title" @back="goBack" />
</el-card>
<el-card class="!border-none mt-2" shadow="never" v-loading="pager.loading">
<div class="mb-4">
<el-button type="primary" @click="handleAdd()">
<template #icon>
<icon name="el-icon-Plus" />
</template>
新增
</el-button>
</div>
<div class="mt-2">
<el-table
ref="tableRef"
size="large"
v-loading="pager.loading"
:data="pager.lists"
row-key="id"
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
>
<el-table-column label="ID" prop="id" />
<el-table-column label="主图">
<template #default="{ row }">
<image-contain
v-if="row.img_url"
:src="getImageUrl(row.img_url, 200)"
:width="80"
:height="80"
:preview-src-list="[getImageUrl(row.img_url)]"
preview-teleported
fit="contain"
/>
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column label="名称" prop="title" min-width="120" />
<el-table-column label="排序" prop="idx" />
<el-table-column label="单位" min-width="120">
<template #default="{ row }">
<div>{{ row.width }} X {{ row.height }} 像素</div>
</template>
</el-table-column>
<el-table-column label="分辨率" min-width="120">
<template #default="{ row }">
<div>{{ row.dpi }} DPI</div>
</template>
</el-table-column>
<el-table-column label="下载" min-width="120">
<template #default="{ row }">
<div>
<el-button type="primary" link>
<a
v-if="row.psd_url"
target="_blank"
:href="getImageUrl(row.psd_url)"
>下载PSD文件</a
>
</el-button>
</div>
<div>
<el-button type="primary" link>
<a
v-if="row.psd_svg"
target="_blank"
:href="getImageUrl(row.psd_svg)"
>下载SVG文件</a
>
</el-button>
</div>
</template>
</el-table-column>
<el-table-column
label="创建时间"
prop="create_date"
min-width="120"
/>
<el-table-column label="操作" width="120" fixed="right">
<template #default="{ row }">
<el-button type="primary" link @click="handleEdit(row)">
编辑
</el-button>
<el-button type="danger" link @click="handleDelete(row.id)">
删除
</el-button>
</template>
</el-table-column>
</el-table>
</div>
</el-card>
<edit-popup
v-if="showEdit"
ref="editRef"
@success="getLists"
@close="showEdit = false"
/>
</div>
</template>
<script lang="ts" setup name="productFenlei">
import {
apiDiyTemplateChimaList,
apiDiyTemplateChimaDelete
} from '@/api/product'
import { usePaging } from '@/hooks/usePaging'
import feedback from '@/utils/feedback'
import EditPopup from './edit.vue'
import type { ElTable } from 'element-plus'
import useMultipleTabs from '@/hooks/useMultipleTabs'
import { getImageUrl } from '@/utils/getImgUrl'
const { removeTab } = useMultipleTabs()
const route = useRoute()
const router = useRouter()
const goBack = () => {
removeTab()
router.go(-1)
}
const editRef = shallowRef<InstanceType<typeof EditPopup>>()
const tableRef = shallowRef<InstanceType<typeof ElTable>>()
const showEdit = ref(false)
const paramsData: any = reactive({
diy_id: route.query.did
})
// eslint-disable-next-line vue/no-setup-props-destructure
const { type } = defineProps(['type'])
type && (paramsData.type = type)
const { pager, getLists } = usePaging({
fetchFun: apiDiyTemplateChimaList,
params: paramsData
})
const handleAdd = async () => {
showEdit.value = true
await nextTick()
editRef.value?.open('add', pager)
}
const handleEdit = async (data: any) => {
showEdit.value = true
await nextTick()
editRef.value?.open('edit', pager)
editRef.value?.getDetail(data)
}
const handleDelete = async (id: number) => {
await feedback.confirm('确定要删除?')
await apiDiyTemplateChimaDelete({ id })
getLists()
}
getLists()
</script>
<template>
<div class="edit-popup">
<popup
ref="popupRef"
:title="popupTitle"
:async="true"
width="500px"
@confirm="handleSubmit"
@close="handleClose"
>
<el-form
ref="formRef"
:model="formData"
label-width="80px"
:rules="formRules"
>
<el-form-item label="名称" prop="title">
<el-input
v-model="formData.title"
placeholder="请输入名称"
clearable
/>
</el-form-item>
<el-form-item label="排序" prop="idx">
<div>
<el-input-number v-model="formData.idx" :min="1" :max="9999" />
<div class="form-tips">默认为1, 数值越小越排前</div>
</div>
</el-form-item>
<el-form-item label="色值" prop="sezhi">
<el-color-picker v-model="formData.sezhi" />
</el-form-item>
</el-form>
</popup>
</div>
</template>
<script lang="ts" setup>
import type { FormInstance } from 'element-plus'
import {
apiDiyTemplateColorUpdate,
apiDiyTemplateColorCreate
} from '@/api/product'
import Popup from '@/components/popup/index.vue'
const emit = defineEmits(['success', 'close'])
const formRef = shallowRef<FormInstance>()
const popupRef = shallowRef<InstanceType<typeof Popup>>()
const mode = ref('add')
const popupTitle = computed(() => {
return mode.value == 'edit' ? '编辑颜色' : '新增颜色'
})
const route = useRoute()
const formData = reactive({
id: '',
title: '',
idx: 1,
sezhi: '',
diy_id: route.query.did
})
const formRules: any = reactive({
title: [
{
required: true,
message: '请输入标签名称',
trigger: 'blur'
}
],
idx: [
{
required: true,
message: '请输入排序',
trigger: 'blur'
}
],
sezhi: [
{
required: true,
message: '请输入色值',
trigger: 'blur'
}
]
})
const handleSubmit = async () => {
await formRef.value?.validate()
const obj: any = { ...toRaw(formData) }
if (obj.id === '') delete obj.id
if (obj.id) delete obj.diy_id
mode.value == 'edit'
? await apiDiyTemplateColorUpdate(obj)
: await apiDiyTemplateColorCreate(obj)
popupRef.value?.close()
emit('success')
}
const open = (key = 'add', pager: any) => {
mode.value = key
popupRef.value?.open()
}
const setFormData = (data: Record<any, any>) => {
for (const key in formData) {
if (data[key] != null && data[key] != undefined) {
//@ts-ignore
formData[key] = data[key]
}
}
}
const getDetail = async (row: Record<string, any>) => {
setFormData(row)
}
const handleClose = () => {
emit('close')
}
defineExpose({
open,
setFormData,
getDetail
})
</script>
<template>
<div>
<el-card class="!border-none mt-2" shadow="never" v-loading="pager.loading">
<el-tabs v-model="activeTab" class="bg-white" @tab-change="onChange">
<el-tab-pane label="效果图" name="xiaoguotu"></el-tab-pane>
<el-tab-pane label="颜色" name="color"></el-tab-pane>
</el-tabs>
<div class="mb-4 mt-2">
<el-button type="primary" @click="handleAdd()">
<template #icon>
<icon name="el-icon-Plus" />
</template>
新增颜色
</el-button>
</div>
<div class="mt-2">
<el-table
ref="tableRef"
size="large"
v-loading="pager.loading"
:data="pager.lists"
row-key="id"
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
>
<el-table-column label="ID" prop="id" />
<el-table-column label="名称" prop="title" min-width="120" />
<el-table-column label="排序" prop="idx" />
<el-table-column label="色值" min-width="120">
<template #default="{ row }">
<div
class="w-[20px] h-[20px]"
:style="{ background: row.sezhi }"
></div>
</template>
</el-table-column>
<el-table-column
label="创建时间"
prop="create_date"
min-width="120"
/>
<el-table-column label="操作" width="120" fixed="right">
<template #default="{ row }">
<el-button type="primary" link @click="handleEdit(row)">
编辑
</el-button>
<el-button type="danger" link @click="handleDelete(row.id)">
删除
</el-button>
</template>
</el-table-column>
</el-table>
</div>
</el-card>
<edit-popup
v-if="showEdit"
ref="editRef"
@success="getLists"
@close="showEdit = false"
/>
</div>
</template>
<script lang="ts" setup name="productFenlei">
import {
apiDiyTemplateColorList,
apiDiyTemplateColorDelete
} from '@/api/product'
import { usePaging } from '@/hooks/usePaging'
import feedback from '@/utils/feedback'
import EditPopup from './edit.vue'
import type { ElTable } from 'element-plus'
import { getImageUrl } from '@/utils/getImgUrl'
const route = useRoute()
const editRef = shallowRef<InstanceType<typeof EditPopup>>()
const tableRef = shallowRef<InstanceType<typeof ElTable>>()
const showEdit = ref(false)
const isExpand = false
const paramsData: any = reactive({
diy_id: route.query.did
})
const { type } = defineProps(['type', 'activeTab'])
type && (paramsData.type = type)
const emit = defineEmits(['onChange'])
const onChange = (e: any) => {
emit('onChange', e)
}
const { pager, getLists } = usePaging({
fetchFun: apiDiyTemplateColorList,
params: paramsData
})
const handleAdd = async () => {
showEdit.value = true
await nextTick()
editRef.value?.open('add', pager)
}
const handleEdit = async (data: any) => {
showEdit.value = true
await nextTick()
editRef.value?.open('edit', pager)
editRef.value?.getDetail(data)
}
const handleDelete = async (id: number) => {
await feedback.confirm('确定要删除?')
await apiDiyTemplateColorDelete({ id })
getLists()
}
getLists()
</script>
<template>
<div class="edit-popup">
<popup
ref="popupRef"
:title="popupTitle"
:async="true"
width="1000px"
@confirm="handleSubmit"
@close="handleClose"
>
<el-form
ref="formRef"
:model="formData"
label-width="140px"
:rules="formRules"
>
<el-row :gutter="20">
<el-col :span="14">
<el-form-item label="名称" prop="title">
<el-input
v-model="formData.title"
placeholder="请输入名称"
clearable
/>
</el-form-item>
<el-form-item label="排序" prop="idx">
<div>
<el-input-number v-model="formData.idx" :min="1" :max="9999" />
<div class="form-tips">默认为1, 数值越小越排前</div>
</div>
</el-form-item>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="宽度(像素)" prop="width">
<el-input
v-model="formData.width"
placeholder="请输入宽度"
clearable
type="number"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="高度(像素)" prop="height">
<el-input
v-model="formData.height"
placeholder="请输入高度"
clearable
type="number"
/>
</el-form-item>
</el-col>
</el-row>
<el-form-item label="对应效果图psd图层" prop="xg_tuceng">
<el-input
v-model="formData.xg_tuceng"
placeholder="示例:sucai1,sucai2"
clearable
/>
<div class="text-xs">
提示:必须与PSD文件图层标题一致,英文命名,多个图层之间使用英文逗号分割,禁止输入空格及特殊字符
</div>
</el-form-item>
<el-form-item label="对应尺码psd图层 " prop="sc_tuceng">
<el-input
v-model="formData.sc_tuceng"
placeholder="示例:zhengmian,beimian"
clearable
/>
<div class="text-xs">
提示:必须与PSD文件图层标题一致,英文命名,多个图层之间使用英文逗号分割,禁止输入空格及特殊字符
</div>
</el-form-item>
</el-col>
<el-col :span="10">
<el-form-item label="层面主图" prop="img_url">
<div>
<div>
<material-picker v-model="formData.img_url" :limit="1" />
</div>
<div class="text-xs">
png,jpg,jpeg等格式,最大为100kb,750*750像素
</div>
</div>
</el-form-item>
<el-form-item label="蒙版图 (png格式)" prop="mask_url">
<div>
<div>
<material-picker v-model="formData.mask_url" :limit="1" />
</div>
<div class="text-xs">png格式,最大为100kb</div>
</div>
</el-form-item>
</el-col>
</el-row>
</el-form>
</popup>
</div>
</template>
<script lang="ts" setup>
import type { FormInstance } from 'element-plus'
import {
apiDiyTemplateFaceUpdate,
apiDiyTemplateFaceCreate
} from '@/api/product'
import Popup from '@/components/popup/index.vue'
const emit = defineEmits(['success', 'close'])
const formRef = shallowRef<FormInstance>()
const popupRef = shallowRef<InstanceType<typeof Popup>>()
const mode = ref('add')
const popupTitle = computed(() => {
return mode.value == 'edit' ? '编辑层面' : '新增层面'
})
const route = useRoute()
const formData = reactive({
id: '',
title: '',
idx: 1,
width: '',
height: '',
img_url: '',
mask_url: '',
xg_tuceng: '',
sc_tuceng: '',
diy_id: route.query.did
})
const formRules: any = reactive({
title: [
{
required: true,
message: '请输入标签名称',
trigger: 'blur'
}
],
idx: [
{
required: true,
message: '请输入排序',
trigger: 'blur'
}
],
width: [
{
required: true,
message: '宽度',
trigger: 'blur'
}
],
height: [
{
required: true,
message: '高度',
trigger: 'blur'
}
],
img_url: [
{
required: true,
message: '主图',
trigger: 'blur'
}
],
mask_url: [
{
required: true,
message: '蒙版图',
trigger: 'blur'
}
]
})
const handleSubmit = async () => {
await formRef.value?.validate()
const obj: any = { ...toRaw(formData) }
if (obj.id === '') delete obj.id
if (obj.id) delete obj.diy_id
mode.value == 'edit'
? await apiDiyTemplateFaceUpdate(obj)
: await apiDiyTemplateFaceCreate(obj)
popupRef.value?.close()
emit('success')
}
const open = (key = 'add', pager: any) => {
mode.value = key
popupRef.value?.open()
}
const setFormData = (data: Record<any, any>) => {
for (const key in formData) {
if (data[key] != null && data[key] != undefined) {
//@ts-ignore
formData[key] = data[key]
}
}
}
const getDetail = async (row: Record<string, any>) => {
setFormData(row)
}
const handleClose = () => {
emit('close')
}
defineExpose({
open,
setFormData,
getDetail
})
</script>
<template>
<div>
<el-card class="!border-none" shadow="never">
<el-page-header :content="$route.meta.title" @back="goBack" />
</el-card>
<el-card class="!border-none mt-2" shadow="never" v-loading="pager.loading">
<div class="mb-4">
<el-button type="primary" @click="handleAdd()">
<template #icon>
<icon name="el-icon-Plus" />
</template>
新增
</el-button>
</div>
<div class="mt-2">
<el-table
ref="tableRef"
size="large"
v-loading="pager.loading"
:data="pager.lists"
row-key="id"
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
>
<el-table-column label="ID" prop="id" />
<el-table-column label="主图">
<template #default="{ row }">
<image-contain
v-if="row.img_url"
:src="getImageUrl(row.img_url, 200)"
:width="80"
:height="80"
:preview-src-list="[row.img_url]"
preview-teleported
fit="contain"
/>
</template>
</el-table-column>
<el-table-column label="遮罩">
<template #default="{ row }">
<image-contain
v-if="row.mask_url"
:src="getImageUrl(row.mask_url, 200)"
:width="80"
:height="80"
:preview-src-list="[row.mask_url]"
preview-teleported
fit="contain"
/>
</template>
</el-table-column>
<el-table-column label="排序" prop="idx" />
<el-table-column label="名称" prop="title" min-width="120" />
<el-table-column label="单位" min-width="120">
<template #default="{ row }">
<div>{{ row.width }} X {{ row.height }} 像素</div>
</template>
</el-table-column>
<el-table-column label="效果图图层" min-width="120">
<template #default="{ row }">
<div>{{ row.xg_tuceng }}</div>
</template>
</el-table-column>
<el-table-column label="生产图图层" min-width="120">
<template #default="{ row }">
<div>{{ row.sc_tuceng }}</div>
</template>
</el-table-column>
<el-table-column
label="创建时间"
prop="create_date"
min-width="120"
/>
<el-table-column label="操作" width="120" fixed="right">
<template #default="{ row }">
<el-button type="primary" link @click="handleEdit(row)">
编辑
</el-button>
<el-button type="danger" link @click="handleDelete(row.id)">
删除
</el-button>
</template>
</el-table-column>
</el-table>
</div>
</el-card>
<edit-popup
v-if="showEdit"
ref="editRef"
@success="getLists"
@close="showEdit = false"
/>
</div>
</template>
<script lang="ts" setup name="productFenlei">
import { apiDiyTemplateFaceList, apiDiyTemplateFaceDelete } from '@/api/product'
import { usePaging } from '@/hooks/usePaging'
import feedback from '@/utils/feedback'
import EditPopup from './edit.vue'
import type { ElTable } from 'element-plus'
import useMultipleTabs from '@/hooks/useMultipleTabs'
import { getImageUrl } from '@/utils/getImgUrl'
const { removeTab } = useMultipleTabs()
const route = useRoute()
const router = useRouter()
const goBack = () => {
removeTab()
router.go(-1)
}
const editRef = shallowRef<InstanceType<typeof EditPopup>>()
const tableRef = shallowRef<InstanceType<typeof ElTable>>()
const showEdit = ref(false)
const paramsData: any = reactive({
diy_id: route.query.did,
})
const { type } = defineProps(['type'])
type && (paramsData.type = type)
const { pager, getLists } = usePaging({
fetchFun: apiDiyTemplateFaceList,
params: paramsData,
})
const handleAdd = async () => {
showEdit.value = true
await nextTick()
editRef.value?.open('add', pager)
}
const handleEdit = async (data: any) => {
showEdit.value = true
await nextTick()
editRef.value?.open('edit', pager)
editRef.value?.getDetail(data)
}
const handleDelete = async (id: number) => {
await feedback.confirm('确定要删除?')
await apiDiyTemplateFaceDelete({ id })
getLists()
}
getLists()
</script>
<template>
<div class="edit-popup">
<popup
ref="popupRef"
:title="popupTitle"
:async="true"
width="550px"
@confirm="handleSubmit"
@close="handleClose"
>
<el-form
ref="formRef"
:model="formData"
label-width="120px"
:rules="formRules"
>
<el-form-item label="分类名称" prop="title">
<el-input
v-model="formData.title"
placeholder="请输入分类名称"
clearable
/>
</el-form-item>
<el-form-item label="父级菜单" prop="parent_id" v-if="mode == 'add'">
<el-tree-select
class="flex-1"
v-model="formData.parent_id"
:data="menuOptions"
clearable
node-key="id"
:props="{
label: 'title'
}"
:default-expand-all="true"
placeholder="请选择父级菜单"
check-strictly
/>
</el-form-item>
<el-form-item label="排序" prop="idx">
<div>
<el-input-number v-model="formData.idx" :min="1" :max="9999" />
<div class="form-tips">默认为1, 数值越小越排前</div>
</div>
</el-form-item>
</el-form>
</popup>
</div>
</template>
<script lang="ts" setup>
import type { FormInstance } from 'element-plus'
import { shopTypeUpdate, shopTypeSave } from '@/api/product'
import Popup from '@/components/popup/index.vue'
import { arrayToTree, treeToArray } from '@/utils/util'
const emit = defineEmits(['success', 'close'])
const formRef = shallowRef<FormInstance>()
const popupRef = shallowRef<InstanceType<typeof Popup>>()
const mode = ref('add')
const popupTitle = computed(() => {
return mode.value == 'edit' ? '编辑分类' : '新增分类'
})
const menuOptions = ref<any[]>([])
const formData = reactive({
id: '',
title: '',
idx: 1,
status: 1,
parent_id: ''
})
const formRules: any = reactive({
title: [
{
required: true,
message: '请输入标签名称',
trigger: 'blur'
}
],
idx: [
{
required: true,
message: '请输入排序',
trigger: 'blur'
}
]
})
const getMenu = (menuList: any[]) => {
const menu: any = { id: 'all', title: '顶级', children: [] }
menu.children = arrayToTree(treeToArray(menuList, { children: 'list' }), {
children: 'children',
id: 'id',
parentId: 'parent_id',
number: 2
})
menuOptions.value.push(menu)
}
const handleSubmit = async () => {
await formRef.value?.validate()
const obj: any = { ...toRaw(formData) }
if (obj.parent_id == 'all') {
delete obj.parent_id
}
if (obj.id === '') delete obj.id
if (obj.id && obj.parent_id) delete obj.parent_id
mode.value == 'edit' ? await shopTypeUpdate(obj) : await shopTypeSave(obj)
popupRef.value?.close()
emit('success')
}
const open = (key = 'add', pager: any) => {
mode.value = key
popupRef.value?.open()
getMenu(pager.lists)
}
const setFormData = (data: Record<any, any>) => {
for (const key in formData) {
if (data[key] != null && data[key] != undefined) {
//@ts-ignore
formData[key] = data[key]
}
}
}
const getDetail = async (row: Record<string, any>) => {
setFormData(row)
}
const handleClose = () => {
emit('close')
}
defineExpose({
open,
setFormData,
getDetail
})
</script>
<template>
<div>
<el-card class="!border-none" shadow="never" v-loading="pager.loading">
<div class="mb-4">
<el-button type="primary" @click="handleAdd()">
<template #icon>
<icon name="el-icon-Plus" />
</template>
新增
</el-button>
<el-button @click="handleExpand"> 展开/折叠 </el-button>
</div>
<div class="mt-2">
<el-table
ref="tableRef"
size="large"
v-loading="pager.loading"
:data="pager.lists"
row-key="id"
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
>
<el-table-column label="ID" prop="id" min-width="120" />
<el-table-column label="名称" prop="title" min-width="120" />
<el-table-column label="排序" prop="idx" min-width="120" />
<el-table-column
label="创建时间"
prop="create_date"
min-width="120"
/>
<el-table-column label="操作" width="120" fixed="right">
<template #default="{ row }">
<el-button type="primary" link @click="handleEdit(row)">
编辑
</el-button>
<el-button type="danger" link @click="handleDelete(row.id)">
删除
</el-button>
</template>
</el-table-column>
</el-table>
</div>
</el-card>
<edit-popup
v-if="showEdit"
ref="editRef"
@success="getLists"
@close="showEdit = false"
/>
</div>
</template>
<script lang="ts" setup name="productFenlei">
import {
shopTypeChangeStatus,
shopTypeList,
shopTypeChangeTop
} from '@/api/product'
import { usePaging } from '@/hooks/usePaging'
import feedback from '@/utils/feedback'
import EditPopup from './edit.vue'
import type { ElTable } from 'element-plus'
const editRef = shallowRef<InstanceType<typeof EditPopup>>()
const tableRef = shallowRef<InstanceType<typeof ElTable>>()
const showEdit = ref(false)
let isExpand = false
// type*==1设计产品==2成品==4系统素材
const paramsData: any = reactive({
type: 1
})
const { type } = defineProps(['type'])
type && (paramsData.type = type)
const { pager, getLists } = usePaging({
fetchFun: shopTypeList,
params: paramsData
})
const handleAdd = async () => {
showEdit.value = true
await nextTick()
editRef.value?.open('add', pager)
}
const handleEdit = async (data: any) => {
showEdit.value = true
await nextTick()
editRef.value?.open('edit', pager)
editRef.value?.getDetail(data)
}
const handleDelete = async (id: number) => {
await feedback.confirm('确定要删除?')
await shopTypeChangeStatus({ id })
getLists()
}
const handleExpand = () => {
isExpand = !isExpand
toggleExpand(pager.lists, isExpand)
}
const toggleExpand = (children: any[], unfold = true) => {
for (const key in children) {
tableRef.value?.toggleRowExpansion(children[key], unfold)
if (children[key].list) {
toggleExpand(children[key].list!, unfold)
}
}
}
getLists()
</script>
<template>
<div class="edit-popup-2">
<popup
ref="popupRef"
title="绑定模板"
:async="true"
width="700px"
@confirm="handleSubmit"
@close="handleClose"
>
<el-form
ref="formRef"
:model="formData"
label-width="120px"
:rules="formRules"
>
<el-form-item label="模板选择" required>
<foxpsd-template-choose
:haveInput="false"
@change="templateChange"
></foxpsd-template-choose>
</el-form-item>
<el-form-item label="模板已选择列表">
<div>
<div class="flex flex-wrap">
<div
class="mr-2 w-[200px] relative"
v-for="(item, index) in mobanList"
:key="item.id"
>
<div v-if="formData.default_diy_id == item.id">
<el-tag>默认</el-tag>
</div>
<image-contain
v-if="item.img_url"
:src="getImageUrl(item.img_url, 200)"
:width="100"
:height="100"
:preview-src-list="[item.img_url]"
preview-teleported
fit="contain"
/>
<div>
<overflow-tooltip :content="item.title" />
</div>
<el-button
v-if="mobanList.length > 1"
link
type="primary"
@click="mobanList.splice(index, 1)"
>删除</el-button
>
</div>
</div>
</div>
</el-form-item>
</el-form>
</popup>
</div>
</template>
<script lang="ts" setup>
import type { FormInstance } from 'element-plus'
import {
apiDiyTemplateUpdate,
apiDiyTemplateCreate,
apiDiyTemplateBindDiy,
} from '@/api/product'
import Popup from '@/components/popup/index.vue'
import { getImageUrl } from '@/utils/getImgUrl'
import feedback from '@/utils/feedback'
const emit = defineEmits(['success', 'close'])
const formRef = shallowRef<FormInstance>()
const popupRef = shallowRef<InstanceType<typeof Popup>>()
const mode = ref('add')
const mobanList: any = ref([])
const formData = reactive({
id: '',
diy_ids: '', //待绑定的模板
default_diy_id: '',
})
const formRules: any = reactive({
title: [
{
required: true,
message: '请输入标签名称',
trigger: 'blur',
},
],
})
const templateChange = (e: any) => {
console.log(e.id)
if (e.id == formData.id) {
feedback.msgError('不能选择此模板')
return
}
const list = mobanList.value.filter((item: any) => item.id != e.id)
list.push(e)
mobanList.value = list
}
const setDefaultDiy = (item: any) => {
console.log(item)
}
const handleSubmit = async () => {
await formRef.value?.validate()
const obj: any = { ...toRaw(formData) }
if (mobanList.value.length <= 0) {
feedback.msgError('请至少选择一个模板')
return
}
obj.diy_ids = mobanList.value.map((item: any) => item.id).join(',')
await apiDiyTemplateBindDiy(obj)
popupRef.value?.close()
emit('success')
}
const open = async (key = 'add') => {
mode.value = key
popupRef.value?.open()
}
const setFormData = (data: Record<any, any>) => {
formData.id = data.id
formData.default_diy_id = data.id
if (data.children) {
mobanList.value = data.children
}
}
const getDetail = async (row: Record<string, any>) => {
setFormData(row)
}
const handleClose = () => {
emit('close')
}
defineExpose({
open,
setFormData,
getDetail,
})
</script>
<template>
<div class="edit-popup">
<popup ref="popupRef" :title="popupTitle" :async="true" width="700px" @confirm="handleSubmit" @close="handleClose">
<el-form ref="formRef" :model="formData" label-width="120px" :rules="formRules">
<el-form-item label="模板名称" prop="title">
<el-input v-model="formData.title" placeholder="请输入模板名称" clearable />
</el-form-item>
<el-form-item label="产品主图" prop="img_url">
<div>
<div>
<material-picker v-model="formData.img_url" :limit="1" />
</div>
<div class="form-tips">建议尺寸1000*1000px</div>
</div>
</el-form-item>
<el-form-item label="分类" prop="type_id">
<el-cascader v-model="formData.type_id" :options="type_list" :props="{ label: 'title', value: 'id' }" />
</el-form-item>
<el-form-item label="自定义编码" prop="bianma">
<el-input v-model="formData.bianma" placeholder="请输入自定义编码" clearable />
<div class=" text-xs">自定义编码会合成到生产图中(英文或数字)</div>
</el-form-item>
<el-form-item label="生产图格式" prop="sc_img_type">
<div>
<el-radio-group v-model="formData.sc_img_type">
<el-radio :label="1">JPG</el-radio>
<el-radio :label="2">SVG</el-radio>
<el-radio :label="3">TIFF</el-radio>
</el-radio-group>
<div class=" text-xs">没特殊需求,请选择方法jpg及svg,其中svg性能最好</div>
</div>
</el-form-item>
<el-form-item label="尺码图是否立即生成" prop="chima_now_render">
<div>
<el-radio-group v-model="formData.chima_now_render">
<el-radio :label="0">后续生成</el-radio>
<el-radio :label="1">立刻生成</el-radio>
</el-radio-group>
<div class=" text-xs">默认为【后续生成】,可以通过接口等用户下单后再去合成</div>
</div>
</el-form-item>
<el-form-item label="排序" prop="idx">
<div>
<el-input-number v-model="formData.idx" :min="1" :max="9999" />
<div class="form-tips">默认为1, 数值越小越排前</div>
</div>
</el-form-item>
<el-form-item label="描述" prop="content">
<el-input v-model="formData.content" placeholder="请输入描述" type="textarea"
:autosize="{ minRows: 3, maxRows: 3 }" maxlength="200" show-word-limit clearable />
</el-form-item>
</el-form>
</popup>
</div>
</template>
<script lang="ts" setup>
import type { FormInstance } from 'element-plus'
import { shopTypeList, apiDiyTemplateUpdate, apiDiyTemplateCreate } from '@/api/product'
import Popup from '@/components/popup/index.vue'
const emit = defineEmits(['success', 'close'])
const formRef = shallowRef<FormInstance>()
const popupRef = shallowRef<InstanceType<typeof Popup>>()
const mode = ref('add')
const popupTitle = computed(() => {
return mode.value == 'edit' ? '编辑模板' : '新增模板'
})
const formData = reactive({
id: '',
title: '',
idx: 1,
img_url: '',
type_id: '',
bianma: '',
content: '',
sc_img_type: 1, // 1 JPG 2 SVG
chima_now_render:0
})
const formRules: any = reactive({
title: [
{
required: true,
message: '请输入标签名称',
trigger: 'blur'
}
],
idx: [
{
required: true,
message: '请输入排序',
trigger: 'blur'
}
],
img_url: [
{
required: true,
message: '主图',
trigger: 'blur'
}
],
type_id: [
{
required: true,
message: '分类',
trigger: 'blur'
}
],
bianma: [
{
required: true,
message: '自定义编码',
trigger: 'blur'
}
],
sc_img_type: [
{
required: true,
message: '生产图输出格式',
trigger: 'blur'
}
]
})
const handleSubmit = async () => {
await formRef.value?.validate();
let obj: any = { ...toRaw(formData) };
if (obj.id === '') delete obj.id
if (obj.type_id && obj.type_id.length > 0) {
obj.type_id = obj.type_id[obj.type_id.length - 1]
}
mode.value == 'edit' ? await apiDiyTemplateUpdate(obj) : await apiDiyTemplateCreate(obj)
popupRef.value?.close()
emit('success')
}
const type_list = ref([]);
const getData = async () => {
let res = await shopTypeList()
console.log(res)
type_list.value = res.data.list;
}
const open = async (key = 'add') => {
mode.value = key
popupRef.value?.open();
await getData()
}
const setFormData = (data: Record<any, any>) => {
for (const key in formData) {
if (data[key] != null && data[key] != undefined) {
//@ts-ignore
formData[key] = data[key]
}
}
}
const getDetail = async (row: Record<string, any>) => {
setFormData(row);
}
const handleClose = () => {
emit('close')
}
defineExpose({
open,
setFormData,
getDetail
})
</script>
<template>
<div class="article-lists">
<el-card class="!border-none" shadow="never">
<el-form ref="formRef" class="mb-[-16px]" @submit.native.prevent :model="queryParams" :inline="true">
<el-form-item label="编号/标题">
<el-input class="w-[280px]" v-model="queryParams.content" clearable @keyup.enter="resetPage" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="resetPage">查询</el-button>
<el-button @click="resetParams">重置</el-button>
</el-form-item>
</el-form>
</el-card>
<el-card class="!border-none mt-4" shadow="never">
<div class="flex justify-between">
<div class="flex mb-4">
<el-button type="primary" @click="handleAdd">
<template #icon>
<icon name="el-icon-Plus" />
</template>
添加模板
</el-button>
<el-button @click="handleExpand"> 展开/折叠 </el-button>
</div>
<pagination v-model="pager" @change="getLists" />
</div>
<el-table ref="tableRef" class="mt20" @selection-change="handleSelectionChange" size="large" v-loading="pager.loading"
:data="pager.lists" :tree-props="{ children: 'children', hasChildren: 'hasChildren' }" row-key="id">
<el-table-column type="selection" width="55" />
<el-table-column label="展开">
<template #default="{ row }">
<span v-if="row.children && row.children.length >0">关联模板数: {{ row.children.length }}</span>
</template>
</el-table-column>
<el-table-column label="SKU" width="180">
<template #default="{ row }">
<div class="two" v-copy="row.sku">
{{ row.sku }}
<icon class="ml-2" :size="14" color="#38f" name="el-icon-DocumentCopy" />
</div>
</template>
</el-table-column>
<el-table-column label="商品信息">
<template #default="{ row }">
<div class="flex relative">
<image-contain v-if="row.img_url" :src="getImageUrl(row.img_url, 200)" :width="100" :height="100"
:preview-src-list="[row.img_url]" preview-teleported
fit="contain" />
<div class="goodsInfo ml-4">
<div class="title">{{ row.title }}</div>
<div class="mt-2">
<div class="flex">
<div class="one">分类:</div>
<div class="two">
<span v-if="row.db_diy_type">{{ row.db_diy_type.title}}</span>
</div>
</div>
</div>
</div>
</div>
</template>
</el-table-column>
<el-table-column label="编码" prop="bianma" min-width="40" />
<el-table-column label="排序" prop="idx" min-width="40" />
<el-table-column label="生产图生成格式">
<template #default="{ row }">
<el-tag v-if="row.sc_img_type==1">JPG</el-tag>
<el-tag v-if="row.sc_img_type==2">SVG</el-tag>
<el-tag v-if="row.sc_img_type==3">TIFF</el-tag>
</template>
</el-table-column>
<el-table-column label="尺码图是否立即生成">
<template #default="{ row }">
<el-tag v-if="row.chima_now_render==1">立刻生成</el-tag>
<el-tag v-else>后续生成</el-tag>
</template>
</el-table-column>
<el-table-column label="创建时间" prop="create_date"/>
<el-table-column label="上下架">
<template #default="{ row }">
<el-switch v-model="row.status" :active-value="1" :inactive-value="0"
@change="changeStatus($event as number, row.id)" />
</template>
</el-table-column>
<el-table-column label="操作" width="120" fixed="right">
<template #default="{ row }">
<div>
<el-button type="primary" link>
<router-link :to="{
path: '/product/face',
query: {
did: row.id
}
}">
创建层面
</router-link>
</el-button>
</div>
<div>
<el-button type="primary" link>
<router-link :to="{
path: '/product/xiaoguotu',
query: {
did: row.id
}
}">
创建效果图
</router-link>
</el-button>
</div>
<div>
<el-button type="primary" link>
<router-link :to="{
path: '/product/chima',
query: {
did: row.id
}
}">
创建尺码
</router-link>
</el-button>
</div>
<div class=" mt-3">
<el-button type="primary" link @click="handleEdit(row)">
编辑
</el-button>
</div>
<div v-if="!row.parent_id">
<el-button type="primary" link @click="handleEdit(row,'bindDiy')">
绑定模板
</el-button>
</div>
<div v-if="row.children && row.children.length>0">
<el-button type="primary" link @click="unbindDiy(row)">
解绑模板
</el-button>
</div>
<div class="">
<el-button type="danger" link @click="handleDelete(row.id)">
删除
</el-button>
</div>
</template>
</el-table-column>
</el-table>
<div class="flex justify-end mt-4">
<pagination v-model="pager" @change="getLists" />
</div>
</el-card>
<edit-popup v-if="showEdit" ref="editRef" @success="getLists" @close="showEdit = false" />
<bind-diy-popup ref="bindDiyRef" v-if="showEdit2" @success="getLists" @close="showEdit2 = false" />
</div>
</template>
<script lang="ts" setup name="productLists">
import {
foxpsdDiyTemplateListFindAndCountAll,
apiDiyTemplateDelete,
apiDiyTemplateStatus,
apiDiyTemplateUnbindDiy
} from '@/api/product'
import { usePaging } from '@/hooks/usePaging'
import feedback from '@/utils/feedback'
import { getImageUrl } from "@/utils/getImgUrl";
import BindDiyPopup from "./bindDiy.vue"
import EditPopup from './edit.vue'
import type { ElTable } from 'element-plus'
const editRef = shallowRef<InstanceType<typeof EditPopup>>()
const bindDiyRef = shallowRef<InstanceType<typeof BindDiyPopup>>()
const showEdit = ref(false)
const showEdit2 = ref(false)
let isExpand = false
const tableRef = shallowRef<InstanceType<typeof ElTable>>()
const queryParams = reactive({
content: '',
type: 'all',
have_all:0
})
const { pager, getLists, resetPage, resetParams } = usePaging({
fetchFun: foxpsdDiyTemplateListFindAndCountAll,
params: queryParams
})
const selectData = ref<any[]>([])
const handleSelectionChange = (val: any[]) => {
selectData.value = val.map(({ id }) => id)
}
const handleAdd = async () => {
showEdit.value = true;
await nextTick();
editRef.value?.open('add');
}
const handleEdit = async (data: any,key='edit') => {
if(key=='edit'){
showEdit.value = true;
await nextTick();
editRef.value?.open('edit');
editRef.value?.getDetail(data)
}else{
showEdit2.value = true;
await nextTick();
bindDiyRef.value?.open('edit');
bindDiyRef.value?.getDetail(data)
}
}
const unbindDiy = async (row:any)=>{
await feedback.confirm('确定要解绑吗?')
let res = await apiDiyTemplateUnbindDiy({
id:row.id
})
getLists()
}
//上下架
const changeStatus = async (status: number, id: number) => {
try {
await apiDiyTemplateStatus({ id, status })
getLists()
} catch (error) {
getLists()
}
}
const handleExpand = () => {
isExpand = !isExpand
toggleExpand(pager.lists, isExpand)
}
const toggleExpand = (children: any[], unfold = true) => {
for (const key in children) {
tableRef.value?.toggleRowExpansion(children[key], unfold)
if (children[key].list) {
toggleExpand(children[key].list!, unfold)
}
}
}
const handleDelete = async (id: number) => {
await feedback.confirm('确定要删除?')
await apiDiyTemplateDelete({ id})
getLists()
}
onActivated(() => {
getLists()
})
onMounted(() => {
getLists()
})
</script>
<style lang="scss" scoped>
.goodsInfo {
.title {
font-weight: bold;
}
}
:deep(.el-table__row--level-1) {
--el-table-tr-bg-color: var(--el-color-warning-light-9);
}
.foxpsd_box {
.zhutu_data {
display: flex;
align-items: flex-start;
justify-content: space-between;
.right_txt {
font-size: 16px;
font-weight: bold;
color: #333;
.ts {
color: #666;
font-weight: 400;
}
}
}
.boy_detail {
margin-bottom: 20px;
.boy_biaoti {
font-size: 16px;
color: #38f;
}
.img_list {
display: flex;
flex-wrap: wrap;
.item_xiaoguo {
text-align: center;
font-size: 14px;
margin-bottom: 5px;
margin-right: 5px;
}
}
}
}
.nav_her_btn {
display: flex;
align-items: center;
justify-content: flex-end;
font-size: 18px;
color: #38f;
cursor: pointer;
}
</style>
\ No newline at end of file
<template>
<div class="edit-popup">
<popup ref="popupRef" :title="popupTitle" :async="true" width="1000px" @confirm="handleSubmit" @close="handleClose">
<el-form ref="formRef" :model="formData" label-width="140px" :rules="formRules">
<el-row :gutter="20">
<el-col :span="14">
<el-form-item label="名称" prop="title">
<el-input v-model="formData.title" placeholder="请输入名称" clearable />
</el-form-item>
<el-form-item label="排序" prop="idx">
<div>
<el-input-number v-model="formData.idx" :min="1" :max="9999" />
<div class="form-tips">默认为1, 数值越小越排前</div>
</div>
</el-form-item>
<el-form-item label="颜色" prop="color_id">
<el-select v-model="formData.color_id">
<el-option value="">不绑定颜色</el-option>
<el-option :label="item.title" :value="item.id" v-for="item in colorList" :key="item.id"/>
</el-select>
</el-form-item>
<el-form-item class="!mb-0">
<div>
<upload :multiple="false" :action="`${config.baseUrl}/api/v1/upload`" @change="onChange"
@error="onError" type="psd" :saveFoxpsd="false" :show-progress="true">
<el-button :loading="uploadPsdLoading" type="primary">上传PSD文件</el-button>
</upload>
<div>上传时间较长,请耐心等待</div>
</div>
</el-form-item>
<el-form-item label="PSD文件" prop="psd_url">
<el-input v-model="formData.psd_url" placeholder="psd 文件路径" clearable disabled />
</el-form-item>
</el-col>
<el-col :span="10">
<el-form-item label="主图" prop="img_url">
<div>
<div>
<material-picker v-model="formData.img_url" :limit="1" />
</div>
<div class="text-xs">png,jpg,jpeg等格式,最大为100kb,750*750像素</div>
</div>
</el-form-item>
</el-col>
</el-row>
</el-form>
</popup>
</div>
</template>
<script lang="ts" setup>
import type { FormInstance } from 'element-plus'
import {
apiDiyTemplateXiaoguotuUpdate,
apiDiyTemplateXiaoguotuCreate,
apiPsdParser,
apiDiyTemplateColorList
} from '@/api/product'
import Popup from '@/components/popup/index.vue'
import config from '@/config'
import feedback from '@/utils/feedback'
const emit = defineEmits(['success', 'close'])
const formRef = shallowRef<FormInstance>()
const popupRef = shallowRef<InstanceType<typeof Popup>>()
const mode = ref('add')
const popupTitle = computed(() => {
return mode.value == 'edit' ? '编辑效果图' : '新增效果图'
})
const route = useRoute();
const uploadPsdLoading = ref(false)
const formData = reactive({
id: '',
title: '',
idx: 1,
img_url: '',
psd_url: '',
psd_svg: '',
psd_txt: '',
color_id: '',
dpi: '',
width: '',
height: '',
diy_id: route.query.did
})
const formRules: any = reactive({
title: [
{
required: true,
message: '请输入标签名称',
trigger: 'blur'
}
],
idx: [
{
required: true,
message: '请输入排序',
trigger: 'blur'
}
],
width: [
{
required: true,
message: '宽度',
trigger: 'blur'
}
],
height: [
{
required: true,
message: '高度',
trigger: 'blur'
}
],
img_url: [
{
required: true,
message: '主图',
trigger: 'blur'
}
],
mask_url: [
{
required: true,
message: '蒙版图',
trigger: 'blur'
}
]
})
const onChange = async (e: any) => {
console.log(e);
uploadPsdLoading.value = true;
let relativePath = e.response.data.relativePath;
let res = await apiPsdParser({
lianjie: relativePath,
upload: 'oss'
})
if (res.data.width > 1600 || res.data.height > 1600) {
feedback.msgError("psd 最大可上传1600*1600像素");
return
}
formData.img_url = res.data.img_url;
formData.psd_url = res.data.relativePath;
formData.psd_svg = res.data.svg;
formData.psd_txt = res.data.txt;
formData.dpi = res.data.dpi;
formData.width = res.data.width;
formData.height = res.data.height;
uploadPsdLoading.value = false;
}
const onError = (e: any) => {
console.log(e);
}
const handleSubmit = async () => {
await formRef.value?.validate();
let obj: any = { ...toRaw(formData) };
if (obj.id === '') delete obj.id
if (obj.id) delete obj.diy_id
mode.value == 'edit' ? await apiDiyTemplateXiaoguotuUpdate(obj) : await apiDiyTemplateXiaoguotuCreate(obj)
popupRef.value?.close()
emit('success')
}
const colorList:any= ref([]);
const getData = async () => {
let res:any = await apiDiyTemplateColorList({
diy_id: route.query.did
})
colorList.value = res.data.list;
}
const open = async (key = 'add', pager: any) => {
mode.value = key
popupRef.value?.open();
await getData();
}
const setFormData = (data: Record<any, any>) => {
for (const key in formData) {
if (data[key] != null && data[key] != undefined) {
//@ts-ignore
formData[key] = data[key]
}
}
}
const getDetail = async (row: Record<string, any>) => {
setFormData(row);
}
const handleClose = () => {
emit('close')
}
defineExpose({
open,
setFormData,
getDetail
})
</script>
<template>
<div>
<el-card class="!border-none" shadow="never">
<el-page-header :content="$route.meta.title" @back="goBack" />
</el-card>
<el-card class="!border-none mt-2" shadow="never" v-loading="pager.loading" v-if="activeTab=='xiaoguotu'">
<el-tabs v-model="activeTab" class=" bg-white" >
<el-tab-pane label="效果图" name="xiaoguotu"></el-tab-pane>
<el-tab-pane label="颜色" name="color"></el-tab-pane>
</el-tabs>
<div class="mb-4 mt-2">
<el-button type="primary" @click="handleAdd()">
<template #icon>
<icon name="el-icon-Plus" />
</template>
新增效果图
</el-button>
</div>
<div class="mt-2">
<el-table ref="tableRef" size="large" v-loading="pager.loading" :data="pager.lists" row-key="id"
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }">
<el-table-column label="ID" prop="id" />
<el-table-column label="主图">
<template #default="{ row }">
<image-contain v-if="row.img_url" :src="getImageUrl(row.img_url, 200)" :width="80" :height="80"
:preview-src-list="[row.img_url]" preview-teleported fit="contain" />
</template>
</el-table-column>
<el-table-column label="名称" prop="title" min-width="120" />
<el-table-column label="排序" prop="idx" />
<el-table-column label="尺寸" min-width="120">
<template #default="{ row }">
<div>{{ row.width }} X {{ row.height }} 像素</div>
</template>
</el-table-column>
<el-table-column label="颜色" min-width="120">
<template #default="{ row }">
<div v-if="row.db_diy_color" >
<div class="w-[20px] h-[20px]" :style="{background:row.db_diy_color.sezhi}"></div>
<div>{{ row.db_diy_color.title }}</div>
</div>
<span v-else>未绑定</span>
</template>
</el-table-column>
<el-table-column label="分辨率" min-width="120">
<template #default="{ row }">
<div>{{ row.dpi }} DPI</div>
</template>
</el-table-column>
<el-table-column label="创建时间" prop="create_date" min-width="120" />
<el-table-column label="操作" width="120" fixed="right">
<template #default="{ row }">
<el-button type="primary" link @click="handleEdit(row)">
编辑
</el-button>
<el-button type="danger" link @click="handleDelete(row.id)">
删除
</el-button>
</template>
</el-table-column>
</el-table>
</div>
</el-card>
<edit-popup v-if="showEdit" ref="editRef" @success="getLists" @close="showEdit = false" />
<ColorPage :activeTab="activeTab" v-if="activeTab=='color'" @on-change="(e)=>{activeTab=e}"/>
</div>
</template>
<script lang="ts" setup name="productFenlei">
import { apiDiyTemplateXiaoguotuList, apiDiyTemplateXiaoguotuDelete } from '@/api/product'
import { usePaging } from '@/hooks/usePaging'
import feedback from '@/utils/feedback'
import EditPopup from './edit.vue'
import type { ElTable } from 'element-plus'
import useMultipleTabs from '@/hooks/useMultipleTabs'
import { getImageUrl } from "@/utils/getImgUrl";
import ColorPage from "../color/index.vue";
const { removeTab } = useMultipleTabs()
const route = useRoute();
const router = useRouter();
const goBack = () => {
removeTab();
router.go(-1);
}
const editRef = shallowRef<InstanceType<typeof EditPopup>>()
const tableRef = shallowRef<InstanceType<typeof ElTable>>()
const showEdit = ref(false)
const activeTab = ref('xiaoguotu')
const paramsData: any = reactive({
diy_id: route.query.did
})
const { type } = defineProps(['type']);
type && (paramsData.type = type);
const { pager, getLists } = usePaging({
fetchFun: apiDiyTemplateXiaoguotuList,
params: paramsData
})
const handleAdd = async () => {
showEdit.value = true;
await nextTick();
editRef.value?.open('add', pager);
}
const handleEdit = async (data: any) => {
showEdit.value = true;
await nextTick();
editRef.value?.open('edit', pager);
editRef.value?.getDetail(data)
}
const handleDelete = async (id: number) => {
await feedback.confirm('确定要删除?')
await apiDiyTemplateXiaoguotuDelete({ id })
getLists()
}
getLists()
</script>
<!-- 个人资料 -->
<template>
<div class="user-setting">
<el-card class="!border-none" shadow="never">
<el-form ref="formRef" class="ls-form" :model="formData" :rules="rules" label-width="100px">
<el-form-item label="当前密码:" prop="password_3">
<div class="w-80">
<el-input v-model.trim="formData.password_3" placeholder="修改密码时必填, 不修改密码时留空" type="password"
show-password />
</div>
</el-form-item>
<el-form-item label="新的密码:" prop="password_1">
<div class="w-80">
<el-input v-model.trim="formData.password_1" placeholder="修改密码时必填, 不修改密码时留空" type="password"
show-password />
</div>
</el-form-item>
<el-form-item label="确定密码:" prop="password_2">
<div class="w-80">
<el-input v-model.trim="formData.password_2" placeholder="修改密码时必填, 不修改密码时留空" type="password"
show-password />
</div>
</el-form-item>
</el-form>
</el-card>
<footer-btns>
<el-button type="primary" @click="handleSubmit">保存</el-button>
</footer-btns>
</div>
</template>
<script setup lang="ts" name="userSetting">
import { setUserInfo } from '@/api/user'
import useUserStore from '@/stores/modules/user/user'
import feedback from '@/utils/feedback'
import type { FormInstance } from 'element-plus'
const formRef = ref<FormInstance>()
const userStore = useUserStore()
// 表单数据
const formData = reactive({
password_3: '', // 当前密码
password_1: '', // 新的密码
password_2: '' // 确定密码
})
// 表单校验规则
const rules = reactive<object>({
password_1: [
{
required: true,
message: '请输入新的密码',
trigger: ['blur']
}
],
password_2: [
{
required: true,
message: '请输入确定密码',
trigger: ['blur']
}
],
password_3: [
{
required: true,
message: '请输入当前密码',
trigger: ['blur']
}
]
})
// 设置个人设置
const setUser = async () => {
if (formData.password_3 || formData.password_1 || formData.password_2) {
if (!formData.password_3) {
return feedback.msgError('请输入当前密码')
}
if (!formData.password_1) {
return feedback.msgError('请输入新的密码')
}
if (!formData.password_2) {
return feedback.msgError('请输入确定密码')
}
if (formData.password_1 != formData.password_2) {
return feedback.msgError('两次输入的密码不一样')
}
}
if (formData.password_3 && formData.password_1 && formData.password_2) {
if (formData.password_3.length < 6 || formData.password_3.length > 32) {
return feedback.msgError('密码长度在6到32之间')
}
if (formData.password_1.length < 6 || formData.password_1.length > 32) {
return feedback.msgError('密码长度在6到32之间')
}
if (formData.password_2.length < 6 || formData.password_2.length > 32) {
return feedback.msgError('密码长度在6到32之间')
}
}
await setUserInfo(formData)
feedback.msgSuccess("操作成功");
userStore.getUserInfo();
}
// 提交数据
const handleSubmit = async () => {
await formRef.value?.validate()
setUser()
}
</script>
<style lang="scss" scoped></style>
<template>
<div>
<el-card class="!border-none" shadow="never">
<el-page-header :content="$route.meta.title" @back="goBack" />
</el-card>
<template v-if="data">
<el-card class="!border-none mt-2" shadow="never">
<el-descriptions class="margin-top" :title="data.sku + ' ' + data.db_diy.title" :column="3" :border="true">
<template #extra>
<div class="flex">
<div>
<el-tag size="large" type="warning" v-if="data.xgt_status == 9">效果图待生成</el-tag>
<el-tag size="large" type="success" v-else-if="data.xgt_status == 1">效果图已生成</el-tag>
<el-tag size="large" type="danger" v-else>效果图失败</el-tag>
</div>
<div class="ml-3">
<el-tag size="large" type="warning" v-if="data.status == 9">总待生成</el-tag>
<el-tag size="large" type="success" v-else-if="data.status == 1">总已生成</el-tag>
<el-tag size="large" type="danger" v-else>总失败</el-tag>
</div>
</div>
</template>
<el-descriptions-item label="SKU">{{ data.sku }}</el-descriptions-item>
<el-descriptions-item label="自定义编码">{{ data.bianma }}</el-descriptions-item>
<el-descriptions-item label="模板SKU">{{ data.db_diy.sku }}</el-descriptions-item>
<el-descriptions-item label="用户昵称">{{ data.db_diy_user.name }}</el-descriptions-item>
<el-descriptions-item label="用户SKU">{{ data.db_diy_user.sku }}</el-descriptions-item>
<el-descriptions-item label="回调地址">{{ data.callback }}</el-descriptions-item>
<el-descriptions-item label="创建时间">{{ data.create_date }}</el-descriptions-item>
<el-descriptions-item label="效果图完成时间">{{ data.xgt_update_date }}</el-descriptions-item>
<el-descriptions-item label="总完成时间">{{ data.update_date }}</el-descriptions-item>
</el-descriptions>
</el-card>
<el-card class="!border-none mt-2" shadow="never">
<div class=" font-bold">用户设计图</div>
<div class="mt-2">
<image-contain v-for="item in data.face_list" :src="getImageUrl(item.img_url || morenImg, 100)"
:width="80" :height="80" :preview-src-list="[getImageUrl(item.img_url || morenImg)]"
preview-teleported fit="contain" />
</div>
</el-card>
<el-card class="!border-none mt-2" shadow="never">
<div class=" font-bold">效果图</div>
<div class="mt-4">
<image-contain v-for="item in data.xiaoguotu_list" :src="getImageUrl(item.img_url || morenImg, 100)"
:width="80" :height="80" :preview-src-list="[getImageUrl(item.img_url || morenImg)]"
preview-teleported fit="contain" />
</div>
</el-card>
<el-card class="!border-none mt-2" shadow="never">
<div class=" font-bold">尺码图</div>
<div class="flex mt-4">
<el-table class="mt-4" size="large" :data="data.chima_list">
<el-table-column label="标题" prop="title"></el-table-column>
<el-table-column label="编码" prop="title"></el-table-column>
<el-table-column label="文件路径">
<template #default="{ row }">
<el-button link type="primary" v-if="row.img_url">
<a :href="getImageUrl(row.img_url)" target="_blank">{{row.img_url}}</a>
</el-button>
<div v-else>未生成</div>
</template>
</el-table-column>
<el-table-column label="文件路径">
<template #default="{ row }">
<el-button link type="primary" v-if="row.img_url">
<a :href="getImageUrl(row.img_url)" target="_blank">下载</a>
</el-button>
</template>
</el-table-column>
</el-table>
</div>
</el-card>
</template>
</div>
</template>
<script lang="ts" setup name="productFenlei">
import type { ElTable } from 'element-plus'
import useMultipleTabs from '@/hooks/useMultipleTabs'
import { getImageUrl } from "@/utils/getImgUrl";
import { apiDiyUserSaveItem } from "@/api/member"
const morenImg = 'https://foxpsd.com/diy/shop/images/xiaoguotu.jpg';
const { removeTab } = useMultipleTabs()
const router = useRouter();
const route = useRoute();
const goBack = () => {
removeTab();
router.go(-1);
}
const data = ref();
const getData = async () => {
let res: any = await apiDiyUserSaveItem({ sku: route.query.sku })
data.value = res.data;
}
const getHouzhui = (url: string): boolean => {
if (/\.(svg|tiff)$/.test(url)) {
return true
} else {
return false
}
}
onActivated(() => {
getData();
})
onMounted(() => {
getData();
})
</script>
<template>
<div class="article-lists">
<el-card class="!border-none" shadow="never">
<el-form ref="formRef" class="mb-[-16px]" @submit.native.prevent :model="queryParams" :inline="true">
<el-form-item label="编号/标题">
<el-input class="w-[280px]" v-model="queryParams.content" clearable @keyup.enter="resetPage" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="resetPage">查询</el-button>
<el-button @click="resetParams">重置</el-button>
</el-form-item>
</el-form>
</el-card>
<el-card class="!border-none mt-4" shadow="never">
<div class="flex justify-between">
<div class="flex mb-4">
<el-button type="primary" @click="downUserSave(selectData.join(','))" :disabled="selectData.length>0?false:true">批量下载</el-button>
<el-button type="danger" @click="handleDelete(selectData.join(','))" :disabled="selectData.length>0?false:true">批量删除</el-button>
</div>
<pagination v-model="pager" @change="getLists" />
</div>
<el-table class="mt-4" @selection-change="handleSelectionChange" size="large" v-loading="pager.loading"
:data="pager.lists">
<el-table-column type="selection" width="55" />
<el-table-column label="SKU" width="200">
<template #default="{ row }">
<div>
<div>
<router-link :to="`/userSave/lists/item?sku=${row.sku}`">
<el-button link type="primary">{{ row.sku }}</el-button>
</router-link>
</div>
<div v-copy="row.sku" class="flex items-center">
<el-button link type="primary">复制</el-button>
<icon class="ml-2" :size="14" color="#38f" name="el-icon-DocumentCopy" />
</div>
</div>
</template>
</el-table-column>
<el-table-column label="基础信息" width="150" >
<template #default="{ row }">
<div v-if="row.db_diy">模板标题:{{ row.db_diy.title }}</div>
<div>自定义编码:{{row.bianma}}</div>
</template>
</el-table-column>
<el-table-column label="用户设计图" min-width="150">
<template #default="{ row }">
<div class="flex flex-wrap relative" v-if="row.face_list.length > 0">
<image-contain v-for="item in row.face_list" :src="getImageUrl(item.img_url || morenImg, 100)"
:width="50" :height="50" :preview-src-list="[getImageUrl(item.img_url || morenImg)]"
preview-teleported fit="contain" class="mr-2 mb-2"/>
</div>
<div v-else>-</div>
</template>
</el-table-column>
<el-table-column label="效果图" min-width="150">
<template #default="{ row }">
<div class="flex flex-wrap relative" v-if="row.xiaoguotu_list.length > 0">
<image-contain v-for="item in row.xiaoguotu_list"
:src="getImageUrl(item.img_url || morenImg, 100)" :width="50" :height="50"
:preview-src-list="[getImageUrl(item.img_url || morenImg)]" preview-teleported
fit="contain" class="mr-2 mb-2"/>
</div>
<div v-else>-</div>
</template>
</el-table-column>
<el-table-column label="尺码图" min-width="150">
<template #default="{ row }">
<div class="flex relative" v-if="row.chima_list.length > 0">
<router-link :to="`/userSave/lists/item?sku=${row.sku}`">
<el-button type="primary" link>
点击查看
</el-button>
</router-link>
</div>
<div v-else>-</div>
</template>
</el-table-column>
<el-table-column label="效果图状态">
<template #default="{ row }">
<el-tag type="success" v-if="row.xgt_status == 1">已生成</el-tag>
<el-tag type="warning" v-else-if="row.xgt_status == 9">待生成</el-tag>
<el-tag type="danger" v-else>失败</el-tag>
</template>
</el-table-column>
<el-table-column label="总状态">
<template #default="{ row }">
<el-tag type="success" v-if="row.status == 1">已生成</el-tag>
<el-tag type="warning" v-else-if="row.status == 9">待生成</el-tag>
<el-tag type="danger" v-else>失败</el-tag>
</template>
</el-table-column>
<el-table-column label="时间" width="180">
<template #default="{ row }">
<div>创建时间:<div>{{ row.create_date }}</div></div>
<div>效果图完成时间:<div>{{ row.xgt_update_date }}</div></div>
<div>总完成时间:<div>{{ row.update_date }}</div></div>
</template>
</el-table-column>
<el-table-column label="操作" width="160" fixed="right">
<template #default="{ row }">
<div class="">
<router-link :to="`/userSave/lists/item?sku=${row.sku}`">
<el-button type="primary" link>
详情
</el-button>
</router-link>
</div>
<div class="">
<el-button type="primary" link @click="handleAdd(row)">
重新生成指定尺码
</el-button>
</div>
<div class="mt-1">
<el-button type="danger" link @click="handleDelete(row.sku)">
删除
</el-button>
</div>
</template>
</el-table-column>
</el-table>
<div class="flex justify-end mt-4">
<pagination v-model="pager" @change="getLists" />
</div>
</el-card>
<RenderChima v-if="showEdit" ref="editRef" @success="getLists" @close="showEdit = false" />
</div>
</template>
<script lang="ts" setup name="productLists">
import { apiDiyUserSaveList, apiDiyUserSaveDelete,apiDiyUserDownCreate} from "@/api/member"
import { usePaging } from '@/hooks/usePaging'
import feedback from '@/utils/feedback'
import { getImageUrl } from "@/utils/getImgUrl";
import RenderChima from "./renderChima.vue"
const showEdit = ref(false)
const editRef = shallowRef<InstanceType<typeof RenderChima>>()
const morenImg = 'https://foxpsd.com/diy/shop/images/xiaoguotu.jpg';
const queryParams = reactive({
content: '',
})
const { pager, getLists, resetPage, resetParams } = usePaging({
fetchFun: apiDiyUserSaveList,
params: queryParams
})
const selectData = ref<any[]>([])
const handleSelectionChange = (val: any[]) => {
selectData.value = val.map(({ sku }) => sku)
}
const downUserSave =async (skus: string) => {
await feedback.confirm('确定要下载吗?')
await apiDiyUserDownCreate({ skus })
feedback.msgSuccess("操作成功")
getLists()
}
const handleDelete = async (skus: string) => {
await feedback.confirm('确定要删除?')
await apiDiyUserSaveDelete({ skus })
getLists()
}
const handleAdd = async (row:any) => {
showEdit.value = true;
await nextTick();
editRef.value?.open('add',row);
}
onActivated(() => {
getLists()
})
onMounted(() => {
getLists()
})
</script>
<style lang="scss" scoped>
.goodsInfo {
.title {
font-weight: bold;
}
}
.foxpsd_box {
.zhutu_data {
display: flex;
align-items: flex-start;
justify-content: space-between;
.right_txt {
font-size: 16px;
font-weight: bold;
color: #333;
.ts {
color: #666;
font-weight: 400;
}
}
}
.boy_detail {
margin-bottom: 20px;
.boy_biaoti {
font-size: 16px;
color: #38f;
}
.img_list {
display: flex;
flex-wrap: wrap;
.item_xiaoguo {
text-align: center;
font-size: 14px;
margin-bottom: 5px;
margin-right: 5px;
}
}
}
}
.nav_her_btn {
display: flex;
align-items: center;
justify-content: flex-end;
font-size: 18px;
color: #38f;
cursor: pointer;
}</style>
\ No newline at end of file
<template>
<div class="edit-popup">
<popup ref="popupRef" title="重新生成指定尺码" :async="true" width="800px" @confirm="handleSubmit" @close="handleClose">
<el-form ref="formRef" :model="formData" label-width="160px" :rules="formRules" class="w-[90%]" v-if="diy">
<el-form-item label="选择尺码" prop="chima_id">
<el-select v-model="formData.chima_id" placeholder="请选择要生成的尺码">
<el-option :value="item.id" :label="'标题:'+item.title + ' 编码:' + item.bianma"
v-for="item in diy.chimaList"></el-option>
</el-select>
</el-form-item>
<el-form-item label="生成图片格式" prop="sc_img_type">
<el-radio-group v-model="formData.sc_img_type">
<el-radio :label="1">JPG</el-radio>
<el-radio :label="2">SVG</el-radio>
<el-radio :label="3">TIFF</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="额外关联的数据" prop="posts_content">
<div class="w-full">
<el-input v-model="formData.posts_content" placeholder="JSON格式" type="textarea"
:autosize="{ minRows: 3, maxRows: 3 }" maxlength="200" show-word-limit clearable />
<div>非必填,没有可以不写</div>
<div>
<div>结构演示</div>
[
{
"name":"素材",
"content":"https://img.foxpsd.com/images%2Fth3.jpg"
}
]
</div>
</div>
</el-form-item>
</el-form>
</popup>
</div>
</template>
<script lang="ts" setup>
import type { FormInstance } from 'element-plus'
import { apiDiyTemplateItem } from '@/api/product'
import { apiDiyUserSaveChimaRender } from "@/api/member";
import Popup from '@/components/popup/index.vue'
const emit = defineEmits(['success', 'close'])
const formRef = shallowRef<FormInstance>()
const popupRef = shallowRef<InstanceType<typeof Popup>>()
const mode = ref('add')
const formData = reactive({
chima_id: '',
sku:'',
posts_content: '',
sc_img_type:1
})
const formRules: any = reactive({
chima_id: [
{
required: true,
message: '请选择尺码',
trigger: 'blur'
}
]
})
const handleSubmit = async () => {
await formRef.value?.validate();
let obj: any = { ...toRaw(formData) };
if(obj.posts_content){
obj.posts = JSON.parse(obj.posts_content);
delete obj.posts_content;
}
await apiDiyUserSaveChimaRender(obj)
popupRef.value?.close()
emit('success')
}
const userSaveItem = ref();
const diy = ref();
const getData = async (sku: string) => {
let res = await apiDiyTemplateItem({
sku
})
diy.value = res.data
formData.sc_img_type = diy.value.sc_img_type
}
const open = (key = 'add', row: any) => {
userSaveItem.value = row;
formData.sku = row.sku;
getData(row.db_diy.sku)
mode.value = key
popupRef.value?.open();
}
const setFormData = (data: Record<any, any>) => {
for (const key in formData) {
if (data[key] != null && data[key] != undefined) {
//@ts-ignore
formData[key] = data[key]
}
}
}
const getDetail = async (row: Record<string, any>) => {
setFormData(row);
}
const handleClose = () => {
emit('close')
}
defineExpose({
open,
setFormData,
getDetail
})
</script>
<template>
<div class="article-lists">
<el-card class="!border-none" shadow="never">
<el-form ref="formRef" class="mb-[-16px]" @submit.native.prevent :model="queryParams" :inline="true">
<el-form-item label="编号/标题">
<el-input class="w-[280px]" v-model="queryParams.content" clearable @keyup.enter="resetPage" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="resetPage">查询</el-button>
<el-button @click="resetParams">重置</el-button>
</el-form-item>
</el-form>
</el-card>
<el-card class="!border-none mt-4" shadow="never">
<div class="flex justify-between">
<div class="flex mb-4">
<el-button type="danger" @click="handleDelete(selectData.join(','))"
:disabled="selectData.length > 0 ? false : true">批量删除</el-button>
</div>
<pagination v-model="pager" @change="getLists" />
</div>
<el-table class="mt-4" @selection-change="handleSelectionChange" size="large" v-loading="pager.loading"
:data="pager.lists">
<el-table-column type="selection" width="55" />
<el-table-column label="SKU" prop="sku"></el-table-column>
<el-table-column label="状态">
<template #default="{ row }">
<el-tag type="success" v-if="row.status == 1">已生成</el-tag>
<el-tag type="warning" v-else-if="row.status == 9">待生成</el-tag>
<el-tag type="danger" v-else>失败</el-tag>
</template>
</el-table-column>
<el-table-column label="下载链接">
<template #default="{ row }">
<a :href="getImageUrl(row.zip)" v-if="row.zip">
<el-button link type="primary">点击下载</el-button>
</a>
<div v-else>-</div>
</template>
</el-table-column>
<el-table-column label="创建时间" prop="create_date"></el-table-column>
<el-table-column label="更新时间" prop="update_date"></el-table-column>
<el-table-column label="操作" width="120" fixed="right">
<template #default="{ row }">
<div class="mt-1">
<el-button type="danger" link @click="handleDelete(row.sku)">
删除
</el-button>
</div>
</template>
</el-table-column>
</el-table>
<div class="flex justify-end mt-4">
<pagination v-model="pager" @change="getLists" />
</div>
</el-card>
</div>
</template>
<script lang="ts" setup name="productLists">
import { apiDiyUserDownList, apiDiyUserDownDelete } from "@/api/member"
import { usePaging } from '@/hooks/usePaging'
import feedback from '@/utils/feedback'
import { getImageUrl } from "@/utils/getImgUrl";
const queryParams = reactive({
content: '',
})
const { pager, getLists, resetPage, resetParams } = usePaging({
fetchFun: apiDiyUserDownList,
params: queryParams
})
const selectData = ref<any[]>([])
const handleSelectionChange = (val: any[]) => {
selectData.value = val.map(({ sku }) => sku)
}
const handleDelete = async (skus: string) => {
await feedback.confirm('删除后文件也会删掉,确定要删除?')
await apiDiyUserDownDelete({ skus })
getLists()
}
onActivated(() => {
getLists()
})
onMounted(() => {
getLists()
})
</script>
<style lang="scss" scoped>
.goodsInfo {
.title {
font-weight: bold;
}
}
.foxpsd_box {
.zhutu_data {
display: flex;
align-items: flex-start;
justify-content: space-between;
.right_txt {
font-size: 16px;
font-weight: bold;
color: #333;
.ts {
color: #666;
font-weight: 400;
}
}
}
.boy_detail {
margin-bottom: 20px;
.boy_biaoti {
font-size: 16px;
color: #38f;
}
.img_list {
display: flex;
flex-wrap: wrap;
.item_xiaoguo {
text-align: center;
font-size: 14px;
margin-bottom: 5px;
margin-right: 5px;
}
}
}
}
.nav_her_btn {
display: flex;
align-items: center;
justify-content: flex-end;
font-size: 18px;
color: #38f;
cursor: pointer;
}</style>
\ No newline at end of file
<template>
<div class="workbench">
<div class="lg:flex">
<el-card class="!border-none mb-4 flex-1" shadow="never">
FOXPSD DIY 模板管理系统
</el-card>
</div>
</div>
</template>
<script lang="ts" setup name="workbench">
onMounted(() => {
})
</script>
<style lang="scss" scoped>
.card-title {
cursor: pointer;
}
.card-title.cur {
color: #38f;
}
</style>
/** @type {import('tailwindcss').Config} */
module.exports = {
content: ['./index.html', './src/**/*.{vue,js,ts,jsx,tsx}'],
theme: {
colors: {
white: 'var(--color-white)',
primary: {
DEFAULT: 'var(--el-color-primary)',
'light-3': 'var(--el-color-primary-light-3)',
'light-5': 'var(--el-color-primary-light-5)',
'light-7': 'var(--el-color-primary-light-7)',
'light-8': 'var(--el-color-primary-light-8)',
'light-9': 'var(--el-color-primary-light-9)',
'dark-2': 'var(--el-color-primary-dark-2)',
},
success: 'var(--el-color-success)',
warning: 'var(--el-color-warning)',
danger: 'var(--el-color-danger)',
error: 'var(--el-color-error)',
info: 'var(--el-color-info)',
body: 'var(--el-bg-color)',
page: 'var(--el-bg-color-page)',
'tx-primary': 'var(--el-text-color-primary)',
'tx-regular': 'var(--el-text-color-regular)',
'tx-secondary': 'var(--el-text-color-secondary)',
'tx-placeholder': 'var(--el-text-color-placeholder)',
'tx-disabled': 'var(--el-text-color-disabled)',
br: 'var(--el-border-color)',
'br-light': 'var(--el-border-color-light)',
'br-extra-light': 'var(--el-border-color-extra-light)',
'br-dark': 'var( --el-border-color-dark)',
fill: 'var(--el-fill-color)',
'fill-light': 'var(--el-fill-color-light)',
'fill-lighter': 'var(--el-fill-color-lighter)',
mask: 'var(--el-mask-color)',
},
fontFamily: {
sans: [
'PingFang SC',
'Arial',
'Hiragino Sans GB',
'Microsoft YaHei',
'sans-serif',
],
},
boxShadow: {
DEFAULT: 'var(--el-box-shadow)',
light: 'var(--el-box-shadow-light)',
lighter: 'var(--el-box-shadow-lighter)',
dark: 'var(--el-box-shadow-dark)',
},
fontSize: {
xs: 'var(--el-font-size-extra-small)',
sm: 'var( --el-font-size-small)',
base: 'var( --el-font-size-base)',
lg: 'var( --el-font-size-medium)',
xl: 'var( --el-font-size-large)',
'2xl': 'var( --el-font-size-extra-large)',
'3xl': '20px',
'4xl': '24px',
'5xl': '28px',
'6xl': '30px',
'7xl': '36px',
'8xl': '48px',
'9xl': '60px',
},
spacing: {
px: '1px',
0: '0px',
0.5: '2px',
1: '4px',
1.5: '6px',
2: '8px',
2.5: '10px',
3: '12px',
3.5: '14px',
4: '16px',
5: '20px',
6: '24px',
7: '28px',
8: '32px',
9: '36px',
10: '40px',
11: '44px',
12: '48px',
14: '56px',
16: '64px',
20: '80px',
24: '96px',
28: '112px',
32: '128px',
36: '144px',
40: '160px',
44: '176px',
48: '192px',
52: '208px',
56: '224px',
60: '240px',
64: '256px',
72: '288px',
80: '320px',
96: '384px',
},
lineHeight: {
none: '1',
tight: '1.25',
snug: '1.375',
normal: '1.5',
relaxed: '1.625',
loose: '2',
3: '12px',
4: '16px',
5: '20px',
6: '24px',
7: '28px',
8: '32px',
9: '36px',
10: '40px',
},
},
plugins: [
require('@tailwindcss/line-clamp'), // 引入插件
],
}
// {
// "extends": "@vue/tsconfig/tsconfig.node.json",
// "include": ["vite.config.*"],
// "compilerOptions": {
// "composite": true,
// "types": ["node"]
// }
// }
{
"extends": "@vue/tsconfig/tsconfig.node.json",
"include": ["vite.config.*"],
"compilerOptions": {
"composite": true,
"types": ["node"],
"ignoreDeprecations": "5.0",
"verbatimModuleSyntax": true
}
}
\ No newline at end of file
{
"extends": "@vue/tsconfig/tsconfig.web.json",
"include": [
"global.d.ts",
"src/**/*",
"src/**/*.vue",
"components.d.ts",
"auto-imports.d.ts",
"typings/**/*.d.ts"
],
"compilerOptions": {
"importsNotUsedAsValues": "remove",
"ignoreDeprecations": "5.0",
"verbatimModuleSyntax": true,
"isolatedModules": true,
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
}
},
"references": [
{
"path": "./tsconfig.config.json"
}
]
}
declare module 'vue3-video-play'
declare module 'css-color-function'
type PromiseFun = (...arg: any[]) => Promise<any>
import 'vue-router'
declare module 'vue-router' {
// 扩展 RouteMeta
interface RouteMeta {
type?: string
perms?: string
title?: string
icon?: string
hidden?: boolean
activeMenu?: string
hideTab?: boolean
keepAlive?: boolean
}
}
import { fileURLToPath, URL } from 'url'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
import { createStyleImportPlugin, ElementPlusResolve } from 'vite-plugin-style-import'
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'
import vueSetupExtend from 'vite-plugin-vue-setup-extend'
// import legacyPlugin from '@vitejs/plugin-legacy'
// https://vitejs.dev/config/
export default defineConfig({
// base: '/foxpsd/',
server: {
host: "0.0.0.0",
hmr: true
},
plugins: [
vue(),
vueJsx(),
AutoImport({
imports: ['vue', 'vue-router'],
resolvers: [ElementPlusResolver()],
eslintrc: {
enabled: true
}
}),
Components({
directoryAsNamespace: true,
resolvers: [ElementPlusResolver()]
}),
createStyleImportPlugin({
resolves: [ElementPlusResolve()]
}),
createSvgIconsPlugin({
// 配置路劲在你的src里的svg存放文件
iconDirs: [fileURLToPath(new URL('./src/assets/icons', import.meta.url))],
symbolId: 'local-icon-[dir]-[name]'
}),
vueSetupExtend()
// legacyPlugin({
// targets: ['defaults', 'IE 11']
// })
],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
}
},
build: {
rollupOptions: {
manualChunks(id: any) {
if (id.includes('node_modules')) {
return id.toString().split('node_modules/')[1].split('/')[0].toString()
}
}
}
}
})
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment