init and commit
24
.eslintrc.cjs
Normal file
@ -0,0 +1,24 @@
|
||||
module.exports = {
|
||||
root: true,
|
||||
env: { browser: true, es2020: true },
|
||||
extends: [
|
||||
'eslint:recommended',
|
||||
'plugin:@typescript-eslint/recommended',
|
||||
'plugin:react-hooks/recommended',
|
||||
],
|
||||
ignorePatterns: ['dist', '.eslintrc.cjs'],
|
||||
parser: '@typescript-eslint/parser',
|
||||
parserOptions: { ecmaVersion: 'latest', sourceType: 'module' },
|
||||
plugins: ['react-refresh'],
|
||||
rules: {
|
||||
'react-refresh/only-export-components': [
|
||||
'warn',
|
||||
{ allowConstantExport: true },
|
||||
],
|
||||
'@typescript-eslint/no-explicit-any':[
|
||||
'off'
|
||||
],
|
||||
'no-mixed-spaces-and-tabs':'off',
|
||||
// 'no-control-regex':0
|
||||
},
|
||||
}
|
26
.gitignore
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
node_modules
|
||||
dist
|
||||
dist-ssr
|
||||
test
|
||||
_local
|
||||
*.local
|
||||
|
||||
# Editor directories and files
|
||||
.vscode/*
|
||||
!.vscode/extensions.json
|
||||
.idea
|
||||
.DS_Store
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
19
index.html
Normal file
@ -0,0 +1,19 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8"/>
|
||||
<link rel="icon" type="image/png" href="/logo.svg"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||
<title>数字人直播</title>
|
||||
<style>
|
||||
.app-loading-text{font-family:"PingFang SC","Microsoft YaHei",sans-serif;position:fixed;left:0;right:0;text-align:center;top:50%;transform:translateY(-50%);font-size:20px}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root" style="min-height: 100vh;">
|
||||
<div class="app-loading-text">
|
||||
</div>
|
||||
</div>
|
||||
<script type="module" src="/src/main.tsx"></script>
|
||||
</body>
|
||||
</html>
|
54
package.json
Normal file
@ -0,0 +1,54 @@
|
||||
{
|
||||
"name": "digital-news-live",
|
||||
"private": true,
|
||||
"version": "1.0.0",
|
||||
"type": "module",
|
||||
"description": "数字人直播间",
|
||||
"scripts": {
|
||||
"dev": "vite --host",
|
||||
"build": "tsc && vite build",
|
||||
"build-test": "tsc && vite build --mode=test",
|
||||
"build-relative": "tsc && vite build --mode=relative",
|
||||
"build-prod": "tsc && vite build --mode=production",
|
||||
"clean-build": "rm -rf dist",
|
||||
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@dnd-kit/core": "^6.1.0",
|
||||
"@dnd-kit/modifiers": "^7.0.0",
|
||||
"@dnd-kit/sortable": "^8.0.0",
|
||||
"ahooks": "^3.8.1",
|
||||
"antd": "^5.22.1",
|
||||
"axios": "^1.7.7",
|
||||
"clsx": "^2.1.1",
|
||||
"dayjs": "^1.11.11",
|
||||
"file-saver": "^2.0.5",
|
||||
"qs": "^6.12.1",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"react-player": "^2.16.0",
|
||||
"react-router-dom": "^6.28.0",
|
||||
"sass": "^1.81.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/file-saver": "^2.0.7",
|
||||
"@types/lodash": "^4.17.1",
|
||||
"@types/node": "^20.12.11",
|
||||
"@types/qs": "^6.9.15",
|
||||
"@types/react": "^18.2.66",
|
||||
"@types/react-dom": "^18.2.22",
|
||||
"@typescript-eslint/eslint-plugin": "^7.2.0",
|
||||
"@typescript-eslint/parser": "^7.2.0",
|
||||
"@vitejs/plugin-react": "^4.2.1",
|
||||
"autoprefixer": "^10.4.19",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-plugin-react-hooks": "^4.6.0",
|
||||
"eslint-plugin-react-refresh": "^0.4.6",
|
||||
"postcss": "^8.4.40",
|
||||
"tailwindcss": "^3.4.7",
|
||||
"typescript": "^5.2.2",
|
||||
"vite": "^5.2.0"
|
||||
},
|
||||
"packageManager": "yarn@1.22.21+sha1.1959a18351b811cdeedbd484a8f86c3cc3bbaf72"
|
||||
}
|
8
postcss.config.js
Normal file
@ -0,0 +1,8 @@
|
||||
export default {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
6
public/logo.svg
Normal file
@ -0,0 +1,6 @@
|
||||
<svg viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" width="100" height="100">
|
||||
<path d="M671.584 201.142c22.034 0 39.896 17.398 39.896 38.858v163.2l207.98-141.828a20.4 20.4 0 0 1 20.666-1.322c6.602 3.35 10.732 10.002 10.732 17.252V746.7c0 7.25-4.13 13.902-10.732 17.252a20.4 20.4 0 0 1-20.668-1.32L711.48 620.8V784c0 21.46-17.86 38.858-39.896 38.858H113.04c-22.034 0-39.896-17.398-39.896-38.858V240c0-21.46 17.862-38.858 39.896-38.858h558.546z"
|
||||
fill="#9C34FE"></path>
|
||||
<path d="M328.478 388.784c-7.584 0-14.122 5.196-15.64 12.434l-0.32 3.07v215.346c0 5.11 2.58 9.894 6.896 12.796a16.32 16.32 0 0 0 14.73 1.736l2.912-1.398 173.748-107.712c4.106-2.56 6.786-6.806 7.276-11.532 0.49-4.724-1.264-9.408-4.764-12.714l-2.512-1.944-173.748-107.712a16.28 16.28 0 0 0-8.578-2.332v-0.038z"
|
||||
fill="#FFFFFF"></path>
|
||||
</svg>
|
After Width: | Height: | Size: 859 B |
15
src/App.tsx
Normal file
@ -0,0 +1,15 @@
|
||||
import AppRouter from "@/routes";
|
||||
import {ConfigProvider} from "@/contexts/config";
|
||||
import {AuthProvider} from "@/contexts/auth";
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<ConfigProvider>
|
||||
<AuthProvider>
|
||||
<AppRouter/>
|
||||
</AuthProvider>
|
||||
</ConfigProvider>
|
||||
)
|
||||
}
|
||||
|
||||
export default App
|
96
src/assets/core.scss
Normal file
@ -0,0 +1,96 @@
|
||||
:root {
|
||||
font-family: -apple-system, "PingFang SC", 'Microsoft YaHei', sans-serif;
|
||||
line-height: 1.5;
|
||||
font-weight: 400;
|
||||
font-synthesis: none;
|
||||
text-rendering: optimizeLegibility;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
--main-bg-color: #f6f6f6;
|
||||
--brand-color: #43ABFF;
|
||||
--navigation-width: 100vw;
|
||||
--navigation-active-color: #ffe0e0;
|
||||
--app-header-header: 90px;
|
||||
--container-width: 1440px;
|
||||
}
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
|
||||
.btn {
|
||||
@apply px-5 py-2 rounded-md bg-white border text-sm;
|
||||
&:hover {
|
||||
@apply bg-gray-100;
|
||||
}
|
||||
|
||||
&.btn-primary {
|
||||
@apply bg-blue-500 text-white border-blue-500;
|
||||
&:hover {
|
||||
@apply bg-blue-600;
|
||||
}
|
||||
}
|
||||
}
|
||||
.card{
|
||||
@apply bg-white rounded-lg p-5 my-10;
|
||||
}
|
||||
.radio-icon,.checkbox-icon{
|
||||
@apply w-4 h-4 mr-2 border border-gray-400 rounded-2xl inline-block flex items-center justify-center relative;
|
||||
padding: 3px;
|
||||
&:after{
|
||||
@apply inline-block bg-blue-500 w-full h-full;
|
||||
content: ' ';
|
||||
border-radius: 50%;
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
.checkbox-icon{
|
||||
@apply rounded;
|
||||
padding: 0;
|
||||
&:before{
|
||||
content: ' ';
|
||||
display: inline-block;
|
||||
border-left: solid 2px #fff;
|
||||
border-bottom: solid 2px #fff;
|
||||
height: 6px;
|
||||
width: 10px;
|
||||
position: absolute;
|
||||
transform: rotate(-45deg) translateY(-1px) translateX(1px);
|
||||
opacity: 0;
|
||||
}
|
||||
&:after{
|
||||
border-radius: 2px;
|
||||
}
|
||||
}
|
||||
.ant-select-item-option {
|
||||
&.ant-select-item-option-selected{
|
||||
.radio-icon,.checkbox-icon{
|
||||
@apply border-blue-500;
|
||||
&:after,&:before {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.select-hide-checked{
|
||||
.ant-select-item-option-selected{
|
||||
.ant-select-item-option-state{
|
||||
opacity: 0 !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
.select-no-wrap{
|
||||
.ant-select-selector{
|
||||
.ant-select-selection-overflow{
|
||||
@apply flex flex-nowrap;
|
||||
}
|
||||
}
|
||||
}
|
||||
.simple-pagination{
|
||||
.ant-pagination-simple-pager{
|
||||
input[type=text]{
|
||||
width: auto;
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
}
|
BIN
src/assets/images/avatar.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
src/assets/images/blank-qr-code.png
Normal file
After Width: | Height: | Size: 4.1 KiB |
BIN
src/assets/images/error/Error404.png
Normal file
After Width: | Height: | Size: 98 KiB |
BIN
src/assets/images/error/Error500.png
Normal file
After Width: | Height: | Size: 45 KiB |
BIN
src/assets/images/error/TwoCone.png
Normal file
After Width: | Height: | Size: 22 KiB |
BIN
src/assets/images/error/coming-soon.png
Normal file
After Width: | Height: | Size: 110 KiB |
353
src/assets/images/error/under-construction.svg
Normal file
@ -0,0 +1,353 @@
|
||||
<svg shape-rendering="geometricPrecision" text-rendering="geometricPrecision" viewBox="0 0 532 475" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="m266 474.5c146.63 0 265.5-60.442 265.5-135s-118.87-135-265.5-135-265.5 60.442-265.5 135 118.87 135 265.5 135z" fill="#fff"/>
|
||||
<path d="M246.525,353.382l-54.356-31.019c-.888-.51-2.32-.499-3.208.011l-.566.322c-.888.51-.877,1.331.011,1.83l18.526,10.351-18.948,10.939-18.303-10.562c-.888-.51-2.32-.51-3.197,0l-.566.322c-.888.511-.888,1.343,0,1.853l55.277,31.896.599-.71.3.177l21.822-12.569.167.099.322-.377.466-.266-.167-.089l1.821-2.208Z" fill="#f5f5f5"/>
|
||||
<path d="M51.2325,387.902L25.5411,373.079c-1.3881-.797-1.3881-2.092,0-2.89L297.759,213.098c1.388-.797,3.62-.797,5.009,0l25.691,14.823c1.388.797,1.388,2.092,0,2.89L56.2412,387.902c-1.3881.797-3.6206.797-5.0087,0Z" fill="#f5f5f5"/>
|
||||
<path d="M154.674,361.659c6.593,3.706,6.659,9.841.144,13.691-6.505,3.849-17.127,3.96-23.72.255-6.594-3.706-6.66-9.841-.145-13.69c6.505-3.861,17.127-3.972,23.721-.256Z" fill="#f5f5f5"/>
|
||||
<path d="M230.504,419.116L252.88,405.42c.827-.512.827-1.329,0-1.841l-22.376-13.696c-.826-.511-2.172-.511-3.008,0L205.12,403.579c-.827.512-.827,1.329,0,1.841l22.376,13.696c.836.512,2.182.512,3.008,0Z" fill="#f5f5f5"/>
|
||||
<g transform="translate(1e-6 1e-6)">
|
||||
<path d="M208.508,402.685l19.495-11.245c.365-.21.838-.319,1.303-.319.474,0,.947.1,1.312.319l19.486,11.245c.364.209.537.482.537.755v1.421c0,.273-.173.546-.537.756l-19.486,11.244c-.365.21-.838.319-1.312.319s-.948-.1-1.303-.319l-19.495-11.244c-.364-.21-.537-.483-.537-.756v-1.421c0-.264.173-.537.537-.755Z" fill="#fa8c16"/>
|
||||
<path d="M207.971,403.44v1.421c0,.273.173.546.537.756l19.495,11.244c.365.21.838.319,1.303.319v-26.059c-.474,0-.948.1-1.303.319l-19.495,11.245c-.364.218-.537.491-.537.755Z" opacity=".1"/>
|
||||
<path d="M229.307,391.121v26.05c.473,0,.947-.1,1.311-.319l19.486-11.245c.365-.209.538-.482.538-.755v-1.421c0-.273-.173-.546-.538-.755l-19.486-11.245c-.364-.201-.838-.31-1.311-.31Z" opacity=".3"/>
|
||||
<path d="M230.618,415.45l19.495-11.245c.72-.419.72-1.092,0-1.511l-19.495-11.245c-.72-.419-1.895-.419-2.614,0l-19.495,11.245c-.72.419-.72,1.092,0,1.511l19.495,11.245c.719.419,1.894.419,2.614,0Z" fill="#fa8c16"/>
|
||||
<path d="M230.618,415.45l19.495-11.245c.72-.419.72-1.092,0-1.511l-19.495-11.245c-.72-.419-1.895-.419-2.614,0l-19.495,11.245c-.72.419-.72,1.092,0,1.511l19.495,11.245c.719.419,1.894.419,2.614,0Z" fill="#fff" opacity=".5"/>
|
||||
<path d="M229.307,391.13c.473,0,.947.101,1.311.31l19.495,11.245c.72.419.72,1.092,0,1.511l-19.495,11.245c-.364.21-.838.31-1.311.31v-24.621Z" opacity=".05"/>
|
||||
<path d="M217.273,402.029l8.618-25.895c0-.009,0-.009.009-.018l.009-.028c.136-.364.446-.719.938-1.001c1.357-.783,3.553-.783,4.91,0c.492.282.802.637.939,1.001h.009l.009.028c0,0,0,0,0,.009l8.627,25.895c.792,2.249-.319,4.68-3.343,6.428-4.801,2.768-12.572,2.768-17.373,0-3.033-1.739-4.145-4.17-3.352-6.419Z" fill="#fa8c16"/>
|
||||
<path d="M223.421,383.564l.009-.028l1.23-3.678c-.201.628-.018,1.284.537,1.848.21.21.456.41.766.583c1.849,1.065,4.846,1.065,6.695,0c.31-.182.565-.373.766-.583.564-.574.737-1.229.537-1.857l1.23,3.687.009.018c.2.62.109,1.257-.273,1.849-.292.455-.747.883-1.376,1.247-.446.255-.956.446-1.485.61-1.722.519-3.771.519-5.493,0-.528-.164-1.039-.355-1.485-.61-.629-.364-1.084-.792-1.376-1.247-.4-.592-.491-1.229-.291-1.839Z" fill="#fafafa"/>
|
||||
<path d="M218.483,398.396l.009-.028l1.23-3.687c-.2.61-.219,1.238-.073,1.848.155.646.501,1.275,1.039,1.857.446.483,1.011.929,1.712,1.339c3.817,2.203,9.994,2.203,13.811,0c.701-.401,1.266-.856,1.712-1.339.547-.582.884-1.22,1.039-1.857.146-.61.137-1.238-.064-1.848l1.221,3.678.009.037c.2.61.246,1.238.137,1.857-.255,1.402-1.303,2.768-3.171,3.842-4.309,2.486-11.287,2.486-15.596,0-1.858-1.074-2.915-2.44-3.17-3.842-.091-.619-.055-1.247.155-1.857Z" fill="#fafafa"/>
|
||||
<path d="M220.953,390.975l.009-.027l1.23-3.688c-.201.61-.155,1.248.118,1.849.31.682.911,1.32,1.822,1.857.018.009.037.027.055.036c2.833,1.63,7.424,1.63,10.248,0c.019-.009.037-.027.055-.036.911-.537,1.512-1.175,1.822-1.857.273-.61.319-1.239.118-1.849l1.23,3.679.009.027c.201.61.201,1.247,0,1.858-.218.646-.674,1.283-1.348,1.848-.291.246-.61.473-.984.692-.947.546-2.077.938-3.27,1.174-1.777.346-3.717.346-5.493,0-1.194-.236-2.314-.619-3.271-1.174-.373-.219-.701-.446-.984-.692-.674-.565-1.129-1.193-1.348-1.848-.219-.601-.219-1.23-.018-1.849Z" fill="#fafafa"/>
|
||||
<path d="M229.307,374.504c.892,0,1.776.191,2.459.583.492.282.802.637.939,1.001h.009l.009.028c0,0,0,0,0,.009l8.627,25.895c.792,2.249-.319,4.68-3.343,6.428-2.396,1.384-5.539,2.076-8.682,2.076.027,0,.045-.009.073-.009c3.89-.619,6.513-4.334,5.967-8.24l-3.59-25.777-2.468-1.994Z" opacity=".1"/>
|
||||
<path d="M231.766,377.928c1.357-.783,1.357-2.049,0-2.832s-3.553-.783-4.91,0-1.357,2.049,0,2.832c1.348.783,3.553.783,4.91,0Z" fill="#fa8c16"/>
|
||||
<path d="M231.766,377.928c1.357-.783,1.357-2.049,0-2.832s-3.553-.783-4.91,0-1.357,2.049,0,2.832c1.348.783,3.553.783,4.91,0Z" fill="#fff" opacity=".5"/>
|
||||
</g>
|
||||
<path d="M418.987,376.681l20.202-11.66c.755-.433.755-1.132,0-1.564l-20.202-11.66c-.755-.433-1.965-.433-2.719,0l-20.202,11.66c-.755.432-.755,1.131,0,1.564l20.202,11.66c.754.433,1.975.433,2.719,0Z" fill="#f5f5f5"/>
|
||||
<g transform="translate(1e-6)">
|
||||
<path d="M398.486,361.438l17.937-10.351c.333-.2.766-.289,1.199-.289s.877.1,1.21.289l17.937,10.351c.333.199.499.443.499.699v1.309c0,.255-.166.499-.499.699l-17.937,10.35c-.333.2-.777.289-1.21.289s-.866-.1-1.199-.289l-17.937-10.35c-.333-.2-.5-.444-.5-.699v-1.309c.011-.256.167-.5.5-.699Z" fill="#fa8c16"/>
|
||||
<path d="M397.998,362.137v1.309c0,.255.167.499.5.699l17.937,10.35c.333.2.766.289,1.199.289v-23.986c-.433,0-.866.1-1.199.289l-17.937,10.351c-.345.199-.5.443-.5.699Z" opacity=".1"/>
|
||||
<path d="M417.633,350.798v23.986c.433,0,.877-.1,1.21-.289l17.937-10.35c.333-.2.499-.444.499-.699v-1.309c0-.256-.166-.5-.499-.699l-17.937-10.351c-.333-.2-.777-.289-1.21-.289Z" opacity=".3"/>
|
||||
<path d="M418.843,373.186l17.938-10.35c.666-.389.666-1.01,0-1.387l-17.938-10.351c-.666-.388-1.742-.388-2.408,0l-17.937,10.351c-.666.388-.666,1.009,0,1.387l17.937,10.35c.655.378,1.742.378,2.408,0Z" fill="#fa8c16"/>
|
||||
<path d="M418.843,373.186l17.938-10.35c.666-.389.666-1.01,0-1.387l-17.938-10.351c-.666-.388-1.742-.388-2.408,0l-17.937,10.351c-.666.388-.666,1.009,0,1.387l17.937,10.35c.655.378,1.742.378,2.408,0Z" fill="#fff" opacity=".5"/>
|
||||
<path d="M417.633,350.798c.433,0,.877.1,1.21.289l17.937,10.351c.666.388.666,1.009,0,1.386l-17.937,10.351c-.333.189-.766.289-1.21.289v-22.666Z" opacity=".05"/>
|
||||
<path d="M406.556,360.828l7.936-23.831v-.011l.011-.022c.123-.333.411-.666.866-.921c1.254-.721,3.275-.721,4.518,0c.455.267.744.588.866.921l.011.022c0,0,0,0,0,.011l7.936,23.842c.733,2.074-.289,4.315-3.075,5.913-4.417,2.552-11.577,2.552-15.994,0-2.775-1.609-3.797-3.85-3.075-5.924Z" fill="#fa8c16"/>
|
||||
<path d="M412.217,343.831l.011-.022l1.132-3.384c-.189.577-.022,1.187.489,1.709.188.188.421.377.71.543c1.698.977,4.462.977,6.16,0c.289-.166.522-.344.711-.543.51-.522.677-1.132.488-1.709l1.132,3.395.011.022c.189.566.1,1.154-.244,1.709-.266.421-.688.81-1.265,1.142-.411.233-.877.411-1.366.566-1.587.477-3.474.477-5.061,0-.488-.144-.955-.321-1.365-.566-.577-.332-.999-.732-1.266-1.142-.377-.566-.466-1.154-.277-1.72Z" fill="#fafafa"/>
|
||||
<path d="M407.666,357.488l.011-.022l1.132-3.395c-.189.566-.2,1.143-.067,1.709.145.588.456,1.176.955,1.708.411.444.932.855,1.576,1.232c3.508,2.03,9.202,2.03,12.709,0c.644-.377,1.166-.788,1.577-1.232.499-.543.81-1.12.954-1.708.133-.566.122-1.143-.066-1.698l1.132,3.384.011.033c.189.566.222,1.143.122,1.709-.233,1.287-1.199,2.552-2.919,3.539-3.963,2.285-10.39,2.285-14.352,0-1.71-.987-2.686-2.241-2.92-3.539-.077-.577-.044-1.154.145-1.72Z" fill="#fafafa"/>
|
||||
<path d="M409.942,350.654l.011-.022l1.132-3.395c-.189.566-.144,1.143.111,1.709.288.621.843,1.22,1.676,1.708.022.011.033.022.055.034c2.609,1.508,6.827,1.508,9.435,0c.022-.012.034-.023.056-.034.832-.499,1.398-1.087,1.676-1.708.255-.555.288-1.143.111-1.709l1.132,3.395.011.022c.189.566.189,1.143,0,1.709-.2.599-.621,1.176-1.243,1.697-.266.222-.566.433-.91.633-.877.51-1.909.865-3.008,1.076-1.643.321-3.419.321-5.062,0-1.099-.211-2.131-.577-3.008-1.076-.344-.2-.644-.411-.91-.633-.622-.521-1.043-1.098-1.243-1.697-.211-.555-.211-1.143-.022-1.709Z" fill="#fafafa"/>
|
||||
<path d="M417.633,335.5c.821,0,1.631.177,2.264.543.455.266.744.588.866.921l.011.022c0,0,0,0,0,.011l7.936,23.842c.733,2.074-.288,4.315-3.074,5.913-2.209,1.276-5.106,1.908-7.992,1.908.022,0,.044-.011.067-.011c3.585-.577,5.993-3.994,5.494-7.577l-3.297-23.731-2.275-1.841Z" opacity=".1"/>
|
||||
<path d="M419.898,338.65c1.254-.721,1.254-1.886,0-2.607s-3.275-.721-4.518,0c-1.254.721-1.254,1.886,0,2.607c1.254.722,3.264.722,4.518,0Z" fill="#fa8c16"/>
|
||||
<path d="M419.898,338.65c1.254-.721,1.254-1.886,0-2.607s-3.275-.721-4.518,0c-1.254.721-1.254,1.886,0,2.607c1.254.722,3.264.722,4.518,0Z" fill="#fff" opacity=".5"/>
|
||||
</g>
|
||||
<g transform="translate(4e-6 2e-6)">
|
||||
<path d="m50.491 357.3s2.7195-13.291-0.4107-25.317c-3.1301-12.026-9.8788-21.09-17.837-24.396-7.9696-3.306-17.027 2.063-9.9565 10.073s20.89 18.35 21.744 39.995l6.4601-0.355z" fill="#52c41a"/>
|
||||
<path d="m50.491 357.3s2.7195-13.291-0.4107-25.317c-3.1301-12.026-9.8788-21.09-17.837-24.396-7.9696-3.306-17.027 2.063-9.9565 10.073s20.89 18.35 21.744 39.995l6.4601-0.355z" opacity=".15"/>
|
||||
<path d="M49.1816,353.194c.0333,0,.0666.011.0999,0c.2553-.023.444-.233.4218-.488-1.6983-24.053-15.24-38.275-22.1552-42.436-.2109-.133-.4995-.055-.6327.156-.1332.222-.0555.499.1554.632c6.782,4.072,20.0351,18.039,21.7223,41.714.0111.222.1776.388.3885.422Z" fill="#fff"/>
|
||||
</g>
|
||||
<g transform="translate(7e-6 1e-6)">
|
||||
<path d="M10.8098,336.242c-.87689,2.685,1.0323,4.548,2.8304,6.057c1.3875,1.154,2.8971,2.419,3.2856,4.183.7659,3.572-3.4632,6.867-2.553,10.406.3885,1.487,1.6317,2.607,2.9859,3.328c1.1211.61,2.3309.999,3.5075,1.498.5883.177,1.1766.322,1.7649.422c1.7315.299,3.563.809,4.8062,2.141c1.9535,2.119,1.7094,5.38,2.4086,8.176.0111.033.0222.067.0222.1c1.4985,5.813,8.4914,8.199,13.3864,4.715l9.8788-7.034c3.9071-5.258,2.9193-14.688-3.3521-17.773-1.332-.654-2.8527-1.031-3.9183-2.074-1.2875-1.254-1.5983-3.195-1.676-4.993-.0777-1.797,0-3.661-.7326-5.314-1.0212-2.285-3.4632-3.683-5.9273-4.105-2.8859-.499-5.783.677-8.5135-.321-2.7417-.999-5.2835-2.607-8.114-3.317-3.1079-.777-6.6932-.355-9.013,2.152-.4773.51-.8547,1.098-1.0767,1.753Z" fill="#95de64"/>
|
||||
<path d="M39.7466,352.029c-.0222-.067-.0666-.122-.1221-.167-7.348-10.395-18.8585-15.332-22.7546-16.197-.222-.045-.4328.089-.4883.31-.0444.222.0888.433.3107.489c3.6852.821,14.3743,5.38,21.578,14.921-10.2118-3.273-17.8373,1.509-17.915,1.564-.1887.123-.2442.378-.1221.566.0777.111.1998.178.333.189.0777,0,.1665-.022.2331-.067.0777-.055,7.9252-4.981,18.3035-1.109c3.774,5.425,6.3824,12.359,6.116,20.99-.0111.211.1554.399.3663.422.0111,0,.0222,0,.0333,0c.222.011.4107-.167.4218-.4.2664-8.864-2.4198-15.953-6.2936-21.511Z" fill="#fff"/>
|
||||
</g>
|
||||
<path d="m321.48 20.847-5.694-3.306-266.63 153.84v200.76c0 1.931 0.677 3.284 1.7648 3.917h0.0111l5.6831 3.306c1.0989 0.632 2.6196 0.543 4.2956-0.422l254.5-146.85c3.352-1.931 6.071-6.635 6.071-10.506v-200.74z" fill="#d9d9d9"/>
|
||||
<path d="m54.854 375.45c0 3.872 2.7195 5.437 6.0716 3.506l254.5-146.85c3.352-1.931 6.072-6.635 6.072-10.506v-200.76l-266.64 153.85v200.76z" fill="#096dd9"/>
|
||||
<path d="m54.854 375.45c0 3.872 2.7195 5.437 6.0716 3.506l254.5-146.85c3.352-1.931 6.072-6.635 6.072-10.506v-200.76l-266.64 153.85v200.76z" fill="#fff" stroke="#f5f5f5" stroke-miterlimit="10"/>
|
||||
<path d="m54.854 174.69v23.753l266.63-153.84v-23.753l-266.63 153.84z" fill="#1890ff"/>
|
||||
<path d="m54.854 198.44-5.6942-3.306v-23.753l5.6942 3.306v23.753z" fill="#096dd9"/>
|
||||
<path d="m54.854 198.44-5.6942-3.306v-23.753l5.6942 3.306v23.753z" opacity=".2"/>
|
||||
<path d="m265.48 62.55v5.658c0 1.1538 0.822 1.6308 1.821 1.0539l37.106-21.467v-9.8516l-37.106 21.467c-0.999 0.5658-1.821 1.9859-1.821 3.1397z" fill="#fafafa"/>
|
||||
<path d="M313.968,32.4066c1.01-.5769,1.821-.1109,1.821,1.0539v5.6581c0,1.1649-.811,2.5738-1.821,3.1507L304.4,47.7942v-9.8516l9.568-5.536Z" fill="#455a64"/>
|
||||
<path d="M313.268,40.1614l-1.066-.3328c.111-.4549.167-.9208.167-1.3757c0-1.0872-.355-1.9193-.977-2.2743-.455-.2662-1.01-.2441-1.554.0777-1.199.6878-2.131,2.6404-2.131,4.4376c0,1.0873.355,1.9193.977,2.2743.211.1221.433.1776.677.1776.288,0,.588-.0888.877-.2552.721-.4105,1.343-1.2869,1.72-2.3076l1.066.3328c.044.0111.078.0222.122.0222.166,0,.322-.1109.377-.2773.067-.2108-.044-.4327-.255-.4993Zm-3.43,2.0413c-.3.1665-.555.1997-.766.0777-.355-.2108-.577-.8099-.577-1.5975c0-1.4867.799-3.2063,1.732-3.7499.177-.0998.333-.1553.477-.1553.1,0,.2.0222.289.0777.355.2108.577.8098.577,1.5975.011,1.4977-.788,3.2062-1.732,3.7498Z" fill="#fafafa"/>
|
||||
<path d="m314.08 0.94365c-1.099-0.67674-2.642-0.59908-4.351 0.38829l-254.5 146.84c-3.3521 1.931-6.0715 6.635-6.0715 10.506v12.703l5.6942 3.306 266.63-153.84v-12.714c0-1.9193-0.666-3.2728-1.753-3.9051-1.021-0.59908-4.673-2.6848-5.65-3.2839z" fill="#d9d9d9"/>
|
||||
<path d="m54.854 161.99c0-3.871 2.7195-8.575 6.0716-10.506l254.48-146.84c3.352-1.9304 6.072-0.3661 6.072 3.5058v12.703l-266.63 153.84v-12.703z" fill="#f0f0f0"/>
|
||||
<path d="M319.784,4.26071c-1.11-.68784-2.653-.62127-4.374.3772L60.9254,151.48c-1.6761.965-3.1968,2.63-4.2846,4.527l-5.7053-3.295c1.11-1.909,2.6196-3.573,4.3068-4.538L309.727,1.32076c1.71-.97629,3.252-1.053949,4.34-.377205.999.599085,4.64,2.684785,5.661,3.272775.011.02219.045.03329.056.04438Z" fill="#d9d9d9"/>
|
||||
<path d="M292.342,25.3504c-1.577.9097-2.842,3.1175-2.842,4.9258c0,1.8195,1.276,2.5517,2.842,1.642c1.576-.9097,2.841-3.1175,2.841-4.9258.011-1.8084-1.265-2.5406-2.841-1.642Z" fill="#52c41a"/>
|
||||
<path d="M302.308,19.6151c-1.576.9097-2.841,3.1174-2.841,4.9258s1.276,2.5516,2.841,1.6419c1.577-.9097,2.842-3.1174,2.842-4.9258s-1.277-2.5406-2.842-1.6419Z" fill="#fa8c16"/>
|
||||
<path d="m312.26 13.89c-1.576 0.9097-2.841 3.1174-2.841 4.9258 0 1.8194 1.276 2.5517 2.841 1.6419 1.577-0.9097 2.842-3.1174 2.842-4.9258 0-1.8194-1.265-2.5516-2.842-1.6419z" fill="#f5222d"/>
|
||||
<path d="M74.1789,298.001c-.1887,0-.3663-.044-.5328-.144-.333-.189-.5328-.544-.5328-.921v-65.089c0-.378.1998-.733.5328-.921l78.0869-45.054c.333-.188.733-.188,1.066,0c.333.189.532.544.532.921v65.079c0,.377-.199.732-.532.92L74.7116,297.846c-.1553.111-.344.155-.5327.155Zm1.0766-65.533v62.615L151.2,251.261v-62.615L75.2555,232.468Z" fill="#40a9ff"/>
|
||||
<path d="M75.101,283.024l-1.8315-1.087L96.901,242.098c.2997-.499.9324-.666,1.443-.389l15.24,8.632l16.072-32.162c.145-.3.422-.511.755-.566.322-.067.666.022.91.244l21.656,19.115-1.41,1.598-20.623-18.195-15.961,31.929c-.134.267-.367.455-.644.544-.278.089-.577.055-.833-.089l-15.3063-8.675-23.0987,38.94Z" fill="#40a9ff"/>
|
||||
<path d="M109.455,234.343c-.589,0-1.144-.144-1.654-.433-1.155-.665-1.787-1.964-1.787-3.672c0-3.062,2.075-6.657,4.728-8.188c1.476-.843,2.919-.954,4.074-.288c1.154.666,1.787,1.964,1.787,3.672c0,3.062-2.076,6.657-4.729,8.188-.821.477-1.654.721-2.419.721Zm3.718-10.75c-.366,0-.81.144-1.288.421-1.953,1.121-3.596,3.972-3.596,6.224c0,.854.233,1.476.655,1.72.422.233,1.077.133,1.809-.289c1.954-1.12,3.597-3.972,3.597-6.224c0-.854-.233-1.475-.655-1.719-.145-.089-.322-.133-.522-.133Z" fill="#40a9ff"/>
|
||||
<path d="M161.71,183.942L227.454,146c1.499-.865,2.709-.166,2.709,1.564v5.481c0,1.731-1.21,3.827-2.709,4.693L161.71,195.68c-1.498.865-2.708.166-2.708-1.565v-5.48c0-1.731,1.21-3.828,2.708-4.693Z" fill="#096dd9"/>
|
||||
<path d="M160.09,203.357l48.661-28.08c.6-.343,1.088-.066,1.088.622v3.361c0,.688-.488,1.531-1.088,1.875l-48.661,28.08c-.6.343-1.088.066-1.088-.622v-3.361c0-.688.488-1.52,1.088-1.875Z" fill="#f5f5f5"/>
|
||||
<path d="M159.002,218.19c-.222,0-.422-.111-.544-.311-.177-.299-.066-.688.233-.854l96.435-55.648c.3-.167.688-.067.855.233.178.299.067.687-.233.854l-96.435,55.648c-.1.056-.2.078-.311.078Z" fill="#f5f5f5"/>
|
||||
<path d="M159.002,224.058c-.222,0-.422-.111-.544-.31-.177-.3-.066-.688.233-.854l96.435-55.649c.3-.166.688-.066.855.233.178.3.067.688-.233.854l-96.435,55.649c-.1.055-.2.077-.311.077Z" fill="#f5f5f5"/>
|
||||
<path d="M159.002,229.928c-.222,0-.422-.111-.544-.311-.177-.3-.066-.688.233-.854l96.435-55.649c.3-.166.688-.066.855.233.178.3.067.688-.233.855L159.313,229.85c-.1.055-.2.078-.311.078Z" fill="#f5f5f5"/>
|
||||
<path d="M159.002,235.796c-.222,0-.422-.111-.544-.31-.177-.3-.066-.688.233-.855l96.435-55.648c.3-.166.688-.067.855.233.178.3.067.688-.233.854l-96.435,55.649c-.1.044-.2.077-.311.077Z" fill="#f5f5f5"/>
|
||||
<path d="M159.002,241.665c-.222,0-.422-.111-.544-.311-.177-.299-.066-.688.233-.854l96.435-55.648c.3-.167.688-.067.855.233.178.299.067.687-.233.854l-96.435,55.648c-.1.045-.2.078-.311.078Z" fill="#f5f5f5"/>
|
||||
<path d="M159.002,247.523c-.222,0-.422-.111-.544-.311-.177-.299-.066-.677.233-.854l45.754-26.404c.299-.178.688-.067.854.233.178.299.067.676-.233.854l-45.753,26.404c-.1.056-.2.078-.311.078Z" fill="#f5f5f5"/>
|
||||
<path d="m81.471 345.41 55.232-31.918c1.277-0.732 2.309-2.529 2.309-4.005v-29.71c0-1.475-1.032-2.074-2.309-1.331l-55.232 31.918c-1.2765 0.732-2.3088 2.529-2.3088 4.005v29.71c0 1.464 1.0323 2.063 2.3088 1.331z" fill="#fafafa" stroke="#f5f5f5" stroke-miterlimit="10" stroke-width=".9621"/>
|
||||
<path d="M84.6563,312.391l10.7002-6.18c.6438-.366,1.1544-.066,1.1544.666v12.348c0,.732-.5217,1.631-1.1544,1.997l-10.7002,6.179c-.6438.366-1.1543.067-1.1543-.665v-12.348c0-.732.5216-1.631,1.1543-1.997Z" fill="#bae7ff"/>
|
||||
<path d="M101.318,302.784l32.9-19.027c.255-.144.466-.033.466.266v1.62c0,.3-.211.655-.466.799l-32.9,19.026c-.256.145-.466.034-.466-.266v-1.62c0-.299.21-.654.466-.798Z" fill="#bae7ff"/>
|
||||
<path d="M101.318,308.941l32.9-19.027c.255-.144.466-.033.466.267v1.619c0,.3-.211.655-.466.799l-32.9,19.027c-.256.144-.466.033-.466-.267v-1.619c0-.289.21-.644.466-.799Z" fill="#bae7ff"/>
|
||||
<path d="M101.318,315.109l32.9-19.026c.255-.144.466-.034.466.266v1.62c0,.299-.211.654-.466.799l-32.9,19.026c-.256.144-.466.033-.466-.266v-1.62c0-.288.21-.655.466-.799Z" fill="#bae7ff"/>
|
||||
<path d="M83.9681,331.251l50.2489-29c.255-.144.466-.022.466.266v1.62c0,.3-.211.655-.466.799l-50.2489,29c-.2553.144-.4661.022-.4661-.266v-1.62c0-.299.2108-.654.4661-.799Z" fill="#bae7ff"/>
|
||||
<path d="M83.9681,337.42l50.2489-29c.255-.145.466-.023.466.266v1.62c0,.299-.211.654-.466.798L83.9681,340.105c-.2553.144-.4661.022-.4661-.267v-1.619c0-.3.2108-.655.4661-.799Z" fill="#bae7ff"/>
|
||||
<path d="M77.0523,308.23c-.1332,0-.2775-.066-.3441-.199-.111-.189-.0444-.433.1443-.544l1.1543-.666c.1887-.111.4329-.044.5439.145.111.188.0444.432-.1443.543l-1.1543.666c-.0555.044-.1332.055-.1998.055Z" fill="#bae7ff"/>
|
||||
<path d="M80.648,306.167c-.1332,0-.2775-.067-.3441-.2-.111-.188-.0444-.432.1443-.543l2.4308-1.409c.1887-.111.4329-.045.5439.144s.0444.433-.1443.544l-2.4308,1.409c-.0666.033-.1332.055-.1998.055Z" fill="#bae7ff"/>
|
||||
<path d="M85.5112,303.36c-.1332,0-.2775-.066-.3441-.199-.111-.189-.0444-.433.1443-.544l2.4309-1.409c.1887-.111.4329-.044.5439.144.111.189.0444.433-.1443.544l-2.4309,1.409c-.0666.033-.1332.055-.1998.055Z" fill="#bae7ff"/>
|
||||
<path d="M90.3726,300.543c-.1332,0-.2775-.067-.3441-.2-.111-.189-.0444-.433.1443-.544l2.4308-1.409c.1887-.111.4329-.044.5439.144.111.189.0444.433-.1443.544l-2.4308,1.409c-.0555.044-.1221.056-.1998.056Z" fill="#bae7ff"/>
|
||||
<path d="M95.2456,297.735c-.1332,0-.2775-.066-.3441-.199-.111-.189-.0444-.433.1443-.544l2.4309-1.409c.1887-.111.4329-.044.5439.144.111.189.0444.433-.1443.544l-2.4309,1.409c-.0666.044-.1332.055-.1998.055Z" fill="#bae7ff"/>
|
||||
<path d="M100.107,294.929c-.1333,0-.2776-.067-.3442-.2-.111-.189-.0444-.433.1443-.544l2.4309-1.409c.189-.11.433-.044.544.145.111.188.044.432-.144.543l-2.431,1.409c-.056.045-.133.056-.2.056Z" fill="#bae7ff"/>
|
||||
<path d="M105.158,292.022c-.133,0-.278-.067-.344-.2-.111-.188-.045-.432.144-.543l2.431-1.409c.188-.111.433-.045.544.144s.044.433-.145.544l-2.43,1.409c-.067.033-.134.055-.2.055Z" fill="#bae7ff"/>
|
||||
<path d="M110.197,289.105c-.133,0-.278-.067-.344-.2-.111-.189-.045-.433.144-.544l2.431-1.409c.189-.111.433-.044.544.144.111.189.044.433-.145.544l-2.43,1.409c-.056.044-.134.056-.2.056Z" fill="#bae7ff"/>
|
||||
<path d="M115.248,286.187c-.134,0-.278-.067-.345-.2-.111-.189-.044-.433.145-.544l2.431-1.409c.188-.111.433-.044.544.145.111.188.044.432-.145.543l-2.431,1.409c-.066.044-.133.056-.199.056Z" fill="#bae7ff"/>
|
||||
<path d="M120.287,283.28c-.134,0-.278-.067-.344-.2-.111-.188-.045-.433.144-.543l2.431-1.409c.188-.111.433-.045.544.144.111.188.044.432-.145.543l-2.431,1.409c-.055.034-.122.056-.199.056Z" fill="#bae7ff"/>
|
||||
<path d="M125.337,280.362c-.133,0-.277-.066-.344-.199-.111-.189-.044-.433.145-.544l2.43-1.409c.189-.111.433-.044.544.144.111.189.045.433-.144.544l-2.431,1.409c-.066.044-.133.055-.2.055Z" fill="#bae7ff"/>
|
||||
<path d="M130.386,277.456c-.133,0-.277-.067-.344-.2-.111-.189-.044-.433.144-.544l2.431-1.409c.189-.111.433-.044.544.145.111.188.045.432-.144.543l-2.431,1.409c-.067.033-.133.056-.2.056Z" fill="#bae7ff"/>
|
||||
<path d="M135.427,274.538c-.133,0-.277-.067-.344-.2-.111-.189-.044-.433.144-.544l2.431-1.409c.189-.111.433-.044.544.145.111.188.045.432-.144.543l-2.431,1.409c-.067.045-.133.056-.2.056Z" fill="#bae7ff"/>
|
||||
<path d="M140.476,271.62c-.133,0-.277-.066-.344-.2-.111-.188-.044-.432.144-.543l2.431-1.409c.189-.111.433-.044.544.144.111.189.044.433-.144.544l-2.431,1.409c-.067.044-.133.055-.2.055Z" fill="#bae7ff"/>
|
||||
<path d="M145.517,268.713c-.133,0-.277-.066-.344-.199-.111-.189-.044-.433.144-.544l2.431-1.409c.189-.111.433-.044.544.144.111.189.044.433-.144.544l-2.431,1.409c-.056.033-.133.055-.2.055Z" fill="#bae7ff"/>
|
||||
<path d="M150.566,265.795c-.133,0-.278-.066-.344-.199-.111-.189-.045-.433.144-.544l2.431-1.409c.189-.111.433-.044.544.144.111.189.044.433-.144.544l-2.431,1.409c-.067.044-.133.055-.2.055Z" fill="#bae7ff"/>
|
||||
<path d="M155.605,262.889c-.133,0-.278-.066-.344-.199-.111-.189-.045-.433.144-.544l2.431-1.409c.189-.111.433-.044.544.144.111.189.044.433-.144.544l-2.431,1.409c-.056.033-.133.055-.2.055Z" fill="#bae7ff"/>
|
||||
<path d="M160.656,259.971c-.133,0-.278-.066-.344-.199-.111-.189-.045-.433.144-.544l2.431-1.409c.189-.111.433-.044.544.144.111.189.044.433-.145.544l-2.43,1.409c-.067.044-.134.055-.2.055Z" fill="#bae7ff"/>
|
||||
<path d="M165.695,257.053c-.133,0-.278-.066-.344-.199-.111-.189-.045-.433.144-.544l2.431-1.409c.189-.111.433-.044.544.144.111.189.044.433-.145.544l-2.43,1.409c-.056.044-.122.055-.2.055Z" fill="#bae7ff"/>
|
||||
<path d="M170.746,254.147c-.134,0-.278-.067-.344-.2-.111-.189-.045-.433.144-.544l2.431-1.409c.188-.111.433-.044.544.144.111.189.044.433-.145.544l-2.431,1.409c-.066.033-.133.056-.199.056Z" fill="#bae7ff"/>
|
||||
<path d="M175.796,251.229c-.133,0-.277-.067-.344-.2-.111-.188-.044-.432.145-.543l2.43-1.409c.189-.111.433-.045.544.144s.045.433-.144.544l-2.431,1.409c-.066.044-.133.055-.2.055Z" fill="#bae7ff"/>
|
||||
<path d="M180.835,248.322c-.133,0-.277-.066-.344-.199-.111-.189-.044-.433.145-.544l2.431-1.409c.188-.111.432-.044.543.144.111.189.045.433-.144.544l-2.431,1.409c-.055.033-.133.055-.2.055Z" fill="#bae7ff"/>
|
||||
<path d="M185.708,245.515c-.133,0-.277-.066-.344-.2-.111-.188-.044-.432.145-.543l2.431-1.409c.188-.111.432-.044.543.144.111.189.045.433-.144.544l-2.431,1.409c-.066.033-.133.055-.2.055Z" fill="#bae7ff"/>
|
||||
<path d="M190.57,242.697c-.133,0-.278-.066-.344-.199-.111-.189-.045-.433.144-.544l2.431-1.409c.189-.111.433-.044.544.144.111.189.044.433-.145.544l-2.43,1.409c-.067.044-.134.055-.2.055Z" fill="#bae7ff"/>
|
||||
<path d="M195.431,239.891c-.133,0-.277-.067-.344-.2-.111-.189-.044-.433.144-.544l1.155-.665c.188-.111.433-.045.544.144.111.188.044.432-.145.543l-1.154.666c-.056.044-.122.056-.2.056Z" fill="#bae7ff"/>
|
||||
<path d="M75.2765,352.364c-.222,0-.3995-.178-.3995-.4v-1.331c0-.222.1775-.4.3995-.4s.3996.178.3996.4v1.331c0,.211-.1776.4-.3996.4Z" fill="#bae7ff"/>
|
||||
<path d="M75.2765,348.469c-.222,0-.3995-.177-.3995-.399v-2.563c0-.222.1775-.399.3995-.399s.3996.177.3996.399v2.563c0,.222-.1776.399-.3996.399Zm0-5.125c-.222,0-.3995-.178-.3995-.4v-2.563c0-.221.1775-.399.3995-.399s.3996.178.3996.399v2.563c0,.222-.1776.4-.3996.4Zm0-5.115c-.222,0-.3995-.177-.3995-.399v-2.563c0-.222.1775-.399.3995-.399s.3996.177.3996.399v2.563c0,.222-.1776.399-.3996.399Zm0-5.114c-.222,0-.3995-.178-.3995-.4v-2.562c0-.222.1775-.4.3995-.4s.3996.178.3996.4v2.562c0,.222-.1776.4-.3996.4Zm0-5.115c-.222,0-.3995-.177-.3995-.399v-2.563c0-.222.1775-.399.3995-.399s.3996.177.3996.399v2.563c0,.222-.1776.399-.3996.399Zm0-5.114c-.222,0-.3995-.178-.3995-.399v-2.563c0-.222.1775-.4.3995-.4s.3996.178.3996.4v2.563c0,.221-.1776.399-.3996.399Zm0-5.126c-.222,0-.3995-.177-.3995-.399v-2.563c0-.222.1775-.399.3995-.399s.3996.177.3996.399v2.563c0,.222-.1776.399-.3996.399Z" fill="#bae7ff"/>
|
||||
<path d="M75.2765,312.646c-.222,0-.3995-.177-.3995-.399v-1.332c0-.221.1775-.399.3995-.399s.3996.178.3996.399v1.332c0,.222-.1776.399-.3996.399Z" fill="#bae7ff"/>
|
||||
<path d="M195.464,285.022c-.133,0-.277-.067-.344-.2-.111-.188-.044-.432.145-.543l1.154-.666c.189-.111.433-.044.544.144.111.189.044.433-.144.544l-1.155.665c-.055.045-.122.056-.2.056Z" fill="#bae7ff"/>
|
||||
<path d="M80.648,351.31c-.1332,0-.2775-.067-.3441-.2-.111-.189-.0444-.433.1443-.544l2.4308-1.409c.1887-.111.4329-.044.5439.145.111.188.0444.432-.1443.543l-2.4308,1.409c-.0666.045-.1332.056-.1998.056Z" fill="#bae7ff"/>
|
||||
<path d="M85.521,348.502c-.1332,0-.2775-.066-.3441-.199-.111-.189-.0444-.433.1443-.544l2.4309-1.409c.1887-.111.4328-.044.5438.144.111.189.0444.433-.1442.544l-2.4309,1.409c-.0666.033-.1332.055-.1998.055Z" fill="#bae7ff"/>
|
||||
<path d="M90.3823,345.685c-.1332,0-.2775-.067-.3441-.2-.111-.189-.0444-.433.1443-.544l2.4309-1.409c.1887-.111.4329-.044.5439.145.111.188.0444.432-.1443.543l-2.4309,1.409c-.0555.045-.1221.056-.1998.056Z" fill="#bae7ff"/>
|
||||
<path d="M95.2554,342.878c-.1332,0-.2775-.067-.3441-.2-.111-.188-.0444-.432.1443-.543l2.4308-1.409c.1887-.111.4329-.045.5439.144s.0444.433-.1443.544l-2.4308,1.408c-.0555.045-.1332.056-.1998.056Z" fill="#bae7ff"/>
|
||||
<path d="M100.128,340.071c-.1328,0-.2771-.066-.3437-.199-.111-.189-.0444-.433.1443-.544l2.4304-1.409c.189-.111.433-.044.544.144.111.189.045.433-.144.544l-2.431,1.409c-.066.033-.133.055-.2.055Z" fill="#bae7ff"/>
|
||||
<path d="M105.167,337.153c-.133,0-.277-.066-.344-.199-.111-.189-.044-.433.145-.544l2.431-1.409c.188-.111.432-.044.543.144.111.189.045.433-.144.544l-2.431,1.409c-.055.044-.122.055-.2.055Z" fill="#bae7ff"/>
|
||||
<path d="M110.218,334.247c-.133,0-.277-.066-.344-.2-.111-.188-.044-.432.144-.543l2.431-1.409c.189-.111.433-.045.544.144s.045.433-.144.544l-2.431,1.409c-.067.033-.133.055-.2.055Z" fill="#bae7ff"/>
|
||||
<path d="M115.269,331.329c-.133,0-.277-.066-.344-.2-.111-.188-.044-.432.144-.543l2.431-1.409c.189-.111.433-.044.544.144.111.189.044.433-.144.544l-2.431,1.409c-.067.033-.133.055-.2.055Z" fill="#bae7ff"/>
|
||||
<path d="M120.308,328.411c-.133,0-.277-.066-.344-.2-.111-.188-.044-.432.144-.543l2.431-1.409c.189-.111.433-.044.544.144.111.189.044.433-.144.544l-2.431,1.409c-.056.044-.133.055-.2.055Z" fill="#bae7ff"/>
|
||||
<path d="M125.359,325.504c-.133,0-.278-.066-.344-.199-.111-.189-.045-.433.144-.544l2.431-1.409c.189-.111.433-.044.544.144.111.189.044.433-.144.544l-2.431,1.409c-.067.033-.134.055-.2.055Z" fill="#bae7ff"/>
|
||||
<path d="M130.398,322.587c-.133,0-.278-.067-.344-.2-.111-.188-.045-.432.144-.543l2.431-1.409c.189-.111.433-.045.544.144s.044.433-.144.544l-2.431,1.408c-.056.045-.122.056-.2.056Z" fill="#bae7ff"/>
|
||||
<path d="M135.449,319.68c-.133,0-.278-.066-.344-.199-.111-.189-.045-.433.144-.544l2.431-1.409c.188-.111.433-.044.544.144.111.189.044.433-.145.544l-2.43,1.409c-.067.033-.134.055-.2.055Z" fill="#bae7ff"/>
|
||||
<path d="M140.498,316.762c-.134,0-.278-.066-.345-.199-.111-.189-.044-.433.145-.544l2.431-1.409c.188-.111.433-.044.544.144.111.189.044.433-.145.544l-2.431,1.409c-.066.033-.133.055-.199.055Z" fill="#bae7ff"/>
|
||||
<path d="M145.539,313.845c-.134,0-.278-.067-.345-.2-.111-.189-.044-.433.145-.544l2.431-1.408c.188-.111.433-.045.544.144.111.188.044.432-.145.543l-2.431,1.409c-.055.045-.133.056-.199.056Z" fill="#bae7ff"/>
|
||||
<path d="M150.587,310.938c-.133,0-.277-.067-.344-.2-.111-.188-.044-.432.145-.543l2.43-1.409c.189-.111.433-.045.544.144s.045.433-.144.544l-2.431,1.409c-.066.033-.133.055-.2.055Z" fill="#bae7ff"/>
|
||||
<path d="M155.626,308.02c-.133,0-.277-.067-.344-.2-.111-.188-.044-.432.145-.543l2.431-1.409c.188-.111.432-.045.543.144s.045.433-.144.544l-2.431,1.409c-.055.044-.133.055-.2.055Z" fill="#bae7ff"/>
|
||||
<path d="M160.677,305.103c-.133,0-.277-.067-.344-.2-.111-.189-.044-.433.144-.544l2.431-1.409c.189-.111.433-.044.544.145.111.188.045.432-.144.543l-2.431,1.409c-.067.044-.133.056-.2.056Z" fill="#bae7ff"/>
|
||||
<path d="M165.716,302.196c-.133,0-.277-.067-.344-.2-.111-.188-.044-.433.145-.543l2.43-1.409c.189-.111.433-.045.544.144.111.188.045.432-.144.543l-2.431,1.409c-.055.034-.122.056-.2.056Z" fill="#bae7ff"/>
|
||||
<path d="M170.767,299.278c-.133,0-.277-.067-.344-.2-.111-.188-.044-.432.144-.543l2.431-1.409c.189-.111.433-.045.544.144.111.188.044.432-.144.543l-2.431,1.409c-.067.045-.133.056-.2.056Z" fill="#bae7ff"/>
|
||||
<path d="M175.818,296.372c-.133,0-.278-.067-.344-.2-.111-.189-.045-.433.144-.544l2.431-1.409c.189-.111.433-.044.544.145.111.188.044.432-.144.543l-2.431,1.409c-.067.033-.134.056-.2.056Z" fill="#bae7ff"/>
|
||||
<path d="M180.857,293.454c-.133,0-.278-.067-.344-.2-.111-.189-.045-.433.144-.544l2.431-1.409c.189-.111.433-.044.544.145.111.188.044.432-.144.543l-2.431,1.409c-.056.033-.133.056-.2.056Z" fill="#bae7ff"/>
|
||||
<path d="M185.73,290.647c-.133,0-.278-.067-.344-.2-.111-.189-.045-.433.144-.544l2.431-1.409c.189-.111.433-.044.544.144.111.189.044.433-.144.544l-2.431,1.409c-.067.033-.133.056-.2.056Z" fill="#bae7ff"/>
|
||||
<path d="M190.603,287.829c-.133,0-.277-.067-.344-.2-.111-.189-.044-.433.144-.544l2.431-1.409c.189-.111.433-.044.544.145.111.188.044.432-.144.543l-2.431,1.409c-.067.045-.133.056-.2.056Z" fill="#bae7ff"/>
|
||||
<path d="M77.0523,353.384c-.1332,0-.2775-.066-.3441-.2-.111-.188-.0444-.432.1443-.543l1.1543-.666c.1887-.111.4329-.044.5439.144.111.189.0444.433-.1443.544l-1.1543.666c-.0555.033-.1332.055-.1998.055Z" fill="#bae7ff"/>
|
||||
<path d="M198.407,241.566c-.222,0-.399-.178-.399-.4v-1.331c0-.222.177-.399.399-.399s.4.177.4.399v1.331c0,.222-.178.4-.4.4Z" fill="#bae7ff"/>
|
||||
<path d="M198.407,277.377c-.222,0-.399-.177-.399-.399v-2.563c0-.222.177-.399.399-.399s.4.177.4.399v2.563c0,.222-.178.399-.4.399Zm0-5.114c-.222,0-.399-.177-.399-.399v-2.563c0-.222.177-.399.399-.399s.4.177.4.399v2.563c0,.222-.178.399-.4.399Zm0-5.114c-.222,0-.399-.178-.399-.4v-2.563c0-.221.177-.399.399-.399s.4.178.4.399v2.563c0,.222-.178.4-.4.4Zm0-5.115c-.222,0-.399-.177-.399-.399v-2.563c0-.222.177-.399.399-.399s.4.177.4.399v2.563c0,.222-.178.399-.4.399Zm0-5.114c-.222,0-.399-.178-.399-.4v-2.562c0-.222.177-.4.399-.4s.4.178.4.4v2.562c0,.222-.178.4-.4.4Zm0-5.115c-.222,0-.399-.177-.399-.399v-2.563c0-.222.177-.399.399-.399s.4.177.4.399v2.563c0,.211-.178.399-.4.399Zm0-5.125c-.222,0-.399-.178-.399-.399v-2.563c0-.222.177-.4.399-.4s.4.178.4.4v2.563c0,.221-.178.399-.4.399Z" fill="#bae7ff"/>
|
||||
<path d="M198.407,281.272c-.222,0-.399-.178-.399-.4v-1.331c0-.222.177-.399.399-.399s.4.177.4.399v1.331c0,.222-.178.4-.4.4Z" fill="#bae7ff"/>
|
||||
<path d="M196.632,241.255c-.067,0-.133-.022-.2-.055-.122-.067-.2-.2-.2-.344v-4.105c0-.144.078-.277.2-.344l3.552-2.052c.122-.067.278-.067.4,0c.122.066.2.199.2.344v4.104c0,.145-.078.278-.2.344l-3.552,2.053c-.067.044-.133.055-.2.055Zm.4-4.271v3.184l2.752-1.587v-3.184l-2.752,1.587Z" fill="#bae7ff"/>
|
||||
<path d="M196.632,286.408c-.067,0-.133-.022-.2-.055-.122-.067-.2-.2-.2-.344v-4.105c0-.144.078-.277.2-.344l3.552-2.052c.122-.067.278-.067.4,0c.122.066.2.2.2.344v4.105c0,.144-.078.277-.2.344l-3.552,2.052c-.067.033-.133.055-.2.055Zm.4-4.271v3.184l2.752-1.586v-3.184l-2.752,1.586Z" fill="#bae7ff"/>
|
||||
<path d="M73.5012,312.335c-.0666,0-.1332-.022-.1998-.055-.1221-.067-.1998-.2-.1998-.344v-4.105c0-.144.0777-.277.1998-.344l3.5519-2.052c.1221-.067.2775-.067.3996,0c.1221.066.1998.199.1998.344v4.104c0,.145-.0777.278-.1998.344L73.701,312.28c-.0666.044-.1332.055-.1998.055Zm.3995-4.271v3.184l2.7528-1.586v-3.184l-2.7528,1.586Z" fill="#bae7ff"/>
|
||||
<path d="M73.5012,357.489c-.0666,0-.1332-.023-.1998-.056-.1221-.066-.1998-.2-.1998-.344v-4.105c0-.144.0777-.277.1998-.344l3.5519-2.052c.1221-.067.2775-.067.3996,0s.1998.2.1998.344v4.105c0,.144-.0777.277-.1998.344l-3.5519,2.052c-.0666.033-.1332.056-.1998.056Zm.3995-4.272v3.184l2.7528-1.586v-3.184l-2.7528,1.586Z" fill="#bae7ff"/>
|
||||
<path d="M200.193,261.846c0,1.32-.799,2.851-1.787,3.417s-1.787-.034-1.787-1.354.799-2.851,1.787-3.417s1.787.034,1.787,1.354Z" fill="#bae7ff"/>
|
||||
<path d="M141.043,270.732c0,1.32-.799,2.851-1.787,3.417s-1.787-.033-1.787-1.353.799-2.851,1.787-3.417c.988-.577,1.787.033,1.787,1.353Z" fill="#bae7ff"/>
|
||||
<path d="M141.043,315.874c0,1.321-.799,2.852-1.787,3.417-.988.566-1.787-.033-1.787-1.353s.799-2.851,1.787-3.417s1.787.044,1.787,1.353Z" fill="#bae7ff"/>
|
||||
<path d="M77.0644,332.993c0,1.32-.7992,2.851-1.7871,3.417s-1.7871-.033-1.7871-1.353c0-1.321.7992-2.852,1.7871-3.417.9879-.577,1.7871.033,1.7871,1.353Z" fill="#bae7ff"/>
|
||||
<path d="M143.675,277.522c-.111,0-.222-.055-.289-.166-.089-.156-.033-.355.122-.444l50.637-29.222c.156-.089.356-.033.456.122.088.155.033.355-.123.444l-50.637,29.222c-.055.033-.111.044-.166.044Z" fill="#8c8c8c"/>
|
||||
<path d="M143.675,280.606c-.111,0-.222-.055-.289-.166-.089-.156-.033-.355.122-.444l50.637-29.222c.156-.089.356-.045.456.122.088.155.033.355-.123.444l-50.637,29.222c-.055.022-.111.044-.166.044Z" fill="#8c8c8c"/>
|
||||
<path d="M143.675,283.679c-.111,0-.222-.055-.289-.166-.089-.155-.033-.355.122-.444l50.637-29.222c.156-.089.356-.044.456.122.088.155.033.355-.123.444l-50.637,29.222c-.055.033-.111.044-.166.044Z" fill="#8c8c8c"/>
|
||||
<path d="M143.675,286.764c-.111,0-.222-.056-.289-.167-.089-.155-.033-.355.122-.443l50.637-29.222c.156-.089.356-.034.456.122.088.155.033.355-.123.443l-50.637,29.222c-.055.034-.111.045-.166.045Z" fill="#8c8c8c"/>
|
||||
<path d="M143.675,289.848c-.111,0-.222-.056-.289-.167-.089-.155-.033-.355.122-.443l50.637-29.223c.156-.088.356-.044.456.123.088.155.033.355-.123.443l-50.637,29.222c-.055.022-.111.045-.166.045Z" fill="#8c8c8c"/>
|
||||
<path d="M143.675,292.921c-.111,0-.222-.056-.289-.167-.089-.155-.033-.355.122-.444l24.02-13.867c.156-.089.355-.045.444.122.089.155.033.355-.122.444l-24.02,13.867c-.044.034-.1.045-.155.045Z" fill="#8c8c8c"/>
|
||||
<path d="M143.675,300.021c-.111,0-.222-.055-.289-.166-.089-.156-.033-.355.122-.444l50.637-29.222c.156-.089.356-.045.456.122.088.155.033.355-.123.444l-50.637,29.222c-.055.033-.111.044-.166.044Z" fill="#8c8c8c"/>
|
||||
<path d="M143.675,303.094c-.111,0-.222-.055-.289-.166-.089-.155-.033-.355.122-.444l50.637-29.222c.156-.089.356-.044.456.122.088.155.033.355-.123.444L143.841,303.05c-.055.033-.111.044-.166.044Z" fill="#8c8c8c"/>
|
||||
<path d="M143.675,306.178c-.111,0-.222-.055-.289-.166-.089-.155-.033-.355.122-.444l50.637-29.222c.156-.089.356-.033.456.122.088.155.033.355-.123.444l-50.637,29.222c-.055.033-.111.044-.166.044Z" fill="#8c8c8c"/>
|
||||
<path d="M143.675,309.262c-.111,0-.222-.055-.289-.166-.089-.155-.033-.355.122-.444l24.02-13.867c.156-.089.355-.034.455.122.089.155.034.355-.122.454l-24.02,13.868c-.055.022-.111.033-.166.033Z" fill="#8c8c8c"/>
|
||||
<path d="M220.151,272.684c-.044,0-.089-.011-.133-.033-.078-.044-.133-.133-.133-.233v-46.607c0-.099.055-.177.133-.232l37.495-21.634c.078-.044.189-.044.266,0c.078.044.134.133.134.233v46.606c0,.1-.056.189-.134.233l-37.495,21.634c-.044.022-.088.033-.133.033Zm.267-46.717v45.996l36.962-21.334v-45.996l-36.962,21.334Z" fill="#f5f5f5"/>
|
||||
<path d="M223.038,251.039c-.045,0-.089-.011-.133-.033-.078-.044-.134-.133-.134-.233v-23.298c0-.099.056-.177.134-.233l31.723-18.305c.078-.044.189-.044.266,0c.078.044.133.133.133.233v23.298c0,.1-.055.177-.133.233l-31.723,18.305c-.044.022-.089.033-.133.033Zm.266-23.408v22.687l31.191-18.006v-22.687l-31.191,18.006Z" fill="#bae7ff"/>
|
||||
<path d="M223.336,253.924l8.036-4.637c.167-.1.311-.023.311.177v.954c0,.2-.133.433-.311.533l-8.036,4.637c-.166.1-.311.022-.311-.177v-.955c.011-.188.145-.432.311-.532Z" fill="#bae7ff"/>
|
||||
<path d="M223.336,257.252l30.147-17.351c.167-.1.311-.022.311.177v.954c0,.2-.133.433-.311.533l-30.147,17.351c-.166.1-.311.022-.311-.177v-.954c.011-.189.145-.433.311-.533Z" fill="#f5f5f5"/>
|
||||
<path d="M223.336,263.92l30.147-17.351c.167-.1.311-.022.311.177v.954c0,.2-.133.433-.311.533l-30.147,17.351c-.166.1-.311.022-.311-.177v-.954c.011-.2.145-.444.311-.533Z" fill="#f5f5f5"/>
|
||||
<path d="M223.336,260.581l30.147-17.351c.167-.1.311-.022.311.177v.955c0,.199-.133.432-.311.532l-30.147,17.351c-.166.1-.311.023-.311-.177v-.954c.011-.189.145-.433.311-.533Z" fill="#f5f5f5"/>
|
||||
<path d="M254.76,232.734c-.011,0-.023,0-.045,0l-11.033-1.742c-.144-.022-.244-.155-.222-.299s.144-.244.3-.222l11.033,1.742c.144.022.244.155.222.299-.011.122-.122.222-.255.222Z" fill="#bae7ff"/>
|
||||
<path d="M234.081,229.484c-.011,0-.022,0-.044,0l-11.044-1.742c-.145-.022-.245-.155-.222-.299.022-.144.155-.244.299-.222l11.045,1.742c.144.022.244.155.222.299-.011.122-.134.222-.256.222Z" fill="#bae7ff"/>
|
||||
<path d="M223.037,251.04c-.055,0-.111-.022-.166-.056-.122-.088-.144-.255-.044-.377l11.033-14.478c.089-.111.255-.144.377-.044.122.089.144.255.045.377L223.248,250.94c-.055.067-.133.1-.211.1Z" fill="#bae7ff"/>
|
||||
<path d="M243.705,223.925c-.055,0-.111-.022-.166-.055-.122-.089-.144-.255-.044-.377l11.055-14.5c.089-.111.255-.145.377-.045.122.089.145.255.045.377l-11.056,14.5c-.055.067-.133.1-.211.1Z" fill="#bae7ff"/>
|
||||
<path d="M238.898,228.307c-.644.366-1.166,1.476-1.166,2.452s.522,1.487,1.166,1.121s1.165-1.476,1.165-2.452-.532-1.498-1.165-1.121Z" fill="#bae7ff"/>
|
||||
<path d="M241.385,225.29l-.888.51v-.466c0-.3-.155-.444-.344-.333l-2.52,1.453c-.188.111-.344.444-.344.733v.466l-.888.51c-.399.233-.721.91-.721,1.52v4.515c0,.61.322.921.721.688l4.984-2.873c.4-.233.721-.91.721-1.52v-4.516c0-.61-.321-.92-.721-.687Zm-2.486,7.477c-.955.555-1.743-.2-1.743-1.675c0-1.476.777-3.129,1.743-3.683.954-.555,1.742.199,1.742,1.675-.011,1.475-.788,3.128-1.742,3.683Z" fill="#bae7ff"/>
|
||||
<path d="M266.294,246.047c-.045,0-.089-.011-.133-.033-.078-.045-.134-.133-.134-.233v-46.607c0-.1.056-.177.134-.233l37.495-21.633c.077-.045.188-.045.266,0c.078.044.133.133.133.233v46.606c0,.1-.055.189-.133.233l-37.495,21.634c-.033.022-.078.033-.133.033Zm.266-46.717v45.996l36.962-21.334v-45.996L266.56,199.33Z" fill="#f5f5f5"/>
|
||||
<path d="M269.18,224.413c-.044,0-.088-.011-.133-.033-.077-.044-.133-.133-.133-.233v-23.298c0-.099.056-.177.133-.233l31.723-18.305c.078-.044.189-.044.267,0s.133.133.133.233v23.298c0,.1-.055.188-.133.233L269.314,224.38c-.034.022-.089.033-.134.033Zm.267-23.419v22.687l31.19-18.006v-22.687l-31.19,18.006Z" fill="#bae7ff"/>
|
||||
<path d="M269.49,227.298l8.037-4.637c.166-.1.311-.023.311.177v.954c0,.2-.134.433-.311.533l-8.037,4.637c-.166.1-.31.022-.31-.177v-.954c0-.2.144-.433.31-.533Z" fill="#bae7ff"/>
|
||||
<path d="M269.49,230.626l30.148-17.351c.166-.1.31-.022.31.177v.955c0,.199-.133.432-.31.532L269.49,232.29c-.166.1-.31.022-.31-.177v-.954c0-.2.144-.433.31-.533Z" fill="#f5f5f5"/>
|
||||
<path d="M269.49,237.283l30.148-17.351c.166-.1.31-.023.31.177v.954c0,.2-.133.433-.31.533L269.49,238.947c-.166.1-.31.022-.31-.177v-.955c0-.199.144-.432.31-.532Z" fill="#f5f5f5"/>
|
||||
<path d="M269.49,233.954l30.148-17.351c.166-.1.31-.022.31.178v.954c0,.199-.133.432-.31.532L269.49,235.618c-.166.1-.31.023-.31-.177v-.954c0-.2.144-.433.31-.533Z" fill="#f5f5f5"/>
|
||||
<path d="M285.042,198.342c-2.387,1.376-4.329,4.737-4.329,7.489c0,2.762,1.942,3.871,4.329,2.496c2.386-1.376,4.329-4.737,4.329-7.489c0-2.751-1.932-3.872-4.329-2.496Zm2.264,4.049l-3.23,3.861c-.311.377-.566.289-.566-.211v-3.616c0-.488.4-.877.888-.855l2.597.1c.489.023.633.344.311.721Z" fill="#bae7ff"/>
|
||||
<path d="M255.649,100.803c-.422-.189-.988-.134-1.599.221L80.0167,201.271c-1.3208.766-2.3975,2.63-2.3975,4.161v10.062c0,.732.2442,1.265.6549,1.531-.4107-.266-4.0404-2.319-4.4844-2.585-.4217-.255-.6881-.788-.6881-1.542v-10.062c0-1.531,1.0766-3.395,2.4086-4.161L249.533,98.4173c.677-.3883,1.287-.4105,1.72-.1553.389.233,3.541,2.019,4.396,2.541Z" fill="#096dd9"/>
|
||||
<path d="M80.0161,201.271L254.05,101.025c1.332-.766,2.397-.145,2.397,1.386v10.063c0,1.531-1.076,3.395-2.397,4.16L80.0161,216.881c-1.332.765-2.4087.144-2.4087-1.387v-10.062c0-1.531,1.0767-3.395,2.4087-4.161Z" fill="#91d5ff"/>
|
||||
<path d="M78.3185,203.069l-4.5066-2.608c-.4328.755-.7103,1.609-.7103,2.375v10.062c0,.754.2664,1.287.6881,1.542.444.266,4.0737,2.319,4.4844,2.585-.4107-.266-.6549-.799-.6549-1.531v-10.062c0-.766.2664-1.609.6993-2.363Z" opacity=".15"/>
|
||||
<path d="M255.649,100.803c-.854-.522-4.007-2.308-4.395-2.541-.433-.2552-1.044-.233-1.721.1553L75.5108,198.675c-.666.377-1.2654,1.043-1.6983,1.786l4.5065,2.608c.4329-.755,1.0323-1.409,1.6983-1.798L254.051,101.024c.61-.355,1.176-.41,1.598-.221Z" fill="#fff" opacity=".4"/>
|
||||
<path d="M247.434,112.651c0,1.442-1.076,3.217-2.408,3.994l-58.319,33.649c-1.331.765-2.408.221-2.408-1.221s1.077-3.217,2.397-3.994l58.319-33.648c1.343-.766,2.419-.222,2.419,1.22Z" fill="#fafafa"/>
|
||||
<path d="M267.649,97.5518l93.183-53.7845c1.198-.6878,2.164-.1331,2.164,1.2537v84.094c0,1.375-.966,3.062-2.164,3.75l-93.183,53.784c-1.199.688-2.165.133-2.165-1.254v-84.093c0-1.3871.966-3.0623,2.165-3.7502Z" fill="#f0f0f0"/>
|
||||
<path d="M495.62,287.328c11.977,6.745,12.099,17.884.267,24.884-11.833,7.001-31.124,7.212-43.112.466-11.977-6.745-12.099-17.883-.266-24.884c11.832-7,31.135-7.2,43.111-.466Z" fill="#fafafa"/>
|
||||
<path d="m484.92 129.11v174.57l8.591-6.823 1.343-171.32-9.934 3.572z" fill="#d9d9d9"/>
|
||||
<path d="m474.17 123.4c3.208-2.974 12.776 2.618 12.776 5.791l-2.03 174.45-17.816-7.357 7.07-172.88z" fill="#f0f0f0"/>
|
||||
<path d="M476.207,93.1135c3.208-2.6737,6.393-3.3837,8.935-2.3742v-.0111l15.784,7.533-.366.9984c1.032,1.3094,1.798,3.0844,2.186,5.3254c1.399,8.065-2.564,18.86-8.857,24.096-1.721,1.432-3.441,2.286-5.051,2.63l-.377,1.043-15.74-7.522c-2.641-.843-4.65-3.462-5.372-7.633-1.398-8.054,2.564-18.838,8.858-24.0855Z" fill="#1890ff"/>
|
||||
<path d="M476.207,93.1135c3.208-2.6737,6.393-3.3837,8.935-2.3742v-.0111l15.784,7.533-.366.9984c1.032,1.3094,1.798,3.0844,2.186,5.3254c1.399,8.065-2.564,18.86-8.857,24.096-1.721,1.432-3.441,2.286-5.051,2.63l-.377,1.043-15.74-7.522c-2.641-.843-4.65-3.462-5.372-7.633-1.398-8.054,2.564-18.838,8.858-24.0855Z" opacity=".15"/>
|
||||
<g transform="translate(1e-6 1e-6)">
|
||||
<path d="m417.9 109.38-20.391 38.331-6.504-4.139 20.324-37.986 6.571 3.794z" fill="#f0f0f0"/>
|
||||
<path d="m378.54 158.89 18.97-11.183-6.505-4.138-19.047 11.538 6.582 3.783z" fill="#f0f0f0"/>
|
||||
<path d="m421.14 111.11-3.241-1.731-20.39 38.331-18.97 11.183v3.639l22.022-13.114 20.579-38.308z" fill="#d9d9d9"/>
|
||||
<path d="M425.28,104.818l51.836,11.349c2.897-.466,4.873-3.195,4.406-6.102-.466-2.895-3.196-4.87-6.104-4.404-.056.011-.134.022-.189.033l-51.381-8.8307c-2.187.4327-3.608,2.5627-3.175,4.7487.422,2.141,2.476,3.55,4.607,3.206Z" fill="#f0f0f0"/>
|
||||
<path d="M425.28,104.818l51.836,11.349c2.897-.466,4.873-3.195,4.406-6.102-.466-2.895-3.196-4.87-6.104-4.404-.056.011-.134.022-.189.033l-51.381-8.8307c-2.187.4327-3.608,2.5627-3.175,4.7487.422,2.141,2.476,3.55,4.607,3.206Z" fill="#f0f0f0" opacity=".7"/>
|
||||
<path d="M412.326,86.7785c2.287-1.8971,4.551-2.4074,6.36-1.6863v-.0111l11.156,5.7246-.256.71c.733.9319,1.288,2.1967,1.554,3.7942.999,5.7361-1.831,13.4131-6.304,17.1401-1.221,1.021-2.442,1.631-3.597,1.875l-.266.744-11.122-5.725v-.011c-1.876-.599-3.308-2.452-3.83-5.414-.987-5.7357,1.832-13.4128,6.305-17.1405Z" fill="#096dd9"/>
|
||||
<path d="M412.326,86.7785c2.287-1.8971,4.551-2.4074,6.36-1.6863v-.0111l11.156,5.7246-.256.71c.733.9319,1.288,2.1967,1.554,3.7942.999,5.7361-1.831,13.4131-6.304,17.1401-1.221,1.021-2.442,1.631-3.597,1.875l-.266.744-11.122-5.725v-.011c-1.876-.599-3.308-2.452-3.83-5.414-.987-5.7357,1.832-13.4128,6.305-17.1405Z" opacity=".15"/>
|
||||
<path d="m423.72 92.592c-4.473 3.7277-7.293 11.405-6.305 17.14 0.999 5.736 5.428 7.367 9.901 3.639 4.473-3.727 7.293-11.405 6.305-17.14-0.988-5.7468-5.428-7.3776-9.901-3.6389z" fill="#1890ff"/>
|
||||
<path d="M421.639,106.205c.122.687.344,1.253.644,1.675.887,1.298,2.486,1.398,4.095.066c2.132-1.786,3.486-5.447,3.008-8.1982-.31-1.7862-1.298-2.7292-2.541-2.6848-.689,0-1.432.3107-2.187.9541-2.142,1.7862-3.497,5.4469-3.019,8.1879Z" fill="#096dd9"/>
|
||||
<path d="M421.639,106.205c.122.687.344,1.253.644,1.675.887,1.298,2.486,1.398,4.095.066c2.132-1.786,3.486-5.447,3.008-8.1982-.31-1.7862-1.298-2.7292-2.541-2.6848-.689,0-1.432.3107-2.187.9541-2.142,1.7862-3.497,5.4469-3.019,8.1879Z" opacity=".3"/>
|
||||
<path d="M421.639,106.205c.122.687.344,1.253.644,1.675.688,0,1.442-.322,2.197-.954c2.131-1.786,3.486-5.448,3.008-8.1878-.122-.6878-.344-1.2536-.643-1.6752-.689,0-1.432.3106-2.187.9541-2.142,1.7861-3.497,5.4469-3.019,8.1879Z" fill="#455a64"/>
|
||||
<path d="m371.96 158.74 6.582 3.783v-3.627l-6.582-3.784v3.628z" fill="#f0f0f0"/>
|
||||
<path d="m418.53 94.4-6.582-3.8164-21.689-27.913 5.328-1.0872 22.943 32.816z" fill="#f0f0f0"/>
|
||||
<path d="M384.245,65.2119c-.378-.1664-.888-.122-1.443.1997L289.619,119.196c-1.188.688-2.165,2.374-2.165,3.75v84.094c0,.654.222,1.142.589,1.375-.367-.244-3.641-2.085-4.041-2.329-.377-.233-.621-.71-.621-1.387v-84.094c0-1.376.966-3.062,2.175-3.75l93.172-53.7843c.611-.355,1.166-.3661,1.554-.1442.355.1997,3.197,1.8083,3.963,2.2854Z" fill="#096dd9" opacity=".7"/>
|
||||
<path d="M289.62,119.185l93.182-53.7846c1.199-.6878,2.165-.1331,2.165,1.2536v84.094c0,1.375-.966,3.062-2.165,3.75L289.62,208.282c-1.199.688-2.165.133-2.165-1.254v-84.093c0-1.376.966-3.062,2.165-3.75Z" fill="#1890ff"/>
|
||||
<path d="M288.088,120.805l-4.063-2.341c-.399.677-.632,1.442-.632,2.141v84.094c0,.677.244,1.165.621,1.387.4.244,3.674,2.085,4.04,2.329-.366-.244-.588-.721-.588-1.375v-84.094c-.011-.699.233-1.465.622-2.141Z" opacity=".15"/>
|
||||
<path d="M384.245,65.2117c-.765-.466-3.607-2.0746-3.962-2.2854-.389-.233-.944-.2108-1.554.1442L285.557,116.855c-.599.344-1.143.932-1.532,1.609l4.063,2.341c.388-.677.932-1.276,1.532-1.62l93.182-53.7847c.555-.3107,1.066-.3661,1.443-.1886Z" fill="#fff" opacity=".5"/>
|
||||
<path d="M348.448,147.087l7.371,10.351-33.289-30.276-35.075,59.387v20.491c0,1.375.966,1.941,2.165,1.253l93.182-53.784c1.199-.688,2.165-2.374,2.165-3.75v-11.261l-24.819-17.861-11.7,25.45Z" fill="#fafafa" opacity=".95"/>
|
||||
<path d="m352.46 97.296c4.34-2.5073 7.87-0.4771 7.87 4.5379 0 5.014-3.518 11.116-7.87 13.623-4.34 2.508-7.869 0.477-7.869-4.537 0-5.026 3.518-11.117 7.869-13.624z" fill="#fafafa" opacity=".95"/>
|
||||
<path d="M383.768,66.1103c.189,0,.2.4881.2.5436v84.0941c0,1.02-.777,2.374-1.665,2.884L289.12,207.417c-.255.144-.411.166-.466.166-.189,0-.2-.488-.2-.544v-84.093c0-1.021.777-2.374,1.665-2.885l93.183-53.7843c.255-.1442.41-.1664.466-.1664Zm0-.9985c-.289,0-.622.0999-.966.2996L289.62,119.196c-1.199.688-2.165,2.374-2.165,3.75v84.093c0,.977.488,1.543,1.199,1.543.288,0,.621-.1.966-.3l93.182-53.785c1.199-.687,2.165-2.374,2.165-3.749v-84.0941c0-.9763-.489-1.5421-1.199-1.5421Z" fill="#096dd9"/>
|
||||
<path d="m418.53 94.4 2.609-2.8845-24.564-35.046-23.998 13.169v4.7483l22.599-12.137 23.354 32.151z" fill="#d9d9d9"/>
|
||||
<path d="m372.58 74.386-7.593-4.3822v-4.7483l7.593 4.3822v4.7483z" fill="#d9d9d9"/>
|
||||
<path d="m364.99 65.256 23.987-13.18 7.603 4.3933-23.997 13.169-7.593-4.3822z" fill="#f0f0f0"/>
|
||||
</g>
|
||||
<path d="m492.32 100.76c-6.294 5.248-10.256 16.031-8.858 24.097 1.399 8.065 7.637 10.351 13.919 5.114 6.294-5.247 10.257-16.031 8.858-24.096-1.398-8.0659-7.637-10.351-13.919-5.115z" fill="#1890ff"/>
|
||||
<path d="M489.405,119.895c.166.965.477,1.764.91,2.363c1.243,1.819,3.496,1.964,5.761.089c2.996-2.508,4.895-7.666,4.229-11.527-.433-2.507-1.821-3.839-3.575-3.772-.965.011-2.009.444-3.074,1.331-3.03,2.518-4.929,7.677-4.251,11.516Z" fill="#096dd9"/>
|
||||
<path d="M489.405,119.895c.166.965.477,1.764.91,2.363c1.243,1.819,3.496,1.964,5.761.089c2.996-2.508,4.895-7.666,4.229-11.527-.433-2.507-1.821-3.839-3.575-3.772-.965.011-2.009.444-3.074,1.331-3.03,2.518-4.929,7.677-4.251,11.516Z" opacity=".3"/>
|
||||
<path d="M489.405,119.895c.166.965.477,1.764.91,2.363.965-.011,2.02-.444,3.086-1.342c2.996-2.508,4.895-7.667,4.229-11.505-.167-.965-.478-1.764-.911-2.363-.965.011-2.009.444-3.074,1.331-3.019,2.519-4.917,7.677-4.24,11.516Z" fill="#455a64"/>
|
||||
<path d="M221.784,239.834l-30.769,83.683-.011.011c-.067.211-.244.411-.544.577-.777.444-2.031.444-2.808,0-.333-.188-.522-.432-.577-.688-.011-.077-.011-.155,0-.233.011-.188.044-.377.111-.576l30.846-84.15c.377-1.031,1.521-1.564,2.553-1.176c1.054.389,1.576,1.52,1.199,2.552Z" fill="#d9d9d9"/>
|
||||
<path d="m181.77 294.02-2.22 3.843 30.846 17.801 2.22-3.843-30.846-17.801z" fill="#d9d9d9"/>
|
||||
<path d="m204.2 281.07-2.22 3.843 30.847 17.801 2.22-3.843-30.847-17.801z" fill="#91d5ff"/>
|
||||
<path d="m204.2 281.07-2.22 3.843 30.847 17.801 2.22-3.843-30.847-17.801z" opacity=".6"/>
|
||||
<path d="M196.688,234.087l16.449-9.497c1.343-.776,2.853-.887,4.13-.321c1.276.565,2.197,1.764,2.519,3.272l27.317,127.716c.022.089.033.178.033.267.011.088.011.188.011.277-.044.244-.233.488-.577.688-.777.444-2.031.444-2.808,0-.289-.178-.466-.377-.544-.588-.011-.044-.022-.078-.022-.122L215.901,228.374c-.066-.278-.177-.444-.255-.489-.078-.033-.278-.011-.522.134l-16.461,9.496" fill="#d9d9d9"/>
|
||||
<path d="M210.496,295.205l-10.024-5.781c-.333-.188-.599-.654-.599-1.031v-.244c0-.378.266-.843.599-1.032l24.043-13.879c.333-.188.865-.188,1.198,0l10.023,5.78c.333.189.6.655.6,1.032v.233c0,.377-.267.843-.6,1.032l-24.042,13.878c-.333.2-.865.2-1.198.012Z" fill="#f5f5f5"/>
|
||||
<path d="M211.096,293.929v1.42c.222,0,.433-.044.599-.144l12.021-6.934l12.021-6.934c.333-.189.6-.654.6-1.032v-.233c0-.188-.067-.399-.178-.588l-25.063,14.445Z" opacity=".15"/>
|
||||
<path d="M200.051,287.561c-.111.188-.178.399-.178.588v.244c0,.377.266.843.599,1.031l10.024,5.78c.166.1.377.145.599.145v-1.42l-11.044-6.368Z" opacity=".1"/>
|
||||
<path d="M206.155,274.891l-16.649-9.607c-.333-.189-.6-.655-.6-1.032v-.233c0-.377.267-.843.6-1.032l24.042-13.879c.333-.188.866-.188,1.199,0l16.649,9.608c.333.188.6.654.6,1.032v.233c0,.377-.267.843-.6,1.031l-24.042,13.879c-.333.2-.866.2-1.199,0Z" fill="#f5f5f5"/>
|
||||
<path d="M206.754,273.626v1.42c.222,0,.433-.044.599-.144l12.021-6.934l12.021-6.934c.333-.188.6-.654.6-1.031v-.233c0-.189-.067-.4-.178-.588l-25.063,14.444Z" opacity=".15"/>
|
||||
<path d="M189.072,263.42c-.111.189-.177.399-.177.588v.233c0,.377.266.843.599,1.032l16.65,9.607c.166.1.377.144.599.144v-1.42L189.072,263.42Z" opacity=".1"/>
|
||||
<path d="M223.537,356.134l-10.024-5.78c-.333-.189-.599-.655-.599-1.032v-.233c0-.377.266-.843.599-1.032l24.043-13.878c.333-.189.865-.189,1.198,0l10.024,5.78c.333.188.599.654.599,1.031v.233c0,.378-.266.844-.599,1.032l-24.043,13.879c-.333.189-.877.189-1.198,0Z" fill="#f5f5f5"/>
|
||||
<path d="M213.092,348.49c-.111.189-.178.4-.178.588v.233c0,.377.266.843.599,1.032l10.024,5.78c.166.1.377.144.599.144v-1.42l-11.044-6.357Z" opacity=".1"/>
|
||||
<path d="M224.137,354.858v1.42c.211,0,.433-.044.599-.144l12.021-6.934l12.021-6.934c.333-.188.6-.654.6-1.031v-.233c0-.189-.067-.4-.178-.588l-25.063,14.444Z" opacity=".15"/>
|
||||
<path d="M219.187,335.82l-10.023-5.78c-.333-.188-.6-.654-.6-1.031v-.233c0-.378.267-.843.6-1.032l24.042-13.879c.333-.189.866-.189,1.199,0l10.023,5.78c.333.189.599.655.599,1.032v.233c0,.377-.266.843-.599,1.032L220.386,335.82c-.333.189-.866.189-1.199,0Z" fill="#f5f5f5"/>
|
||||
<path d="M208.742,328.177c-.111.188-.178.399-.178.588v.233c0,.377.267.843.6,1.032l10.023,5.78c.166.099.377.144.599.144v-1.42l-11.044-6.357Z" opacity=".1"/>
|
||||
<path d="M219.787,334.545v1.42c.211,0,.433-.045.6-.144l12.021-6.934l12.021-6.934c.333-.189.599-.655.599-1.032v-.233c0-.189-.067-.399-.178-.588l-25.063,14.445Z" opacity=".15"/>
|
||||
<path d="M214.845,315.518l-10.023-5.78c-.333-.189-.599-.655-.599-1.032v-.233c0-.377.266-.843.599-1.032l24.042-13.879c.333-.188.866-.188,1.199,0l10.023,5.78c.333.189.599.655.599,1.032v.233c0,.377-.266.843-.599,1.032l-24.042,13.879c-.333.188-.866.188-1.199,0Z" fill="#f5f5f5"/>
|
||||
<path d="M204.4,307.863c-.111.188-.177.399-.177.588v.233c0,.377.266.843.599,1.032l5.006,2.895l5.006,2.896c.167.1.377.144.599.144v-1.42L204.4,307.863Z" opacity=".1"/>
|
||||
<path d="M215.445,314.242v1.42c.211,0,.433-.044.6-.144l12.021-6.934l12.021-6.934c.333-.188.599-.654.599-1.032v-.233c0-.188-.066-.399-.177-.588l-25.064,14.445Z" opacity=".15"/>
|
||||
<path d="m240.38 304.8-0.844-8.853-7.514 0.444s2.553 9.696 2.974 10.594c1.31 0.178 5.384-2.185 5.384-2.185z" fill="#ffa8a7"/>
|
||||
<path d="M242.718,307.863c.056.322.034.666.012.987-.078,1.143-.145,2.297-.222,3.439-.034.466-.067.899-.167,1.354-.111.51-.033,1.109-.044,1.631-.011.566-.011,1.142-.011,1.708c0,.222-.045.511.011.732.066.233-3.586,2.386-5.062,3.218-.089.044-.166.089-.266.133-1.343.544-2.409-.533-2.409-.533-1.077-2.751.944-4.515.944-4.515s.188.011.133-1.442c-.011-1.032-.033-2.075-.144-3.107-.089-.754-.245-1.519-.389-2.263-.144-.787-.211-1.464-.433-2.518-.055-.266-.166-.544-.055-.799.077-.166.222-.299.366-.41c1.41-1.099,2.975-1.764,4.773-1.809.2-.011.422,0,.566.133.133.111.178.289.222.444.1.377.155.899.366,1.232.156.255.444.51.666.699.422.388.921.876,1.088,1.442.022.089.044.166.055.244Z" fill="#bae7ff"/>
|
||||
<path d="M243.44,308.229c.688.255.533,2.13.122,3.938-.411,1.809-.633,2.441-.4,3.939.233,1.497.367,2.163-.233,2.729-.599.554-5.439,2.884-5.439,2.884s.933-2.318,1.021-5.647c.089-3.328.289-5.469,1.81-7c1.52-1.531,3.119-.843,3.119-.843Z" fill="#263238"/>
|
||||
<path d="M231.263,318.835c0,0,1.909,1.498,4.084,1.72c2.176.222,2.276-.611,2.476-3.195.199-2.574.244-6.136,1.232-7.711.999-1.575,2.686-2.296,3.363-2.141.133-.078.81.41,1.032.71c0,0-1.487-.166-2.83,1.176s-1.554,4.138-1.587,6.69c-.034,2.54-.111,5.491-2.132,5.824-2.02.333-4.184-.51-5.538-1.608-.789-.633-.1-1.465-.1-1.465Z" fill="#37474f"/>
|
||||
<path d="M235.503,316.017c-.177.233-.333.466-.466.699-.644,1.131-.71,2.318-.388,3.727-2.598-.199-3.375-1.608-3.375-1.608s-.155-1.287,1.321-2.252c.189-.122.377-.222.555-.3.011,0,.022-.011.022-.011c1.243-.544,2.331-.255,2.331-.255Z" fill="#91d5ff"/>
|
||||
<path d="M235.646,315.074c0,0-.267.177-.3.477-.022.288.1.965.755,1.331.277.155.511.089.067-.444-.178-.21-.322-.366-.4-.61-.122-.355-.122-.754-.122-.754Z" fill="#263238"/>
|
||||
<path d="M235.602,313.243c0,0-.199.2-.199.433-.012.233.432,1.187.91,1.387.477.21.222-.278-.011-.511-.122-.133-.356-.488-.5-.787-.133-.256-.2-.522-.2-.522Z" fill="#263238"/>
|
||||
<path d="M235.458,311.269c0,0-.178.188-.111.454.044.2.855.766,1.154.81.211.034.378-.122,0-.377-.188-.122-.499-.299-.71-.488-.222-.189-.333-.399-.333-.399Z" fill="#263238"/>
|
||||
<path d="M240.087,299.332c0,0-3.752-.5-6.971,1.841c0,0-.688-1.864-4.118-14.012-1.265-4.493-2.098-8.298-2.852-11.172-.844-3.206-1.144-4.482-1.321-6.756-.6-7.699-.788-30.165-1.11-33.06c0,0,15.984-4.882,15.995-4.849.754,3.473,1.354,7.134-.023,13.835-1.332,9.385-2.508,19.659-2.941,24.718c0,0,1.443,2.984,2.142,7.788.433,2.973,1.199,21.667,1.199,21.667Z" fill="#096dd9"/>
|
||||
<path d="M205.645,307.03c-.299-.055-.144,1.01-.066,1.398.078.389.666,1.398,2.819,2.031c2.154.643,4.129.244,5.506.565c1.265.289,3.685,1.831,4.961,2.153c1.676.432,3.652.099,4.585-.411.355-.2,1.098-.721,1.121-1.076.022-.422.055-.888-.045-.888l-18.881-3.772Z" fill="#37474f"/>
|
||||
<path d="M224.525,310.803c-.444.654-1.365,1.153-2.12,1.386-1.21.378-2.486.378-3.718.045-.722-.2-1.554-.633-2.209-.999-.777-.421-1.587-.632-2.431-.887-1.077-.322-3.152-.333-4.273-.455s-1.732-.333-2.642-.999c-.688-.51-.777-1.597-.81-2.474-.011-.188-.011-.466.066-.632.1-.2.233-.233.433-.344.444-.266.833-.621,1.299-.854.633-.322,3.13-1.087,4.151-.732l.544.122c.422.088,2.065.266,2.497.277.433.011.888-.078,1.233-.333.288-.222.499-.566.821-.732.355-.178.788-.122,1.177-.011.721.188,1.309.299,2.031.033.777-.288,1.465-.987,2.231-1.309.211-.089.51-.1.744.144.199.211.199.588.177.877-.066,1.009.156,2.008.267,3.017.166,1.376.987,2.874.532,4.86Z" fill="#bae7ff"/>
|
||||
<path d="M213.704,303.88c-.455-.056-1.021.299-1.277.677-.155.233-.255.399-.355.665-.111.322-.189.666-.111.999.022.088.111.144.189.133.077-.011.155-.089.166-.167.089-.466.178-.887.422-1.287.111-.177.189-.332.355-.466.156-.122.344-.221.544-.277.056-.011.144-.044.255-.033.045,0,.134.011.134.011c0-.1-.078-.155-.111-.166-.067-.067-.111-.078-.211-.089Z" fill="#263238"/>
|
||||
<path d="M215.103,304.08c-.233-.045-.488,0-.699.133-.244.155-.344.388-.466.643-.145.3-.256.61-.289.943-.022.167-.078.832.244.755.078-.023.133-.089.167-.156.033-.077.044-.155.055-.233.045-.344.122-.676.255-.998.145-.366.422-.832.844-.899.044-.011.1-.011.144-.011.011-.078-.077-.122-.144-.144-.044-.011-.078-.022-.111-.033Z" fill="#263238"/>
|
||||
<path d="M216.324,303.758c-.177.044-.344.122-.466.255-.111.122-.244.344-.3.511-.133.355-.222.621-.244,1.042-.022.267,0,.544.122.788.045.1.145.2.245.155.111-.044.111-.21.133-.299.033-.178.033-.366.055-.544.067-.665.344-1.287.777-1.786.022-.022.056-.078.056-.078-.011-.044-.1-.066-.145-.066-.077-.011-.155,0-.233.022Z" fill="#263238"/>
|
||||
<path d="M212.271,303.847c-.51-.089-1.72.443-2.508,1.941s-.888,3.972-.888,3.972-1.343-.078-2.609-1.509c-.333-.377-.566-.843-.655-1.342.034-1.065.4-1.809.911-2.252.899-.777,1.809-1.276,4.129-1.232c2.086.033,2.153.544,2.153.544l-.533-.122Z" fill="#91d5ff"/>
|
||||
<path d="M222.816,296.402c0,0,.266,4.726.455,5.991.1.71-.411,1.454-2.531,2.086-1.487.444-3.063-.011-3.085-.422l-1.01-4.493l6.171-3.162Z" fill="#ffa8a7"/>
|
||||
<path d="M240,232.378l-25.707,2.663c0,0-5.594,33.637-5.728,37.232-.1,2.607,7.781,27.89,7.781,27.89s4.884.666,6.927-1.753c-.222-3.394-.589-12.004-.822-15.099-.388-4.981-.766-6.9-2.175-11.826c0,0,6.893-17.165,9.224-24.986c11.566-4.371,10.5-14.121,10.5-14.121Z" fill="#0050b3"/>
|
||||
<path d="M240,232.378l-25.707,2.663c0,0-5.594,33.637-5.728,37.232-.1,2.607,7.781,27.89,7.781,27.89s4.884.666,6.927-1.753c-.222-3.394-.589-12.004-.822-15.099-.388-4.981-.766-6.9-2.175-11.826c0,0,5.994-17.418,8.325-25.239C240.167,241.875,240,232.378,240,232.378Z" fill="#096dd9"/>
|
||||
<g transform="translate(2e-6)">
|
||||
<path d="m221.23 191.57 1.065 9.175 9.835-1.431-1.044-9.896-9.856 2.152z" fill="#ffa8a7"/>
|
||||
<path d="m214.95 179.68s-2.264 4.36-2.009 4.682 1.909 0.843 1.909 0.843l0.1-5.525z" fill="#f28f8f"/>
|
||||
<path d="M215.979,182.455c-1.465,0-2.653-1.154-2.653-2.574s1.188-2.574,2.653-2.574s2.653,1.154,2.653,2.574-1.188,2.574-2.653,2.574Zm0-4.582c-1.143,0-2.065.899-2.065,2.008s.922,2.008,2.065,2.008s2.065-.899,2.065-2.008-.933-2.008-2.065-2.008Z" fill="#263238"/>
|
||||
<path d="M221.129,171.261c-4.517.921-5.816,2.851-6.238,9.807-.444,7.267.111,8.82,1.088,9.796.666.666,3.563.977,5.306.899c6.316-.299,8.724-2.319,11.2-5.98c2.897-4.304,3.662-10.129.555-12.514-4.385-3.361-10.079-2.385-11.911-2.008Z" fill="#ffa8a7"/>
|
||||
<path d="M215.979,190.864c.666.666,3.563.977,5.305.899l-.133-1.021c0,0-2.719.322-5.172.122Z" fill="#f28f8f"/>
|
||||
<path d="M213.57,179.337l8.025,1.01-.321.544-7.704-.966v-.588Z" fill="#263238"/>
|
||||
<path d="M214.979,173.48c.211.133.433.233.678.299-.189.855.088,1.809.71,2.43s1.565.899,2.431.71c-.189.499-.133,1.076.133,1.531s.755.777,1.276.854c-.144-.022-.022,1.221.012,1.331.133.5.321.722.788.921c0,0,.71-2.684,3.052-2.352c2.353.344,2.664,3.24,1.188,5.004-1.477,1.753-2.842,1.098-2.864,1.087.133.067.189.921.233,1.087.144.499.344,1.454.6,1.92.51.943.643,1.653,2.375,2.418.843.377,4.728-.066,5.539-1.009c1.376-3.462,3.318-4.749,4.861-7.822.7-1.398,1.499-3.029,1.577-4.615.066-1.376.099-2.851-1.732-4.227.533-.621.61-1.586.178-2.296-.422-.699-1.321-1.088-2.12-.91.233-1.243-.4-2.596-1.488-3.229-.688-.399-1.532-.499-2.298-.31-.222.055-1.942.754-1.886,1.043-.234-1.276-1.421-2.297-2.72-2.352-1.299-.045-2.553.898-2.875,2.152-.644-.987-1.687-1.72-2.841-1.986-.999-.233-2.131-.1-2.875.599s-.855,2.23-.311,3.251c-.777-.067-1.532.144-2.076.81-.466.577-.71,1.264-.599,2.008.1.787.4,1.242,1.054,1.653Z" fill="#263238"/>
|
||||
<path d="M220.952,183.098l.078-3.039c-.866-.023-1.588.643-1.61,1.475-.011.843.666,1.542,1.532,1.564Z" fill="#263238"/>
|
||||
</g>
|
||||
<path d="M234.947,194.547c2.742-.288,5.239.244,6.705,2.896c1.465,2.64,3.307,12.27,4.029,16.63.677,4.105.988,4.859-1.232,6.301-1.465.966-7.57,4.127-7.57,4.127l-1.932-29.954Z" fill="#ffa8a7"/>
|
||||
<path d="M233.783,194.37c2.997-.344,5.328-.222,6.46.81c1.132,1.031,2.331,2.085,3.142,6.079.81,3.994,1.875,9.697,1.875,9.697s-2.22,4.67-10.311,4.016l-1.166-20.602Z" fill="#91d5ff"/>
|
||||
<path d="M233.783,194.37c2.997-.344,5.328-.222,6.46.81c1.132,1.031,2.331,2.085,3.142,6.079.81,3.994,1.875,9.697,1.875,9.697s-2.22,4.67-10.311,4.016l-1.166-20.602Z" fill="#e6f7ff" opacity=".3"/>
|
||||
<path d="M239.776,199.007c-.455-2.474-3.707-5.081-6.759-4.582c0,0-.722.056-1.388.178-.344,1.486-6.871,3.162-9.845,1.808-1.177.311-4.218.899-5.195,1.22-2.797.932-3.952,3.684-4.396,12.814c0,0,1.732,20.868,1.743,26.715c4.729,1.353,10.778,1.586,16.583.288c8.347-1.863,9.479-5.07,9.479-5.07l-.799-9.585c-.011-.011,1.599-18.183.577-23.786Z" fill="#f5f5f5"/>
|
||||
<g transform="translate(1e-6 5e-6)">
|
||||
<g transform="translate(1e-6)">
|
||||
<path d="M177.906,186.382l1.998,11.727c.045.233.233.432.555.554.666.244,1.643.078,2.176-.377.266-.222.388-.477.344-.71l-1.998-11.726-3.075.532Z" fill="#455a64"/>
|
||||
<path d="M181.514,188.878l-2.786,2.297-.822-4.793l3.086-.521.522,3.017Z" opacity=".15"/>
|
||||
<path d="M180.936,176.187l.41,2.385l1.865-1.542.844,4.903c.255,1.476-.478,3.451-1.632,4.405l-3.274,2.718c-.544.444-1.088.599-1.532.466-.045-.011-1.998-.721-2.42-.899-.433-.189-.755-.643-.877-1.353l-.843-4.904l7.459-6.179Z" fill="#37474f"/>
|
||||
<path d="M179.161,189.056l3.274-2.718c1.155-.954,1.887-2.929,1.632-4.416l-.844-4.903-7.448,6.179.844,4.904c.244,1.497,1.387,1.919,2.542.954Z" fill="#455a64"/>
|
||||
<path d="m175.76 183.21 7.448-6.179-1.221-7.156-7.459 6.179 1.232 7.156z" fill="#f0f0f0"/>
|
||||
<path d="m175.76 183.21-1.232-7.155-2.264-0.844 1.221 7.156 2.275 0.843z" fill="#ebebeb"/>
|
||||
<path d="M176.131,185.339l7.448-6.179.166.976-7.437,6.224-.177-1.021Z" fill="#fafafa"/>
|
||||
<path d="M176.131,185.339l-2.276-.843.178,1.032l2.276.832-.178-1.021Z" fill="#e6e6e6"/>
|
||||
<path d="m172.65 177.4s0.987 1.586 2.375 1.442l-0.477-2.784-2.265-0.844 0.367 2.186z" fill="#91d5ff"/>
|
||||
<path d="m172.65 177.4s0.987 1.586 2.375 1.442l-0.477-2.784-2.265-0.844 0.367 2.186z" fill="#096dd9" opacity=".5"/>
|
||||
<path d="M175.01,178.849c0,0,1.587.41,2.753-.81.865-.899.754-3.528,2.641-3.894c1.332-.266,2.476.987,2.476.987l-.899-5.247-7.46,6.179.489,2.785Z" fill="#1890ff"/>
|
||||
<path d="m181.99 169.87-2.275-0.843-7.448 6.179 2.264 0.843 7.459-6.179z" fill="#91d5ff"/>
|
||||
<path d="m181.99 169.87-2.275-0.843-7.448 6.179 2.264 0.843 7.459-6.179z" fill="#69c0ff" opacity=".7"/>
|
||||
</g>
|
||||
<g transform="translate(0 1e-6)">
|
||||
<path d="M181.957,191.497c1.121.066,2.12,1.087,2.153,1.863.034.777-1.631,1.332-1.631,1.332l-.522-3.195Z" fill="#f28f8f"/>
|
||||
<path d="M216.81,197.565c-1.887.4-2.109-.144-7.17,2.918-4.706,2.851-12.898,7.555-15.962,9.308-3.274-2.995-6.77-7.633-8.047-9.874-.344-.599-.477-1.52-.411-2.208.178-1.919-.244-2.096-.31-3.827-.045-1.342.333-2.075.022-2.208-.4-.166-1.321-.133-1.865.921-.277.532-.366,1.021-.588,2.097c0,0-2.853,2.54-3.153-.011l-.555-3.218c-.865,0-2.475.278-2.886,2.219-.355,1.687-.588,5.37.666,7.733.6,1.131,3.142,2.086,4.54,3.006c1.565,1.032,6.327,11.228,9.246,13.191c1.799,1.176,2.964.966,5.284.178c5.206-1.764,17.926-8.121,17.926-8.121s5.317-3.162,3.263-12.104Z" fill="#ffa8a7"/>
|
||||
<path d="m217.29 197.44c-4.118-0.089-6.438 2.086-10.945 4.693-4.795 2.762-6.482 3.739-6.482 3.739s-1.265 6.257 3.53 9.108l10.855-5.048c3.042-1.964 5.184-7.422 3.042-12.492z" fill="#91d5ff"/>
|
||||
<path d="m217.29 197.44c-4.118-0.089-6.438 2.086-10.945 4.693-4.795 2.762-6.482 3.739-6.482 3.739s-1.265 6.257 3.53 9.108l10.855-5.048c3.042-1.964 5.184-7.422 3.042-12.492z" fill="#e6f7ff" opacity=".3"/>
|
||||
</g>
|
||||
</g>
|
||||
<path d="M199.351,252.781l-30.736,83.583-.011.022-.066.189c-.089.178-.256.333-.5.488-.777.444-2.031.444-2.808,0-.333-.2-.522-.444-.577-.688-.011-.077-.011-.155,0-.233.011-.199.044-.388.122-.577l30.846-84.149c.378-1.031,1.51-1.553,2.553-1.176c1.033.366,1.554,1.509,1.177,2.541Z" fill="#d9d9d9"/>
|
||||
<path d="M198.662,237.515c-.91.533-1.543,1.942-1.321,2.963l27.317,127.704c.022.1.044.211.044.311.012.067.012.144,0,.222-.044.244-.233.499-.577.699-.777.444-2.031.444-2.808,0-.289-.167-.466-.366-.544-.577c0-.011,0-.011-.011-.022l-.033-.167L193.445,241.31c-.577-2.685.833-5.869,3.219-7.234" fill="#d9d9d9"/>
|
||||
<path d="M157.75,345.983h-28.859l1.298,20.502c-.022,1.908,1.221,3.816,3.719,5.303c4.995,2.962,13.153,3.051,18.226.2c2.553-1.443,3.829-3.351,3.829-5.27l1.787-20.735Z" fill="#bae7ff"/>
|
||||
<path d="M133.163,339.604c-5.672,3.195-5.727,8.465-.122,11.782c5.606,3.317,14.741,3.417,20.424.222c5.672-3.196,5.727-8.465.122-11.782-5.617-3.318-14.752-3.417-20.424-.222Z" fill="#455a64"/>
|
||||
<path d="M156.495,345.739c0,.377-.078.754-.2,1.131-.444,1.354-1.621,2.608-3.452,3.639-2.564,1.432-5.972,2.197-9.612,2.164-3.63-.045-7.027-.877-9.557-2.374-1.776-1.054-2.942-2.319-3.341-3.639-.145-.389-.2-.799-.2-1.21.033-1.764,1.321-3.45,3.663-4.759c2.542-1.442,5.971-2.219,9.601-2.163c3.641.033,7.037.876,9.568,2.374c2.287,1.375,3.552,3.084,3.53,4.837Z" fill="#e6f7ff"/>
|
||||
<path d="M143.375,348.024c-3.629-.033-7.048.743-9.601,2.186-.045.022-.089.055-.133.077.011.011.022.011.033.022c2.531,1.487,5.927,2.319,9.557,2.375c3.641.033,7.048-.744,9.612-2.164.045-.022.089-.055.133-.089-.011-.011-.022-.011-.033-.022-2.531-1.486-5.916-2.33-9.568-2.385Z" fill="#1890ff"/>
|
||||
<path d="M122.875,366.524c-3.629-.033-1.322,1.034-3.875,2.476c6.226,1.291,0-1.5,0-1.5c1.259-.629-4-1.264-2,1.21s2.101,2.418,5.731,2.474c3.641.033.705.236,3.269-1.184v-1.29-.71c-2.531-1.487.527-1.42-3.125-1.476Z" fill="#1890ff"/>
|
||||
<path d="M144.308,352.662c-.977-.211-1.876-.544-2.631-.988-.944-.566-1.565-1.242-1.787-1.941-.078-.211-.111-.433-.111-.644c0-.288.078-.566.211-.843-2.331.322-4.485.976-6.216,1.964-.045.022-.089.055-.133.077.011.012.022.012.033.023c2.531,1.486,5.927,2.318,9.557,2.374.355,0,.721-.011,1.077-.022Z" opacity=".15"/>
|
||||
<path d="M148.792,353.693c.566-.322,1.021-.055,1.01.599-.011.644-.466,1.431-1.032,1.753s-1.021.056-1.01-.599.466-1.431,1.032-1.753Z" fill="#263238"/>
|
||||
<path d="M129.223,351.718c-1.244,3.184-2.209,7.522.577,9.586.155.111.3.21.444.31l-.011,1.343c-.367-.222-.744-.477-1.11-.744-4.14-3.062-1.61-9.774-.022-13.035l.122,2.54Z" fill="#455a64"/>
|
||||
<path d="M149.269,355.135c-.155.322-4.14,7.933-10.678,9.464-.755.177-1.498.266-2.253.266-2.031,0-4.063-.633-6.094-1.908l.011-1.343c2.709,1.875,5.428,2.519,8.092,1.908c6.038-1.42,9.912-8.831,9.934-8.897.145-.277.489-.377.755-.233.278.122.389.455.233.743Z" fill="#455a64"/>
|
||||
<path d="M142.5,357.5c.931-1.392.206-4.897-1.5-5-1.752-.105-3.064,3.562-2.103,5c.846,1.265,2.758,1.265,3.603,0Z" fill="#1890ff"/>
|
||||
<path d="M141.42,357.616c.93-1.392,1.375-4.423-.5-5-1.5-.461-2.984,3.446-2.023,4.884.845,1.265,1.677,1.381,2.523.116Z" fill="#147bd9"/>
|
||||
<path d="M292.228,454.049l-44.963-26.25c-1.02-.6-1.02-1.562,0-2.163L354.983,362.95c1.02-.601,2.689-.601,3.709,0l45.043,26.21c1.02.6,1.02,1.562,0,2.163L295.924,454.049c-1.007.601-2.663.601-3.696,0Z" fill="#fafafa"/>
|
||||
<path d="M350.303,376.467l-5.134,2.965c-.519.292-1.344.292-1.862,0l-1.636-.944c-.519-.293-.838-1.011-.705-1.596l17.038-80.613c.119-.585.638-1.29,1.157-1.596l5.134-2.964c.519-.293,1.343-.293,1.862,0l1.636.944c.519.292.838,1.01.705,1.595L351.46,374.872c-.133.585-.652,1.303-1.157,1.595Z" fill="#f0f0f0"/>
|
||||
<path d="M350.303,376.467l-5.134,2.965c-.519.292-.838.066-.705-.519L361.502,298.3c.12-.585.638-1.29,1.157-1.596l5.134-2.964c.519-.293.838-.067.705.518L351.46,374.872c-.133.585-.652,1.303-1.157,1.595Z" fill="#d9d9d9"/>
|
||||
<path d="m347.57 371.2 1.517-7.192 3.498-2.007 32.373 18.678 1.517 8.947-3.485 2.007-35.42-20.433z" fill="#d9d9d9"/>
|
||||
<path d="m382.99 391.64-35.42-20.433 1.517-7.192 32.373 18.678 1.53 8.947z" fill="#f0f0f0"/>
|
||||
<path d="M388.756,398.655l-5.134,2.965c-.519.292-1.344.292-1.862,0l-1.636-.944c-.519-.293-1.011-1.011-1.117-1.596L361.889,298.313c-.093-.585.239-1.302.758-1.595l5.134-2.964c.519-.293,1.343-.293,1.862,0l1.636.943c.519.293,1.011,1.011,1.117,1.596L389.514,397.06c.093.585-.239,1.303-.758,1.595Z" fill="#37474f"/>
|
||||
<path d="M361.902,298.3l.652,3.815l16.479,96.965c.107.585.599,1.303,1.104,1.596l1.636.944c.519.292,1.357.292,1.862,0l5.121-2.965c.519-.306.851-1.01.758-1.595L372.449,296.638l-.066-.345c-.106-.585-.599-1.303-1.104-1.596l-1.636-.943c-.519-.293-1.357-.293-1.862,0l-5.134,2.964c-.505.293-.851.997-.745,1.582Z" fill="#d9d9d9"/>
|
||||
<path d="M372.384,296.292L389.502,397.06c.093.584-.239,1.302-.758,1.595l-5.134,2.964c-.519.293-1.011.067-1.117-.518L365.375,300.32c-.093-.585.239-1.302.758-1.595l5.134-2.964c.519-.293,1.024-.054,1.117.531Z" fill="#f0f0f0"/>
|
||||
<path d="M269.867,422.876l-5.134,2.964c-.519.293-1.343.293-1.862,0l-1.636-.944c-.519-.292-.838-1.01-.705-1.595l17.038-80.614c.12-.585.639-1.289,1.157-1.595l5.134-2.964c.519-.293,1.344-.293,1.862,0l1.636.943c.519.293.838,1.011.705,1.596L271.024,421.28c-.119.585-.638,1.303-1.157,1.596Z" fill="#f0f0f0"/>
|
||||
<path d="M269.867,422.876l-5.134,2.964c-.519.293-.838.067-.705-.518l17.038-80.614c.12-.585.639-1.29,1.157-1.595l5.134-2.965c.519-.292.838-.066.705.519L271.024,421.28c-.119.585-.638,1.303-1.157,1.596Z" fill="#d9d9d9"/>
|
||||
<path d="m267.05 417.73 1.516-7.192 3.498-2.008 32.374 18.678 1.516 8.947-3.485 2.021-35.419-20.446z" fill="#d9d9d9"/>
|
||||
<path d="m302.47 438.18-35.419-20.445 1.516-7.192 32.387 18.691 1.516 8.946z" fill="#f0f0f0"/>
|
||||
<path d="M308.33,445.077l-5.134,2.964c-.519.293-1.343.293-1.862,0l-1.636-.943c-.519-.293-1.011-1.011-1.117-1.596L281.463,344.735c-.093-.585.239-1.303.758-1.595l5.134-2.965c.519-.292,1.343-.292,1.862,0l1.636.944c.519.293,1.011,1.011,1.117,1.596l17.118,100.767c.093.571-.239,1.289-.758,1.595Z" fill="#37474f"/>
|
||||
<path d="M281.476,344.722l.652,3.815l16.479,96.965c.107.585.599,1.303,1.104,1.595l1.636.944c.519.293,1.357.293,1.862,0l5.121-2.964c.519-.306.851-1.011.758-1.596L292.024,343.047l-.067-.346c-.106-.585-.598-1.303-1.104-1.595l-1.636-.944c-.518-.293-1.356-.293-1.862,0l-5.134,2.964c-.505.293-.851,1.011-.745,1.596Z" fill="#d9d9d9"/>
|
||||
<path d="M291.959,342.701l17.117,100.767c.094.585-.239,1.303-.758,1.595l-5.134,2.965c-.518.292-1.011.066-1.117-.519L284.949,346.742c-.093-.585.24-1.303.758-1.595l5.134-2.965c.519-.306,1.024-.066,1.118.519Z" fill="#f0f0f0"/>
|
||||
<path d="m277.79 357.78 108.39-62.535-1.769-1.023-108.37 62.547 1.756 1.011z" fill="#ff7875"/>
|
||||
<path d="m277.79 357.78 108.39-62.535-1.769-1.023-108.37 62.547 1.756 1.011z" fill="#fff" opacity=".4"/>
|
||||
<path d="m277.79 357.77 5.267 31.28 108.39-62.534-5.267-31.28-108.39 62.534z" fill="#ff7875"/>
|
||||
<path d="m276.03 356.76 5.254 31.281 1.769 1.01-5.267-31.28-1.756-1.011z" fill="#d9d9d9"/>
|
||||
<path d="m277.12 363.28 2.913 17.309 1.756 1.01-2.9-17.295-1.769-1.024z" fill="#cf1322"/>
|
||||
<path d="m277.12 363.28 2.913 17.309 1.756 1.01-2.9-17.295" opacity=".2"/>
|
||||
<path d="m287.74 352.04-4.682 37.01-5.267-31.28 9.949-5.73z" fill="#ebebeb"/>
|
||||
<path d="m381.49 332.25 4.682-37.01 5.267 31.281-9.949 5.729z" fill="#ebebeb"/>
|
||||
<path d="m301.25 378.55 4.682-37.01-10.76 6.195-4.682 37.024 10.76-6.209z" fill="#ebebeb"/>
|
||||
<path d="m319.45 368.05 4.681-37.01-10.76 6.194-4.681 37.024 10.76-6.208z" fill="#ebebeb"/>
|
||||
<path d="m337.66 357.55 4.681-37.01-10.76 6.208-4.682 37.01 10.761-6.208z" fill="#ebebeb"/>
|
||||
<path d="m355.85 347.06 4.682-37.023-10.76 6.208-4.682 37.01 10.76-6.195z" fill="#ebebeb"/>
|
||||
<path d="m374.06 336.56 4.682-37.024-10.76 6.208-4.682 37.01 10.76-6.194z" fill="#ebebeb"/>
|
||||
<path d="m295.17 347.74-1.769-1.01 10.774-6.208 1.755 1.023-10.76 6.195z" fill="#fafafa"/>
|
||||
<path d="m313.37 337.24-1.756-1.01 10.76-6.208 1.756 1.023-10.76 6.195z" fill="#fafafa"/>
|
||||
<path d="m331.58 326.75-1.769-1.023 10.773-6.208 1.756 1.023-10.76 6.208z" fill="#fafafa"/>
|
||||
<path d="m349.77 316.24-1.755-1.024 10.76-6.208 1.755 1.024-10.76 6.208z" fill="#fafafa"/>
|
||||
<path d="m367.98 305.74-1.769-1.024 10.773-6.208 1.756 1.024-10.76 6.208z" fill="#fafafa"/>
|
||||
<path d="m277.79 357.77-1.756-1.01 9.936-5.743 1.769 1.024-9.949 5.729z" fill="#fafafa"/>
|
||||
<path d="m278.9 364.3 2.899 17.296 108.39-62.548-2.899-17.295-108.39 62.547z" fill="#cf1322"/>
|
||||
<path d="M284.171,375.797c-.626-.307-1.049-1.003-1.254-2.09l-1.419-7.497c-.063-.345.143-.641.603-.916l.488-.276c.46-.262.729-.227.792.117l1.387,7.339c.079.437.241.74.484.908s.511.162.832-.017c.306-.179.527-.449.66-.837.133-.389.167-.802.074-1.225l-1.387-7.339c-.063-.344.128-.641.603-.916l.474-.262c.46-.262.729-.227.792.117l1.419,7.498c.205,1.086.111,2.072-.28,2.97-.391.899-1.054,1.604-1.946,2.113-.935.511-1.695.619-2.322.313Z" fill="#fff"/>
|
||||
<path d="M290.483,372.52l-1.955-10.319c-.063-.344.129-.641.603-.916l.307-.179c.153-.096.293-.139.406-.128.099-.002.213.076.315.22l3.155,4.019c.159.223.378.565.655,1.024l.041-.054c-.165-.515-.286-.925-.335-1.216l-.976-5.14c-.064-.344.128-.641.602-.916l.293-.165c.46-.262.729-.228.792.117l1.955,10.319c.063.344-.143.641-.603.916l-.237.138c-.153.096-.293.139-.406.141s-.227-.075-.315-.22l-3.341-4.175c-.101-.118-.276-.407-.525-.841l-.054.081c.164.462.255.806.302,1.045l1.009,5.298c.063.345-.143.655-.603.916l-.293.166c-.46.248-.729.214-.792-.131Z" fill="#fff"/>
|
||||
<path d="M297.826,368.704c-.086-.065-.16-.21-.206-.435l-1.892-10.001c-.047-.225-.036-.411.017-.559.054-.147.15-.255.303-.351l2.288-1.309c1.046-.593,1.892-.57,2.569.095.676.651,1.181,1.931,1.542,3.812.362,1.894.379,3.45.065,4.666s-1.002,2.121-2.034,2.713l-2.287,1.308c-.153.11-.28.112-.365.061Zm2.188-3.421c.419-.248.678-.678.764-1.318s.011-1.596-.241-2.894c-.237-1.285-.508-2.144-.799-2.577-.29-.433-.645-.519-1.063-.271l-.767.441l1.339,7.06.767-.441Z" fill="#fff"/>
|
||||
<path d="M304.758,364.736c-.086-.064-.159-.209-.206-.434l-1.892-10.001c-.046-.226-.036-.412.017-.559.054-.148.151-.256.304-.352l3.556-2.025c.126-.069.225-.058.297.047.087.091.147.29.195.568l.095.503c.048.279.066.504.027.665-.025.16-.107.268-.233.337l-2.12,1.212.441,2.331l1.883-1.074c.112-.069.225-.058.297.047.073.092.147.289.195.568l.095.503c.048.278.066.504.027.664-.039.161-.107.282-.233.351l-1.883,1.074.49,2.61l2.134-1.213c.125-.068.224-.057.297.048.072.091.147.289.194.568l.095.503c.048.278.066.504.041.664s-.093.268-.219.337l-3.556,2.025c-.111.082-.238.098-.338.033Z" fill="#fff"/>
|
||||
<path d="M310.048,361.36l-1.923-10.16c-.047-.225-.036-.411.017-.558.054-.148.164-.27.331-.366l2.009-1.144c.739-.427,1.372-.519,1.913-.277.54.229.921.926,1.141,2.052.236,1.258.033,2.379-.624,3.376l.015.066c.198.023.398.152.6.374s.376.471.509.774l1.295,2.687.074.171c.062.292-.172.575-.66.864l-.419.235c-.418.247-.7.24-.804-.024l-1.225-2.702c-.116-.197-.232-.314-.345-.352-.114-.037-.268-.008-.464.103l-.292.165.693,3.643c.063.344-.143.654-.631.93l-.404.234c-.46.275-.729.254-.806-.091Zm1.403-7.447c.182-.097.305-.298.383-.606.079-.307.071-.679-.008-1.143-.08-.451-.212-.741-.37-.884s-.342-.152-.551-.042l-.642.359.505,2.689.683-.373Z" fill="#fff"/>
|
||||
<path d="M318.291,355.785c-.69-.638-1.224-1.957-1.603-3.971-.363-1.934-.366-3.529-.024-4.772.356-1.257,1.099-2.19,2.214-2.837.377-.22.741-.36,1.078-.42.267-.045.44.111.503.482.079.41.101.809.052,1.182-.049.387-.157.588-.34.605-.282.046-.548.131-.799.282-.474.275-.788.774-.901,1.494-.126.734-.079,1.69.156,2.896.236,1.205.52,2.037.868,2.495.348.459.787.543,1.302.24.154-.083.279-.165.376-.26s.222-.217.388-.367c.027-.027.055-.054.097-.081.167-.097.31-.033.441.19.131.224.237.554.316.991.031.159.034.319.009.452-.025.147-.093.281-.231.43-.125.136-.291.299-.513.476-.208.177-.445.328-.682.466-1.115.673-2.018.665-2.707.027Z" fill="#fff"/>
|
||||
<path d="M321.946,348.851c-.725-3.841-.042-6.368,2.064-7.567c1.032-.592,1.893-.556,2.611.068s1.251,1.93,1.629,3.917c.378,1.973.382,3.582.026,4.826s-1.043,2.148-2.075,2.74c-2.106,1.199-3.529-.129-4.255-3.984Zm4.494,1.134c.135-.322.197-.762.185-1.346-.012-.585-.111-1.341-.286-2.295-.173-.927-.357-1.642-.55-2.13s-.396-.776-.61-.892c-.214-.115-.467-.084-.76.082-.293.165-.5.409-.649.717-.134.322-.21.776-.198,1.361.011.584.097,1.341.285,2.281.174.941.357,1.642.564,2.129.193.489.397.79.624.892.214.116.482.084.761-.081.293-.153.499-.396.634-.718Z" fill="#fff"/>
|
||||
<path d="M330.301,349.802l-1.954-10.319c-.063-.345.128-.641.602-.916l.307-.179c.153-.096.293-.139.406-.128.113-.002.214.076.315.22l3.155,4.019c.16.223.378.564.641,1.024l.041-.054c-.165-.515-.286-.925-.334-1.216l-.977-5.14c-.063-.344.128-.641.602-.916l.293-.165c.461-.262.729-.228.793.117l1.954,10.319c.063.344-.143.641-.603.916l-.222.138c-.154.096-.294.138-.407.141-.113.002-.227-.076-.314-.22l-3.342-4.175c-.101-.118-.276-.407-.524-.841l-.055.081c.164.462.256.806.303,1.044l1.008,5.299c.063.344-.128.654-.602.916l-.293.165c-.461.262-.73.214-.793-.13Z" fill="#fff"/>
|
||||
<path d="M338.162,345.736c-.408.062-.733.015-.962-.153-.144-.131-.232-.288-.264-.474-.062-.304-.055-.637.008-1.024s.157-.615.311-.697c.069-.042.182-.044.338-.007.156.023.283.047.354.046.353.046.648-.013.885-.151.251-.138.459-.354.609-.61.15-.269.2-.589.121-.986-.062-.292-.151-.503-.281-.66-.13-.143-.287-.247-.443-.297-.17-.049-.397-.098-.694-.132-.693-.119-1.234-.348-1.608-.713s-.64-.971-.812-1.845c-.175-.967-.094-1.86.257-2.664.35-.818.916-1.441,1.683-1.869.28-.152.574-.264.897-.323.323-.06.591-.065.79.01.17.05.272.208.319.433.048.278.068.597.033.97-.035.359-.115.587-.254.67-.056.041-.183.056-.366.073-.352.021-.619.079-.828.203-.321.179-.528.396-.608.65-.079.255-.103.494-.056.733.079.397.211.66.411.776s.483.203.88.262l.311.047c.637.107,1.121.35,1.453.702.331.353.582.933.739,1.741.111.609.123,1.22.023,1.834-.101.627-.315,1.203-.643,1.741-.327.539-.784.973-1.37,1.304-.419.208-.811.349-1.233.41Z" fill="#fff"/>
|
||||
<path d="M343.816,342.1l-1.639-8.69-1.339.758c-.126.069-.225.058-.298-.047-.086-.091-.146-.29-.194-.568l-.095-.503c-.048-.279-.066-.504-.027-.665.039-.16.107-.281.233-.35l4.574-2.604c.126-.069.239-.058.311.034.087.091.147.289.209.567l.095.504c.048.278.066.504.027.664s-.107.281-.247.351l-1.353.771l1.64,8.69c.063.344-.128.641-.602.916l-.489.276c-.474.275-.728.24-.806-.104Z" fill="#fff"/>
|
||||
<path d="M348.156,339.621l-1.923-10.16c-.047-.226-.037-.412.017-.559.053-.148.164-.269.345-.366l2.008-1.144c.739-.427,1.386-.519,1.927-.277.541.228.921.912,1.142,2.064.236,1.259.033,2.38-.624,3.377l.015.066c.198.023.398.152.6.374s.376.484.509.787l1.295,2.687.074.171c.062.292-.172.576-.66.865l-.418.247c-.433.248-.701.24-.805-.024l-1.224-2.701c-.117-.197-.232-.315-.346-.352-.113-.038-.268-.008-.463.102l-.293.166.693,3.642c.063.345-.142.655-.63.93l-.405.234c-.488.249-.771.215-.834-.129Zm1.389-7.434c.182-.097.304-.299.383-.619.078-.308.085-.68-.009-1.13-.093-.451-.212-.754-.37-.884-.158-.143-.356-.152-.551-.042l-.642.358.519,2.689.67-.372Z" fill="#fff"/>
|
||||
<path d="M355.007,335.403c-.627-.307-1.05-1.003-1.255-2.089l-1.418-7.498c-.063-.344.142-.654.602-.916l.488-.276c.461-.262.729-.227.793.117l1.387,7.339c.079.437.24.74.484.921.229.169.511.163.818-.016.306-.179.527-.449.66-.838.133-.388.168-.787.074-1.224l-1.387-7.339c-.063-.344.142-.641.602-.916l.461-.262c.46-.262.729-.227.792.117l1.419,7.498c.205,1.086.111,2.072-.28,2.971-.391.885-1.054,1.603-1.947,2.113-.893.496-1.666.604-2.293.298Z" fill="#fff"/>
|
||||
<path d="M361.763,331c-.689-.638-1.223-1.957-1.602-3.971-.363-1.934-.366-3.529-.024-4.773.355-1.257,1.099-2.189,2.214-2.836.377-.22.74-.36,1.078-.42.267-.045.439.111.503.482.079.41.101.809.052,1.182-.049.387-.158.588-.341.605-.281.046-.547.131-.798.282-.474.275-.789.774-.901,1.494-.127.734-.08,1.69.156,2.895.236,1.206.52,2.038.868,2.496.347.459.786.543,1.302.24.154-.083.279-.165.376-.26s.221-.217.387-.367c.028-.027.056-.054.098-.081.167-.097.309-.033.441.19.131.224.236.554.316.991.031.159.034.319.009.452-.026.147-.094.281-.232.43-.124.136-.29.298-.512.476-.222.177-.445.328-.682.465-1.129.674-2.032.666-2.708.028Z" fill="#fff"/>
|
||||
<path d="M367.999,328.31l-1.654-8.69-1.339.758c-.126.069-.225.058-.298-.047-.086-.091-.146-.29-.194-.568l-.095-.503c-.048-.279-.066-.504-.027-.665.025-.16.107-.281.233-.35l4.574-2.604c.126-.069.239-.058.311.034.087.091.147.289.195.568l.095.503c.047.278.066.504.027.664-.025.16-.107.282-.247.351l-1.353.771l1.654,8.69c.063.344-.142.641-.602.916l-.503.276c-.446.275-.714.24-.777-.104Z" fill="#fff"/>
|
||||
<path d="M372.309,325.843l-1.954-10.319c-.064-.358.127-.668.602-.93l.502-.289c.46-.262.715-.213.793.144l1.954,10.319c.063.358-.128.667-.588.929l-.502.289c-.475.263-.729.214-.807-.143Z" fill="#fff"/>
|
||||
<path d="M374.315,318.982c-.725-3.842-.042-6.368,2.064-7.567c1.018-.579,1.893-.556,2.611.068.704.624,1.252,1.929,1.63,3.916.377,1.974.381,3.583.025,4.826-.356,1.244-1.043,2.149-2.075,2.741-2.106,1.199-3.515-.13-4.255-3.984Zm4.508,1.133c.135-.321.197-.761.185-1.346s-.111-1.341-.285-2.295c-.174-.927-.357-1.641-.551-2.13-.193-.488-.396-.776-.61-.892-.214-.115-.467-.083-.76.082s-.499.409-.648.718c-.135.321-.211.775-.199,1.36s.097,1.341.271,2.281c.174.941.357,1.642.564,2.13.193.488.397.79.625.892.228.115.481.083.76-.082.293-.152.5-.396.648-.718Z" fill="#fff"/>
|
||||
<path d="M382.672,319.933l-1.955-10.319c-.063-.344.143-.641.603-.916l.307-.179c.153-.096.293-.139.406-.128.113-.002.213.076.315.22l3.155,4.019c.159.223.378.565.641,1.025l.041-.054c-.166-.529-.286-.925-.335-1.217l-.976-5.139c-.064-.345.128-.641.602-.917l.293-.165c.46-.262.729-.227.792.117l1.955,10.319c.063.345-.143.655-.603.917l-.223.124c-.153.096-.294.138-.42.141-.113.002-.214-.076-.315-.22l-3.341-4.175c-.102-.118-.277-.407-.525-.854l-.055.081c.164.462.256.806.303,1.044l1.008,5.299c.063.344-.142.641-.602.916l-.293.166c-.446.288-.701.24-.778-.105Z" fill="#fff"/>
|
||||
</svg>
|
After Width: | Height: | Size: 78 KiB |
91
src/assets/index.scss
Normal file
@ -0,0 +1,91 @@
|
||||
@use 'core.scss';
|
||||
|
||||
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.box-sizing {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
font-size: 16px;
|
||||
font-family: -apple-system, "PingFang SC", 'Microsoft YaHei', sans-serif;
|
||||
background-color: var(--main-bg-color);
|
||||
min-width: 1000px;
|
||||
}
|
||||
|
||||
|
||||
.dashboard-layout {
|
||||
background-color: var(--main-bg-color);
|
||||
}
|
||||
|
||||
.navigation-container {
|
||||
//width: var(--navigation-width);
|
||||
background-color: #fff;
|
||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
|
||||
|
||||
.nav-item {
|
||||
padding: 0px 30px;
|
||||
&.active{
|
||||
@apply text-blue-500;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.app-header {
|
||||
@apply w-full navigation-container flex justify-between items-center p-basic fixed top-0 inset-x-0 z-10;
|
||||
height: var(--app-header-header);
|
||||
}
|
||||
.app-content{
|
||||
padding-top: var(--app-header-header);
|
||||
}
|
||||
|
||||
.logo-container {
|
||||
svg {
|
||||
max-height: 100%;
|
||||
display: block;
|
||||
width: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 90%;
|
||||
width: var(--container-width,1200px);
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.article-action-icon{
|
||||
@apply cursor-pointer text-gray-500 hover:text-blue-500 block;
|
||||
}
|
||||
|
||||
img{
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 2000px) {
|
||||
:root {
|
||||
line-height: 1.2;
|
||||
--app-header-header: 70px;
|
||||
}
|
||||
.logo-container {
|
||||
height: 36px;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1280px) {
|
||||
:root {
|
||||
--navigation-width: 200px;
|
||||
}
|
||||
.container {
|
||||
max-width: 98%;
|
||||
padding: 20px 0;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 800px) {
|
||||
}
|
7
src/assets/loading.svg
Normal file
@ -0,0 +1,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="margin: auto; display: block;" width="200px" height="200px" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid">
|
||||
<circle cx="50" cy="50" r="30" stroke="#6a6a6a" stroke-width="6" fill="none"></circle>
|
||||
<circle cx="50" cy="50" r="30" stroke="#aaaaaa" stroke-width="6" stroke-linecap="round" fill="none">
|
||||
<animateTransform attributeName="transform" type="rotate" repeatCount="indefinite" dur="1s" values="0 50 50;180 50 50;720 50 50" keyTimes="0;0.5;1"></animateTransform>
|
||||
<animate attributeName="stroke-dasharray" repeatCount="indefinite" dur="1s" values="18.84955592153876 169.64600329384882;94.2477796076938 94.24777960769377;18.84955592153876 169.64600329384882" keyTimes="0;0.5;1"></animate>
|
||||
</circle>
|
||||
</svg>
|
After Width: | Height: | Size: 828 B |
54
src/components/article/article.module.scss
Normal file
@ -0,0 +1,54 @@
|
||||
.blockContainer {
|
||||
@apply flex mb-5;
|
||||
}
|
||||
|
||||
.block {
|
||||
@apply border border-gray-300 border-dashed p-3 rounded flex-1;
|
||||
|
||||
&:last-child {
|
||||
@apply mb-0;
|
||||
}
|
||||
|
||||
.blockBody {
|
||||
@apply flex flex-col gap-3
|
||||
}
|
||||
}
|
||||
|
||||
.blockItem {
|
||||
|
||||
}
|
||||
|
||||
.group {
|
||||
}
|
||||
|
||||
.image {
|
||||
@apply border border-blue-200 p-2 flex-1 rounded focus:border-blue-200;
|
||||
min-height: 100px;
|
||||
:global{
|
||||
.ant-upload-wrapper{
|
||||
display: block;
|
||||
border: none;
|
||||
padding: 0;
|
||||
}
|
||||
.ant-upload{
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.uploadImage {
|
||||
@apply flex justify-center items-center cursor-pointer;
|
||||
img {
|
||||
display: block;
|
||||
max-width: 100%;
|
||||
max-height: 200px;
|
||||
}
|
||||
}
|
||||
|
||||
.text {
|
||||
@apply border border-blue-200 overflow-hidden flex-1 rounded focus:border-blue-200;
|
||||
}
|
||||
|
||||
.textarea {
|
||||
@apply border-0
|
||||
}
|
109
src/components/article/block.tsx
Normal file
@ -0,0 +1,109 @@
|
||||
import React from "react";
|
||||
import clsx from "clsx";
|
||||
|
||||
import {IconAdd, IconAddImage, IconAddText, IconDelete} from "@/components/icons";
|
||||
import {BlockImage, BlockText} from "./item.tsx";
|
||||
|
||||
import styles from './article.module.scss'
|
||||
import {Button, Popconfirm} from "antd";
|
||||
|
||||
type Props = {
|
||||
children?: React.ReactNode;
|
||||
className?: string;
|
||||
blocks: BlockContent[];
|
||||
editable?: boolean;
|
||||
onChange?: (blocks: BlockContent[]) => void;
|
||||
onRemove?: () => void;
|
||||
onAdd?: () => void;
|
||||
}
|
||||
|
||||
export default function ArticleBlock({className, blocks, editable, onRemove, onAdd, onChange}: Props) {
|
||||
const handleBlockRemove = (index: number) => {
|
||||
// 删除当前项
|
||||
onChange?.(blocks.filter((_, idx) => index !== idx))
|
||||
}
|
||||
// 新增
|
||||
const handleAddBlock = (type: 'text' | 'image', insertIndex: number = -1) => {
|
||||
const newBlock: BlockContent = type === 'text' ? {type: 'text', content: ''} : {type: 'image', content: ''};
|
||||
const _blocks = [...blocks]
|
||||
if (insertIndex == -1 || insertIndex >= blocks.length) { // -1或者越界表示新增
|
||||
_blocks.push(newBlock)
|
||||
} else {
|
||||
_blocks.splice(insertIndex, 0, newBlock)
|
||||
}
|
||||
onChange?.(_blocks)
|
||||
}
|
||||
|
||||
const handleBlockChange = (index: number, block: BlockContent) => {
|
||||
const _blocks = [...blocks]
|
||||
_blocks[index] = block
|
||||
onChange?.(_blocks)
|
||||
}
|
||||
|
||||
return <div className={styles.blockContainer}>
|
||||
<div className={clsx(className || '', styles.block,' hover:bg-blue-10')}>
|
||||
<div className={styles.blockBody}>
|
||||
{blocks.map((it, idx) => (
|
||||
<div key={idx} className={clsx(styles.blockItem, 'flex')}>
|
||||
{
|
||||
it.type === 'text'
|
||||
? <BlockText onChange={(block) => handleBlockChange(idx, block)} data={it}
|
||||
editable={editable}/>
|
||||
: <BlockImage data={it} editable={editable}/>
|
||||
}
|
||||
{editable && <div className="create-container ml-2 flex flex-col justify-between">
|
||||
<Popconfirm
|
||||
title="提示"
|
||||
description={<div style={{minWidth: 150}}>
|
||||
<span>请确认删除此{it.type === 'text' ? '文本' : '图片'}?</span>
|
||||
</div>}
|
||||
onConfirm={() => handleBlockRemove(idx)}
|
||||
okText="删除"
|
||||
cancelText="取消"
|
||||
>
|
||||
<span
|
||||
className="article-action-icon"
|
||||
title={`删除此${it.type === 'text' ? '文本' : '图片'}`}>
|
||||
<IconDelete style={{fontSize: 18}}/>
|
||||
</span>
|
||||
</Popconfirm>
|
||||
<div>
|
||||
<span onClick={() => handleAddBlock('text', idx + 1)}
|
||||
className="article-action-icon" title="新增文本"><IconAddText
|
||||
style={{fontSize: 18}}/></span>
|
||||
<span onClick={() => handleAddBlock('image', idx + 1)}
|
||||
className="article-action-icon mt-1" title="新增图片"><IconAddImage
|
||||
style={{fontSize: 16}}/></span>
|
||||
</div>
|
||||
</div>}
|
||||
</div>
|
||||
))}
|
||||
{editable && blocks.length == 0 &&
|
||||
<div style={{minHeight: 80}} className="flex items-center justify-center">
|
||||
<div className="flex gap-5">
|
||||
<Button onClick={() => handleAddBlock('text')}>添加文本</Button>
|
||||
<Button onClick={() => handleAddBlock('image')}>添加图片</Button>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
{editable && <div className="ml-2 flex flex-col justify-between ">
|
||||
<Popconfirm
|
||||
title="提示"
|
||||
description={<div style={{minWidth: 150}}>
|
||||
<span>请确认删除此删除此分组?</span>
|
||||
</div>}
|
||||
onConfirm={onRemove}
|
||||
okText="删除"
|
||||
cancelText="取消"
|
||||
>
|
||||
<span className="article-action-icon" title="删除此分组"><IconDelete
|
||||
style={{fontSize: 24}}/></span>
|
||||
</Popconfirm>
|
||||
<span onClick={onAdd} className="article-action-icon" title="新增分组"><IconAdd
|
||||
style={{fontSize: 24}}/></span>
|
||||
</div>}
|
||||
</div>
|
||||
}
|
50
src/components/article/group.tsx
Normal file
@ -0,0 +1,50 @@
|
||||
|
||||
import {message} from "antd"
|
||||
import ArticleBlock from "@/components/article/block.tsx";
|
||||
|
||||
import styles from './article.module.scss'
|
||||
|
||||
type Props = {
|
||||
groups: ArticleContentGroup[];
|
||||
editable?: boolean;
|
||||
onChange?: (groups: ArticleContentGroup[]) => void;
|
||||
}
|
||||
export default function ArticleGroup({groups, editable, onChange}: Props) {
|
||||
/**
|
||||
* 添加一个组
|
||||
* @param insertIndex 插入的位置,-1表示插入到末尾
|
||||
*/
|
||||
const handleAddGroup = ( insertIndex: number = -1) => {
|
||||
const newGroup: ArticleContentGroup = {blocks: []}
|
||||
const _groups = [...groups]
|
||||
if (insertIndex == -1 || insertIndex >= groups.length) { // -1或者越界表示新增
|
||||
_groups.push(newGroup)
|
||||
} else {
|
||||
_groups.splice(insertIndex, 0, newGroup)
|
||||
}
|
||||
onChange?.(_groups)
|
||||
}
|
||||
return <div className={styles.group}>
|
||||
{groups.map((g, index) => (
|
||||
<ArticleBlock
|
||||
editable={editable} key={index} blocks={g.blocks}
|
||||
onChange={(blocks) => {
|
||||
groups[index].blocks = blocks
|
||||
onChange?.([...groups])
|
||||
}}
|
||||
onAdd={() => {
|
||||
handleAddGroup?.(index + 1)
|
||||
}}
|
||||
onRemove={async () => {
|
||||
if (groups.length == 1) {
|
||||
message.warning('至少保留一个内容块')
|
||||
return;
|
||||
}
|
||||
onChange?.(groups.filter((_, idx) => index !== idx))
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
{groups.length == 0 && editable &&
|
||||
<ArticleBlock editable onChange={blocks => onChange?.([{blocks}])} blocks={[]}/>}
|
||||
</div>
|
||||
}
|
35
src/components/article/item.tsx
Normal file
@ -0,0 +1,35 @@
|
||||
import React from "react";
|
||||
import styles from './article.module.scss'
|
||||
import {Input, Upload} from "antd";
|
||||
|
||||
type Props = {
|
||||
children?: React.ReactNode;
|
||||
className?: string;
|
||||
data: BlockContent;
|
||||
editable?: boolean;
|
||||
onChange?: (data: BlockContent) => void;
|
||||
}
|
||||
|
||||
export function BlockImage({data,editable}: Props) {
|
||||
return <div className={styles.image}>
|
||||
{editable ? <div>
|
||||
<Upload accept="image/*">
|
||||
<div className={styles.uploadImage} >
|
||||
<img src={data.content}/>
|
||||
</div>
|
||||
</Upload>
|
||||
</div> : <div className={styles.uploadImage}><img src={data.content}/></div>}
|
||||
</div>
|
||||
}
|
||||
|
||||
export function BlockText({data,editable,onChange}: Props) {
|
||||
return <div className={styles.text}>
|
||||
{editable ? <div>
|
||||
{/*<textarea className={styles.textarea} defaultValue={data.content}/>*/}
|
||||
<Input.TextArea onChange={e => {
|
||||
onChange?.({type:'text',content:e.target.value})
|
||||
// console.log(e)
|
||||
}} placeholder={'请输入文本'} value={data.content} autoSize={{minRows:3}} variant={"borderless"} />
|
||||
</div>: <p className="p-2">{data.content}</p>}
|
||||
</div>
|
||||
}
|
18
src/components/card/card.scss
Normal file
@ -0,0 +1,18 @@
|
||||
.card-container {
|
||||
background-color: #ffffff;
|
||||
border-radius: 5px;
|
||||
padding: 20px;
|
||||
&.card-padding{
|
||||
}
|
||||
|
||||
.card-header {
|
||||
margin-bottom: 10px;
|
||||
color: #333;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
font-size: 20px;
|
||||
}
|
||||
.card-body{
|
||||
}
|
||||
}
|
23
src/components/card/index.tsx
Normal file
@ -0,0 +1,23 @@
|
||||
import React, {CSSProperties} from "react";
|
||||
|
||||
import './card.scss'
|
||||
import {clsx} from "clsx";
|
||||
|
||||
type CardProps = {
|
||||
title?: React.ReactNode;
|
||||
headerRight?: React.ReactNode;
|
||||
children?: React.ReactNode;
|
||||
bordered?: boolean;
|
||||
style?: CSSProperties;
|
||||
className?: string;
|
||||
}
|
||||
export const Card: React.FC<CardProps> = (props) => {
|
||||
|
||||
return (<div style={props.style} className={clsx(props.className,'card-container',{'card-padding':!(props.title || props.headerRight)})}>
|
||||
{(props.title || props.headerRight) && <div className={'card-header'}>
|
||||
<div className="card-title">{props.title}</div>
|
||||
<div className="card-right">{props.headerRight}</div>
|
||||
</div>}
|
||||
<div className="card-body">{props.children}</div>
|
||||
</div>)
|
||||
}
|
14
src/components/document.tsx
Normal file
@ -0,0 +1,14 @@
|
||||
import React, {useEffect} from "react";
|
||||
|
||||
type DocumentTitleProps = {
|
||||
children?: string;
|
||||
text?: string;
|
||||
}
|
||||
export const DocumentTitle: React.FC<DocumentTitleProps> = ({children, text}) => {
|
||||
useEffect(() => {
|
||||
if (text || children) {
|
||||
document.title = text || children || '';
|
||||
}
|
||||
}, []);
|
||||
return <></>
|
||||
}
|
15
src/components/form/input-container.tsx
Normal file
@ -0,0 +1,15 @@
|
||||
import React from "react";
|
||||
|
||||
interface Props {
|
||||
children: React.ReactNode
|
||||
className?: string;
|
||||
prefix?: React.ReactNode;
|
||||
suffix?: React.ReactNode;
|
||||
}
|
||||
|
||||
export default function InputContainer(props: Props) {
|
||||
return (<div
|
||||
className="border border-gray-300 rounded-3xl mt-2 flex items-center px-3 focus-within:border-blue-500 focus-within:shadow focus-within:shadow-blue-200">
|
||||
{props.prefix}{props.children}{props.suffix}
|
||||
</div>)
|
||||
}
|
64
src/components/form/sms-code.tsx
Normal file
@ -0,0 +1,64 @@
|
||||
import {LockOutlined} from "@ant-design/icons";
|
||||
import {Input} from "antd";
|
||||
import {useCountDown} from "ahooks";
|
||||
import {useState} from "react";
|
||||
|
||||
import InputContainer from "@/components/form/input-container.tsx";
|
||||
import {clsx} from "clsx";
|
||||
|
||||
type Props = {
|
||||
onChange?: (code: string) => void;
|
||||
phone?:string;
|
||||
}
|
||||
|
||||
export function useSmsCode() {
|
||||
const [targetDate, setTargetDate] = useState<number>();
|
||||
const [sending, setSending] = useState<boolean>();
|
||||
const [countdown] = useCountDown({
|
||||
targetDate,
|
||||
onEnd: () => {
|
||||
setTargetDate(undefined)
|
||||
},
|
||||
});
|
||||
const sendCode = (phone?:string,interval = 60) => {
|
||||
if (countdown > 0 || sending || !phone) return;
|
||||
setSending(true)
|
||||
setTimeout(() => {
|
||||
setTargetDate(Date.now() + interval * 1000)
|
||||
setSending(false)
|
||||
}, 500)
|
||||
}
|
||||
return {
|
||||
sendCode,
|
||||
countdown,
|
||||
sending,
|
||||
}
|
||||
}
|
||||
|
||||
export default function SmsCode(props:Props) {
|
||||
|
||||
const [targetDate, setTargetDate] = useState<number>();
|
||||
const [sending, setSending] = useState<boolean>();
|
||||
const [countdown] = useCountDown({
|
||||
targetDate,
|
||||
onEnd: () => {
|
||||
setTargetDate(undefined)
|
||||
},
|
||||
});
|
||||
const handleSendCode = () => {
|
||||
if (countdown > 0 || sending || !props.phone) return;
|
||||
setSending(true)
|
||||
setTimeout(() => {
|
||||
setTargetDate(Date.now() + 10 * 1000)
|
||||
setSending(false)
|
||||
}, 500)
|
||||
}
|
||||
return (<InputContainer
|
||||
prefix={<LockOutlined/>}
|
||||
suffix={<span className={clsx(`text-nowrap text-sm ${countdown > 0 || sending || !props.phone ? 'text-gray-400 cursor-not-allowed':'text-blue-500 cursor-pointer'}`)} onClick={handleSendCode}>
|
||||
{sending ? '发送中...' : (countdown > 0 ? `${Math.ceil(countdown/1000)} s` : '获取验证码')}
|
||||
</span>}>
|
||||
<Input style={{borderRadius: 20}} size={'large'} variant={'borderless'}
|
||||
placeholder="请输入验证码" />
|
||||
</InputContainer>)
|
||||
}
|
494
src/components/icons/index.tsx
Normal file
@ -0,0 +1,494 @@
|
||||
import React from "react";
|
||||
|
||||
type IconProps = { style?: React.CSSProperties }
|
||||
export const IconRise = ({style}: IconProps) => {
|
||||
return (
|
||||
<svg className="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||||
width="1em" height="1em" style={style}>
|
||||
<path
|
||||
d="M928 361.6v182.4c0 19.2 12.8 32 32 32s32-12.8 32-32v-224c0-35.2-28.8-64-64-64h-224c-19.2 0-32 12.8-32 32s12.8 32 32 32h176l-272 272-204.8-204.8c-6.4-6.4-16-9.6-22.4-9.6-9.6 0-16 3.2-22.4 9.6l-316.8 316.8c-12.8 12.8-12.8 32 0 44.8 12.8 12.8 32 12.8 44.8 0l294.4-294.4 204.8 204.8c6.4 6.4 16 9.6 22.4 9.6 9.6 0 16-3.2 22.4-9.6l297.6-297.6z"
|
||||
fill="currentColor"></path>
|
||||
</svg>
|
||||
)
|
||||
|
||||
}
|
||||
export const IconDown = ({style}: IconProps) => {
|
||||
return (
|
||||
<svg className="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||||
width="1em" height="1em" style={style}>
|
||||
<path
|
||||
d="M886.4 736h-182.4c-19.2 0-32 12.8-32 32s12.8 32 32 32h224c35.2 0 64-28.8 64-64v-224c0-19.2-12.8-32-32-32s-32 12.8-32 32v172.8l-297.6-297.6c-6.4-6.4-16-9.6-22.4-9.6-9.6 0-16 3.2-22.4 9.6l-204.8 204.8-294.4-294.4c-12.8-12.8-32-12.8-44.8 0-12.8 12.8-12.8 32 0 44.8l316.8 316.8c6.4 6.4 16 9.6 22.4 9.6 9.6 0 16-3.2 22.4-9.6l204.8-204.8 278.4 281.6z"
|
||||
fill="currentColor"></path>
|
||||
</svg>
|
||||
)
|
||||
|
||||
}
|
||||
export const IconChecked = ({style}: IconProps) => {
|
||||
return (
|
||||
<svg className="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||||
width="1em" height="1em" style={style}>
|
||||
<path
|
||||
d="M369.792 704.32L930.304 128 1024 223.616 369.984 896l-20.288-20.864-0.128 0.128L0 516.8 96.128 423.68l273.664 280.64z"
|
||||
fill="currentColor" p-id="4399"></path>
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
export const IconCheckedFill = ({style}: IconProps) => {
|
||||
return (
|
||||
<svg className="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||||
width="1em" height="1em" style={style}>
|
||||
<path
|
||||
d="M512.45568 57.344c251.35104 0 455.11168 203.76064 455.11168 455.11168 0 251.35104-203.76064 455.11168-455.11168 455.11168C261.10464 967.56736 57.344 763.80672 57.344 512.45568 57.344 261.10464 261.10464 57.344 512.45568 57.344z m272.444416 288.876544c-5.842944-5.445632-16.21504-5.953536-22.995968-1.074176l-0.315392 0.232448-301.232128 228.097024c-5.515264 4.176896-15.601664 4.72064-21.655552 1.186816l-0.320512-0.193536-113.998848-71.015424c-7.031808-4.380672-16.93696-2.89792-22.390784 3.219456l-0.24576 0.2816-13.169664 15.497216c-5.553152 6.53312-4.62848 15.625216 1.519616 21.586944l0.27136 0.258048 140.93312 131.342336c10.247168 9.550848 26.529792 10.051584 36.615168 0.9728l0.313344-0.28672 323.310592-301.310976c6.679552-6.223872 7.225344-15.606784 1.036288-21.63712l-0.254976-0.241664-7.419904-6.915072z"
|
||||
fill="currentColor"></path>
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
export const IconLoading = ({size, color}: { size?: string | number, color?: string; }) => (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" style={{
|
||||
margin: 'auto', display: 'block', ...(size ? {fontSize: size} : {}), ...(color ? {color} : {})
|
||||
}} width="1em" height="1em" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid">
|
||||
<circle cx="50" cy="50" r="30" stroke="#6a6a6a" strokeWidth="15" fill="none"></circle>
|
||||
<circle cx="50" cy="50" r="30" stroke="#aaaaaa" strokeWidth="15" strokeLinecap="round" fill="none">
|
||||
<animateTransform attributeName="transform" type="rotate" repeatCount="indefinite" dur="1s"
|
||||
values="0 50 50;180 50 50;720 50 50" keyTimes="0;0.5;1"></animateTransform>
|
||||
<animate attributeName="stroke-dasharray" repeatCount="indefinite" dur="1s"
|
||||
values="18.84955592153876 169.64600329384882;94.2477796076938 94.24777960769377;18.84955592153876 169.64600329384882"
|
||||
keyTimes="0;0.5;1"></animate>
|
||||
</circle>
|
||||
</svg>)
|
||||
|
||||
export const IconQRCode = ({style}: { style?: React.CSSProperties }) => (
|
||||
<svg className={'svg-icon'} style={style} xmlns="http://www.w3.org/2000/svg" fill="none" version="1.1"
|
||||
width="1em" height="1em" viewBox="0 0 15 15">
|
||||
<path
|
||||
d="M40.022 29.257C39.8411 28.9562 38.2126 26.9064 37.1812 25.2328C36.8193 24.6499 36.6565 23.9541 36.6927 23.2771C36.8555 19.4785 35.6613 15.0406 33.7614 11.9942C33.11 10.9599 32.0425 9.5872 30.4864 8.28967C32.7662 4.22783 33.7071 1.16264 32.6758 0.260012C32.6396 0.241207 32.6215 0.222402 32.5853 0.184792C32.5672 0.184792 32.5672 0.165988 32.5491 0.165988C31.4815 -0.492181 28.9665 0.842961 25.7819 3.53205C23.3211 5.63819 20.4622 8.55293 17.5852 11.9566C16.7348 12.878 8.82758 22.0924 8.89996 23.8224C8.97233 25.6653 12.5369 23.4463 11.8131 24.0105C11.1979 24.4806 8.99043 25.6841 8.14 24.8191C7.28957 23.9353 8.41141 21.5659 10.4742 18.6135C13.134 14.8149 14.5634 13.2353 16.0653 11.4865C15.2872 11.2984 14.473 11.2044 13.6225 11.2044C10.7456 11.2044 8.1219 12.3327 6.13154 14.1756C8.70092 10.8847 12.5188 8.77859 16.8976 8.77859C17.4042 8.77859 17.8928 8.79739 18.3632 8.85381C19.7746 7.29301 21.204 5.84504 22.5611 4.56631C21.4573 4.35946 20.2631 4.22783 18.9965 4.22783C17.3319 4.22783 15.7577 4.41587 14.292 4.77317C11.0532 5.65699 7.00006 8.47771 4.684 12.107C1.66226 16.9023 1.35466 22.1864 3.07361 27.0193H3.09171C3.32693 27.6586 3.61644 28.2792 3.94214 28.8621C0.667082 34.2027 -0.816645 38.3586 0.449951 39.468C1.71655 40.5963 5.48015 38.3209 10.0399 34.0146C13.8578 30.3853 19.1051 23.9353 19.2137 21.6787C19.3222 19.4221 14.7806 22.0172 15.6672 21.359C16.4272 20.7949 18.9242 19.3845 19.9193 20.4752C20.9145 21.5659 19.4127 24.6687 17.8023 27.1509C16.3005 29.5015 14.2378 32.0025 11.9217 34.466C12.4826 34.56 13.0616 34.5976 13.6406 34.5976C19.8651 34.5976 24.9133 29.3511 24.9133 22.8822C24.9133 18.3878 22.4887 14.4953 18.9242 12.5207C20.4079 10.7719 21.4212 9.68122 21.4212 9.66242L21.5478 9.53078C26.759 11.4489 30.215 16.545 30.215 22.807C30.215 22.8258 31.4273 33.0744 21.9097 39.6373C20.0822 40.8972 19.5755 42.4204 19.847 44C24.0629 43.5675 26.6323 43.9436 31.0654 43.9624C34.25 43.9624 35.1004 43.0974 35.607 41.9503C36.1318 40.8032 35.3899 39.468 35.3899 39.1672C35.3899 38.8663 35.6613 38.697 36.2584 38.0389C36.8555 37.3807 36.9098 36.6285 36.7108 36.4029C36.5298 36.1772 36.1318 35.8387 36.3127 35.8011C37.3803 35.6883 37.706 35.237 37.4888 34.8797C37.2717 34.5224 36.566 33.5445 37.1631 32.8487C37.7602 32.153 39.2259 32.1718 40.0039 31.7017C40.9086 31.1751 40.5106 30.0656 40.022 29.257ZM2.15081 37.6252C1.98796 37.6252 1.8613 37.5876 1.77083 37.5123C1.33657 37.1362 1.44513 35.0865 4.57543 29.8776C5.60681 31.3444 6.98197 32.5479 8.53807 33.3753C5.64299 36.0268 3.27265 37.6252 2.15081 37.6252ZM15.3053 22.6377L14.871 22.7318C14.2558 22.8634 13.7854 23.3523 13.6587 23.9917L13.5683 24.443C13.5321 24.5934 13.333 24.5934 13.2969 24.443L13.2064 23.9917C13.0797 23.3523 12.6093 22.8634 11.9941 22.7318L11.5598 22.6377C11.4151 22.6001 11.4151 22.3933 11.5598 22.3557L11.9941 22.2616C12.6093 22.13 13.0797 21.6411 13.2064 21.0017L13.2969 20.5504C13.333 20.4 13.5321 20.4 13.5683 20.5504L13.6587 21.0017C13.7854 21.6411 14.2558 22.13 14.871 22.2616L15.3053 22.3557C15.4501 22.3933 15.4501 22.6001 15.3053 22.6377ZM29.6902 7.6315C28.5684 6.80409 27.2656 6.03309 25.7276 5.45014C29.2198 2.32854 30.6492 1.97125 31.1197 1.97125C31.2644 1.97125 31.373 2.00886 31.4454 2.06527C31.8434 2.42256 31.6263 4.09619 29.6902 7.6315Z"
|
||||
fill="#F5222D"/>
|
||||
|
||||
</svg>
|
||||
)
|
||||
|
||||
export const IconQuery = ({style}: { style?: React.CSSProperties }) => (
|
||||
<svg className={'svg-icon'} style={style} xmlns="http://www.w3.org/2000/svg" fill="none" version="1.1"
|
||||
width="1em" height="1em" viewBox="0 0 15 15">
|
||||
<defs>
|
||||
<clipPath id="master_svg0_1_3654/1_0572">
|
||||
<rect x="0" y="0" width="15" height="15" rx="0"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
<g clipPath="url(#master_svg0_1_3654/1_0572)">
|
||||
<g>
|
||||
<path
|
||||
d="M8.4375,8.20313Q8.4375,8.2607,8.43186,8.31799Q8.426210000000001,8.37528,8.41498,8.431750000000001Q8.40375,8.48821,8.387039999999999,8.5433Q8.37033,8.59839,8.3483,8.65158Q8.32626,8.70477,8.29913,8.75554Q8.27199,8.80632,8.24,8.85418Q8.20802,8.90205,8.1715,8.94655Q8.13497,8.991060000000001,8.09427,9.03177Q8.053560000000001,9.07247,8.00905,9.109Q7.96455,9.14552,7.9166799999999995,9.1775Q7.8688199999999995,9.20949,7.81804,9.23663Q7.76727,9.26376,7.71408,9.2858Q7.66089,9.30783,7.6058,9.324539999999999Q7.5507100000000005,9.34125,7.49425,9.35248Q7.43778,9.363710000000001,7.38049,9.36936Q7.3232,9.375,7.26563,9.375Q7.20805,9.375,7.15076,9.36936Q7.093468,9.363710000000001,7.037003,9.35248Q6.980539,9.34125,6.925448,9.324539999999999Q6.870356,9.30783,6.817168,9.2858Q6.76398,9.26376,6.713207,9.23663Q6.662434,9.20949,6.614566,9.1775Q6.566698,9.14552,6.522195,9.109Q6.477693,9.07247,6.436984,9.03177Q6.396276,8.991060000000001,6.3597529999999995,8.94655Q6.323231,8.90205,6.291247,8.85418Q6.259262,8.80632,6.232123,8.75554Q6.204985,8.70477,6.1829537,8.65158Q6.1609224,8.59839,6.1442105,8.5433Q6.1274987,8.48821,6.1162672,8.431750000000001Q6.1050358,8.37528,6.0993929,8.31799Q6.09375,8.2607,6.09375,8.20313Q6.09375,8.14555,6.0993929,8.08826Q6.1050358,8.030968,6.1162672,7.974503Q6.1274987,7.918039,6.1442105,7.862948Q6.1609224,7.807856,6.1829537,7.754668Q6.204985,7.70148,6.232123,7.650707Q6.259262,7.599934,6.291247,7.552066Q6.323231,7.504198,6.3597529999999995,7.459695Q6.396276,7.415193,6.436984,7.374484Q6.477693,7.333776,6.522195,7.2972529999999995Q6.566698,7.260731,6.614566,7.228747Q6.662434,7.196762,6.713207,7.169623Q6.76398,7.142485,6.817168,7.1204537Q6.870356,7.0984224,6.925448,7.0817105Q6.980539,7.0649987,7.037003,7.0537672Q7.093468,7.0425358,7.15076,7.0368929Q7.20805,7.03125,7.26563,7.03125Q7.3232,7.03125,7.38049,7.0368929Q7.43778,7.0425358,7.49425,7.0537672Q7.5507100000000005,7.0649987,7.6058,7.0817105Q7.66089,7.0984224,7.71408,7.1204537Q7.76727,7.142485,7.81804,7.169623Q7.8688199999999995,7.196762,7.9166799999999995,7.228747Q7.96455,7.260731,8.00905,7.2972529999999995Q8.053560000000001,7.333776,8.09427,7.374484Q8.13497,7.415193,8.1715,7.459695Q8.20802,7.504198,8.24,7.552066Q8.27199,7.599934,8.29913,7.650707Q8.32626,7.70148,8.3483,7.754668Q8.37033,7.807856,8.387039999999999,7.862948Q8.40375,7.918039,8.41498,7.974503Q8.426210000000001,8.030968,8.43186,8.08826Q8.4375,8.14555,8.4375,8.20313Z"
|
||||
fill="currentColor"/>
|
||||
</g>
|
||||
<g>
|
||||
<path
|
||||
d="M3.28125,0.9375C2.5046049999999997,0.9375,1.875,1.567105,1.875,2.34375L1.875,12.6563C1.875,13.4329,2.5046049999999997,14.0625,3.28125,14.0625L11.71875,14.0625C12.4954,14.0625,13.125,13.4329,13.125,12.6563L13.125,5.15622L10.3125,5.15622C9.53585,5.15622,8.90625,4.526619999999999,8.90625,3.74997L8.90625,0.9375L3.28125,0.9375ZM9.375,8.20312C9.375,8.61589,9.25644,9.00097,9.05152,9.32616L10.32722,10.60187L9.66431,11.2648L8.38859,9.98906C8.06342,10.19396,7.67836,10.3125,7.26562,10.3125C6.10065,10.3125,5.15625,9.3681,5.15625,8.20312C5.15625,7.03815,6.10065,6.09375,7.26562,6.09375C8.4306,6.09375,9.375,7.03815,9.375,8.20312Z"
|
||||
fill="currentColor"/>
|
||||
</g>
|
||||
<g>
|
||||
<path
|
||||
d="M12.84958,3.55950103515625C13.02483,3.73431103515625,13.1238,3.97131103515625,13.12499,4.21872103515625L10.3125,4.21872103515625C10.053619,4.21872103515625,9.84375,4.008851035156249,9.84375,3.74997103515625L9.84375,0.93756103515625C10.088203,0.94027833515625,10.322109,1.03840803515625,10.495386,1.21125403515625L12.84958,3.55950103515625Z"
|
||||
fill="currentColor"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
)
|
||||
export const IconAiChat = ({style}: { style?: React.CSSProperties }) => (
|
||||
<svg className={'svg-icon icon-ai-chat'} style={style} xmlns="http://www.w3.org/2000/svg" fill="none" version="1.1"
|
||||
width="1em" height="1em" viewBox="0 0 32 32">
|
||||
<path fillRule="evenodd" clipRule="evenodd"
|
||||
d="M16 32C24.8366 32 32 24.8366 32 16C32 7.16344 24.8366 0 16 0C7.16344 0 0 7.16344 0 16C0 18.9091 0.776402 21.637 2.1333 23.9875V29.8666H8.01239C10.363 31.2236 13.0908 32 16 32Z"
|
||||
fill="#F5222D"/>
|
||||
<path fillRule="evenodd" clipRule="evenodd"
|
||||
d="M16 32C24.8366 32 32 24.8366 32 16C32 7.16344 24.8366 0 16 0C7.16344 0 0 7.16344 0 16C0 18.9091 0.776402 21.637 2.1333 23.9875V29.8666H8.01239C10.363 31.2236 13.0908 32 16 32Z"
|
||||
fill="url(#paint0_linear_145_39)"/>
|
||||
<circle cx="8" cy="16" r="2" fill="white"/>
|
||||
<circle cx="16" cy="16" r="2" fill="white"/>
|
||||
<circle cx="24" cy="16" r="2" fill="white"/>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_145_39" x1="28" y1="2.5332e-07" x2="2" y2="32"
|
||||
gradientUnits="userSpaceOnUse">
|
||||
<stop stopColor="#FFCB7E"/>
|
||||
<stop offset="1" stopColor="#F5222D"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
)
|
||||
|
||||
export const IconAiIndex = ({style}: { style?: React.CSSProperties }) => (
|
||||
<svg className={'svg-icon icon-ai-chat'} style={style} xmlns="http://www.w3.org/2000/svg" fill="none" version="1.1"
|
||||
width="1em" height="1em" viewBox="0 0 27 27">
|
||||
<path
|
||||
d="M22.8219 10.5025L16.5786 4.25927C16.4139 4.09457 16.1986 4.01349 15.9832 4.01349C15.7678 4.01349 15.5525 4.09457 15.3878 4.25927L11.3058 8.34373C10.9967 8.30825 10.6851 8.29305 10.3734 8.29305C8.51867 8.29305 6.66394 8.90369 5.14114 10.125C4.75094 10.4366 4.72053 11.0219 5.07273 11.3767L9.67661 15.9805L4.21884 21.4333C4.15196 21.4997 4.11069 21.5877 4.10229 21.6816L4.01614 22.6241C3.99334 22.8623 4.18337 23.065 4.41901 23.065C4.43168 23.065 4.44435 23.065 4.45702 23.0625L5.39959 22.9763C5.49334 22.9687 5.58202 22.9256 5.6479 22.8598L11.1057 17.402L15.7096 22.0059C15.8742 22.1706 16.0896 22.2517 16.305 22.2517C16.5508 22.2517 16.794 22.1452 16.9612 21.9375C18.3878 20.1562 18.9807 17.9265 18.74 15.7702L22.8219 11.6883C23.1487 11.364 23.1487 10.8319 22.8219 10.5025Z"
|
||||
fill="#F5222D"/>
|
||||
<path
|
||||
d="M22.8219 10.5025L16.5786 4.25927C16.4139 4.09457 16.1986 4.01349 15.9832 4.01349C15.7678 4.01349 15.5525 4.09457 15.3878 4.25927L11.3058 8.34373C10.9967 8.30825 10.6851 8.29305 10.3734 8.29305C8.51867 8.29305 6.66394 8.90369 5.14114 10.125C4.75094 10.4366 4.72053 11.0219 5.07273 11.3767L9.67661 15.9805L4.21884 21.4333C4.15196 21.4997 4.11069 21.5877 4.10229 21.6816L4.01614 22.6241C3.99334 22.8623 4.18337 23.065 4.41901 23.065C4.43168 23.065 4.44435 23.065 4.45702 23.0625L5.39959 22.9763C5.49334 22.9687 5.58202 22.9256 5.6479 22.8598L11.1057 17.402L15.7096 22.0059C15.8742 22.1706 16.0896 22.2517 16.305 22.2517C16.5508 22.2517 16.794 22.1452 16.9612 21.9375C18.3878 20.1562 18.9807 17.9265 18.74 15.7702L22.8219 11.6883C23.1487 11.364 23.1487 10.8319 22.8219 10.5025Z"
|
||||
fill="url(#paint0_linear_541_309)"/>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_541_309" x1="20.6854" y1="4.01349" x2="5.20628" y2="23.066"
|
||||
gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FFCB7E"/>
|
||||
<stop offset="1" stop-color="#F5222D"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
)
|
||||
|
||||
export const IconFileSearch = ({style}: { style?: React.CSSProperties }) => (
|
||||
<svg className={'svg-icon icon-file-search'} style={style} xmlns="http://www.w3.org/2000/svg" fill="none"
|
||||
version="1.1"
|
||||
width="1em" height="1em" viewBox="0 0 32 32">
|
||||
<path
|
||||
d="M26.7062 9.02188C26.8937 9.20938 27 9.4625 27 9.72812V29C27 29.5531 26.5531 30 26 30H6C5.44687 30 5 29.5531 5 29V3C5 2.44687 5.44687 2 6 2H19.2719C19.5375 2 19.7938 2.10625 19.9813 2.29375L26.7062 9.02188ZM24.6938 10.1875L18.8125 4.30625V10.1875H24.6938ZM10 15.0625C9.9337 15.0625 9.87011 15.0888 9.82322 15.1357C9.77634 15.1826 9.75 15.2462 9.75 15.3125V16.8125C9.75 16.8788 9.77634 16.9424 9.82322 16.9893C9.87011 17.0362 9.9337 17.0625 10 17.0625H22C22.0663 17.0625 22.1299 17.0362 22.1768 16.9893C22.2237 16.9424 22.25 16.8788 22.25 16.8125V15.3125C22.25 15.2462 22.2237 15.1826 22.1768 15.1357C22.1299 15.0888 22.0663 15.0625 22 15.0625H10ZM10 19.3125C9.9337 19.3125 9.87011 19.3388 9.82322 19.3857C9.77634 19.4326 9.75 19.4962 9.75 19.5625V21.0625C9.75 21.1288 9.77634 21.1924 9.82322 21.2393C9.87011 21.2862 9.9337 21.3125 10 21.3125H15.75C15.8163 21.3125 15.8799 21.2862 15.9268 21.2393C15.9737 21.1924 16 21.1288 16 21.0625V19.5625C16 19.4962 15.9737 19.4326 15.9268 19.3857C15.8799 19.3388 15.8163 19.3125 15.75 19.3125H10Z"
|
||||
fill="#F5222D"/>
|
||||
<path
|
||||
d="M26.7062 9.02188C26.8937 9.20938 27 9.4625 27 9.72812V29C27 29.5531 26.5531 30 26 30H6C5.44687 30 5 29.5531 5 29V3C5 2.44687 5.44687 2 6 2H19.2719C19.5375 2 19.7938 2.10625 19.9813 2.29375L26.7062 9.02188ZM24.6938 10.1875L18.8125 4.30625V10.1875H24.6938ZM10 15.0625C9.9337 15.0625 9.87011 15.0888 9.82322 15.1357C9.77634 15.1826 9.75 15.2462 9.75 15.3125V16.8125C9.75 16.8788 9.77634 16.9424 9.82322 16.9893C9.87011 17.0362 9.9337 17.0625 10 17.0625H22C22.0663 17.0625 22.1299 17.0362 22.1768 16.9893C22.2237 16.9424 22.25 16.8788 22.25 16.8125V15.3125C22.25 15.2462 22.2237 15.1826 22.1768 15.1357C22.1299 15.0888 22.0663 15.0625 22 15.0625H10ZM10 19.3125C9.9337 19.3125 9.87011 19.3388 9.82322 19.3857C9.77634 19.4326 9.75 19.4962 9.75 19.5625V21.0625C9.75 21.1288 9.77634 21.1924 9.82322 21.2393C9.87011 21.2862 9.9337 21.3125 10 21.3125H15.75C15.8163 21.3125 15.8799 21.2862 15.9268 21.2393C15.9737 21.1924 16 21.1288 16 21.0625V19.5625C16 19.4962 15.9737 19.4326 15.9268 19.3857C15.8799 19.3388 15.8163 19.3125 15.75 19.3125H10Z"
|
||||
fill="url(#paint0_linear_253_170)"/>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_253_170" x1="24.25" y1="2" x2="1.02087" y2="24.4633"
|
||||
gradientUnits="userSpaceOnUse">
|
||||
<stop stopColor="#FFCB7E"/>
|
||||
<stop offset="1" stopColor="#F5222D"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
|
||||
</svg>
|
||||
)
|
||||
|
||||
export const IconProfile = ({style}: { style?: React.CSSProperties }) => (
|
||||
<svg className={'svg-icon icon-profile'} style={style} xmlns="http://www.w3.org/2000/svg" fill="none" version="1.1"
|
||||
width="1em" height="1em" viewBox="0 0 32 32">
|
||||
<path
|
||||
d="M27.5 3.5H4.5C3.94687 3.5 3.5 3.94687 3.5 4.5V27.5C3.5 28.0531 3.94687 28.5 4.5 28.5H27.5C28.0531 28.5 28.5 28.0531 28.5 27.5V4.5C28.5 3.94687 28.0531 3.5 27.5 3.5ZM11.875 21.75C11.1844 21.75 10.625 21.1906 10.625 20.5C10.625 19.8094 11.1844 19.25 11.875 19.25C12.5656 19.25 13.125 19.8094 13.125 20.5C13.125 21.1906 12.5656 21.75 11.875 21.75ZM11.875 17.25C11.1844 17.25 10.625 16.6906 10.625 16C10.625 15.3094 11.1844 14.75 11.875 14.75C12.5656 14.75 13.125 15.3094 13.125 16C13.125 16.6906 12.5656 17.25 11.875 17.25ZM11.875 12.75C11.1844 12.75 10.625 12.1906 10.625 11.5C10.625 10.8094 11.1844 10.25 11.875 10.25C12.5656 10.25 13.125 10.8094 13.125 11.5C13.125 12.1906 12.5656 12.75 11.875 12.75ZM21.375 21.25C21.375 21.3875 21.2625 21.5 21.125 21.5H15.375C15.2375 21.5 15.125 21.3875 15.125 21.25V19.75C15.125 19.6125 15.2375 19.5 15.375 19.5H21.125C21.2625 19.5 21.375 19.6125 21.375 19.75V21.25ZM21.375 16.75C21.375 16.8875 21.2625 17 21.125 17H15.375C15.2375 17 15.125 16.8875 15.125 16.75V15.25C15.125 15.1125 15.2375 15 15.375 15H21.125C21.2625 15 21.375 15.1125 21.375 15.25V16.75ZM21.375 12.25C21.375 12.3875 21.2625 12.5 21.125 12.5H15.375C15.2375 12.5 15.125 12.3875 15.125 12.25V10.75C15.125 10.6125 15.2375 10.5 15.375 10.5H21.125C21.2625 10.5 21.375 10.6125 21.375 10.75V12.25Z"
|
||||
fill="#F5222D"/>
|
||||
<path
|
||||
d="M27.5 3.5H4.5C3.94687 3.5 3.5 3.94687 3.5 4.5V27.5C3.5 28.0531 3.94687 28.5 4.5 28.5H27.5C28.0531 28.5 28.5 28.0531 28.5 27.5V4.5C28.5 3.94687 28.0531 3.5 27.5 3.5ZM11.875 21.75C11.1844 21.75 10.625 21.1906 10.625 20.5C10.625 19.8094 11.1844 19.25 11.875 19.25C12.5656 19.25 13.125 19.8094 13.125 20.5C13.125 21.1906 12.5656 21.75 11.875 21.75ZM11.875 17.25C11.1844 17.25 10.625 16.6906 10.625 16C10.625 15.3094 11.1844 14.75 11.875 14.75C12.5656 14.75 13.125 15.3094 13.125 16C13.125 16.6906 12.5656 17.25 11.875 17.25ZM11.875 12.75C11.1844 12.75 10.625 12.1906 10.625 11.5C10.625 10.8094 11.1844 10.25 11.875 10.25C12.5656 10.25 13.125 10.8094 13.125 11.5C13.125 12.1906 12.5656 12.75 11.875 12.75ZM21.375 21.25C21.375 21.3875 21.2625 21.5 21.125 21.5H15.375C15.2375 21.5 15.125 21.3875 15.125 21.25V19.75C15.125 19.6125 15.2375 19.5 15.375 19.5H21.125C21.2625 19.5 21.375 19.6125 21.375 19.75V21.25ZM21.375 16.75C21.375 16.8875 21.2625 17 21.125 17H15.375C15.2375 17 15.125 16.8875 15.125 16.75V15.25C15.125 15.1125 15.2375 15 15.375 15H21.125C21.2625 15 21.375 15.1125 21.375 15.25V16.75ZM21.375 12.25C21.375 12.3875 21.2625 12.5 21.125 12.5H15.375C15.2375 12.5 15.125 12.3875 15.125 12.25V10.75C15.125 10.6125 15.2375 10.5 15.375 10.5H21.125C21.2625 10.5 21.375 10.6125 21.375 10.75V12.25Z"
|
||||
fill="url(#paint0_linear_253_60)"/>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_253_60" x1="25.375" y1="3.5" x2="5.0625" y2="28.5"
|
||||
gradientUnits="userSpaceOnUse">
|
||||
<stop stopColor="#FFCB7E"/>
|
||||
<stop offset="1" stopColor="#F5222D"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
)
|
||||
export const IconInteraction = ({style}: { style?: React.CSSProperties }) => (
|
||||
<svg className={'svg-icon icon-interaction'} style={style} xmlns="http://www.w3.org/2000/svg" fill="none"
|
||||
version="1.1" width="1em" height="1em" viewBox="0 0 32 32">
|
||||
<path
|
||||
d="M27.5 3.5H4.5C3.94687 3.5 3.5 3.94687 3.5 4.5V27.5C3.5 28.0531 3.94687 28.5 4.5 28.5H27.5C28.0531 28.5 28.5 28.0531 28.5 27.5V4.5C28.5 3.94687 28.0531 3.5 27.5 3.5ZM22.6875 18.3031C22.6875 20.0312 21.2906 21.4312 19.5719 21.4312H13.1438V23.1C13.1438 23.2781 12.9406 23.375 12.8031 23.2656L9.39375 20.5875C9.28438 20.5031 9.28438 20.3375 9.39375 20.2531L12.8031 17.575C12.9406 17.4656 13.1438 17.5656 13.1438 17.7406V19.4094H19.5719C20.1844 19.4094 20.6812 18.9094 20.6812 18.2969V15.8313C20.6812 15.7156 20.775 15.6187 20.8937 15.6187H22.4781C22.5938 15.6187 22.6906 15.7125 22.6906 15.8313V18.3031H22.6875ZM22.6063 11.7437L19.1969 14.4219C19.0594 14.5312 18.8563 14.4313 18.8563 14.2563V12.5875H12.4281C11.8156 12.5875 11.3188 13.0875 11.3188 13.7V16.1656C11.3188 16.2812 11.225 16.3781 11.1062 16.3781H9.52188C9.40625 16.3781 9.30937 16.2844 9.30937 16.1656V13.7C9.30937 11.9719 10.7063 10.5719 12.425 10.5719H18.8531V8.90312C18.8531 8.725 19.0563 8.62813 19.1938 8.7375L22.6031 11.4156C22.7156 11.4937 22.7156 11.6594 22.6063 11.7437Z"
|
||||
fill="#F5222D"/>
|
||||
<path
|
||||
d="M27.5 3.5H4.5C3.94687 3.5 3.5 3.94687 3.5 4.5V27.5C3.5 28.0531 3.94687 28.5 4.5 28.5H27.5C28.0531 28.5 28.5 28.0531 28.5 27.5V4.5C28.5 3.94687 28.0531 3.5 27.5 3.5ZM22.6875 18.3031C22.6875 20.0312 21.2906 21.4312 19.5719 21.4312H13.1438V23.1C13.1438 23.2781 12.9406 23.375 12.8031 23.2656L9.39375 20.5875C9.28438 20.5031 9.28438 20.3375 9.39375 20.2531L12.8031 17.575C12.9406 17.4656 13.1438 17.5656 13.1438 17.7406V19.4094H19.5719C20.1844 19.4094 20.6812 18.9094 20.6812 18.2969V15.8313C20.6812 15.7156 20.775 15.6187 20.8937 15.6187H22.4781C22.5938 15.6187 22.6906 15.7125 22.6906 15.8313V18.3031H22.6875ZM22.6063 11.7437L19.1969 14.4219C19.0594 14.5312 18.8563 14.4313 18.8563 14.2563V12.5875H12.4281C11.8156 12.5875 11.3188 13.0875 11.3188 13.7V16.1656C11.3188 16.2812 11.225 16.3781 11.1062 16.3781H9.52188C9.40625 16.3781 9.30937 16.2844 9.30937 16.1656V13.7C9.30937 11.9719 10.7063 10.5719 12.425 10.5719H18.8531V8.90312C18.8531 8.725 19.0563 8.62813 19.1938 8.7375L22.6031 11.4156C22.7156 11.4937 22.7156 11.6594 22.6063 11.7437Z"
|
||||
fill="url(#paint0_linear_253_68)"/>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_253_68" x1="25.375" y1="3.5" x2="5.0625" y2="28.5"
|
||||
gradientUnits="userSpaceOnUse">
|
||||
<stop stopColor="#FFCB7E"/>
|
||||
<stop offset="1" stopColor="#F5222D"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
)
|
||||
|
||||
export const IconFire = ({style}: { style?: React.CSSProperties }) => (
|
||||
<svg className={'svg-icon icon-interaction'} style={style} xmlns="http://www.w3.org/2000/svg" fill="none"
|
||||
version="1.1" width="1em" height="1em" viewBox="0 0 29 29">
|
||||
<path
|
||||
d="M23.3009 13.2035C22.768 12.0041 21.9933 10.9276 21.0253 10.0413L20.2266 9.30843C20.1994 9.28423 20.1668 9.26706 20.1315 9.25842C20.0962 9.24978 20.0593 9.24993 20.0241 9.25888C19.9888 9.26782 19.9563 9.28528 19.9294 9.30971C19.9025 9.33414 19.882 9.36481 19.8697 9.39902L19.5129 10.4229C19.2905 11.0652 18.8816 11.7212 18.3024 12.3663C18.2639 12.4075 18.22 12.4184 18.1898 12.4212C18.1596 12.4239 18.113 12.4184 18.0718 12.38C18.0334 12.3471 18.0142 12.2977 18.0169 12.2483C18.1185 10.5958 17.6244 8.732 16.5429 6.70349C15.648 5.0181 14.4046 3.70328 12.8509 2.78647L11.7173 2.11946C11.5691 2.03162 11.3797 2.14691 11.3879 2.31984L11.4483 3.6374C11.4894 4.53774 11.3851 5.33377 11.1381 5.9953C10.8362 6.80506 10.4025 7.55717 9.84798 8.23242C9.4621 8.7017 9.02475 9.12617 8.54414 9.49784C7.38661 10.3876 6.4454 11.5278 5.79097 12.8329C5.13815 14.1494 4.7981 15.5989 4.7973 17.0684C4.7973 18.364 5.05258 19.6184 5.55765 20.8015C6.04533 21.9405 6.74911 22.9743 7.63007 23.8456C8.51943 24.724 9.55153 25.4157 10.7017 25.8961C11.893 26.3956 13.1556 26.6482 14.4595 26.6482C15.7633 26.6482 17.026 26.3956 18.2173 25.8988C19.3646 25.4213 20.4079 24.7248 21.2889 23.8483C22.1782 22.97 22.8754 21.9434 23.3613 20.8042C23.8656 19.6244 24.1243 18.3542 24.1216 17.0711C24.1216 15.7316 23.8471 14.4305 23.3009 13.2035Z"
|
||||
fill="#F5222D"/>
|
||||
<path
|
||||
d="M23.3009 13.2035C22.768 12.0041 21.9933 10.9276 21.0253 10.0413L20.2266 9.30843C20.1994 9.28423 20.1668 9.26706 20.1315 9.25842C20.0962 9.24978 20.0593 9.24993 20.0241 9.25888C19.9888 9.26782 19.9563 9.28528 19.9294 9.30971C19.9025 9.33414 19.882 9.36481 19.8697 9.39902L19.5129 10.4229C19.2905 11.0652 18.8816 11.7212 18.3024 12.3663C18.2639 12.4075 18.22 12.4184 18.1898 12.4212C18.1596 12.4239 18.113 12.4184 18.0718 12.38C18.0334 12.3471 18.0142 12.2977 18.0169 12.2483C18.1185 10.5958 17.6244 8.732 16.5429 6.70349C15.648 5.0181 14.4046 3.70328 12.8509 2.78647L11.7173 2.11946C11.5691 2.03162 11.3797 2.14691 11.3879 2.31984L11.4483 3.6374C11.4894 4.53774 11.3851 5.33377 11.1381 5.9953C10.8362 6.80506 10.4025 7.55717 9.84798 8.23242C9.4621 8.7017 9.02475 9.12617 8.54414 9.49784C7.38661 10.3876 6.4454 11.5278 5.79097 12.8329C5.13815 14.1494 4.7981 15.5989 4.7973 17.0684C4.7973 18.364 5.05258 19.6184 5.55765 20.8015C6.04533 21.9405 6.74911 22.9743 7.63007 23.8456C8.51943 24.724 9.55153 25.4157 10.7017 25.8961C11.893 26.3956 13.1556 26.6482 14.4595 26.6482C15.7633 26.6482 17.026 26.3956 18.2173 25.8988C19.3646 25.4213 20.4079 24.7248 21.2889 23.8483C22.1782 22.97 22.8754 21.9434 23.3613 20.8042C23.8656 19.6244 24.1243 18.3542 24.1216 17.0711C24.1216 15.7316 23.8471 14.4305 23.3009 13.2035Z"
|
||||
fill="url(#paint0_linear_541_295)"/>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_541_295" x1="21.7061" y1="2.08929" x2="1.3308" y2="21.8216"
|
||||
gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FFCB7E"/>
|
||||
<stop offset="1" stop-color="#F5222D"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
)
|
||||
|
||||
export const IconAISearch = ({style}: { style?: React.CSSProperties }) => (
|
||||
<svg className={'svg-icon icon-ai-search'} style={style} xmlns="http://www.w3.org/2000/svg" fill="none"
|
||||
version="1.1" width="1em" height="1em" viewBox="0 0 32 32">
|
||||
<path
|
||||
d="M27.0906 5.30937L16.4719 1.69062C16.3437 1.64687 16.1719 1.625 16 1.625C15.8281 1.625 15.6562 1.64687 15.5281 1.69062L4.90938 5.30937C4.65 5.39687 4.4375 5.69688 4.4375 5.97187V21.0469C4.4375 21.3219 4.61563 21.6844 4.83125 21.8562L15.6031 30.25C15.7125 30.3344 15.8531 30.3781 15.9969 30.3781C16.1406 30.3781 16.2844 30.3344 16.3906 30.25L27.1625 21.8562C27.3781 21.6875 27.5562 21.325 27.5562 21.0469V5.97187C27.5625 5.69688 27.35 5.4 27.0906 5.30937ZM19.5875 17.3125C18.0719 18.8281 15.7438 19.0375 14.0063 17.9406L11.5844 20.3625C11.5374 20.409 11.4739 20.4351 11.4078 20.4351C11.3417 20.4351 11.2782 20.409 11.2312 20.3625L10.1687 19.3C10.1222 19.253 10.0961 19.1896 10.0961 19.1234C10.0961 19.0573 10.1222 18.9939 10.1687 18.9469L12.5906 16.525C11.4937 14.7844 11.7031 12.4594 13.2188 10.9437C14.9781 9.18437 17.8281 9.18437 19.5875 10.9437C21.3469 12.7031 21.3469 15.5531 19.5875 17.3125ZM14.6331 15.8978C14.8649 16.1332 15.141 16.3205 15.4455 16.4487C15.7499 16.5769 16.0768 16.6436 16.4072 16.6448C16.7375 16.6461 17.0649 16.582 17.3704 16.4562C17.6758 16.3303 17.9534 16.1453 18.187 15.9116C18.4205 15.678 18.6056 15.4005 18.7314 15.095C18.8572 14.7895 18.9213 14.4621 18.92 14.1318C18.9187 13.8014 18.852 13.4746 18.7237 13.1701C18.5955 12.8656 18.4083 12.5896 18.1728 12.3578C17.941 12.1224 17.665 11.9352 17.3605 11.807C17.056 11.6787 16.7291 11.6121 16.3988 11.6108C16.0684 11.6095 15.7411 11.6736 15.4356 11.7995C15.1301 11.9253 14.8526 12.1104 14.619 12.344C14.3854 12.5776 14.2003 12.8552 14.0745 13.1606C13.9487 13.4661 13.8846 13.7935 13.8859 14.1238C13.8873 14.4542 13.954 14.7811 14.0822 15.0855C14.2104 15.39 14.3977 15.6661 14.6331 15.8978Z"
|
||||
fill="#F5222D"/>
|
||||
<path
|
||||
d="M27.0906 5.30937L16.4719 1.69062C16.3437 1.64687 16.1719 1.625 16 1.625C15.8281 1.625 15.6562 1.64687 15.5281 1.69062L4.90938 5.30937C4.65 5.39687 4.4375 5.69688 4.4375 5.97187V21.0469C4.4375 21.3219 4.61563 21.6844 4.83125 21.8562L15.6031 30.25C15.7125 30.3344 15.8531 30.3781 15.9969 30.3781C16.1406 30.3781 16.2844 30.3344 16.3906 30.25L27.1625 21.8562C27.3781 21.6875 27.5562 21.325 27.5562 21.0469V5.97187C27.5625 5.69688 27.35 5.4 27.0906 5.30937ZM19.5875 17.3125C18.0719 18.8281 15.7438 19.0375 14.0063 17.9406L11.5844 20.3625C11.5374 20.409 11.4739 20.4351 11.4078 20.4351C11.3417 20.4351 11.2782 20.409 11.2312 20.3625L10.1687 19.3C10.1222 19.253 10.0961 19.1896 10.0961 19.1234C10.0961 19.0573 10.1222 18.9939 10.1687 18.9469L12.5906 16.525C11.4937 14.7844 11.7031 12.4594 13.2188 10.9437C14.9781 9.18437 17.8281 9.18437 19.5875 10.9437C21.3469 12.7031 21.3469 15.5531 19.5875 17.3125ZM14.6331 15.8978C14.8649 16.1332 15.141 16.3205 15.4455 16.4487C15.7499 16.5769 16.0768 16.6436 16.4072 16.6448C16.7375 16.6461 17.0649 16.582 17.3704 16.4562C17.6758 16.3303 17.9534 16.1453 18.187 15.9116C18.4205 15.678 18.6056 15.4005 18.7314 15.095C18.8572 14.7895 18.9213 14.4621 18.92 14.1318C18.9187 13.8014 18.852 13.4746 18.7237 13.1701C18.5955 12.8656 18.4083 12.5896 18.1728 12.3578C17.941 12.1224 17.665 11.9352 17.3605 11.807C17.056 11.6787 16.7291 11.6121 16.3988 11.6108C16.0684 11.6095 15.7411 11.6736 15.4356 11.7995C15.1301 11.9253 14.8526 12.1104 14.619 12.344C14.3854 12.5776 14.2003 12.8552 14.0745 13.1606C13.9487 13.4661 13.8846 13.7935 13.8859 14.1238C13.8873 14.4542 13.954 14.7811 14.0822 15.0855C14.2104 15.39 14.3977 15.6661 14.6331 15.8978Z"
|
||||
fill="url(#paint0_linear_253_116)"/>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_253_116" x1="24.6665" y1="1.625" x2="0.80049" y2="25.2428"
|
||||
gradientUnits="userSpaceOnUse">
|
||||
<stop stopColor="#FFCB7E"/>
|
||||
<stop offset="1" stopColor="#F5222D"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
)
|
||||
|
||||
export const IconAIQuestion = ({style}: { style?: React.CSSProperties }) => (
|
||||
<svg className={'svg-icon icon-ai-question'} style={style} xmlns="http://www.w3.org/2000/svg" fill="none"
|
||||
version="1.1" width="1em" height="1em" viewBox="0 0 32 32">
|
||||
<path
|
||||
d="M26.7062 9.02188C26.8937 9.20938 27 9.4625 27 9.72812V29C27 29.5531 26.5531 30 26 30H6C5.44687 30 5 29.5531 5 29V3C5 2.44687 5.44687 2 6 2H19.2719C19.5375 2 19.7938 2.10625 19.9813 2.29375L26.7062 9.02188ZM24.6938 10.1875L18.8125 4.30625V10.1875H24.6938ZM12.5625 17.1562C12.5625 17.325 12.7 17.4531 12.8687 17.4531H13.8813C14.05 17.4531 14.1875 17.3219 14.1875 17.1594C14.1875 16.2781 14.9937 15.5469 16 15.5469C17.0063 15.5469 17.8125 16.2781 17.8125 17.1562C17.8125 17.9469 17.1562 18.6313 16.2719 18.7469C15.6688 18.8344 15.1938 19.3813 15.1875 20V21C15.1875 21.1719 15.3281 21.3125 15.5 21.3125H16.5C16.6719 21.3125 16.8125 21.1719 16.8125 21V20.6187C16.8125 20.4312 16.9375 20.2594 17.1156 20.2031C18.5094 19.7531 19.4594 18.5156 19.4375 17.1125C19.4125 15.3781 17.9 13.9625 16.0469 13.9375C14.1281 13.9156 12.5625 15.3625 12.5625 17.1562ZM16 24.25C16.2652 24.25 16.5196 24.1446 16.7071 23.9571C16.8946 23.7696 17 23.5152 17 23.25C17 22.9848 16.8946 22.7304 16.7071 22.5429C16.5196 22.3554 16.2652 22.25 16 22.25C15.7348 22.25 15.4804 22.3554 15.2929 22.5429C15.1054 22.7304 15 22.9848 15 23.25C15 23.5152 15.1054 23.7696 15.2929 23.9571C15.4804 24.1446 15.7348 24.25 16 24.25Z"
|
||||
fill="#F5222D"/>
|
||||
<path
|
||||
d="M26.7062 9.02188C26.8937 9.20938 27 9.4625 27 9.72812V29C27 29.5531 26.5531 30 26 30H6C5.44687 30 5 29.5531 5 29V3C5 2.44687 5.44687 2 6 2H19.2719C19.5375 2 19.7938 2.10625 19.9813 2.29375L26.7062 9.02188ZM24.6938 10.1875L18.8125 4.30625V10.1875H24.6938ZM12.5625 17.1562C12.5625 17.325 12.7 17.4531 12.8687 17.4531H13.8813C14.05 17.4531 14.1875 17.3219 14.1875 17.1594C14.1875 16.2781 14.9937 15.5469 16 15.5469C17.0063 15.5469 17.8125 16.2781 17.8125 17.1562C17.8125 17.9469 17.1562 18.6313 16.2719 18.7469C15.6688 18.8344 15.1938 19.3813 15.1875 20V21C15.1875 21.1719 15.3281 21.3125 15.5 21.3125H16.5C16.6719 21.3125 16.8125 21.1719 16.8125 21V20.6187C16.8125 20.4312 16.9375 20.2594 17.1156 20.2031C18.5094 19.7531 19.4594 18.5156 19.4375 17.1125C19.4125 15.3781 17.9 13.9625 16.0469 13.9375C14.1281 13.9156 12.5625 15.3625 12.5625 17.1562ZM16 24.25C16.2652 24.25 16.5196 24.1446 16.7071 23.9571C16.8946 23.7696 17 23.5152 17 23.25C17 22.9848 16.8946 22.7304 16.7071 22.5429C16.5196 22.3554 16.2652 22.25 16 22.25C15.7348 22.25 15.4804 22.3554 15.2929 22.5429C15.1054 22.7304 15 22.9848 15 23.25C15 23.5152 15.1054 23.7696 15.2929 23.9571C15.4804 24.1446 15.7348 24.25 16 24.25Z"
|
||||
fill="url(#paint0_linear_253_172)"/>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_253_172" x1="24.25" y1="2" x2="1.02087" y2="24.4633"
|
||||
gradientUnits="userSpaceOnUse">
|
||||
<stop stopColor="#FFCB7E"/>
|
||||
<stop offset="1" stopColor="#F5222D"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
)
|
||||
|
||||
export const IconSummary = ({style}: { style?: React.CSSProperties }) => (
|
||||
<svg className={'svg-icon icon-summary'} style={style} xmlns="http://www.w3.org/2000/svg" fill="none"
|
||||
version="1.1" width="1em" height="1em" viewBox="0 0 32 32">
|
||||
<path
|
||||
d="M29 7H24V5.25C24 5.1125 23.8875 5 23.75 5H22C21.8625 5 21.75 5.1125 21.75 5.25V7H17.125V5.25C17.125 5.1125 17.0125 5 16.875 5H15.125C14.9875 5 14.875 5.1125 14.875 5.25V7H10.25V5.25C10.25 5.1125 10.1375 5 10 5H8.25C8.1125 5 8 5.1125 8 5.25V7H3C2.44687 7 2 7.44688 2 8V26C2 26.5531 2.44687 27 3 27H29C29.5531 27 30 26.5531 30 26V8C30 7.44688 29.5531 7 29 7ZM13.25 21.5C13.25 21.6375 13.1375 21.75 13 21.75H7.25C7.1125 21.75 7 21.6375 7 21.5V20C7 19.8625 7.1125 19.75 7.25 19.75H13C13.1375 19.75 13.25 19.8625 13.25 20V21.5ZM13.25 17.25C13.25 17.3875 13.1375 17.5 13 17.5H7.25C7.1125 17.5 7 17.3875 7 17.25V15.75C7 15.6125 7.1125 15.5 7.25 15.5H13C13.1375 15.5 13.25 15.6125 13.25 15.75V17.25ZM24.9531 14.3969L19.7969 21.5438C19.7508 21.6076 19.6903 21.6597 19.6202 21.6956C19.5501 21.7314 19.4725 21.7502 19.3937 21.7502C19.315 21.7502 19.2374 21.7314 19.1673 21.6956C19.0972 21.6597 19.0367 21.6076 18.9906 21.5438L15.4219 16.6C15.3031 16.4344 15.4219 16.2031 15.625 16.2031H17.3406C17.5 16.2031 17.65 16.2812 17.7437 16.4094L19.3937 18.6938L22.6344 14.2031C22.7281 14.0719 22.8781 13.9969 23.0375 13.9969H24.75C24.9531 14 25.0719 14.2313 24.9531 14.3969Z"
|
||||
fill="#F5222D"/>
|
||||
<path
|
||||
d="M29 7H24V5.25C24 5.1125 23.8875 5 23.75 5H22C21.8625 5 21.75 5.1125 21.75 5.25V7H17.125V5.25C17.125 5.1125 17.0125 5 16.875 5H15.125C14.9875 5 14.875 5.1125 14.875 5.25V7H10.25V5.25C10.25 5.1125 10.1375 5 10 5H8.25C8.1125 5 8 5.1125 8 5.25V7H3C2.44687 7 2 7.44688 2 8V26C2 26.5531 2.44687 27 3 27H29C29.5531 27 30 26.5531 30 26V8C30 7.44688 29.5531 7 29 7ZM13.25 21.5C13.25 21.6375 13.1375 21.75 13 21.75H7.25C7.1125 21.75 7 21.6375 7 21.5V20C7 19.8625 7.1125 19.75 7.25 19.75H13C13.1375 19.75 13.25 19.8625 13.25 20V21.5ZM13.25 17.25C13.25 17.3875 13.1375 17.5 13 17.5H7.25C7.1125 17.5 7 17.3875 7 17.25V15.75C7 15.6125 7.1125 15.5 7.25 15.5H13C13.1375 15.5 13.25 15.6125 13.25 15.75V17.25ZM24.9531 14.3969L19.7969 21.5438C19.7508 21.6076 19.6903 21.6597 19.6202 21.6956C19.5501 21.7314 19.4725 21.7502 19.3937 21.7502C19.315 21.7502 19.2374 21.7314 19.1673 21.6956C19.0972 21.6597 19.0367 21.6076 18.9906 21.5438L15.4219 16.6C15.3031 16.4344 15.4219 16.2031 15.625 16.2031H17.3406C17.5 16.2031 17.65 16.2812 17.7437 16.4094L19.3937 18.6938L22.6344 14.2031C22.7281 14.0719 22.8781 13.9969 23.0375 13.9969H24.75C24.9531 14 25.0719 14.2313 24.9531 14.3969Z"
|
||||
fill="url(#paint0_linear_253_64)"/>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_253_64" x1="26.5" y1="5" x2="9.93478" y2="30.9483"
|
||||
gradientUnits="userSpaceOnUse">
|
||||
<stop stopColor="#FFCB7E"/>
|
||||
<stop offset="1" stopColor="#F5222D"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
)
|
||||
|
||||
export const IconAIPPT = ({style}: { style?: React.CSSProperties }) => (
|
||||
<svg className={'svg-icon icon-ai-ppt'} style={style} xmlns="http://www.w3.org/2000/svg" fill="none"
|
||||
version="1.1" width="1em" height="1em" viewBox="0 0 32 32">
|
||||
<path
|
||||
d="M26.7062 9.02188C26.8937 9.20938 27 9.4625 27 9.72812V29C27 29.5531 26.5531 30 26 30H6C5.44687 30 5 29.5531 5 29V3C5 2.44687 5.44687 2 6 2H19.2719C19.5375 2 19.7938 2.10625 19.9813 2.29375L26.7062 9.02188ZM24.6938 10.1875L18.8125 4.30625V10.1875H24.6938ZM14.6416 23.75V20.8894H16.4937C18.3866 20.8894 19.625 19.6503 19.625 17.8231C19.625 16.0038 18.3881 14.75 16.5006 14.75H13.25C13.1505 14.75 13.0552 14.7895 12.9848 14.8598C12.9145 14.9302 12.875 15.0255 12.875 15.125V23.75C12.875 23.8495 12.9145 23.9448 12.9848 24.0152C13.0552 24.0855 13.1505 24.125 13.25 24.125H14.2666C14.366 24.125 14.4614 24.0855 14.5317 24.0152C14.6021 23.9448 14.6416 23.8495 14.6416 23.75ZM14.6416 19.3959H15.7322C17.2266 19.3959 17.8319 18.9919 17.8319 17.8231C17.8319 16.8216 17.2656 16.2569 16.2734 16.2569H14.6416V19.3959Z"
|
||||
fill="#F5222D"/>
|
||||
<path
|
||||
d="M26.7062 9.02188C26.8937 9.20938 27 9.4625 27 9.72812V29C27 29.5531 26.5531 30 26 30H6C5.44687 30 5 29.5531 5 29V3C5 2.44687 5.44687 2 6 2H19.2719C19.5375 2 19.7938 2.10625 19.9813 2.29375L26.7062 9.02188ZM24.6938 10.1875L18.8125 4.30625V10.1875H24.6938ZM14.6416 23.75V20.8894H16.4937C18.3866 20.8894 19.625 19.6503 19.625 17.8231C19.625 16.0038 18.3881 14.75 16.5006 14.75H13.25C13.1505 14.75 13.0552 14.7895 12.9848 14.8598C12.9145 14.9302 12.875 15.0255 12.875 15.125V23.75C12.875 23.8495 12.9145 23.9448 12.9848 24.0152C13.0552 24.0855 13.1505 24.125 13.25 24.125H14.2666C14.366 24.125 14.4614 24.0855 14.5317 24.0152C14.6021 23.9448 14.6416 23.8495 14.6416 23.75ZM14.6416 19.3959H15.7322C17.2266 19.3959 17.8319 18.9919 17.8319 17.8231C17.8319 16.8216 17.2656 16.2569 16.2734 16.2569H14.6416V19.3959Z"
|
||||
fill="url(#paint0_linear_253_52)"/>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_253_52" x1="24.25" y1="2" x2="1.02087" y2="24.4633"
|
||||
gradientUnits="userSpaceOnUse">
|
||||
<stop stopColor="#FFCB7E"/>
|
||||
<stop offset="1" stopColor="#F5222D"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
)
|
||||
export const IconArticleReview = ({style}: { style?: React.CSSProperties }) => (
|
||||
<svg className={'svg-icon icon-article-review'} style={style} xmlns="http://www.w3.org/2000/svg" fill="none"
|
||||
version="1.1" width="1em" height="1em" viewBox="0 0 32 32">
|
||||
<path fillRule="evenodd" clipRule="evenodd"
|
||||
d="M27 9.72813C27 9.4625 26.8937 9.20938 26.7062 9.02188L19.9813 2.29375C19.7938 2.10625 19.5375 2 19.2719 2H6C5.44688 2 5 2.44688 5 3V29C5 29.5531 5.44688 30 6 30H26C26.5531 30 27 29.5531 27 29V9.72813ZM18.8125 4.30625L24.6938 10.1875H18.8125V4.30625ZM8.04545 13.1843C8.09233 13.1375 8.15592 13.1111 8.22222 13.1111H20.2222C20.2885 13.1111 20.3521 13.1375 20.399 13.1843C20.4459 13.2312 20.4722 13.2948 20.4722 13.3611V14.8611C20.4722 14.9274 20.4459 14.991 20.399 15.0379C20.3521 15.0848 20.2885 15.1111 20.2222 15.1111H8.22222C8.15592 15.1111 8.09233 15.0848 8.04545 15.0379C7.99856 14.991 7.97222 14.9274 7.97222 14.8611V13.3611C7.97222 13.2948 7.99856 13.2312 8.04545 13.1843ZM8.04545 18.4968C8.09233 18.45 8.15592 18.4236 8.22222 18.4236H13.9722C14.0385 18.4236 14.1021 18.45 14.149 18.4968C14.1959 18.5437 14.2222 18.6073 14.2222 18.6736V20.1736C14.2222 20.2399 14.1959 20.3035 14.149 20.3504C14.1021 20.3973 14.0385 20.4236 13.9722 20.4236H8.22222C8.15592 20.4236 8.09233 20.3973 8.04545 20.3504C7.99856 20.3035 7.97222 20.2399 7.97222 20.1736V18.6736C7.97222 18.6073 7.99856 18.5437 8.04545 18.4968ZM24.8524 19.6923L19.7174 26.5129C19.6813 26.5605 19.6341 26.5993 19.5795 26.6261C19.525 26.6528 19.4646 26.6667 19.4035 26.6667C19.3423 26.6667 19.2819 26.6528 19.2274 26.6261C19.1728 26.5993 19.1256 26.5605 19.0895 26.5129L16.0365 22.4583C15.9448 22.3348 16.0365 22.1623 16.1935 22.1623H17.5268C17.65 22.1623 17.7683 22.2206 17.8408 22.3161L19.4035 24.39L23.0481 19.5478C23.1206 19.4522 23.2365 19.394 23.3621 19.394H24.6954C24.8524 19.3963 24.9441 19.5688 24.8524 19.6923Z"
|
||||
fill="#F5222D"/>
|
||||
<path fillRule="evenodd" clipRule="evenodd"
|
||||
d="M27 9.72813C27 9.4625 26.8937 9.20938 26.7062 9.02188L19.9813 2.29375C19.7938 2.10625 19.5375 2 19.2719 2H6C5.44688 2 5 2.44688 5 3V29C5 29.5531 5.44688 30 6 30H26C26.5531 30 27 29.5531 27 29V9.72813ZM18.8125 4.30625L24.6938 10.1875H18.8125V4.30625ZM8.04545 13.1843C8.09233 13.1375 8.15592 13.1111 8.22222 13.1111H20.2222C20.2885 13.1111 20.3521 13.1375 20.399 13.1843C20.4459 13.2312 20.4722 13.2948 20.4722 13.3611V14.8611C20.4722 14.9274 20.4459 14.991 20.399 15.0379C20.3521 15.0848 20.2885 15.1111 20.2222 15.1111H8.22222C8.15592 15.1111 8.09233 15.0848 8.04545 15.0379C7.99856 14.991 7.97222 14.9274 7.97222 14.8611V13.3611C7.97222 13.2948 7.99856 13.2312 8.04545 13.1843ZM8.04545 18.4968C8.09233 18.45 8.15592 18.4236 8.22222 18.4236H13.9722C14.0385 18.4236 14.1021 18.45 14.149 18.4968C14.1959 18.5437 14.2222 18.6073 14.2222 18.6736V20.1736C14.2222 20.2399 14.1959 20.3035 14.149 20.3504C14.1021 20.3973 14.0385 20.4236 13.9722 20.4236H8.22222C8.15592 20.4236 8.09233 20.3973 8.04545 20.3504C7.99856 20.3035 7.97222 20.2399 7.97222 20.1736V18.6736C7.97222 18.6073 7.99856 18.5437 8.04545 18.4968ZM24.8524 19.6923L19.7174 26.5129C19.6813 26.5605 19.6341 26.5993 19.5795 26.6261C19.525 26.6528 19.4646 26.6667 19.4035 26.6667C19.3423 26.6667 19.2819 26.6528 19.2274 26.6261C19.1728 26.5993 19.1256 26.5605 19.0895 26.5129L16.0365 22.4583C15.9448 22.3348 16.0365 22.1623 16.1935 22.1623H17.5268C17.65 22.1623 17.7683 22.2206 17.8408 22.3161L19.4035 24.39L23.0481 19.5478C23.1206 19.4522 23.2365 19.394 23.3621 19.394H24.6954C24.8524 19.3963 24.9441 19.5688 24.8524 19.6923Z"
|
||||
fill="url(#paint0_linear_253_91)"/>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_253_91" x1="24.25" y1="2" x2="1.02087" y2="24.4633"
|
||||
gradientUnits="userSpaceOnUse">
|
||||
<stop stopColor="#FFCB7E"/>
|
||||
<stop offset="1" stopColor="#F5222D"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
)
|
||||
export const IconDataManagement = ({style,className}: { style?: React.CSSProperties;className?:string; }) => (
|
||||
<svg className={`svg-icon ${className||''} icon-data-management`} style={style} xmlns="http://www.w3.org/2000/svg" fill="none"
|
||||
version="1.1" width="1em" height="1em" viewBox="0 0 32 32">
|
||||
<path
|
||||
d="M26 2H6C5.44687 2 5 2.44687 5 3V10H27V3C27 2.44687 26.5531 2 26 2ZM9 7.25C8.30938 7.25 7.75 6.69063 7.75 6C7.75 5.30938 8.30938 4.75 9 4.75C9.69063 4.75 10.25 5.30938 10.25 6C10.25 6.69063 9.69063 7.25 9 7.25ZM5 29C5 29.5531 5.44687 30 6 30H26C26.5531 30 27 29.5531 27 29V22H5V29ZM9 24.75C9.69063 24.75 10.25 25.3094 10.25 26C10.25 26.6906 9.69063 27.25 9 27.25C8.30938 27.25 7.75 26.6906 7.75 26C7.75 25.3094 8.30938 24.75 9 24.75ZM5 20H27V12H5V20ZM9 14.75C9.69063 14.75 10.25 15.3094 10.25 16C10.25 16.6906 9.69063 17.25 9 17.25C8.30938 17.25 7.75 16.6906 7.75 16C7.75 15.3094 8.30938 14.75 9 14.75Z"
|
||||
fill="#F5222D"/>
|
||||
<path
|
||||
d="M26 2H6C5.44687 2 5 2.44687 5 3V10H27V3C27 2.44687 26.5531 2 26 2ZM9 7.25C8.30938 7.25 7.75 6.69063 7.75 6C7.75 5.30938 8.30938 4.75 9 4.75C9.69063 4.75 10.25 5.30938 10.25 6C10.25 6.69063 9.69063 7.25 9 7.25ZM5 29C5 29.5531 5.44687 30 6 30H26C26.5531 30 27 29.5531 27 29V22H5V29ZM9 24.75C9.69063 24.75 10.25 25.3094 10.25 26C10.25 26.6906 9.69063 27.25 9 27.25C8.30938 27.25 7.75 26.6906 7.75 26C7.75 25.3094 8.30938 24.75 9 24.75ZM5 20H27V12H5V20ZM9 14.75C9.69063 14.75 10.25 15.3094 10.25 16C10.25 16.6906 9.69063 17.25 9 17.25C8.30938 17.25 7.75 16.6906 7.75 16C7.75 15.3094 8.30938 14.75 9 14.75Z"
|
||||
fill="url(#paint0_linear_253_47)"/>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_253_47" x1="24.25" y1="2" x2="1.02087" y2="24.4633"
|
||||
gradientUnits="userSpaceOnUse">
|
||||
<stop stopColor="#FFCB7E"/>
|
||||
<stop offset="1" stopColor="#F5222D"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
|
||||
</svg>
|
||||
)
|
||||
|
||||
export const IconIdCard = ({style,className}: { style?: React.CSSProperties;className?:string; }) => (
|
||||
<svg className={`svg-icon ${className||''} icon-id-card`} style={style} xmlns="http://www.w3.org/2000/svg" fill="none" version="1.1"
|
||||
width="1em" height="1em" viewBox="0 0 32 32">
|
||||
<path
|
||||
d="M11.6562 12.8438C10.7656 12.8438 10.0406 13.5719 10.0406 14.4688C10.0406 15.3656 10.7656 16.0938 11.6562 16.0938C12.5469 16.0938 13.2719 15.3656 13.2719 14.4688C13.2719 13.5719 12.5469 12.8438 11.6562 12.8438ZM29 5H3C2.44687 5 2 5.44687 2 6V26C2 26.5531 2.44687 27 3 27H29C29.5531 27 30 26.5531 30 26V6C30 5.44687 29.5531 5 29 5ZM19 13.125C19 12.9875 19.0312 12.875 19.0719 12.875H22.9281C22.9688 12.875 23 12.9875 23 13.125V14.625C23 14.7625 22.9688 14.875 22.9281 14.875H19.0719C19.0312 14.875 19 14.7625 19 14.625V13.125ZM16.3125 21.0312H14.9406C14.8094 21.0312 14.7031 20.9281 14.6938 20.7969C14.575 19.2188 13.2563 17.9688 11.6562 17.9688C10.0562 17.9688 8.7375 19.2188 8.61875 20.7969C8.60937 20.9281 8.50312 21.0312 8.37187 21.0312H7C6.96609 21.0313 6.93253 21.0244 6.90135 21.0111C6.87017 20.9978 6.84204 20.9782 6.81865 20.9537C6.79527 20.9291 6.77712 20.9001 6.76532 20.8683C6.75352 20.8365 6.7483 20.8026 6.75 20.7687C6.8375 19.1031 7.75 17.6531 9.08125 16.8281C8.49418 16.1828 8.16979 15.3412 8.17188 14.4688C8.17188 12.5344 9.73125 10.9688 11.6531 10.9688C13.575 10.9688 15.1344 12.5344 15.1344 14.4688C15.1344 15.3781 14.7906 16.2031 14.225 16.8281C15.5594 17.6562 16.4688 19.1031 16.5562 20.7687C16.5687 20.9125 16.4563 21.0312 16.3125 21.0312ZM25.0281 19.375H19.2219C19.1 19.375 19 19.2625 19 19.125V17.625C19 17.4875 19.1 17.375 19.2219 17.375H25.025C25.1469 17.375 25.2469 17.4875 25.2469 17.625V19.125H25.25C25.25 19.2625 25.15 19.375 25.0281 19.375Z"
|
||||
fill="#F5222D"/>
|
||||
<path
|
||||
d="M11.6562 12.8438C10.7656 12.8438 10.0406 13.5719 10.0406 14.4688C10.0406 15.3656 10.7656 16.0938 11.6562 16.0938C12.5469 16.0938 13.2719 15.3656 13.2719 14.4688C13.2719 13.5719 12.5469 12.8438 11.6562 12.8438ZM29 5H3C2.44687 5 2 5.44687 2 6V26C2 26.5531 2.44687 27 3 27H29C29.5531 27 30 26.5531 30 26V6C30 5.44687 29.5531 5 29 5ZM19 13.125C19 12.9875 19.0312 12.875 19.0719 12.875H22.9281C22.9688 12.875 23 12.9875 23 13.125V14.625C23 14.7625 22.9688 14.875 22.9281 14.875H19.0719C19.0312 14.875 19 14.7625 19 14.625V13.125ZM16.3125 21.0312H14.9406C14.8094 21.0312 14.7031 20.9281 14.6938 20.7969C14.575 19.2188 13.2563 17.9688 11.6562 17.9688C10.0562 17.9688 8.7375 19.2188 8.61875 20.7969C8.60937 20.9281 8.50312 21.0312 8.37187 21.0312H7C6.96609 21.0313 6.93253 21.0244 6.90135 21.0111C6.87017 20.9978 6.84204 20.9782 6.81865 20.9537C6.79527 20.9291 6.77712 20.9001 6.76532 20.8683C6.75352 20.8365 6.7483 20.8026 6.75 20.7687C6.8375 19.1031 7.75 17.6531 9.08125 16.8281C8.49418 16.1828 8.16979 15.3412 8.17188 14.4688C8.17188 12.5344 9.73125 10.9688 11.6531 10.9688C13.575 10.9688 15.1344 12.5344 15.1344 14.4688C15.1344 15.3781 14.7906 16.2031 14.225 16.8281C15.5594 17.6562 16.4688 19.1031 16.5562 20.7687C16.5687 20.9125 16.4563 21.0312 16.3125 21.0312ZM25.0281 19.375H19.2219C19.1 19.375 19 19.2625 19 19.125V17.625C19 17.4875 19.1 17.375 19.2219 17.375H25.025C25.1469 17.375 25.2469 17.4875 25.2469 17.625V19.125H25.25C25.25 19.2625 25.15 19.375 25.0281 19.375Z"
|
||||
fill="url(#paint0_linear_253_56)"/>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_253_56" x1="26.5" y1="5" x2="9.93478" y2="30.9483"
|
||||
gradientUnits="userSpaceOnUse">
|
||||
<stop stopColor="#FFCB7E"/>
|
||||
<stop offset="1" stopColor="#F5222D"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
)
|
||||
|
||||
export const IconKnowledge = ({style,className}: { style?: React.CSSProperties;className?:string; }) => (
|
||||
<svg className={`svg-icon ${className||''} icon-knowledge`} style={style} xmlns="http://www.w3.org/2000/svg" fill="none"
|
||||
version="1.1"
|
||||
width="1em" height="1em" viewBox="0 0 32 32">
|
||||
<path
|
||||
d="M27 4.5H17.5C17.225 4.5 17 4.725 17 5V14.5C17 14.775 17.225 15 17.5 15H27C27.275 15 27.5 14.775 27.5 14.5V5C27.5 4.725 27.275 4.5 27 4.5ZM27 17H17.5C17.225 17 17 17.225 17 17.5V27C17 27.275 17.225 27.5 17.5 27.5H27C27.275 27.5 27.5 27.275 27.5 27V17.5C27.5 17.225 27.275 17 27 17ZM14.5 4.5H5C4.725 4.5 4.5 4.725 4.5 5V14.5C4.5 14.775 4.725 15 5 15H14.5C14.775 15 15 14.775 15 14.5V5C15 4.725 14.775 4.5 14.5 4.5ZM14.5 17H5C4.725 17 4.5 17.225 4.5 17.5V27C4.5 27.275 4.725 27.5 5 27.5H14.5C14.775 27.5 15 27.275 15 27V17.5C15 17.225 14.775 17 14.5 17Z"
|
||||
fill="#F5222D"/>
|
||||
<path
|
||||
d="M27 4.5H17.5C17.225 4.5 17 4.725 17 5V14.5C17 14.775 17.225 15 17.5 15H27C27.275 15 27.5 14.775 27.5 14.5V5C27.5 4.725 27.275 4.5 27 4.5ZM27 17H17.5C17.225 17 17 17.225 17 17.5V27C17 27.275 17.225 27.5 17.5 27.5H27C27.275 27.5 27.5 27.275 27.5 27V17.5C27.5 17.225 27.275 17 27 17ZM14.5 4.5H5C4.725 4.5 4.5 4.725 4.5 5V14.5C4.5 14.775 4.725 15 5 15H14.5C14.775 15 15 14.775 15 14.5V5C15 4.725 14.775 4.5 14.5 4.5ZM14.5 17H5C4.725 17 4.5 17.225 4.5 17.5V27C4.5 27.275 4.725 27.5 5 27.5H14.5C14.775 27.5 15 27.275 15 27V17.5C15 17.225 14.775 17 14.5 17Z"
|
||||
fill="url(#paint0_linear_253_41)"/>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_253_41" x1="24.625" y1="4.5" x2="5.9375" y2="27.5"
|
||||
gradientUnits="userSpaceOnUse">
|
||||
<stop stopColor="#FFCB7E"/>
|
||||
<stop offset="1" stopColor="#F5222D"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
)
|
||||
|
||||
export const IconAudio = ({style,className}: { style?: React.CSSProperties;className?:string; }) => (
|
||||
<svg className={`svg-icon ${className||''} icon-audio`} style={style} xmlns="http://www.w3.org/2000/svg" fill="none" version="1.1"
|
||||
width="1em" height="1em" viewBox="0 0 20 20">
|
||||
<path
|
||||
d="M10 12.1875C11.834 12.1875 13.3203 10.7188 13.3203 8.90625V4.53125C13.3203 2.71875 11.834 1.25 10 1.25C8.16602 1.25 6.67969 2.71875 6.67969 4.53125V8.90625C6.67969 10.7188 8.16602 12.1875 10 12.1875ZM16.4453 8.86719C16.4453 8.78125 16.375 8.71094 16.2891 8.71094H15.1172C15.0312 8.71094 14.9609 8.78125 14.9609 8.86719C14.9609 11.6074 12.7402 13.8281 10 13.8281C7.25977 13.8281 5.03906 11.6074 5.03906 8.86719C5.03906 8.78125 4.96875 8.71094 4.88281 8.71094H3.71094C3.625 8.71094 3.55469 8.78125 3.55469 8.86719C3.55469 12.1621 6.02734 14.8809 9.21875 15.2656V17.2656H6.38086C6.11328 17.2656 5.89844 17.5449 5.89844 17.8906V18.5938C5.89844 18.6797 5.95313 18.75 6.01953 18.75H13.9805C14.0469 18.75 14.1016 18.6797 14.1016 18.5938V17.8906C14.1016 17.5449 13.8867 17.2656 13.6191 17.2656H10.7031V15.2754C13.9316 14.9238 16.4453 12.1895 16.4453 8.86719Z"
|
||||
fill="#515151"/>
|
||||
|
||||
</svg>
|
||||
)
|
||||
export const IconSend = ({style,className}: { style?: React.CSSProperties;className?:string; }) => (
|
||||
<svg className={`svg-icon ${className||''} icon-audio`} style={style} xmlns="http://www.w3.org/2000/svg" fill="none" version="1.1"
|
||||
width="1em" height="1em" viewBox="0 0 24 24">
|
||||
<path
|
||||
d="M23.2348 11.6535L0.828538 0.419538C0.737466 0.374002 0.633002 0.363288 0.533895 0.387395C0.423901 0.414587 0.329163 0.484257 0.270425 0.581149C0.211687 0.678041 0.193736 0.79426 0.220502 0.904359L2.52943 10.3383C2.56425 10.4803 2.66872 10.5954 2.808 10.641L6.76425 11.999L2.81068 13.357C2.67139 13.4053 2.56693 13.5178 2.53479 13.6597L0.220502 23.107C0.196395 23.2061 0.207109 23.3106 0.252645 23.399C0.357109 23.6106 0.614252 23.6963 0.828538 23.5919L23.2348 12.4222C23.3178 12.382 23.3848 12.3124 23.4276 12.232C23.5321 12.0178 23.4464 11.7606 23.2348 11.6535ZM2.86157 20.4231L4.2089 14.916L12.116 12.2026C12.1776 12.1811 12.2285 12.1329 12.25 12.0686C12.2875 11.9561 12.2285 11.8356 12.116 11.7954L4.2089 9.08472L2.86693 3.599L19.6884 12.0338L2.86157 20.4231Z"
|
||||
fill="currentColor"/>
|
||||
|
||||
</svg>
|
||||
)
|
||||
export const IconSync = ({style,className}: { style?: React.CSSProperties;className?:string; }) => (
|
||||
<svg className={`svg-icon ${className||''} icon-sync`} style={style} xmlns="http://www.w3.org/2000/svg" fill="none" version="1.1"
|
||||
width="1em" height="1em" viewBox="0 0 16 16">
|
||||
<g clipPath="url(#clip0_144_44)">
|
||||
<path
|
||||
d="M1.85719 7.86072C1.87504 7.08036 2.03576 6.32322 2.33754 5.61072C2.64647 4.87857 3.08933 4.22321 3.65362 3.65714C4.2179 3.09107 4.87504 2.64821 5.60719 2.33929C6.36433 2.01964 7.1679 1.85714 7.99826 1.85714C8.82862 1.85714 9.63219 2.01964 10.3875 2.33929C11.1176 2.64758 11.7805 3.09521 12.3393 3.65714C12.5161 3.83393 12.6822 4.02143 12.8358 4.21786L11.7608 5.05714C11.7395 5.0736 11.7233 5.09572 11.714 5.12097C11.7048 5.14622 11.7028 5.17356 11.7084 5.19987C11.714 5.22617 11.7269 5.25036 11.7457 5.26965C11.7644 5.28895 11.7882 5.30256 11.8143 5.30893L14.9518 6.07679C15.0411 6.09822 15.1286 6.03036 15.1286 5.93929L15.1429 2.70893C15.1429 2.58929 15.0054 2.52143 14.9125 2.59643L13.9054 3.38393C12.5322 1.62679 10.3965 0.5 7.99647 0.5C3.9054 0.5 0.57683 3.77857 0.500045 7.85357C0.499568 7.87263 0.502911 7.89159 0.509876 7.90934C0.516842 7.92709 0.527289 7.94326 0.540603 7.9569C0.553916 7.97055 0.569826 7.98139 0.587395 7.9888C0.604964 7.9962 0.623837 8.00001 0.642902 8H1.71433C1.7929 8 1.8554 7.9375 1.85719 7.86072ZM15.3572 8H14.2858C14.2072 8 14.1447 8.0625 14.1429 8.13929C14.125 8.91964 13.9643 9.67679 13.6625 10.3893C13.3536 11.1214 12.9108 11.7786 12.3465 12.3429C11.7769 12.9148 11.0998 13.3683 10.3541 13.6772C9.60843 13.9861 8.80897 14.1444 8.00183 14.1429C7.19496 14.1444 6.39578 13.9861 5.6504 13.6771C4.90502 13.3682 4.22819 12.9147 3.65897 12.3429C3.48219 12.1661 3.31612 11.9786 3.16254 11.7821L4.23754 10.9429C4.25881 10.9264 4.27501 10.9043 4.28426 10.879C4.29352 10.8538 4.29546 10.8264 4.28986 10.8001C4.28427 10.7738 4.27136 10.7496 4.25263 10.7304C4.2339 10.7111 4.2101 10.6974 4.18397 10.6911L1.04647 9.92322C0.957188 9.90179 0.869687 9.96964 0.869687 10.0607L0.857188 13.2929C0.857188 13.4125 0.994688 13.4804 1.08754 13.4054L2.09469 12.6179C3.4679 14.3732 5.60362 15.5 8.00362 15.5C12.0965 15.5 15.4233 12.2196 15.5 8.14643C15.5005 8.12737 15.4972 8.10841 15.4902 8.09066C15.4832 8.07292 15.4728 8.05674 15.4595 8.0431C15.4462 8.02945 15.4303 8.01861 15.4127 8.01121C15.3951 8.00381 15.3763 8 15.3572 8Z"
|
||||
fill="currentColor"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_144_44">
|
||||
<rect width="16" height="16" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
)
|
||||
|
||||
export const IconCopy = ({style,className}: { style?: React.CSSProperties;className?:string; }) => (
|
||||
<svg className={`svg-icon ${className||''} icon-copy`} style={style} xmlns="http://www.w3.org/2000/svg" fill="none" version="1.1"
|
||||
width="1em" height="1em" viewBox="0 0 16 16">
|
||||
<g clipPath="url(#clip0_144_46)">
|
||||
<path
|
||||
d="M13.7139 0H4.14244C4.06387 0 3.99958 0.0642857 3.99958 0.142857V1.14286C3.99958 1.22143 4.06387 1.28571 4.14244 1.28571H12.9996V13.5714C12.9996 13.65 13.0639 13.7143 13.1424 13.7143H14.1424C14.221 13.7143 14.2853 13.65 14.2853 13.5714V0.571429C14.2853 0.255357 14.0299 0 13.7139 0ZM11.4282 2.28571H2.2853C1.96922 2.28571 1.71387 2.54107 1.71387 2.85714V12.3339C1.71387 12.4857 1.77458 12.6304 1.88172 12.7375L4.97637 15.8321C5.01565 15.8714 5.0603 15.9036 5.10851 15.9304V15.9643H5.18351C5.24601 15.9875 5.31208 16 5.37994 16H11.4282C11.7442 16 11.9996 15.7446 11.9996 15.4286V2.85714C11.9996 2.54107 11.7442 2.28571 11.4282 2.28571ZM5.10672 14.1464L3.56922 12.6071H5.10672V14.1464ZM10.7139 14.7143H6.24958V12.1786C6.24958 11.7839 5.92994 11.4643 5.5353 11.4643H2.99958V3.57143H10.7139V14.7143Z"
|
||||
fill="currentColor"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_144_46">
|
||||
<rect width="16" height="16" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
)
|
||||
export const IconShare = ({style,className}: { style?: React.CSSProperties;className?:string; }) => (
|
||||
<svg className={`svg-icon ${className||''} icon-share`} style={style} xmlns="http://www.w3.org/2000/svg" fill="none" version="1.1"
|
||||
width="1em" height="1em" viewBox="0 0 16 16">
|
||||
<path
|
||||
d="M12.2856 10.7143C11.7766 10.7143 11.307 10.8929 10.9391 11.1911L7.23915 8.51429C7.3011 8.17423 7.3011 7.82577 7.23915 7.48572L10.9391 4.80893C11.307 5.10714 11.7766 5.28572 12.2856 5.28572C13.4677 5.28572 14.4284 4.325 14.4284 3.14286C14.4284 1.96071 13.4677 1 12.2856 1C11.1034 1 10.1427 1.96071 10.1427 3.14286C10.1427 3.35 10.1713 3.54821 10.2266 3.7375L6.71236 6.28214C6.19093 5.59107 5.36236 5.14286 4.42843 5.14286C2.84986 5.14286 1.57129 6.42143 1.57129 8C1.57129 9.57857 2.84986 10.8571 4.42843 10.8571C5.36236 10.8571 6.19093 10.4089 6.71236 9.71786L10.2266 12.2625C10.1713 12.4518 10.1427 12.6518 10.1427 12.8571C10.1427 14.0393 11.1034 15 12.2856 15C13.4677 15 14.4284 14.0393 14.4284 12.8571C14.4284 11.675 13.4677 10.7143 12.2856 10.7143ZM12.2856 2.21429C12.7981 2.21429 13.2141 2.63036 13.2141 3.14286C13.2141 3.65536 12.7981 4.07143 12.2856 4.07143C11.7731 4.07143 11.357 3.65536 11.357 3.14286C11.357 2.63036 11.7731 2.21429 12.2856 2.21429ZM4.42843 9.57143C3.56236 9.57143 2.857 8.86607 2.857 8C2.857 7.13393 3.56236 6.42857 4.42843 6.42857C5.2945 6.42857 5.99986 7.13393 5.99986 8C5.99986 8.86607 5.2945 9.57143 4.42843 9.57143ZM12.2856 13.7857C11.7731 13.7857 11.357 13.3696 11.357 12.8571C11.357 12.3446 11.7731 11.9286 12.2856 11.9286C12.7981 11.9286 13.2141 12.3446 13.2141 12.8571C13.2141 13.3696 12.7981 13.7857 12.2856 13.7857Z"
|
||||
fill="currentColor"/>
|
||||
</svg>
|
||||
)
|
||||
export const IconDownload = ({style,className}: { style?: React.CSSProperties;className?:string; }) => (
|
||||
<svg className={`svg-icon ${className||''} icon-download`} style={style} xmlns="http://www.w3.org/2000/svg" fill="none" version="1.1"
|
||||
width="1em" height="1em" viewBox="0 0 16 16">
|
||||
<path
|
||||
d="M7.88736 10.6575C7.90072 10.6745 7.9178 10.6883 7.93729 10.6978C7.95678 10.7073 7.97818 10.7123 7.99986 10.7123C8.02154 10.7123 8.04294 10.7073 8.06243 10.6978C8.08192 10.6883 8.099 10.6745 8.11236 10.6575L10.1124 8.1271C10.1856 8.03424 10.1195 7.89674 9.99986 7.89674H8.67665V1.85389C8.67665 1.77531 8.61236 1.71103 8.53379 1.71103H7.46236C7.38379 1.71103 7.3195 1.77531 7.3195 1.85389V7.89496H5.99986C5.88022 7.89496 5.81415 8.03246 5.88736 8.12532L7.88736 10.6575ZM14.5356 10.0325H13.4641C13.3856 10.0325 13.3213 10.0967 13.3213 10.1753V12.9253H2.67843V10.1753C2.67843 10.0967 2.61415 10.0325 2.53557 10.0325H1.46415C1.38557 10.0325 1.32129 10.0967 1.32129 10.1753V13.711C1.32129 14.0271 1.57665 14.2825 1.89272 14.2825H14.107C14.4231 14.2825 14.6784 14.0271 14.6784 13.711V10.1753C14.6784 10.0967 14.6141 10.0325 14.5356 10.0325Z"
|
||||
fill="currentColor"/>
|
||||
</svg>
|
||||
)
|
||||
|
||||
export const IconDelete = ({style,className}: { style?: React.CSSProperties;className?:string; }) => (
|
||||
<svg className={`svg-icon ${className||''} icon-delete`} style={style} xmlns="http://www.w3.org/2000/svg"
|
||||
width="1em" height="1em" viewBox="0 0 1024 1024" version="1.1">
|
||||
<path
|
||||
d="M765.505691 191.942567H639.627772c0-35.32453-28.636201-63.960731-63.96073-63.960731H447.74558c-35.32453 0-63.960731 28.636201-63.96073 63.960731H257.905908c-36.452213 0-66.00325 29.551036-66.00325 66.00325v59.875692c0 36.452213 29.551036 66.00325 66.00325 66.00325h-2.042519v445.681572c0 36.452213 29.551036 66.00325 66.003249 66.00325h379.679346c36.452213 0 66.00325-29.551036 66.00325-66.00325V383.823736h-2.04252c36.452213 0 66.00325-29.551036 66.00325-66.00325v-59.875693c-0.001023-36.452213-29.551036-66.002226-66.004273-66.002226z m-61.918211 611.470479c-0.101307 3.123131-1.743714 27.813462-27.961842 28.134781H347.905688c-27.988448-0.343831-27.969005-28.459169-27.969005-28.459169l-0.112564 0.031722V383.823736h383.763361v419.58931z m31.980365-483.550041H287.843754c-17.662265 0-31.980365-14.3181-31.980365-31.980365 0-17.662265 14.3181-31.980365 31.980365-31.980366H735.568868c17.662265 0 31.980365 14.3181 31.980366 31.980366-0.001023 17.662265-14.319124 31.980365-31.981389 31.980365z"
|
||||
fill="currentColor"/>
|
||||
<path
|
||||
d="M447.74558 767.588119c17.662265 0 31.980365-14.3181 31.980366-31.980365V479.764831c0-17.662265-14.3181-31.980365-31.980366-31.980365-17.662265 0-31.980365 14.3181-31.980365 31.980365v255.842923c0 17.662265 14.3181 31.980365 31.980365 31.980365zM575.667042 767.588119c17.662265 0 31.980365-14.3181 31.980365-31.980365V479.764831c0-17.662265-14.3181-31.980365-31.980365-31.980365-17.662265 0-31.980365 14.3181-31.980366 31.980365v255.842923c0 17.662265 14.3181 31.980365 31.980366 31.980365z"
|
||||
fill="currentColor"/>
|
||||
</svg>
|
||||
)
|
||||
export const IconAddText = ({style,className}: { style?: React.CSSProperties;className?:string; }) => (
|
||||
<svg className={`svg-icon ${className||''} icon-delete`} style={style} xmlns="http://www.w3.org/2000/svg"
|
||||
width="1em" height="1em" viewBox="0 0 1024 1024" version="1.1">
|
||||
<path
|
||||
d="M714.688 512a224 224 0 1 1 0 448 224 224 0 0 1 0-448z m96-448a64 64 0 0 1 64 64v284.992a36.032 36.032 0 0 1-71.424 5.76l-0.64-5.76V136h-624v752h212.032a35.968 35.968 0 1 1 0 72H170.688a64 64 0 0 1-64-64V128a64 64 0 0 1 64-64h640z m-96 512a160 160 0 1 0 0 320 160 160 0 0 0 0-320z m0 28.032c15.424 0 27.968 12.48 27.968 27.968v76.032h76.032a28.032 28.032 0 0 1 0 55.936h-76.032v76.032a28.032 28.032 0 0 1-56 0v-76.032H610.688a27.968 27.968 0 1 1 0-55.936h75.968V631.936c0-15.488 12.544-28.032 28.032-28.032zM401.664 672a32 32 0 1 1 0 64h-112a32 32 0 1 1 0-64h112z m57.984-192a32 32 0 0 1 0 64H289.664a32 32 0 1 1 0-64h169.984z m230.016-192a32 32 0 0 1 0 64h-400a32 32 0 1 1 0-64h400z"
|
||||
fill="currentColor"/>
|
||||
</svg>
|
||||
)
|
||||
|
||||
|
||||
export const IconAddImage = ({style,className}: { style?: React.CSSProperties;className?:string; }) => (
|
||||
<svg className={`svg-icon ${className||''} icon-delete`} style={style} xmlns="http://www.w3.org/2000/svg"
|
||||
width="1em" height="1em" viewBox="0 0 1024 1024" version="1.1">
|
||||
<path
|
||||
d="M160 128a96 96 0 0 0-96 96v576a96 96 0 0 0 96 96h262.72a374.464 374.464 0 0 1-25.216-64H160a31.872 31.872 0 0 1-32-32v-59.264l227.52-256.512 74.496 78.336c10.752-19.008 23.232-36.992 37.248-53.504L353.92 389.76 128 644.224V224c0-17.728 14.272-32 32-32h704c17.728 0 32 14.272 32 32v198.72c22.72 11.776 44.48 25.536 64 41.792V224a96 96 0 0 0-96-96z m544 128c-35.2 0-64 28.8-64 64s28.8 64 64 64 64-28.8 64-64-28.8-64-64-64z m32 192c-158.72 0-288 129.28-288 288s129.28 288 288 288 288-129.28 288-288-129.28-288-288-288z m0 64c124.032 0 224 100.032 224 224 0 124.032-100.032 224-224 224a223.616 223.616 0 0 1-224-224c0-124.032 100.032-224 224-224z m-32 64v128H576v64h128v128h64V768h128v-64H768V576z"
|
||||
fill="currentColor"/>
|
||||
</svg>
|
||||
)
|
||||
|
||||
export const IconAdd = ({style,className}: { style?: React.CSSProperties;className?:string; }) => (
|
||||
<svg className={`svg-icon ${className||''} icon-delete`} style={style} xmlns="http://www.w3.org/2000/svg"
|
||||
width="1em" height="1em" viewBox="0 0 1024 1024" version="1.1">
|
||||
<path
|
||||
d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64z m271.5 719.5c-35.3 35.3-76.3 63-122.1 82.3-47.3 20-97.6 30.2-149.5 30.2-51.9 0-102.1-10.1-149.5-30.2-45.7-19.3-86.8-47-122.1-82.3s-63-76.3-82.3-122.1c-20-47.3-30.2-97.6-30.2-149.5s10.1-102.1 30.2-149.5c19.3-45.7 47-86.8 82.3-122.1s76.3-63 122.1-82.3c47.3-20 97.6-30.2 149.5-30.2 51.9 0 102.1 10.1 149.5 30.2 45.7 19.3 86.8 47 122.1 82.3s63 76.3 82.3 122.1c20 47.3 30.2 97.6 30.2 149.5S885.9 614 865.8 661.4c-19.3 45.8-47 86.9-82.3 122.1z"
|
||||
fill="currentColor"/>
|
||||
<path d="M544 288v448c0 17.6-14.4 32-32 32s-32-14.4-32-32V288c0-17.6 14.4-32 32-32s32 14.4 32 32z"
|
||||
fill="currentColor"/>
|
||||
<path d="M736 544H288c-17.6 0-32-14.4-32-32s14.4-32 32-32h448c17.6 0 32 14.4 32 32s-14.4 32-32 32z"
|
||||
fill="currentColor"/>
|
||||
</svg>
|
||||
)
|
||||
|
||||
export const IconPlay = ({style,className}: { style?: React.CSSProperties;className?:string; }) => (
|
||||
<svg className={`svg-icon ${className||''} icon-delete`} style={style} xmlns="http://www.w3.org/2000/svg"
|
||||
width="1em" height="1em" viewBox="0 0 1024 1024" version="1.1">
|
||||
<path
|
||||
d="M512 97.52381c228.912762 0 414.47619 185.563429 414.47619 414.47619s-185.563429 414.47619-414.47619 414.47619S97.52381 740.912762 97.52381 512 283.087238 97.52381 512 97.52381z m-57.782857 268.190476c-21.942857 0-39.740952 17.798095-39.740953 39.740952v209.13981a39.740952 39.740952 0 0 0 61.196191 33.426285l164.352-105.593904a39.740952 39.740952 0 0 0-0.292571-67.047619l-164.352-103.545905a39.740952 39.740952 0 0 0-21.187048-6.119619z"
|
||||
fill="currentColor"/>
|
||||
</svg>
|
||||
)
|
||||
|
||||
export const IconLive = ({style,className}: { style?: React.CSSProperties;className?:string; }) => (
|
||||
<svg className={`svg-icon ${className||''} icon-delete`} style={style} xmlns="http://www.w3.org/2000/svg"
|
||||
width="1em" height="1em" viewBox="0 0 1024 1024" version="1.1">
|
||||
<path
|
||||
d="M772.437333 97.52381l51.712 51.712-126.342095 126.342095H828.952381a73.142857 73.142857 0 0 1 73.142857 73.142857v487.619048a73.142857 73.142857 0 0 1-73.142857 73.142857H195.047619a73.142857 73.142857 0 0 1-73.142857-73.142857v-487.619048a73.142857 73.142857 0 0 1 73.142857-73.142857h131.120762L199.850667 149.23581 251.562667 97.52381l178.054095 178.054095h164.742095L772.437333 97.52381zM828.952381 348.720762H195.047619v487.619048h633.904762v-487.619048z m-280.380952 73.142857v341.333333h-73.142858v-341.333333h73.142858z m-134.095239 73.142857v195.047619h-73.142857v-195.047619h73.142857z m268.190477 24.380953v146.285714h-73.142857v-146.285714h73.142857z"
|
||||
fill="currentColor"/>
|
||||
</svg>
|
||||
)
|
32
src/components/icons/logo.tsx
Normal file
@ -0,0 +1,32 @@
|
||||
import React from "react";
|
||||
import useConfig from "@/hooks/useConfig.ts";
|
||||
|
||||
const AppLogo = ({style}: { style?: React.CSSProperties, theme?: 'origin' | 'color' }) => {
|
||||
return (
|
||||
<svg style={style} viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" width="100" height="100">
|
||||
<path
|
||||
d="M671.584 201.142c22.034 0 39.896 17.398 39.896 38.858v163.2l207.98-141.828a20.4 20.4 0 0 1 20.666-1.322c6.602 3.35 10.732 10.002 10.732 17.252V746.7c0 7.25-4.13 13.902-10.732 17.252a20.4 20.4 0 0 1-20.668-1.32L711.48 620.8V784c0 21.46-17.86 38.858-39.896 38.858H113.04c-22.034 0-39.896-17.398-39.896-38.858V240c0-21.46 17.862-38.858 39.896-38.858h558.546z"
|
||||
fill="#9C34FE"></path>
|
||||
<path
|
||||
d="M328.478 388.784c-7.584 0-14.122 5.196-15.64 12.434l-0.32 3.07v215.346c0 5.11 2.58 9.894 6.896 12.796a16.32 16.32 0 0 0 14.73 1.736l2.912-1.398 173.748-107.712c4.106-2.56 6.786-6.806 7.276-11.532 0.49-4.724-1.264-9.408-4.764-12.714l-2.512-1.944-173.748-107.712a16.28 16.28 0 0 0-8.578-2.332v-0.038z"
|
||||
fill="#FFFFFF"></path>
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
export const LogoText = ({style}: { style?: React.CSSProperties, theme?: 'origin' | 'color' }) => {
|
||||
const {appName} = useConfig()
|
||||
return (
|
||||
<div className={'align-middle flex items-center h-full'}>
|
||||
<svg style={style} viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" width="44" height="44">
|
||||
<path
|
||||
d="M671.584 201.142c22.034 0 39.896 17.398 39.896 38.858v163.2l207.98-141.828a20.4 20.4 0 0 1 20.666-1.322c6.602 3.35 10.732 10.002 10.732 17.252V746.7c0 7.25-4.13 13.902-10.732 17.252a20.4 20.4 0 0 1-20.668-1.32L711.48 620.8V784c0 21.46-17.86 38.858-39.896 38.858H113.04c-22.034 0-39.896-17.398-39.896-38.858V240c0-21.46 17.862-38.858 39.896-38.858h558.546z"
|
||||
fill="#9C34FE"></path>
|
||||
<path
|
||||
d="M328.478 388.784c-7.584 0-14.122 5.196-15.64 12.434l-0.32 3.07v215.346c0 5.11 2.58 9.894 6.896 12.796a16.32 16.32 0 0 0 14.73 1.736l2.912-1.398 173.748-107.712c4.106-2.56 6.786-6.806 7.276-11.532 0.49-4.724-1.264-9.408-4.764-12.714l-2.512-1.944-173.748-107.712a16.28 16.28 0 0 0-8.578-2.332v-0.038z"
|
||||
fill="#FFFFFF"></path>
|
||||
</svg>
|
||||
<span className={'ml-4 text-xl'}>{appName}</span>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default AppLogo
|
10
src/components/icons/user-avatar.tsx
Normal file
@ -0,0 +1,10 @@
|
||||
import Avatar from "@/assets/images/avatar.png";
|
||||
import React from "react";
|
||||
|
||||
export const UserAvatar = ( {className,style}: { style?: React.CSSProperties;className?: string }) => {
|
||||
return (
|
||||
<span>
|
||||
<img src={Avatar} style={style} className={className}/>
|
||||
</span>
|
||||
)
|
||||
}
|
15
src/components/loader.tsx
Normal file
@ -0,0 +1,15 @@
|
||||
import {LinearProgress} from "@/components/progress";
|
||||
|
||||
const Loader = () => (
|
||||
<div style={{
|
||||
position: 'fixed',
|
||||
top: 0,
|
||||
left: 0,
|
||||
zIndex: 2001,
|
||||
width: '100%',
|
||||
}}>
|
||||
<LinearProgress />
|
||||
</div>
|
||||
);
|
||||
|
||||
export default Loader;
|
6
src/components/progress/index.tsx
Normal file
@ -0,0 +1,6 @@
|
||||
import './progressbar.scss'
|
||||
|
||||
//color="primary"
|
||||
export const LinearProgress = () => {
|
||||
return <div className="linear-progress"></div>
|
||||
}
|
18
src/components/progress/progressbar.scss
Normal file
@ -0,0 +1,18 @@
|
||||
@keyframes linear-progress-anim {
|
||||
0% {
|
||||
background-position: -150% 0, -150% 0
|
||||
}
|
||||
50% {
|
||||
background-position: 250% 0, -150% 0
|
||||
}
|
||||
100% {
|
||||
background-position: 250% 0, 250% 0
|
||||
}
|
||||
}
|
||||
|
||||
.linear-progress {
|
||||
height: 4px;
|
||||
background: linear-gradient(#766DF4 0 0) no-repeat #E4E4ED;
|
||||
background-size: 60% 100%;
|
||||
animation: linear-progress-anim 3s infinite linear;
|
||||
}
|
39
src/components/video/player.tsx
Normal file
@ -0,0 +1,39 @@
|
||||
import ReactPlayer from 'react-player'
|
||||
import {useSetState} from "ahooks";
|
||||
import {PauseOutlined, PlayCircleOutlined, FullscreenOutlined, FullscreenExitOutlined} from "@ant-design/icons"
|
||||
import {Progress} from "antd";
|
||||
|
||||
export function Player({url, cover}: { url: string; cover?: string }) {
|
||||
const [state, setState] = useSetState({
|
||||
playing: false,
|
||||
muted: false,
|
||||
// 是否全屏
|
||||
fullscreen: false,
|
||||
progress: 30
|
||||
})
|
||||
return <div className="video-player">
|
||||
<ReactPlayer
|
||||
url={url}
|
||||
controls={true}
|
||||
light={cover}
|
||||
width="100%"
|
||||
height="250px"
|
||||
/>
|
||||
<div className="video-control p-2 flex items-center gap-2">
|
||||
<button>
|
||||
{state.playing ? <PauseOutlined/> : <PlayCircleOutlined/>}
|
||||
</button>
|
||||
<div className="whitespace-nowrap flex items-center text-sm">
|
||||
<span>00:00</span>
|
||||
<span>/</span>
|
||||
<span>00:00</span>
|
||||
</div>
|
||||
<div className="flex-1">
|
||||
<Progress size="small" percent={state.progress} showInfo={false}/>
|
||||
</div>
|
||||
<button>
|
||||
{state.fullscreen ? <FullscreenExitOutlined/> : <FullscreenOutlined/>}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
}
|
136
src/contexts/auth/index.tsx
Normal file
@ -0,0 +1,136 @@
|
||||
import React, {createContext, useEffect, useReducer} from "react";
|
||||
|
||||
import Loader from "@/components/loader";
|
||||
import {getAuthToken, setAuthToken} from "@/hooks/useAuth.ts";
|
||||
import {auth, getUserInfo} from "@/service/api/user.ts";
|
||||
|
||||
|
||||
const UserRoleStorageKey = 'user-current-role';
|
||||
|
||||
function getCurrentRole() {
|
||||
return (localStorage.getItem(UserRoleStorageKey)) as UserRole
|
||||
}
|
||||
|
||||
export function setCurrentRole(role: UserRole) {
|
||||
localStorage.setItem(UserRoleStorageKey, role)
|
||||
}
|
||||
|
||||
function removeRoleStorage() {
|
||||
localStorage.removeItem(UserRoleStorageKey)
|
||||
}
|
||||
|
||||
type AuthAction = { action?: string, payload: Partial<AuthProps> }
|
||||
|
||||
// 权限相关 context
|
||||
const AuthContext = createContext<AuthContextType | null>(null)
|
||||
|
||||
// 权限相关初始化数据
|
||||
const initialState: AuthProps = {
|
||||
isLoggedIn: false,
|
||||
isInitialized: false,
|
||||
user: null
|
||||
};
|
||||
|
||||
// 状态 reducer
|
||||
const authReducer = (prevState: AuthProps, {payload}:AuthAction ) => {
|
||||
return {
|
||||
...prevState,
|
||||
...payload,
|
||||
} as AuthProps
|
||||
}
|
||||
|
||||
export const AuthProvider = ({children}: { children: React.ReactNode }) => {
|
||||
const [state, dispatch] = useReducer(authReducer, initialState);
|
||||
|
||||
// MOCK INIT DATA
|
||||
const init = async () => {
|
||||
const token = getAuthToken();
|
||||
if (!token) {
|
||||
dispatch({
|
||||
payload: {
|
||||
isInitialized: true,
|
||||
}
|
||||
})
|
||||
return 'initialized'
|
||||
}
|
||||
getUserInfo().then(user => {
|
||||
dispatch({
|
||||
action: 'init',
|
||||
payload: {
|
||||
isInitialized: true,
|
||||
isLoggedIn: !!user,
|
||||
user: {
|
||||
...user,
|
||||
role: getCurrentRole()
|
||||
}
|
||||
}
|
||||
})
|
||||
}).finally(() => {
|
||||
dispatch({
|
||||
payload: {
|
||||
isInitialized: true,
|
||||
}
|
||||
})
|
||||
})
|
||||
return 'initialized'
|
||||
}
|
||||
// 登录
|
||||
const login = async (code: string, state: string) => {
|
||||
const user = await auth(code, state)
|
||||
// 保存token
|
||||
setAuthToken(user.token, user.expiration_time ? (new Date(user.expiration_time)).getTime() : -1);
|
||||
|
||||
//
|
||||
dispatch({
|
||||
action: 'login',
|
||||
payload: {
|
||||
isLoggedIn: true,
|
||||
user: {
|
||||
...user,
|
||||
role: getCurrentRole()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
// 登出
|
||||
const logout = async () => {
|
||||
setAuthToken(null)
|
||||
removeRoleStorage()
|
||||
dispatch({
|
||||
action: 'logout',
|
||||
payload: {
|
||||
isLoggedIn: false,
|
||||
user: null
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const updateUser = async (user: Partial<UserProfile>) => {
|
||||
dispatch({
|
||||
action: 'updateUser',
|
||||
payload: {
|
||||
user: {
|
||||
...state.user,
|
||||
...user
|
||||
} as never,
|
||||
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
init().then(console.log)
|
||||
}, [])
|
||||
|
||||
// 判断是否已经初始化
|
||||
if (state.isInitialized !== undefined && !state.isInitialized) {
|
||||
return <Loader/>;
|
||||
}
|
||||
return (<AuthContext.Provider value={{
|
||||
...state,
|
||||
login,
|
||||
logout,
|
||||
updateUser
|
||||
}}>{children}</AuthContext.Provider>)
|
||||
}
|
||||
export default AuthContext
|
43
src/contexts/config/index.tsx
Normal file
@ -0,0 +1,43 @@
|
||||
import useLocalStorage from "@/hooks/useLocalStorage";
|
||||
import {createContext} from "react";
|
||||
|
||||
const config: ConfigProps = {
|
||||
fontFamily: `'Public Sans', sans-serif`,
|
||||
i18n: 'zh-CN',
|
||||
appName: "数字人直播",
|
||||
};
|
||||
|
||||
const initialState: CustomizationProps = {
|
||||
...config,
|
||||
onChangeContainer: () => {
|
||||
},
|
||||
onChangeLocalization: (_: I18n) => {
|
||||
},
|
||||
onChangeFontFamily: (_: string) => {
|
||||
}
|
||||
};
|
||||
|
||||
// ==============================|| CONFIG CONTEXT & PROVIDER ||============================== //
|
||||
|
||||
const ConfigContext = createContext(initialState);
|
||||
export const ConfigProvider = ({children}: { children: React.ReactNode }) => {
|
||||
const [config, setConfig] = useLocalStorage('app-payment-config', initialState);
|
||||
// 改变语言
|
||||
const onChangeLocalization = (lang: I18n) => {
|
||||
setConfig({
|
||||
...config,
|
||||
i18n: lang
|
||||
});
|
||||
};
|
||||
// 更改字体
|
||||
const onChangeFontFamily = (fontFamily: string) => {
|
||||
setConfig({...config, fontFamily})
|
||||
}
|
||||
|
||||
return (
|
||||
<ConfigContext.Provider value={{
|
||||
...config, onChangeFontFamily, onChangeLocalization
|
||||
}}>{children}</ConfigContext.Provider>
|
||||
)
|
||||
}
|
||||
export default ConfigContext
|
40
src/contexts/counter.tsx
Normal file
@ -0,0 +1,40 @@
|
||||
import React, {useReducer} from 'react';
|
||||
|
||||
// 定义状态的类型
|
||||
type CounterState = {
|
||||
count: number;
|
||||
};
|
||||
|
||||
// 定义要执行的动作的类型
|
||||
type CounterAction = { type: 'increment'; amount: number }
|
||||
| { type: 'decrement'; amount: number }
|
||||
| { type: 'reset' };
|
||||
|
||||
// 使用Reducer函数处理状态变化
|
||||
function counterReducer(state: CounterState, action: CounterAction): CounterState {
|
||||
|
||||
switch (action.type) {
|
||||
case 'increment':
|
||||
return {count: state.count + action.amount};
|
||||
case 'decrement':
|
||||
return {count: state.count - action.amount};
|
||||
case 'reset':
|
||||
return {count: 0};
|
||||
default:
|
||||
throw new Error(`Unhandled action type`);
|
||||
}
|
||||
}
|
||||
|
||||
// 使用useReducer钩子
|
||||
export const Counter: React.FC = () => {
|
||||
const [state, dispatch] = useReducer(counterReducer, {count: 0});
|
||||
|
||||
return (
|
||||
<div>
|
||||
Value: {state.count}
|
||||
<button onClick={() => dispatch({type: 'increment', amount: 1})}>Increment</button>
|
||||
<button disabled={state.count <= 0} onClick={() => dispatch({type: 'decrement', amount: 1})}>Decrement</button>
|
||||
<button onClick={() => dispatch({type: 'reset'})}>Reset</button>
|
||||
</div>
|
||||
);
|
||||
};
|
5
src/hooks/useAppUrl.ts
Normal file
@ -0,0 +1,5 @@
|
||||
export function getAppUrl() {
|
||||
const {host, protocol} = location //AppConfig.SITE_URL
|
||||
const rootUrl = (typeof (APP_SITE_URL) == "string" ? APP_SITE_URL : undefined) || `${protocol}//${host}`
|
||||
return rootUrl;
|
||||
}
|
42
src/hooks/useAuth.ts
Normal file
@ -0,0 +1,42 @@
|
||||
import {useContext} from 'react';
|
||||
|
||||
// auth provider
|
||||
import AuthContext from '@/contexts/auth';
|
||||
|
||||
// ==============================|| AUTH HOOKS ||============================== //
|
||||
|
||||
const useAuth = () => {
|
||||
const context = useContext(AuthContext);
|
||||
|
||||
if (!context) throw new Error('context must be use inside provider');
|
||||
|
||||
return context;
|
||||
};
|
||||
|
||||
export const setAuthToken = (token: string | null, expiry_time = -1) => {
|
||||
if (!token) {
|
||||
localStorage.removeItem(AppConfig.AUTH_TOKEN_KEY);
|
||||
return;
|
||||
}
|
||||
localStorage.setItem(AppConfig.AUTH_TOKEN_KEY, JSON.stringify({
|
||||
token, expiry_time
|
||||
}));
|
||||
}
|
||||
|
||||
export const getAuthToken = () => {
|
||||
const data = localStorage.getItem(AppConfig.AUTH_TOKEN_KEY);
|
||||
if (!data) return;
|
||||
try {
|
||||
const {token, expiry_time} = JSON.parse(data) as { token: string, expiry_time: number };
|
||||
if (expiry_time != -1 && expiry_time < Date.now()) {
|
||||
localStorage.removeItem(AppConfig.AUTH_TOKEN_KEY);
|
||||
return;
|
||||
}
|
||||
return token;
|
||||
} catch (_e) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export default useAuth;
|
8
src/hooks/useConfig.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import ConfigContext from '@/contexts/config';
|
||||
import { useContext } from 'react';
|
||||
|
||||
// ==============================|| CONFIG - HOOKS ||============================== //
|
||||
|
||||
const useConfig = () => useContext(ConfigContext);
|
||||
|
||||
export default useConfig;
|
33
src/hooks/useLocalStorage.ts
Normal file
@ -0,0 +1,33 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
export default function useLocalStorage<ValueType>(key: string, defaultValue: ValueType) {
|
||||
const [value, setValue] = useState(() => {
|
||||
const storedValue = typeof window !== 'undefined' ? localStorage.getItem(key) : null;
|
||||
return storedValue === null ? defaultValue : JSON.parse(storedValue);
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
const listener = (e: StorageEvent) => {
|
||||
if (typeof window !== 'undefined' && e.storageArea === localStorage && e.key === key) {
|
||||
setValue(e.newValue ? JSON.parse(e.newValue) : e.newValue);
|
||||
}
|
||||
};
|
||||
window.addEventListener('storage', listener);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener('storage', listener);
|
||||
};
|
||||
}, [key, defaultValue]);
|
||||
|
||||
const setValueInLocalStorage = (newValue: ValueType) => {
|
||||
setValue((currentValue: never) => {
|
||||
const result = typeof newValue === 'function' ? newValue(currentValue) : newValue;
|
||||
if (typeof window !== 'undefined') localStorage.setItem(key, JSON.stringify(result));
|
||||
return result;
|
||||
});
|
||||
};
|
||||
|
||||
return [value, setValueInLocalStorage];
|
||||
}
|
42
src/hooks/usePagination.ts
Normal file
@ -0,0 +1,42 @@
|
||||
import { useState } from 'react';
|
||||
|
||||
// ==============================|| CARD - PAGINATION ||============================== //
|
||||
|
||||
export default function usePagination(data: any, itemsPerPage: number) {
|
||||
const [currentPage, setCurrentPage] = useState<number>(1);
|
||||
const maxPage = Math.ceil(data.length / itemsPerPage);
|
||||
|
||||
function currentData() {
|
||||
const begin = (currentPage - 1) * itemsPerPage;
|
||||
const end = begin + itemsPerPage;
|
||||
return data.slice(begin, end);
|
||||
}
|
||||
|
||||
function next() {
|
||||
setCurrentPage((currentPage: number) => Math.min(currentPage + 1, maxPage));
|
||||
}
|
||||
|
||||
function prev() {
|
||||
setCurrentPage((currentPage: number) => Math.max(currentPage - 1, 1));
|
||||
}
|
||||
|
||||
function jump(page: number) {
|
||||
const pageNumber = Math.max(1, page);
|
||||
setCurrentPage(() => Math.min(pageNumber, maxPage));
|
||||
}
|
||||
|
||||
return { next, prev, jump, currentData, currentPage, maxPage };
|
||||
}
|
||||
|
||||
export function getEmptyPageData<T>(){
|
||||
return {
|
||||
list: [1,2,3,4,5,6],
|
||||
pagination:{
|
||||
total: 0,
|
||||
pageSize: 0,
|
||||
current: 0,
|
||||
recordTotal: 0,
|
||||
}
|
||||
} as RecordList<T>
|
||||
|
||||
}
|
18
src/hooks/useScriptRef.ts
Normal file
@ -0,0 +1,18 @@
|
||||
import { useEffect, useRef } from 'react';
|
||||
|
||||
// ==============================|| ELEMENT REFERENCE HOOKS ||============================== //
|
||||
|
||||
const useScriptRef = () => {
|
||||
const scripted = useRef(true);
|
||||
|
||||
useEffect(
|
||||
() => () => {
|
||||
scripted.current = false;
|
||||
},
|
||||
[]
|
||||
);
|
||||
|
||||
return scripted;
|
||||
};
|
||||
|
||||
export default useScriptRef;
|
11
src/main.tsx
Normal file
@ -0,0 +1,11 @@
|
||||
import React from 'react'
|
||||
import ReactDOM from 'react-dom/client'
|
||||
|
||||
import App from './App.tsx'
|
||||
import '@/assets/index.scss'
|
||||
|
||||
ReactDOM.createRoot(document.getElementById('root')!).render(
|
||||
<React.StrictMode>
|
||||
<App/>
|
||||
</React.StrictMode>,
|
||||
)
|
75
src/pages/create/index.tsx
Normal file
@ -0,0 +1,75 @@
|
||||
import ArticleGroup from "@/components/article/group.tsx";
|
||||
import {Input, Modal} from "antd";
|
||||
import {useState} from "react";
|
||||
|
||||
|
||||
const GroupList: ArticleContentGroup[] = [
|
||||
{
|
||||
groupId: 1,
|
||||
blocks: [
|
||||
{
|
||||
type: "image",
|
||||
content: "//www.81.cn/yw_208727/_attachment/2024/11/21/16353257_1f06b18bee0ab586e4775aec26490544.jpg"
|
||||
},
|
||||
{
|
||||
type: "text",
|
||||
content: "新华社巴西利亚11月20日电(记者杨依军 周永穗)当地时间11月20日上午,国家主席习近平同巴西总统卢拉在巴西利亚总统官邸黎明宫会谈后共同会见记者。"
|
||||
},
|
||||
{
|
||||
type: "text",
|
||||
content: "习近平指出,这是我时隔5年再次踏上这片“充满爱和希望的土地”。启程前夕,我收到多封巴西各界友好人士的来信,信中洋溢着巴西人民对中巴友谊的珍视和对深化两国友好的期盼,令我深受感动。刚才,我同卢拉总统举行了亲切友好、富有成果的会谈。我们共同回顾中巴关系50年发展历程,一致认为两国关系正处于历史最好时期,日益彰显全球性、战略性、长远性影响,成为发展中大国携手共进、团结合作的典范。"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
groupId: 2,
|
||||
blocks: [
|
||||
{
|
||||
type: "image",
|
||||
content: "https://s3.cdnjson.com/images/2024/11/19/54419747-6fe5-4358-9fa8-d41d786e9f16.jpg"
|
||||
},
|
||||
{
|
||||
type: "text",
|
||||
content: "我们就中巴关系未来发展达成新的战略共识,其中最重要的是,我们共同决定将双边关系提升为携手构建更公正世界和更可持续星球的中巴命运共同体,同时将共建“一带一路”倡议同巴西发展战略对接。在世界格局加速演变的背景下,这体现了中巴两个发展中大国识变、应变、求变的决心,必将推动两国关系继往开来、开启下一个“黄金50年”,同时为全球南方国家团结自强树立榜样,为提升发展中国家在全球治理中的代表性和发言权作出新的贡献。"
|
||||
},
|
||||
{
|
||||
type: "text",
|
||||
content: "hello world"
|
||||
}
|
||||
]
|
||||
},
|
||||
]
|
||||
export default function CreateIndex() {
|
||||
const [visible, setVisible] = useState(true)
|
||||
const [groups, setGroups] = useState<ArticleContentGroup[]>(GroupList);
|
||||
return (<div>
|
||||
<h1>create index</h1>
|
||||
<Modal
|
||||
title={'编辑文章'}
|
||||
open={visible}
|
||||
maskClosable={false}
|
||||
keyboard={false}
|
||||
width={800}
|
||||
onCancel={() => setVisible(false)}
|
||||
>
|
||||
<div className="article-title mt-5">
|
||||
<div className="title">
|
||||
<span className="text text-base">标题</span>
|
||||
<span className="require ml-1 font-bold text-red-500">*</span>
|
||||
</div>
|
||||
<div className="box mt-1">
|
||||
<Input placeholder={'请输入文章标题'}/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="aricle-body mt-2">
|
||||
<div className="title">
|
||||
<span className="text text-base">正文</span>
|
||||
<span className="require ml-1 font-bold text-red-500">*</span>
|
||||
</div>
|
||||
<div className="box mt-1">
|
||||
<ArticleGroup groups={groups} onChange={list => setGroups(() => list)}/>
|
||||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
</div>)
|
||||
}
|
BIN
src/pages/library/components/cover.png
Normal file
After Width: | Height: | Size: 64 KiB |
59
src/pages/library/components/search-form.tsx
Normal file
@ -0,0 +1,59 @@
|
||||
import {Button, DatePicker, Form, Input, Select, Space} from "antd";
|
||||
import {useSetState} from "ahooks";
|
||||
import {ListTimes, NewsSources} from "@/pages/news/components/news-source.ts";
|
||||
import {useState} from "react";
|
||||
|
||||
type SearchParams = {
|
||||
keywords?: string;
|
||||
date?: string;
|
||||
}
|
||||
|
||||
type Props = {
|
||||
onSearch?: (params: SearchParams) => Promise<void>;
|
||||
onBtnStartClick?: () => Promise<void>;
|
||||
}
|
||||
export default function SearchForm({onSearch, onBtnStartClick}: Props) {
|
||||
const [state, setState] = useSetState<{
|
||||
timeRange: string;
|
||||
keywords: string;
|
||||
searching: boolean;
|
||||
}>({
|
||||
keywords: "", searching: false, timeRange: ""
|
||||
})
|
||||
// 二级分类
|
||||
const [subOptions, setSubOptions] = useState<OptionItem[]>([])
|
||||
const onFinish = (values: any) => {
|
||||
setState({searching: true})
|
||||
onSearch?.({
|
||||
keywords: values.keywords,
|
||||
date: values.timeRange.join('-'),
|
||||
}).finally(() => {
|
||||
setState({searching: false})
|
||||
})
|
||||
}
|
||||
|
||||
return (<div className={'search-panel'}>
|
||||
<div className="flex justify-end items-center">
|
||||
<div className="search-form">
|
||||
<Form className={""} layout="inline" onFinish={onFinish}>
|
||||
<Form.Item name="keywords">
|
||||
<Input placeholder={'请输入搜索信息'}/>
|
||||
</Form.Item>
|
||||
<Form.Item label={'更新时间'} name="timeRange">
|
||||
<DatePicker.RangePicker />
|
||||
</Form.Item>
|
||||
<Form.Item>
|
||||
<Space size={10}>
|
||||
<Button type={'primary'} htmlType={'submit'}>搜索</Button>
|
||||
<Button htmlType={'reset'}>重置</Button>
|
||||
</Space>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</div>
|
||||
<Space size={10}>
|
||||
<Button loading={state.searching} type={'primary'}
|
||||
onClick={onBtnStartClick}>一键推流</Button>
|
||||
</Space>
|
||||
</div>
|
||||
</div>)
|
||||
}
|
42
src/pages/library/components/video-detail.tsx
Normal file
@ -0,0 +1,42 @@
|
||||
import {Button, Modal} from "antd";
|
||||
|
||||
import {Player} from "@/components/video/player.tsx";
|
||||
|
||||
type Props = {
|
||||
video?: VideoInfo;
|
||||
onClose?: () => void
|
||||
}
|
||||
export default function VideoDetail({video, onClose}: Props) {
|
||||
const startStream = () => {
|
||||
}
|
||||
const downloadVideo = () => {
|
||||
}
|
||||
|
||||
return (<>
|
||||
<Modal open={!!video} title="新闻视频详情" width={900} footer={null}>
|
||||
<div className="flex gap-2 my-5">
|
||||
<div className="news-video w-[350px]">
|
||||
<div className="video-container bg-gray-100 rounded overflow-hidden">
|
||||
<Player url={'http://[2409:8087:74d9:21::6]:80/270000001128/9900000025/index.m3u8'} />
|
||||
</div>
|
||||
<div className="video-info text-right text-sm text-gray-600">
|
||||
<span>创建时间: 5小时前</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="detail">
|
||||
<div className="title"></div>
|
||||
<div className="content-container"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="footer flex justify-between">
|
||||
<div className="action flex gap-2">
|
||||
<Button type="primary" onClick={startStream}>一键推流</Button>
|
||||
<Button onClick={downloadVideo}>下载视频</Button>
|
||||
</div>
|
||||
<div className="close">
|
||||
<Button onClick={onClose}>关闭</Button>
|
||||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
</>)
|
||||
}
|
39
src/pages/library/components/video-item.tsx
Normal file
@ -0,0 +1,39 @@
|
||||
import {Checkbox, Image, Tag} from "antd";
|
||||
import {IconDelete} from "@/components/icons";
|
||||
import {useState} from "react";
|
||||
|
||||
|
||||
import ImageCover from './cover.png'
|
||||
|
||||
type VideoItemProps = {
|
||||
videoInfo: VideoInfo;
|
||||
onLive?: boolean;
|
||||
onClick?: () => void;
|
||||
onRemove?: () => void;
|
||||
}
|
||||
export default function VideoItem(props: VideoItemProps) {
|
||||
const [state, setState] = useState({
|
||||
checked: false
|
||||
})
|
||||
return <div className={'video-item bg-white p-2 rounded relative group'}>
|
||||
<div className={`controls absolute top-1 right-1 z-[2] p-1 rounded items-center gap-2 bg-white/80 ${state.checked?'flex':'hidden'} group-hover:flex`}>
|
||||
<span onClick={props.onRemove} className={'cursor-pointer text-blue-500 text-2xl cursor-pointer'}><IconDelete /></span>
|
||||
{!props.onLive && <Checkbox onChange={e=>setState({checked: e.target.checked})} />}
|
||||
</div>
|
||||
<div className="cover" onClick={props.onClick}>
|
||||
<Image className={'w-full rounded cursor-pointer'} preview={false} src={ImageCover}/>
|
||||
</div>
|
||||
<div className="text-sm">
|
||||
<div className="title my-1 cursor-pointer" onClick={props.onClick}>把丰碑立在人民心中</div>
|
||||
<div className="info flex justify-between gap-2 text-sm">
|
||||
<div className="video-time-info text-gray-500">
|
||||
<span>时长: 2年半</span>
|
||||
<span className="ml-1">16小时前</span>
|
||||
</div>
|
||||
{props.onLive && <div className="live-info">
|
||||
<Tag color="processing">已在直播间</Tag>
|
||||
</div>}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
48
src/pages/library/index.tsx
Normal file
@ -0,0 +1,48 @@
|
||||
import {useState} from "react";
|
||||
import {Modal, Pagination} from "antd";
|
||||
|
||||
import {getEmptyPageData} from "@/hooks/usePagination.ts"
|
||||
import VideoItem from "@/pages/library/components/video-item.tsx";
|
||||
import SearchForm from "@/pages/library/components/search-form.tsx";
|
||||
import VideoDetail from "@/pages/library/components/video-detail.tsx";
|
||||
|
||||
export default function LibraryIndex() {
|
||||
const [modal, contextHolder] = Modal.useModal();
|
||||
const [videoData,] = useState(getEmptyPageData<VideoInfo>())
|
||||
const handleRemove = (video: VideoInfo) => {
|
||||
modal.confirm({
|
||||
title: '删除提示',
|
||||
content: '是否要删除该视频',
|
||||
onOk: () => {
|
||||
console.log('OK', video);
|
||||
}
|
||||
})
|
||||
}
|
||||
const [detailVideo, setDetailVideo] = useState<VideoInfo>()
|
||||
|
||||
return (<>
|
||||
<div className={'container py-20'}>
|
||||
{contextHolder}
|
||||
<div className="search-form-container mb-5">
|
||||
<SearchForm onSearch={async () => {
|
||||
}}/>
|
||||
</div>
|
||||
<div>
|
||||
<div className={'video-list-container grid gap-5 grid-cols-4'}>
|
||||
{videoData.list.map((it, idx) => (
|
||||
<VideoItem
|
||||
onLive={idx == 2} key={it.id}
|
||||
videoInfo={it}
|
||||
onRemove={() => handleRemove(it)}
|
||||
onClick={() => setDetailVideo(it)}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
<div className="video-page-container flex justify-center mt-5">
|
||||
<Pagination defaultCurrent={1} total={50}/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<VideoDetail video={detailVideo} onClose={() => setDetailVideo(undefined)} />
|
||||
</>)
|
||||
}
|
122
src/pages/library/sort-demo.tsx
Normal file
@ -0,0 +1,122 @@
|
||||
import React, {useState} from 'react';
|
||||
import { restrictToVerticalAxis } from "@dnd-kit/modifiers";
|
||||
import {
|
||||
DndContext,
|
||||
closestCenter,
|
||||
KeyboardSensor,
|
||||
PointerSensor,
|
||||
useSensor,
|
||||
useSensors,
|
||||
} from '@dnd-kit/core';
|
||||
|
||||
import {
|
||||
useSortable, arrayMove,
|
||||
SortableContext,
|
||||
sortableKeyboardCoordinates,
|
||||
verticalListSortingStrategy,
|
||||
} from '@dnd-kit/sortable';
|
||||
|
||||
type TestData = {
|
||||
id: number;
|
||||
}
|
||||
type SortableItemProps = {
|
||||
data: TestData;
|
||||
active?: boolean;
|
||||
id: number;
|
||||
}
|
||||
|
||||
function SortableItem(props: SortableItemProps) {
|
||||
const {
|
||||
attributes,
|
||||
listeners,
|
||||
setNodeRef,
|
||||
transform,
|
||||
transition,
|
||||
} = useSortable({
|
||||
resizeObserverConfig: {},
|
||||
id: props.data.id
|
||||
});
|
||||
|
||||
return (
|
||||
<div ref={setNodeRef} style={{
|
||||
transform: `translateY(${transform ? transform?.y:0}px)`,
|
||||
transition,
|
||||
// marginTop:10,
|
||||
// marginBottom:10
|
||||
}} className={props.active ? 'drop-shadow shadow-blue-400 drop-shadow-md' : ''}>
|
||||
<div className="h-[100px] mb-5 border p-5 rounded bg-white flex justify-between items-center">
|
||||
<div className="flex-1">
|
||||
<div>
|
||||
{JSON.stringify(props.data)}
|
||||
</div>
|
||||
<div>{JSON.stringify(transform)}</div>
|
||||
</div>
|
||||
<button {...attributes} {...listeners} className="cursor-move">Move</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export function SortDemo() {
|
||||
const [items, setItems] = useState<TestData[]>([
|
||||
{id: 1},
|
||||
{id: 2},
|
||||
{id: 3},
|
||||
{id: 4},
|
||||
{id: 5},
|
||||
]);
|
||||
const [activeId, setActiveId] = useState<number>();
|
||||
|
||||
function handleDragEnd(event) {
|
||||
const {active, over} = event;
|
||||
setActiveId(undefined)
|
||||
console.log(JSON.stringify({
|
||||
items,
|
||||
active: active.id,
|
||||
over: over.id,
|
||||
}))
|
||||
if (active.id !== over.id) {
|
||||
setItems((items) => {
|
||||
const oldIndex = items.findIndex(s=>s.id == active.id);
|
||||
const newIndex = items.findIndex(s=>s.id == over.id);
|
||||
const _newArr = arrayMove(items, oldIndex, newIndex);
|
||||
console.log(JSON.stringify({
|
||||
_newArr,
|
||||
items,
|
||||
oldIndex,
|
||||
newIndex
|
||||
}))
|
||||
return _newArr;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// const sensors = useSensors(
|
||||
// useSensor(PointerSensor),
|
||||
// useSensor(KeyboardSensor, {
|
||||
// coordinateGetter: sortableKeyboardCoordinates,
|
||||
// })
|
||||
// );
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div>{JSON.stringify(items)}</div>
|
||||
<DndContext
|
||||
modifiers={[restrictToVerticalAxis]}
|
||||
onDragEnd={handleDragEnd}
|
||||
onDragStart={e => {
|
||||
if (e.active && e.active.id) {
|
||||
setActiveId(Number(e.active.id))
|
||||
}
|
||||
}}
|
||||
>
|
||||
<SortableContext
|
||||
items={items}
|
||||
>
|
||||
{items.map(it => <SortableItem active={it.id == activeId} key={it.id} data={it} id={it.id}/>)}
|
||||
</SortableContext>
|
||||
</DndContext>
|
||||
</div>
|
||||
);
|
||||
|
||||
}
|
182
src/pages/live/index.tsx
Normal file
@ -0,0 +1,182 @@
|
||||
import React, {useEffect, useRef, useState} from "react";
|
||||
import {Modal} from "antd";
|
||||
import {MenuOutlined, MinusCircleFilled, CheckCircleFilled} from "@ant-design/icons";
|
||||
import {useSetState} from "ahooks";
|
||||
import {clsx} from "clsx";
|
||||
import {SortableContext, useSortable,arrayMove} from '@dnd-kit/sortable';
|
||||
import {DndContext} from "@dnd-kit/core";
|
||||
|
||||
import {IconPlay} from "@/components/icons";
|
||||
|
||||
const VideoInfoItem = ({index,id, video, onPlay, onRemove, checked, onCheckedChange}: {
|
||||
video: VideoInfo,
|
||||
index?: number;
|
||||
checked?: boolean;
|
||||
onCheckedChange?: (checked: boolean) => void;
|
||||
onPlay?: () => void;
|
||||
onRemove?: () => void;
|
||||
id:number;
|
||||
}) => {
|
||||
const {
|
||||
attributes, listeners,
|
||||
setNodeRef, transform
|
||||
} = useSortable({resizeObserverConfig: {}, id})
|
||||
|
||||
|
||||
const [state, setState] = useSetState({
|
||||
checked: false
|
||||
})
|
||||
useEffect(() => {
|
||||
setState({checked})
|
||||
}, [checked])
|
||||
|
||||
return <div
|
||||
className={'video-item flex items-center gap-3 mb-5'}
|
||||
ref={setNodeRef} style={{transform: `translateY(${transform?.y || 0}px)`,}}>
|
||||
{index && index > 0 && <div className="flex items-center px-2">
|
||||
<div
|
||||
className="index-value w-[40px] h-[40px] flex items-center justify-center bg-gray-100 rounded-3xl">{id}</div>
|
||||
</div>}
|
||||
<div className={'video-item-info flex gap-2 flex-1 bg-gray-100 min-h-[40px] rounded-lg p-3'}>
|
||||
<div className={'video-title leading-7 flex-1'}>{video.id} - {video.title}</div>
|
||||
<div className={'video-item-cover'}>
|
||||
<img className="w-[100px] rounded-md" src={video.cover} alt={video.title}/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="operation flex items-center gap-3 text-lg text-gray-400">
|
||||
<button className="hover:text-blue-500" {...attributes} {...listeners}>
|
||||
<MenuOutlined/>
|
||||
</button>
|
||||
{onPlay && <button className="hover:text-blue-500" onClick={onPlay} style={{fontSize: '1.3em'}}><IconPlay/>
|
||||
</button>}
|
||||
<button className="hover:text-blue-300" onClick={() => {
|
||||
if (onCheckedChange) {
|
||||
onCheckedChange(!state.checked)
|
||||
} else {
|
||||
setState({checked: !state.checked})
|
||||
}
|
||||
}}><CheckCircleFilled className={clsx({'text-blue-500': state.checked})}/></button>
|
||||
{onRemove && <button className="hover:text-blue-500" onClick={onRemove}><MinusCircleFilled/></button>}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
export default function LiveIndex() {
|
||||
const [videoData, setVideoData] = useState<VideoInfo[]>([
|
||||
{
|
||||
id: 1,
|
||||
title: '习近平出席巴西总统卢拉举行的欢迎宴会',
|
||||
cover: '//www.81.cn/syjdt/_attachment/2024/11/21/16353279_e74ba3ed3897343b03ecee69dd0e2c19.jpg',
|
||||
duration: 100,
|
||||
width: 100,
|
||||
height: 100,
|
||||
play_url: 'https://reflect.app/home/build/q-c3d7becf.webm',
|
||||
description: '1',
|
||||
tags: ['1'],
|
||||
create_time: 1732187665,
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: '习近平向2024年世界互联网大会乌镇峰会开幕视频致贺 指明方向凝聚共识',
|
||||
cover: '//www.81.cn/syjdt/_attachment/2024/11/21/16353279_e74ba3ed3897343b03ecee69dd0e2c19.jpg',
|
||||
duration: 100,
|
||||
width: 100,
|
||||
height: 100,
|
||||
play_url: 'https://file.wx.wm-app.xyz/os/media/ymca.mp4',
|
||||
description: '1',
|
||||
tags: ['1'],
|
||||
create_time: 1732187665,
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
title: '中华人民共和国和巴西联邦共和国关于携手构建更公正世界和更可持续星球的中巴命运共同体的联合声明',
|
||||
cover: '//www.81.cn/syjdt/_attachment/2024/11/21/16353279_e74ba3ed3897343b03ecee69dd0e2c19.jpg',
|
||||
duration: 100,
|
||||
width: 100,
|
||||
height: 100,
|
||||
play_url: 'https://reflect.app/home/build/q-c3d7becf.webm',
|
||||
description: '1',
|
||||
tags: ['1'],
|
||||
create_time: 1732187665,
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
title: '中华人民共和国和巴西联邦共和国关于携手构建更公正世界和更可持续星球的中巴命运共同体的联合声明',
|
||||
cover: '//www.81.cn/syjdt/_attachment/2024/11/21/16353279_e74ba3ed3897343b03ecee69dd0e2c19.jpg',
|
||||
duration: 100,
|
||||
width: 100,
|
||||
height: 100,
|
||||
play_url: 'https://file.wx.wm-app.xyz/os/media/ymca.mp4',
|
||||
description: '1',
|
||||
tags: ['1'],
|
||||
create_time: 1732187665,
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
title: '中华人民共和国和巴西联邦共和国关于携手构建更公正世界和更可持续星球的中巴命运共同体的联合声明',
|
||||
cover: '//www.81.cn/syjdt/_attachment/2024/11/21/16353279_e74ba3ed3897343b03ecee69dd0e2c19.jpg',
|
||||
duration: 100,
|
||||
width: 100,
|
||||
height: 100,
|
||||
play_url: 'https://reflect.app/home/build/q-c3d7becf.webm',
|
||||
description: '1',
|
||||
tags: ['1'],
|
||||
create_time: 1732187665,
|
||||
}
|
||||
])
|
||||
const [modal, contextHolder] = Modal.useModal()
|
||||
const videoRef = useRef<HTMLVideoElement | null>(null)
|
||||
const playVideo = (video: VideoInfo) => {
|
||||
console.log('play',video)
|
||||
if (videoRef.current) {
|
||||
videoRef.current!.src = video.play_url
|
||||
}
|
||||
}
|
||||
|
||||
return (<div className="container py-10 page-live">
|
||||
{contextHolder}
|
||||
<div className="flex">
|
||||
<div className="video-list-container bg-white p-10 rounded flex-1">
|
||||
<DndContext onDragEnd={(e) => {
|
||||
const {active, over} = e;
|
||||
if (over && active.id !== over.id) {
|
||||
let oldIndex = -1, newIndex = -1;
|
||||
const originArr = [...videoData]
|
||||
setVideoData((items) => {
|
||||
oldIndex = items.findIndex(s => s.id == active.id);
|
||||
newIndex = items.findIndex(s => s.id == over.id);
|
||||
return arrayMove(items, oldIndex, newIndex);
|
||||
});
|
||||
modal.confirm({
|
||||
title: '提示',
|
||||
content: '是否要移动到指定位置',
|
||||
onCancel: () => {
|
||||
setVideoData(originArr);
|
||||
}
|
||||
})
|
||||
}
|
||||
}}>
|
||||
<SortableContext items={videoData}>
|
||||
{videoData.map((v, index) => (
|
||||
<VideoInfoItem
|
||||
video={v}
|
||||
index={index + 1}
|
||||
id={v.id}
|
||||
key={index}
|
||||
onPlay={() => playVideo(v)}
|
||||
onRemove={() => {
|
||||
}}
|
||||
/>))}
|
||||
</SortableContext>
|
||||
</DndContext>
|
||||
</div>
|
||||
<div className="video-player-container ml-5 w-[300px] flex flex-col">
|
||||
<div className="text-center text-base">预览视频</div>
|
||||
<div className="video-player flex items-center justify-center flex-1">
|
||||
<div className="bg-white rounded overflow-hidden">
|
||||
<video ref={videoRef} autoPlay className="w-full"></video>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>)
|
||||
}
|
180
src/pages/news/components/news-source.ts
Normal file
@ -0,0 +1,180 @@
|
||||
|
||||
/*
|
||||
人民日报客户端
|
||||
环球时报客户端
|
||||
新华社客户端
|
||||
央视新闻客户端
|
||||
解放军报客户端
|
||||
澎湃新闻
|
||||
海客新闻客户端
|
||||
中新经纬客户端
|
||||
央视体育客户端
|
||||
参考消息客户端
|
||||
百姓关注
|
||||
大象新闻
|
||||
四川观察
|
||||
新京报
|
||||
北京日报
|
||||
中国纪检监察报
|
||||
腾讯网
|
||||
红网
|
||||
新湖南客户端
|
||||
晨视频客户端
|
||||
中国气象局
|
||||
中国政府网
|
||||
最高人民检察院
|
||||
中央纪委国家监委
|
||||
国家应急管理部
|
||||
中国外交部
|
||||
中华人民共和国最高人民法院
|
||||
中国人民银行
|
||||
中国商务部
|
||||
|
||||
*/
|
||||
export const NewsSources:OptionItem[] = [
|
||||
{
|
||||
label: '全部',
|
||||
value: 'all',
|
||||
},
|
||||
{
|
||||
label: '人民日报',
|
||||
value: 'people',
|
||||
children: [
|
||||
{
|
||||
label: '要闻',
|
||||
value: 'important'
|
||||
},
|
||||
{
|
||||
label: '国际',
|
||||
value: 'international'
|
||||
},
|
||||
{
|
||||
label: '国内',
|
||||
value: 'domestic'
|
||||
},
|
||||
{
|
||||
label: '社会',
|
||||
value: 'society'
|
||||
},
|
||||
{
|
||||
label: '娱乐',
|
||||
value: 'entertainment'
|
||||
},
|
||||
{
|
||||
label: '军事',
|
||||
value: 'military'
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
label: '环球时报',
|
||||
value: 'global'
|
||||
},
|
||||
{
|
||||
label: '新华社',
|
||||
value: 'xh-net'
|
||||
},
|
||||
{
|
||||
label: '央视新闻',
|
||||
value: 'cctv'
|
||||
},
|
||||
{
|
||||
label: '解放军报',
|
||||
value: '81'
|
||||
},
|
||||
{
|
||||
label: '澎湃新闻',
|
||||
value: 'the-paper'
|
||||
},
|
||||
{
|
||||
label: '海客新闻',
|
||||
value: 'haike'
|
||||
},
|
||||
{
|
||||
label: '中新经纬',
|
||||
value: 'zxjw'
|
||||
},
|
||||
{
|
||||
label: '央视体育',
|
||||
value: 'cctv-sports'
|
||||
},
|
||||
{
|
||||
label: '参考消息',
|
||||
value: 'can-kao'
|
||||
},
|
||||
{
|
||||
label: '百姓关注',
|
||||
value: 'baixin'
|
||||
},
|
||||
{
|
||||
label: '大象新闻',
|
||||
value: 'dx-news'
|
||||
},
|
||||
{
|
||||
label: '四川观察',
|
||||
value: 'sc-news'
|
||||
},
|
||||
{
|
||||
label: '新京报',
|
||||
value: 'xjb'
|
||||
},
|
||||
{
|
||||
label: '北京日报',
|
||||
value: 'bjrb'
|
||||
},
|
||||
{
|
||||
label: '中国纪检监察报',
|
||||
value: 'jx-news'
|
||||
},
|
||||
{
|
||||
label: '腾讯网',
|
||||
value: 'qq'
|
||||
},
|
||||
{
|
||||
label: '红网',
|
||||
value: 'hong-news'
|
||||
},
|
||||
{
|
||||
label: '新湖南客户端',
|
||||
value: 'xhn'
|
||||
},
|
||||
{
|
||||
label: '晨视频客户端',
|
||||
value: 'chen-video'
|
||||
},
|
||||
]
|
||||
|
||||
export const ListTimes = [
|
||||
{
|
||||
label: '半小时',
|
||||
value: '30'
|
||||
},
|
||||
{
|
||||
label: '一小时',
|
||||
value: '60'
|
||||
},
|
||||
{
|
||||
label: '两小时',
|
||||
value: '120'
|
||||
},
|
||||
{
|
||||
label: '四小时',
|
||||
value: '240'
|
||||
},
|
||||
{
|
||||
label: '近一天',
|
||||
value: '1440'
|
||||
},
|
||||
{
|
||||
label: '近一周',
|
||||
value: '10080'
|
||||
},
|
||||
{
|
||||
label: '近一月',
|
||||
value: '43800'
|
||||
},
|
||||
{
|
||||
label: '全部',
|
||||
value: '-1'
|
||||
}
|
||||
]
|
112
src/pages/news/components/search-panel.tsx
Normal file
@ -0,0 +1,112 @@
|
||||
import {Button, Form, Input, Select, Space} from "antd";
|
||||
import {useSetState} from "ahooks";
|
||||
import {ListTimes, NewsSources} from "@/pages/news/components/news-source.ts";
|
||||
import {useState} from "react";
|
||||
|
||||
type SearchParams = {
|
||||
search: string;
|
||||
date: string;
|
||||
source: string;
|
||||
}
|
||||
|
||||
type SearchPanelProps = {
|
||||
onSearch?: (params: SearchParams) => Promise<void>;
|
||||
onVideoCreateClick?: () => Promise<void> | void;
|
||||
onVideoDownloadClick?: () => Promise<void>;
|
||||
}
|
||||
export default function SearchPanel({onSearch, onVideoCreateClick, onVideoDownloadClick}: SearchPanelProps) {
|
||||
const [state, setState] = useSetState<{
|
||||
time: string;
|
||||
source: string;
|
||||
searching: boolean;
|
||||
subOptions: string[]
|
||||
}>({
|
||||
time: '-1',
|
||||
source: 'all',
|
||||
searching: false,
|
||||
subOptions: []
|
||||
})
|
||||
// 二级分类
|
||||
const [subOptions, setSubOptions] = useState<OptionItem[]>([])
|
||||
const onFinish = (values: any) => {
|
||||
setState({searching: true})
|
||||
onSearch?.({
|
||||
search: values.search,
|
||||
date: values.date.join('-'),
|
||||
source: state.source
|
||||
}).finally(() => {
|
||||
setState({searching: false})
|
||||
})
|
||||
}
|
||||
|
||||
return (<div className={'search-panel'}>
|
||||
<div className="flex justify-between items-center">
|
||||
<div className="search-form">
|
||||
<Form className={""} layout="inline" onFinish={onFinish}>
|
||||
<Form.Item name="search">
|
||||
<Input placeholder={'请输入搜索信息'}/>
|
||||
</Form.Item>
|
||||
<Form.Item label={'更新时间'} name="date" className="w-[220px]">
|
||||
<Select
|
||||
defaultValue={state.time} options={ListTimes}
|
||||
optionRender={(option) => (
|
||||
<div className="flex items-center">
|
||||
<span role="icon" className={`radio-icon`}></span>
|
||||
<span role="listitem" aria-label={String(option.label)}>{option.label}</span>
|
||||
</div>
|
||||
)}
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item>
|
||||
<Space size={10}>
|
||||
<Button type={'primary'} htmlType={'submit'}>搜索</Button>
|
||||
<Button htmlType={'reset'}>重置</Button>
|
||||
</Space>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</div>
|
||||
<Space size={10}>
|
||||
<Button loading={state.searching} type={'primary'}
|
||||
onClick={onVideoCreateClick}>推入视频生成界面</Button>
|
||||
<Button onClick={onVideoDownloadClick}>下载</Button>
|
||||
</Space>
|
||||
</div>
|
||||
<div className="filter-container flex items-start mt-5">
|
||||
<div className={'mt-2.5'}>新闻来源:</div>
|
||||
<div className="list-container flex-1">
|
||||
<div className="news-source-lv-1 flex flex-wrap">
|
||||
{
|
||||
NewsSources.map(it => (
|
||||
<div
|
||||
className={`filter-item whitespace-nowrap px-2 py-1 mt-1 text-sm mr-1 cursor-pointer rounded ${state.source == it.value ? 'bg-blue-500 text-white' : 'hover:bg-gray-100'}`}
|
||||
key={it.value}
|
||||
onClick={() => {
|
||||
setState({source: it.value,subOptions:[]})
|
||||
setSubOptions(it.children||[])
|
||||
}}>{it.label}</div>)
|
||||
)
|
||||
}
|
||||
</div>
|
||||
{subOptions.length > 0 && <div className="news-source-lv-2 bg-gray-100 p-2 rounded mt-2 flex flex-wrap">
|
||||
{
|
||||
subOptions.map(it => (
|
||||
<div
|
||||
className={`filter-item whitespace-nowrap px-2 py-1 mt-1 text-sm mr-1 cursor-pointer rounded ${state.subOptions.includes(it.value)? 'bg-blue-500 text-white' : 'hover:bg-gray-100'}`}
|
||||
key={it.value}
|
||||
onClick={() => {
|
||||
const options = [...state.subOptions]
|
||||
if (options.includes(it.value)) {
|
||||
options.splice(options.indexOf(it.value), 1)
|
||||
} else {
|
||||
options.push(it.value)
|
||||
}
|
||||
setState({subOptions:options})
|
||||
}}>{it.label}</div>)
|
||||
)
|
||||
}
|
||||
</div>}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>)
|
||||
}
|
152
src/pages/news/edit.tsx
Normal file
@ -0,0 +1,152 @@
|
||||
import {Button, Input, Select, Table, TableColumnsType, TableProps} from "antd";
|
||||
import {SearchOutlined} from "@ant-design/icons";
|
||||
import {Card} from "@/components/card";
|
||||
import React from "react";
|
||||
import {NewsSources} from "@/pages/news/components/news-source.ts";
|
||||
import {useRequest, useSetState} from "ahooks";
|
||||
import {formatTime} from "@/util/strings.ts";
|
||||
|
||||
|
||||
const columns: TableColumnsType<NewsInfo> = [
|
||||
{
|
||||
title: '标题',
|
||||
dataIndex: 'title',
|
||||
// render: (text: string) => <a>{text}</a>,
|
||||
},
|
||||
{
|
||||
title: '内容',
|
||||
dataIndex: 'content',
|
||||
},
|
||||
{
|
||||
title: '来源',
|
||||
dataIndex: 'source',
|
||||
},
|
||||
{
|
||||
title: '时间',
|
||||
dataIndex: 'time',
|
||||
render: (_, record) => {
|
||||
return formatTime(record.time, 'YYYY-MM-DD HH:mm')
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
align: 'center',
|
||||
render: () => (<Button type="link">编辑</Button>),
|
||||
},
|
||||
];
|
||||
|
||||
const dataList: NewsInfo[] = [
|
||||
{
|
||||
id: 1,
|
||||
title: '习近平抵达巴西利亚开始对巴西进行国事访问',
|
||||
content: '当地时间11月19日下午,国家主席习近平乘专机抵达巴西利亚,开始对巴西进行国事访问。',
|
||||
source: '环球时报',
|
||||
time: 1732333214,
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: '习近平向2024年世界互联网大会乌镇峰会开幕视频致贺',
|
||||
content: '新华社北京11月20日电 11月20日,国家主席习近平向2024年世界互联网大会乌镇峰会开幕视频致贺。',
|
||||
source: '环球时报',
|
||||
time: 1732333214,
|
||||
}
|
||||
];
|
||||
// rowSelection object indicates the need for row selection
|
||||
const rowSelection: TableProps<NewsInfo>['rowSelection'] = {
|
||||
onChange: (selectedRowKeys: React.Key[], selectedRows: NewsInfo[]) => {
|
||||
console.log(`selectedRowKeys: ${selectedRowKeys}`, 'selectedRows: ', selectedRows);
|
||||
},
|
||||
getCheckboxProps: (record: NewsInfo) => ({
|
||||
name: record.title,
|
||||
}),
|
||||
};
|
||||
|
||||
export default function NewEdit() {
|
||||
const [state, setState] = useSetState({
|
||||
source: NewsSources.map(s => s.value),
|
||||
search: '',
|
||||
page: 1
|
||||
})
|
||||
const {data} = useRequest(async () => {
|
||||
return [...dataList]
|
||||
}, {
|
||||
refreshDeps: [state]
|
||||
})
|
||||
|
||||
const handleSelectChange = (values: string[]) => {
|
||||
if (values.length == 0) {
|
||||
setState({source: []})
|
||||
return;
|
||||
}
|
||||
const lastValue = values[values.length - 1];
|
||||
const source = NewsSources.map(s => s.value) || [];
|
||||
const isChecked = values.length > state.source.length; // 是选中还是取消选中
|
||||
if (lastValue == 'all') {
|
||||
setState({source})
|
||||
} else if (isChecked && values.length == source.length - 1 && !values.includes('all')) { // 除全部之外已经都选了 则直接勾选所有
|
||||
setState({source})
|
||||
} else {
|
||||
const diffValues = state.source.filter(s => !values.includes(s));
|
||||
// 取消的是全部 则取消所有勾选
|
||||
if (state.source.length > 0 && state.source.length > values.length && diffValues.includes('all')) {
|
||||
setState({source: []})
|
||||
return;
|
||||
}
|
||||
setState({source: values.filter(s => s != 'all')})
|
||||
}
|
||||
}
|
||||
return (<div className="container pb-5 news-edit">
|
||||
<Card className="search-panel-container my-5">
|
||||
<div className="search-form flex gap-5 justify-between">
|
||||
<div className="search-form-input flex gap-2 items-center">
|
||||
<Input
|
||||
onPressEnter={(e) => {
|
||||
setState({search: e.target.value})
|
||||
}}
|
||||
type="text" className="rounded px-3 w-[220px]"
|
||||
suffix={<SearchOutlined/>}
|
||||
placeholder="请输入你先搜索的关键词"
|
||||
/>
|
||||
<span className="ml-5 text-sm">来源</span>
|
||||
<Select
|
||||
value={state.source} className="min-w-[300px] select-no-wrap select-hide-checked max-w-[300px] "
|
||||
options={NewsSources} popupClassName="select-hide-checked"
|
||||
mode="multiple" showSearch={false}
|
||||
onChange={handleSelectChange}
|
||||
placeholder="请选择你要筛选的新闻"
|
||||
optionRender={(option) => (
|
||||
<div className="flex items-center">
|
||||
<span role="icon" className={`checkbox-icon`}></span>
|
||||
<span role="listitem" aria-label={String(option.label)}>{option.label}</span>
|
||||
</div>
|
||||
)}
|
||||
labelRender={(props) => {
|
||||
if (props.value == 'all') return <span>全部</span>
|
||||
|
||||
return <span>{props.label}</span>
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<Button type="primary">手动新增</Button>
|
||||
</div>
|
||||
<div className="news-list-container mt-5">
|
||||
<Table<NewsInfo>
|
||||
rowSelection={{type: 'checkbox', ...rowSelection}}
|
||||
columns={columns}
|
||||
dataSource={data as any}
|
||||
rowKey={'id'}
|
||||
pagination={{
|
||||
position: ['bottomLeft'],
|
||||
simple: true,
|
||||
defaultCurrent:1,
|
||||
total:5000004,
|
||||
pageSize:20,
|
||||
showSizeChanger:false,
|
||||
rootClassName:'simple-pagination',
|
||||
onChange: (page)=>setState({page})
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</Card>
|
||||
</div>)
|
||||
}
|
79
src/pages/news/index.tsx
Normal file
@ -0,0 +1,79 @@
|
||||
import {useState} from "react";
|
||||
import {Checkbox, Modal, Pagination} from "antd";
|
||||
|
||||
import {Card} from "@/components/card";
|
||||
import SearchPanel from "@/pages/news/components/search-panel.tsx";
|
||||
|
||||
import styles from './style.module.scss'
|
||||
|
||||
export default function NewsIndex() {
|
||||
const [list,] = useState([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
|
||||
const [activeNews, setActiveNews] = useState<NewsInfo>()
|
||||
return (<div className={'container pb-5'}>
|
||||
<Card className="search-panel-container my-5">
|
||||
<SearchPanel/>
|
||||
</Card>
|
||||
<Card className="news-list-container">
|
||||
<Modal open={!!activeNews} width={1000} footer={null} onCancel={() => setActiveNews(undefined)}>
|
||||
<div className="news-detail px-3 pb-5">
|
||||
<div className="new-title text-2xl">{activeNews?.title}</div>
|
||||
<div className="info mt-2 mb-5 text-sm flex gap-3">
|
||||
<span className="source">
|
||||
<a className="text-blue-700 hover:underline"
|
||||
href="https://www.peopleapp.com/column/30047416072-500005929952"
|
||||
target="_blank">人民日报客户端</a>
|
||||
</span>
|
||||
<span className="create-time text-gray-400">2024-11-20 11:11:11</span>
|
||||
</div>
|
||||
<div className="overflow-auto leading-7 text-base" style={{maxHeight: 1000}}>
|
||||
<p>当地时间11月19日下午,国家主席习近平乘专机抵达巴西利亚,开始对巴西进行国事访问。</p>
|
||||
<p>专机抵达巴西利亚空军基地时,巴西总统府首席部长科斯塔、巴西利亚空军基地司令米格尔、司法部长莱万多夫斯基、总统府机构关系部长帕迪利亚等高级官员在机场热情迎接,代表卢拉总统和巴西政府热烈欢迎习近平主席到访。</p>
|
||||
<p>几十名巴塔拉艺术家演奏热情奔放的巴西特色鼓乐。</p>
|
||||
<p>蔡奇、王毅等陪同人员同机抵达。</p>
|
||||
<p>习近平乘车从机场赴下榻饭店途中,当地华侨华人、中资机构和留学生代表在道路旁挥舞中巴两国国旗,高举“欢迎习近平主席访问巴西”“中巴友谊万岁!”等红色横幅,热烈欢迎习近平到访。</p>
|
||||
<p>习近平是在结束二十国集团领导人第十九次峰会活动后离开里约热内卢抵达巴西利亚的。</p>
|
||||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
<div className={styles.newsList}>
|
||||
{list.map(id => (
|
||||
<div key={id} className={`py-3 flex items-start border-b border-gray-100 group`}>
|
||||
<div className="checkbox mr-2 opacity-0 group-hover:opacity-100">
|
||||
<Checkbox/>
|
||||
</div>
|
||||
<div className="news-content">
|
||||
<div className="title text-lg cursor-pointer" onClick={() => {
|
||||
setActiveNews({
|
||||
id: 1,
|
||||
title: '习近平抵达巴西利亚开始对巴西进行国事访问',
|
||||
content: '', cover: "", source: "", time: ""
|
||||
})
|
||||
}}>习近平抵达巴西利亚开始对巴西进行国事访问
|
||||
</div>
|
||||
<div className="content flex gap-3 mt-2 mb-3">
|
||||
<div className="cover border border-gray-100 flex items-center rounded overflow-hidden"
|
||||
style={{width: 100, height: 100}}>
|
||||
<img className="w-full h-full object-cover"
|
||||
src={'https://file.wx.wm-app.xyz/os/picture/20241119160600.png'}/>
|
||||
</div>
|
||||
<div className="text text-gray-600 text-sm leading-6 flex-1 text-justify">
|
||||
当地时间11月19日下午,国家主席习近平乘专机抵达巴西利亚,开始对巴西进行国事访问。<br/>
|
||||
专机抵达巴西利亚空军基地时,巴西总统府首席部长科斯塔、巴西利亚空军基地司令米格尔、司法部长莱万多夫斯基、总统府机构关系部长帕迪利亚等高级官员在机场热情迎接,代表卢拉总统和巴西政府热烈欢迎习近平主席到访。
|
||||
</div>
|
||||
</div>
|
||||
<div className="info text-gray-300 flex items-center gap-3 text-sm">
|
||||
<div>来源: <span>新华社</span></div>
|
||||
{/*<Divider type="vertical" />*/}
|
||||
<div>发布时间: <span>2024-11-18 10:10:12</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="flex justify-center mt-10">
|
||||
<Pagination defaultCurrent={1} total={50}/>
|
||||
</div>
|
||||
</Card>
|
||||
</div>)
|
||||
}
|
3
src/pages/news/style.module.scss
Normal file
@ -0,0 +1,3 @@
|
||||
.newsList{
|
||||
|
||||
}
|
90
src/pages/user/components/form-login.tsx
Normal file
@ -0,0 +1,90 @@
|
||||
import {useState} from "react";
|
||||
import {useNavigate, useSearchParams} from "react-router-dom";
|
||||
import type {FormProps} from 'antd';
|
||||
import {LockOutlined, UserOutlined} from '@ant-design/icons';
|
||||
import {Button, Checkbox, Flex, Form, Input} from 'antd';
|
||||
import {clsx} from "clsx";
|
||||
|
||||
import useAuth from "@/hooks/useAuth.ts";
|
||||
import {useSmsCode} from "@/components/form/sms-code.tsx";
|
||||
|
||||
type FieldType = {
|
||||
username?: string;
|
||||
password?: string;
|
||||
};
|
||||
|
||||
|
||||
export default function FormLogin() {
|
||||
const [disabled, setDisabled] = useState(true)
|
||||
const [error, setError] = useState<string>()
|
||||
const {login} = useAuth();
|
||||
const navigate = useNavigate()
|
||||
const [params] = useSearchParams()
|
||||
const [phone, setPhone] = useState<string>()
|
||||
const {sending, countdown, sendCode} = useSmsCode()
|
||||
const onFinish: FormProps<FieldType>['onFinish'] = (values) => {
|
||||
if (values.username != 'admin') {
|
||||
setError('账号或密码错误')
|
||||
return
|
||||
}
|
||||
login(values.username, values.password!).then(() => {
|
||||
navigate(params.get('from') || '/')
|
||||
}).catch(e => {
|
||||
setError(e.message)
|
||||
});
|
||||
};
|
||||
|
||||
return (<div className="form">
|
||||
<h1 className={'text-center text-2xl pb-10 pt-4'}>欢迎登录</h1>
|
||||
<Form<FieldType>
|
||||
name="basic"
|
||||
style={{maxWidth: 600}}
|
||||
initialValues={{remember: true}}
|
||||
onFinish={onFinish}
|
||||
onValuesChange={(_, values) => {
|
||||
setError(undefined)
|
||||
setPhone(values.username)
|
||||
setDisabled(!values.username || !values.password)
|
||||
}}
|
||||
autoComplete="off"
|
||||
>
|
||||
<Form.Item<FieldType> name="username">
|
||||
<div
|
||||
className="border border-gray-300 rounded-3xl mt-2 flex items-center px-3 focus-within:border-blue-500 focus-within:shadow focus-within:shadow-blue-200">
|
||||
<UserOutlined/>
|
||||
<Input size={'large'} variant={'borderless'} placeholder="请输入账号" />
|
||||
</div>
|
||||
</Form.Item>
|
||||
<Form.Item name="password">
|
||||
|
||||
<div
|
||||
className="border border-gray-300 rounded-3xl mt-2 flex items-center px-3 focus-within:border-blue-500 focus-within:shadow focus-within:shadow-blue-200">
|
||||
<LockOutlined/>
|
||||
<Input style={{borderRadius: 20}} size={'large'} variant={'borderless'}
|
||||
placeholder="请输入验证码"/>
|
||||
<span
|
||||
className={clsx(`text-nowrap text-sm ${countdown > 0 || sending || !phone ? 'text-gray-400 cursor-not-allowed' : 'text-blue-500 cursor-pointer'}`)}
|
||||
onClick={() => sendCode(phone)}>
|
||||
{sending ? '发送中...' : (countdown > 0 ? `${Math.ceil(countdown / 1000)} s` : '获取验证码')}
|
||||
</span>
|
||||
</div>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item>
|
||||
<div className="absolute text-red-500 text-center inset-x-0" style={{top: -20}}>{error}</div>
|
||||
<Flex justify="space-between" align="center">
|
||||
<Form.Item name="remember" valuePropName="checked" noStyle>
|
||||
<Checkbox>记住密码</Checkbox>
|
||||
</Form.Item>
|
||||
<a href="">忘记密码</a>
|
||||
</Flex>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item>
|
||||
<Button disabled={disabled} type="primary" size={'large'} htmlType="submit" block shape={'round'}>
|
||||
立即登录
|
||||
</Button>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</div>)
|
||||
}
|
10
src/pages/user/index.tsx
Normal file
@ -0,0 +1,10 @@
|
||||
import styles from './style.module.scss'
|
||||
import FormLogin from "./components/form-login.tsx";
|
||||
|
||||
export default function UserIndex(){
|
||||
return (<div className={styles.main}>
|
||||
<div className={styles.boxLogin}>
|
||||
<FormLogin />
|
||||
</div>
|
||||
</div>)
|
||||
}
|
27
src/pages/user/style.module.scss
Normal file
@ -0,0 +1,27 @@
|
||||
.main {
|
||||
@apply py-10;
|
||||
background-image: url(https://lf-webcast-platform.bytetos.com/obj/webcast-platform-cdn/ies/webcast_union_platform/static/image/bg.71a36267.png);
|
||||
background-size: 100% 100%;
|
||||
height: 100vh;
|
||||
min-height: 500px;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
justify-content: right;
|
||||
}
|
||||
|
||||
.boxLogin {
|
||||
@apply bg-white rounded-2xl ;
|
||||
width: 400px;
|
||||
margin-right: 15%;
|
||||
|
||||
//background: #fff;
|
||||
//border-radius: 20px;
|
||||
//box-sizing: border-box;
|
||||
//height: 450px;
|
||||
//overflow-x: hidden;
|
||||
//overflow-y: auto;
|
||||
padding: 30px 40px;
|
||||
//position: relative;
|
||||
//width: 400px;
|
||||
}
|
77
src/routes/error.tsx
Normal file
@ -0,0 +1,77 @@
|
||||
import React from "react";
|
||||
import {isRouteErrorResponse, useNavigate, useRouteError} from 'react-router-dom';
|
||||
import {Button} from "antd";
|
||||
|
||||
import error500 from "@/assets/images/error/Error500.png";
|
||||
// ==============================|| ELEMENT ERROR - COMMON ||============================== //
|
||||
const ErrorBoundary: React.FC<{
|
||||
minHeight?: string | number;
|
||||
errorCode?: 401 | 404 | 503
|
||||
}> = ({ errorCode}) => {
|
||||
const error = useRouteError() as Error;
|
||||
let errorMessage = '服务异常,请稍后再试或者联系管理员.'
|
||||
|
||||
const errorConfig: {
|
||||
[key: number]: string
|
||||
} = {
|
||||
401: '您没有权限访问本页面!',
|
||||
404: '访问的页面不存在!',
|
||||
503: '服务异常请联系管理员!',
|
||||
}
|
||||
if (isRouteErrorResponse(error)) {
|
||||
if (errorConfig[error.status]) {
|
||||
errorMessage = `Error ${error.status} - ${errorConfig[error.status]}`;
|
||||
}
|
||||
}
|
||||
if (errorCode) {
|
||||
if (errorConfig[errorCode]) {
|
||||
errorMessage = `Error ${errorCode} - ${errorConfig[errorCode]}`;
|
||||
}
|
||||
}
|
||||
const navigate = useNavigate()
|
||||
const handleGoBack = () => {
|
||||
navigate('/')
|
||||
}
|
||||
return (<div className="max-w-screen-lg mx-auto flex items-center h-screen">
|
||||
<div className={'flex flex-row '}>
|
||||
<div className="flex-col">
|
||||
<div className="sm:w-396px">
|
||||
<img src={error500} alt="error" className="w-full"/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex-col md:w-full ml-10">
|
||||
<div className="text-center">
|
||||
<div className="text-4xl">
|
||||
Internal Server Error
|
||||
</div>
|
||||
<div className="text-gray-400 my-5">
|
||||
{errorMessage}
|
||||
</div>
|
||||
{process.env.NODE_ENV == 'development' && error && <div>
|
||||
<pre style={{
|
||||
font: 'inherit',
|
||||
textAlign: 'left',
|
||||
maxWidth: 700,
|
||||
marginTop: 20,
|
||||
maxHeight: 300,
|
||||
overflow: 'auto'
|
||||
}}>
|
||||
<code style={{
|
||||
wordBreak: 'break-all',
|
||||
font: 'inherit',
|
||||
whiteSpace: 'break-spaces'
|
||||
}}>{error.stack}</code>
|
||||
</pre>
|
||||
</div>}
|
||||
<div className="flex flex-grow gap-2 mt-5 justify-center">
|
||||
<Button type='primary' className="px-5" onClick={handleGoBack}>
|
||||
<h1>返回首页</h1>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>);
|
||||
};
|
||||
|
||||
export default ErrorBoundary;
|
43
src/routes/index.tsx
Normal file
@ -0,0 +1,43 @@
|
||||
import {createBrowserRouter, RouterProvider,} from "react-router-dom";
|
||||
import {Suspense,} from "react";
|
||||
import {ConfigProvider} from "antd";
|
||||
import zhCN from 'antd/locale/zh_CN';
|
||||
// for date-picker i18n
|
||||
import 'dayjs/locale/zh-cn';
|
||||
|
||||
import ErrorBoundary from "./error.tsx";
|
||||
import Loader from "@/components/loader.tsx";
|
||||
import routes from "@/routes/routes.tsx";
|
||||
|
||||
|
||||
const router = createBrowserRouter([
|
||||
...routes,
|
||||
{path: '*', element: <ErrorBoundary/>}
|
||||
], {
|
||||
basename: import.meta.env.VITE_APP_BASE_NAME,
|
||||
future: {
|
||||
v7_fetcherPersist: true,
|
||||
v7_relativeSplatPath: true,
|
||||
v7_normalizeFormMethod: true,
|
||||
v7_skipActionErrorRevalidation: true,
|
||||
v7_partialHydration: true,
|
||||
}
|
||||
})
|
||||
|
||||
// future={{v7_startTransition: true,v7_relativeSplatPath: true}}
|
||||
const AppRouter = () => {
|
||||
return (<ConfigProvider
|
||||
locale={zhCN}
|
||||
theme={{
|
||||
token: {
|
||||
borderRadius: 4,
|
||||
},
|
||||
}}
|
||||
>
|
||||
<Suspense fallback={<Loader/>}>
|
||||
<RouterProvider future={{v7_startTransition: true}} router={router}/>
|
||||
</Suspense>
|
||||
</ConfigProvider>)
|
||||
}
|
||||
|
||||
export default AppRouter;
|
29
src/routes/layout/auth-guard.tsx
Normal file
@ -0,0 +1,29 @@
|
||||
import { useEffect } from 'react';
|
||||
import { useLocation, useNavigate } from 'react-router-dom';
|
||||
|
||||
// project import
|
||||
import useAuth from '@/hooks/useAuth';
|
||||
|
||||
|
||||
// ==============================|| AUTH GUARD ||============================== //
|
||||
|
||||
const AuthGuard = ({ children }:BasicComponentProps) => {
|
||||
const { isLoggedIn,isInitialized } = useAuth();
|
||||
const navigate = useNavigate();
|
||||
const location = useLocation();
|
||||
|
||||
useEffect(() => {
|
||||
if (isInitialized && !isLoggedIn) {
|
||||
navigate(`/user?from=${location.pathname}`, {
|
||||
state: {
|
||||
from: location.pathname
|
||||
},
|
||||
replace: true
|
||||
});
|
||||
}
|
||||
}, [isLoggedIn, navigate, location]);
|
||||
|
||||
return children;
|
||||
};
|
||||
|
||||
export default AuthGuard;
|
68
src/routes/layout/dashboard-layout.tsx
Normal file
@ -0,0 +1,68 @@
|
||||
import {Outlet, useNavigate} from "react-router-dom";
|
||||
import {Dropdown, MenuProps} from "antd";
|
||||
import React from "react";
|
||||
|
||||
import AuthGuard from "@/routes/layout/auth-guard.tsx";
|
||||
import {LogoText} from "@/components/icons/logo.tsx";
|
||||
|
||||
import {UserAvatar} from "@/components/icons/user-avatar.tsx";
|
||||
import {DashboardNavigation} from "@/routes/layout/dashboard-navigation.tsx";
|
||||
|
||||
import useAuth from "@/hooks/useAuth.ts";
|
||||
|
||||
|
||||
type LayoutProps = {
|
||||
children: React.ReactNode
|
||||
}
|
||||
const NavigationUserContainer = () => {
|
||||
const {logout} = useAuth()
|
||||
const navigate = useNavigate()
|
||||
const items: MenuProps['items'] = [
|
||||
{
|
||||
key: '1',
|
||||
label: '个人中心',
|
||||
},
|
||||
{
|
||||
key: '2',
|
||||
label: <div onClick={()=>{
|
||||
logout().then(()=>navigate('/user'))
|
||||
}}>退出</div>,
|
||||
},
|
||||
];
|
||||
return (<div className={"flex items-center justify-between gap-2"}>
|
||||
<Dropdown menu={{items}} placement="bottom" arrow>
|
||||
<div className="flex items-center hover:bg-gray-200 px-2 py-1 cursor-pointer rounded">
|
||||
<UserAvatar className="user-avatar size-8"/>
|
||||
<span className={"username ml-2 text-sm"}>180xxxx7788</span>
|
||||
</div>
|
||||
</Dropdown>
|
||||
</div>)
|
||||
}
|
||||
export const BaseLayout: React.FC<LayoutProps> = ({children}) => {
|
||||
return (<div className={'dashboard-layout min-h-screen'}>
|
||||
<div className="min-h-screen w-full">
|
||||
<div className="app-header">
|
||||
<div className="logo-container">
|
||||
<LogoText/>
|
||||
</div>
|
||||
<DashboardNavigation/>
|
||||
<NavigationUserContainer/>
|
||||
</div>
|
||||
<div className="app-content flex-1 box-sizing">
|
||||
<div className="content-container">
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>)
|
||||
}
|
||||
|
||||
|
||||
const DashboardLayout: React.FC<{ children?: React.ReactNode }> = ({children}) => {
|
||||
return <AuthGuard>
|
||||
<BaseLayout>
|
||||
{children ? children : <Outlet/>}
|
||||
</BaseLayout>
|
||||
</AuthGuard>
|
||||
}
|
||||
export default DashboardLayout
|
47
src/routes/layout/dashboard-navigation.tsx
Normal file
@ -0,0 +1,47 @@
|
||||
|
||||
import {clsx} from "clsx";
|
||||
import {NavLink} from "react-router-dom";
|
||||
|
||||
const NavItems = [
|
||||
{
|
||||
key: 'news',
|
||||
name: '新闻素材库',
|
||||
icon: '+',
|
||||
path:'/'
|
||||
},
|
||||
{
|
||||
key: 'video',
|
||||
name: '新闻素材编辑',
|
||||
icon: '+',
|
||||
path:'/edit'
|
||||
},
|
||||
{
|
||||
key: 'create',
|
||||
name: '数字人视频生成',
|
||||
icon: '+',
|
||||
path:'/create'
|
||||
},
|
||||
{
|
||||
key: 'library',
|
||||
name: '数字人视频库',
|
||||
icon: '+',
|
||||
path:'/library'
|
||||
},
|
||||
{
|
||||
key: 'live',
|
||||
name: '数字人直播间',
|
||||
icon: '+',
|
||||
path:'/live'
|
||||
}
|
||||
]
|
||||
|
||||
export function DashboardNavigation() {
|
||||
return (<div className={'flex'}>
|
||||
{NavItems.map((it, idx) => (
|
||||
<NavLink to={it.path} key={it.key} className={clsx('nav-item cursor-pointer items-center')}>
|
||||
<span className="menu-text ml-2">{it.name}</span>
|
||||
</NavLink>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
11
src/routes/layout/main-layout.tsx
Normal file
@ -0,0 +1,11 @@
|
||||
import React from "react";
|
||||
import {Outlet} from "react-router-dom";
|
||||
|
||||
const MainLayout: React.FC<{ children?: React.ReactNode }> = ({children}) => {
|
||||
return (<div className="main-bg-container">
|
||||
<div className="main-content">
|
||||
{children ? children : <Outlet/>}
|
||||
</div>
|
||||
</div>)
|
||||
}
|
||||
export default MainLayout
|
44
src/routes/routes.tsx
Normal file
@ -0,0 +1,44 @@
|
||||
import {RouteObject} from "react-router-dom";
|
||||
import ErrorBoundary from "@/routes/error.tsx";
|
||||
import UserAuth from "@/pages/user";
|
||||
import CreateIndex from "@/pages/create";
|
||||
import LibraryIndex from "@/pages/library";
|
||||
import LiveIndex from "@/pages/live";
|
||||
import NewsIndex from "@/pages/news";
|
||||
import NewsEdit from "@/pages/news/edit.tsx";
|
||||
import DashboardLayout from "@/routes/layout/dashboard-layout.tsx";
|
||||
|
||||
const routes: RouteObject[] = [
|
||||
{
|
||||
path: '/user',
|
||||
element: <UserAuth/>,
|
||||
},
|
||||
{
|
||||
path: '/',
|
||||
element: <DashboardLayout/>,
|
||||
errorElement: <ErrorBoundary/>,
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
element: <NewsIndex/>
|
||||
},
|
||||
{
|
||||
path: 'edit',
|
||||
element: <NewsEdit/>
|
||||
},
|
||||
{
|
||||
path: 'create',
|
||||
element: <CreateIndex/>
|
||||
},
|
||||
{
|
||||
path: 'library',
|
||||
element: <LibraryIndex/>
|
||||
},
|
||||
{
|
||||
path: 'live',
|
||||
element: <LiveIndex/>
|
||||
},
|
||||
]
|
||||
},
|
||||
]
|
||||
export default routes
|
26
src/service/api/user.ts
Normal file
@ -0,0 +1,26 @@
|
||||
import {sleep} from "@/util/basic.ts";
|
||||
|
||||
const mockUser: UserProfile = {
|
||||
id: 1,
|
||||
token: '123',
|
||||
email: 'admin@qq.com',
|
||||
username: 'admin',
|
||||
role: 'normal',
|
||||
expiration_time: '2025-12-31 23:23:23',
|
||||
}
|
||||
|
||||
export async function getUserInfo() {
|
||||
await sleep(500);
|
||||
return mockUser;
|
||||
// return get<UserProfile>('/userinfo')
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用 sso 返回的code、state换取登录凭证或用户信息
|
||||
* @param code
|
||||
* @param state
|
||||
*/
|
||||
export async function auth(_username: string, _password: string) {
|
||||
return mockUser;
|
||||
//return post<UserProfile>('/auth', {code, state})
|
||||
}
|
80
src/service/request.ts
Normal file
@ -0,0 +1,80 @@
|
||||
import axios from 'axios';
|
||||
import {stringify} from 'qs'
|
||||
import {BizError} from './types';
|
||||
import {getAuthToken} from "@/hooks/useAuth.ts";
|
||||
|
||||
const JSON_FORMAT: string = 'application/json';
|
||||
const REQUEST_TIMEOUT = 300000; // 超时时长5min
|
||||
|
||||
const Axios = axios.create({
|
||||
baseURL: AppConfig.API_PREFIX || '/api',
|
||||
timeout: REQUEST_TIMEOUT,
|
||||
headers: {'Content-Type': JSON_FORMAT}
|
||||
})
|
||||
|
||||
|
||||
// 请求前拦截
|
||||
Axios.interceptors.request.use(config => {
|
||||
const token = getAuthToken();
|
||||
if (token) {
|
||||
config.headers['Token'] = `${token}`;
|
||||
}
|
||||
if (config.data && config.data instanceof FormData) {
|
||||
config.headers['Content-Type'] = 'multipart/form-data';
|
||||
}
|
||||
return config
|
||||
}, err => {
|
||||
return Promise.reject(err)
|
||||
})
|
||||
|
||||
export function request<T>(url: string, method: RequestMethod, data: AllType = null, getOriginResult = false) {
|
||||
return new Promise<T>((resolve, reject) => {
|
||||
Axios.request<APIResponse<T>>({
|
||||
url,
|
||||
method,
|
||||
data,
|
||||
}).then(res => {
|
||||
if (res.status != 200) {
|
||||
reject(new BizError("Service Internal Exception,Please Try Later!", res.status))
|
||||
return;
|
||||
}
|
||||
if (getOriginResult) {
|
||||
resolve(res.data as unknown as T)
|
||||
return;
|
||||
}
|
||||
// const
|
||||
const {code, message, data,request_id} = res.data
|
||||
if (code == 0) {
|
||||
resolve(data as unknown as T)
|
||||
} else {
|
||||
reject(new BizError(message, code,request_id, data as unknown as AllType))
|
||||
}
|
||||
}).catch(e => {
|
||||
reject(new BizError(e.message, 500))
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
export function post<T>(url: string, data: AllType = {}, returnOrigin = false) {
|
||||
return request<T>(url, 'post', data, returnOrigin)
|
||||
}
|
||||
|
||||
export function get<T>(url: string, data: AllType = null, returnOrigin = false) {
|
||||
if (data) {
|
||||
url += (url.indexOf('?') === -1 ? '?' : '&') + stringify(data)
|
||||
}
|
||||
return request<T>(url, 'get', data, returnOrigin)
|
||||
}
|
||||
|
||||
export function put<T>(url: string, data: AllType = {}) {
|
||||
return request<T>(url, 'put', data)
|
||||
}
|
||||
|
||||
export function getFileBlob(url: string) {
|
||||
return new Promise<Blob>((resolve, reject) => {
|
||||
fetch(url).then(res => res.blob()).then(res => {
|
||||
resolve(res)
|
||||
}).catch(reject);
|
||||
});
|
||||
}
|
15
src/service/types.ts
Normal file
@ -0,0 +1,15 @@
|
||||
export class BizError extends Error {
|
||||
/**
|
||||
* 错误码
|
||||
*/
|
||||
code = 1;
|
||||
request_id = '';
|
||||
data: string | number | object | undefined | null;
|
||||
|
||||
constructor(message: string, code = 1,request_id='', data?: AllType) {
|
||||
super(message);
|
||||
this.request_id = request_id;
|
||||
this.code = code;
|
||||
this.data = data;
|
||||
}
|
||||
}
|
29
src/types/api.d.ts
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
// 请求方式
|
||||
declare type RequestMethod = 'get' | 'post' | 'put' | 'delete'
|
||||
|
||||
// 接口返回数据类型
|
||||
declare interface APIResponse<T> {
|
||||
/**
|
||||
* 错误码,0:成功,其他失败
|
||||
*/
|
||||
code: number;
|
||||
data?: T;
|
||||
/**
|
||||
* 非0情况下,提示信息
|
||||
*/
|
||||
message: string;
|
||||
request_id: string;
|
||||
}
|
||||
|
||||
declare interface VideoInfo {
|
||||
id: number;
|
||||
title: string;
|
||||
cover: string;
|
||||
duration: number;
|
||||
width: number;
|
||||
height: number;
|
||||
play_url: string;
|
||||
description: string;
|
||||
tags: string[];
|
||||
create_time: number;
|
||||
}
|
25
src/types/auth.d.ts
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
declare type UserRole = string
|
||||
declare type UserProfile = {
|
||||
id: string | number;
|
||||
token: string;
|
||||
email: string;
|
||||
username: string;
|
||||
role: UserRole;
|
||||
expiration_time?:number | string
|
||||
}
|
||||
|
||||
declare interface AuthProps {
|
||||
isLoggedIn: boolean;
|
||||
isInitialized?: boolean;
|
||||
user?: UserProfile | null;
|
||||
token?: string | null;
|
||||
}
|
||||
|
||||
declare type AuthContextType = {
|
||||
isLoggedIn: boolean;
|
||||
isInitialized?: boolean;
|
||||
user?: UserProfile | null | undefined;
|
||||
logout: () => Promise<void>;
|
||||
login: (username:string,password:string) => Promise<void>;
|
||||
updateUser: (user:Partial<UserProfile>) => Promise<void>;
|
||||
};
|
12
src/types/config.d.ts
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
type I18n = 'en-US' | 'zh-CN' | 'zh-HK';
|
||||
|
||||
type ConfigProps = {
|
||||
fontFamily: string;
|
||||
i18n: I18n;
|
||||
appName: string;
|
||||
}
|
||||
type CustomizationProps = {
|
||||
onChangeContainer: () => void,
|
||||
onChangeLocalization: (lang: I18n) => void,
|
||||
onChangeFontFamily: (fontFamily: string) => void
|
||||
} & ConfigProps;
|
38
src/types/core.d.ts
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
declare interface RecordList<T> {
|
||||
list: T[];
|
||||
pagination: {
|
||||
total: number;
|
||||
pageSize: number;
|
||||
current: number;
|
||||
recordTotal: number;
|
||||
sort?: string;
|
||||
filter?: string;
|
||||
};
|
||||
}
|
||||
declare interface OptionItem {
|
||||
label: string;value: string;
|
||||
children?: OptionItem[];
|
||||
}
|
||||
declare interface BlockContent {
|
||||
type: 'text' | 'image';
|
||||
content: string;
|
||||
}
|
||||
declare interface ArticleContentGroup {
|
||||
groupId?: number;
|
||||
blocks: BlockContent[];
|
||||
}
|
||||
|
||||
declare interface ArticleInfo {
|
||||
id: number;
|
||||
title: string;
|
||||
content: ArticleContentGroup[]
|
||||
}
|
||||
|
||||
declare interface NewsInfo {
|
||||
id: number;
|
||||
title: string;
|
||||
cover?: string;
|
||||
content: string;
|
||||
source: string;
|
||||
time: string|number;
|
||||
}
|
0
src/types/user.d.ts
vendored
Normal file
9
src/util/basic.ts
Normal file
@ -0,0 +1,9 @@
|
||||
/**
|
||||
*
|
||||
* @param delay The number of milliseconds to wait before calling the callback,注意单位是ms
|
||||
*/
|
||||
export function sleep(delay: number) {
|
||||
return new Promise<void>((resolve) => {
|
||||
setTimeout(resolve, delay)
|
||||
});
|
||||
}
|
82
src/util/strings.ts
Normal file
@ -0,0 +1,82 @@
|
||||
import dayjs from "dayjs";
|
||||
import relativeTime from "dayjs/plugin/relativeTime"
|
||||
|
||||
|
||||
dayjs.extend(relativeTime)
|
||||
|
||||
export function countString(str: string) {
|
||||
str = str.replace(/\n/, '')
|
||||
const chinese = Array.from(str)
|
||||
.filter(ch => /[\u4e00-\u9fa5]/.test(ch))
|
||||
.length
|
||||
const english = Array.from(str)
|
||||
.map(ch => /[a-zA-Z0-9\s]/.test(ch) ? ch : '')
|
||||
.join('').length//.split(/\s+/).filter(s => s)
|
||||
|
||||
return chinese + english
|
||||
}
|
||||
|
||||
export function formatFileSize(bytes: number) {
|
||||
if (bytes <= 0) return '0KB';
|
||||
const units = ['KB', 'MB', 'GB', 'TB'];
|
||||
let i = 0;
|
||||
while (bytes >= 1024 && i < units.length - 1) {
|
||||
bytes /= 1024;
|
||||
i++;
|
||||
}
|
||||
return bytes.toFixed(2) + units[i];
|
||||
}
|
||||
|
||||
export function formatWordCount(count: number) {
|
||||
if (count < 10000) {
|
||||
return count;
|
||||
}
|
||||
return (count / 10000).toFixed(2).replace(/.[0]+$/g,'') + '万'
|
||||
}
|
||||
|
||||
const REGEX = {
|
||||
phone: /^(\d{3})\d{4}(\d{4})$/
|
||||
}
|
||||
|
||||
export function hidePhone(phone?: string | null) {
|
||||
if (!phone || !REGEX.phone.test(phone)) return phone;
|
||||
return phone.replace(REGEX.phone, '$1****$2')
|
||||
}
|
||||
|
||||
export function isPhone(phone?: string) {
|
||||
return phone && REGEX.phone.test(phone)
|
||||
}
|
||||
function getDayjs(time:any){
|
||||
const str = time.toString();
|
||||
if(str.length == 10){
|
||||
time *= 1000;
|
||||
}
|
||||
return dayjs(time);
|
||||
}
|
||||
|
||||
export function formatTime(time:any,template = 'YYYY-MM-DD HH:mm:ss') {
|
||||
if(!time) return '-';
|
||||
return getDayjs(time).format(template)
|
||||
}
|
||||
|
||||
export function timeFromNow(time: any) {
|
||||
return getDayjs(time).fromNow();
|
||||
}
|
||||
|
||||
export function calcContentLengthLikeWord(str:string) {
|
||||
try {
|
||||
//先将回车换行符做特殊处理
|
||||
// eslint-disable-next-line no-irregular-whitespace
|
||||
str = str.replace(/(\r\n+|\s+| +)/g, "龘");
|
||||
// eslint-disable-next-line no-control-regex
|
||||
str = str.replace(/[\x00-\xff]/g, "m");
|
||||
//合并字符m,连续字母、数字、英文符号视为一个单词
|
||||
str = str.replace(/m+/g, "*");
|
||||
//去掉回车换行符
|
||||
str = str.replace(/龘+/g, "");
|
||||
//返回字数
|
||||
return str.length;
|
||||
} catch (e) {
|
||||
return str.length
|
||||
}
|
||||
}
|
18
src/vite-env.d.ts
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
/// <reference types="vite/client" />
|
||||
/// <reference types="@types/auth" />
|
||||
|
||||
declare type decimal = number;
|
||||
declare type int = number;
|
||||
declare type AllType = string | number | object | undefined | null;
|
||||
declare const APP_SITE_URL: string;
|
||||
declare const AppConfig: {
|
||||
// 登录凭证 token key
|
||||
AUTH_TOKEN_KEY: string;
|
||||
API_PREFIX: string;
|
||||
};
|
||||
declare const AppMode: 'test' | 'production' | 'development';
|
||||
|
||||
declare type BasicComponentProps = {
|
||||
children?: React.ReactNode;
|
||||
}
|
||||
declare type BasicComponent<T> = React.FC<BasicComponentProps & T>
|
57
tailwind.config.js
Normal file
@ -0,0 +1,57 @@
|
||||
|
||||
const themeConfig = {
|
||||
colors:{
|
||||
'primary':'#7356f6',
|
||||
'primary-bg': '#f6f6f6',
|
||||
'active': '#FFE0E0',
|
||||
'primary-red':'#F5222D',
|
||||
'primary-red-70':'rgba(245,34,45,0.7)',
|
||||
},
|
||||
widths:{
|
||||
'chat-avatar-size': '32px',
|
||||
'chat-container-width':'1000px',
|
||||
}
|
||||
}
|
||||
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
export default {
|
||||
content: [
|
||||
'./index.html',
|
||||
'./src/**/*.{mjs,js,ts,jsx,tsx,html}'
|
||||
],
|
||||
theme: {
|
||||
extend: {
|
||||
width: {
|
||||
'396px': '396px',
|
||||
'1200px': '1200px',
|
||||
'1000px': '1000px',
|
||||
'chat-input':'800px',
|
||||
...themeConfig.widths,
|
||||
},
|
||||
margin:{
|
||||
...themeConfig.widths,
|
||||
},
|
||||
padding: {
|
||||
'basic': '20px',
|
||||
...themeConfig.widths,
|
||||
},
|
||||
color:{
|
||||
...themeConfig.colors,
|
||||
},
|
||||
borderColor:{
|
||||
...themeConfig.colors,
|
||||
},
|
||||
backgroundColor: {
|
||||
...themeConfig.colors,
|
||||
}
|
||||
},
|
||||
screens: {
|
||||
sm: '768px',
|
||||
md: '1024px',
|
||||
lg: '1200px',
|
||||
xl: '1440px',
|
||||
}
|
||||
},
|
||||
plugins: [],
|
||||
}
|
||||
|
29
tsconfig.json
Normal file
@ -0,0 +1,29 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2020",
|
||||
"useDefineForClassFields": true,
|
||||
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
||||
"module": "ESNext",
|
||||
"skipLibCheck": true,
|
||||
|
||||
/* Bundler mode */
|
||||
"moduleResolution": "bundler",
|
||||
"allowImportingTsExtensions": true,
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"noEmit": true,
|
||||
"jsx": "react-jsx",
|
||||
"paths": {
|
||||
"@/*": [
|
||||
"./src/*"
|
||||
]
|
||||
},
|
||||
|
||||
/* Linting */
|
||||
"strict": true,
|
||||
"noUnusedLocals": true,
|
||||
"allowSyntheticDefaultImports": true
|
||||
},
|
||||
"include": ["src"],
|
||||
"references": [{ "path": "./tsconfig.node.json" }]
|
||||
}
|
13
tsconfig.node.json
Normal file
@ -0,0 +1,13 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"composite": true,
|
||||
"skipLibCheck": true,
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "bundler",
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"strict": true
|
||||
},
|
||||
"include": [
|
||||
"vite.config.ts"
|
||||
]
|
||||
}
|
42
vite.config.ts
Normal file
@ -0,0 +1,42 @@
|
||||
import {defineConfig} from 'vite'
|
||||
import react from '@vitejs/plugin-react'
|
||||
import {resolve} from "path";
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig(({mode}) => {
|
||||
return {
|
||||
plugins: [react()],
|
||||
base: process.env.PUBLIC_PATH || (mode == 'relative' ? './' : '/'),
|
||||
define: {
|
||||
AppConfig: JSON.stringify({
|
||||
SITE_URL: process.env.APP_SITE_URL || null,
|
||||
API_PREFIX: process.env.APP_API_PREFIX || '/api',
|
||||
AUTH_TOKEN_KEY: process.env.AUTH_TOKEN_KEY || 'ai-chat-token',
|
||||
}),
|
||||
AppMode: JSON.stringify(mode)
|
||||
},
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': resolve(__dirname, './src')
|
||||
}
|
||||
},
|
||||
css:{
|
||||
preprocessorOptions:{
|
||||
scss:{
|
||||
api:'modern'
|
||||
}
|
||||
}
|
||||
},
|
||||
server: {
|
||||
port: 10021,
|
||||
proxy: {
|
||||
'/query': {
|
||||
target: 'http://101.132.145.21:606', //
|
||||
changeOrigin: true,
|
||||
ws: true,
|
||||
//rewrite: (path) => path.replace(/^\/api/, '')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|