├── car ├── mock │ └── .gitkeep ├── .env ├── typings.d.ts ├── .prettierignore ├── .umirc.qiankun.ts ├── src │ └── pages │ │ ├── index.less │ │ ├── detail.tsx │ │ ├── overproof.tsx │ │ └── all.tsx ├── README.md ├── .prettierrc ├── .editorconfig ├── .gitignore ├── tsconfig.json ├── .umirc.ts └── package.json ├── home ├── mock │ └── .gitkeep ├── .env ├── typings.d.ts ├── .prettierignore ├── .umirc.qiankun.ts ├── README.md ├── src │ └── pages │ │ ├── index.less │ │ └── index.tsx ├── .prettierrc ├── .umirc.ts ├── .editorconfig ├── .gitignore ├── tsconfig.json └── package.json ├── account ├── mock │ └── .gitkeep ├── .env ├── typings.d.ts ├── .prettierignore ├── .umirc.qiankun.ts ├── src │ ├── wrappers │ │ └── clear.tsx │ ├── typings │ │ └── interface.ts │ └── pages │ │ ├── index.less │ │ └── login.tsx ├── README.md ├── .prettierrc ├── .editorconfig ├── .gitignore ├── tsconfig.json ├── .umirc.ts └── package.json ├── foundation ├── mock │ └── .gitkeep ├── assets │ └── favicon.ico ├── typings.d.ts ├── .prettierignore ├── src │ ├── pages │ │ └── 404.tsx │ ├── components │ │ ├── Account.tsx │ │ ├── BreadCrumb.tsx │ │ ├── Loading.tsx │ │ └── Exception.tsx │ ├── wrappers │ │ ├── brother.tsx │ │ ├── index.less │ │ └── children.tsx │ ├── app.ts │ ├── global.less │ ├── typings │ │ └── interface.ts │ └── utils │ │ ├── routes.ts │ │ ├── permission.ts │ │ └── helpers.ts ├── README.md ├── .prettierrc ├── .editorconfig ├── .gitignore ├── tsconfig.json ├── config │ ├── config.ts │ ├── config.prod.ts │ └── config.dev.ts └── package.json ├── dist ├── favicon.ico ├── Dockerfile ├── index.html ├── car │ ├── index.html │ └── umi.9ec2f624.css ├── home │ ├── index.html │ └── umi.80cf52ba.css ├── account │ └── index.html ├── app.js └── package.json ├── .gitignore ├── Dockerfile ├── .github └── workflows │ └── main.yml ├── app.js ├── package.json ├── LICENSE └── README.md /car/mock/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /home/mock/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /account/mock/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /car/.env: -------------------------------------------------------------------------------- 1 | PORT=3001 2 | -------------------------------------------------------------------------------- /home/.env: -------------------------------------------------------------------------------- 1 | PORT=3000 2 | -------------------------------------------------------------------------------- /account/.env: -------------------------------------------------------------------------------- 1 | PORT=3010 2 | -------------------------------------------------------------------------------- /foundation/mock/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dist/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Vizards/Ming/HEAD/dist/favicon.ico -------------------------------------------------------------------------------- /car/typings.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.css'; 2 | declare module '*.less'; 3 | declare module "*.png"; 4 | -------------------------------------------------------------------------------- /home/typings.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.css'; 2 | declare module '*.less'; 3 | declare module "*.png"; 4 | -------------------------------------------------------------------------------- /account/typings.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.css'; 2 | declare module '*.less'; 3 | declare module "*.png"; 4 | -------------------------------------------------------------------------------- /foundation/assets/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Vizards/Ming/HEAD/foundation/assets/favicon.ico -------------------------------------------------------------------------------- /foundation/typings.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.css'; 2 | declare module '*.less'; 3 | declare module "*.png"; 4 | -------------------------------------------------------------------------------- /car/.prettierignore: -------------------------------------------------------------------------------- 1 | **/*.md 2 | **/*.svg 3 | **/*.ejs 4 | **/*.html 5 | package.json 6 | .umi 7 | .umi-production 8 | .umi-test 9 | -------------------------------------------------------------------------------- /home/.prettierignore: -------------------------------------------------------------------------------- 1 | **/*.md 2 | **/*.svg 3 | **/*.ejs 4 | **/*.html 5 | package.json 6 | .umi 7 | .umi-production 8 | .umi-test 9 | -------------------------------------------------------------------------------- /account/.prettierignore: -------------------------------------------------------------------------------- 1 | **/*.md 2 | **/*.svg 3 | **/*.ejs 4 | **/*.html 5 | package.json 6 | .umi 7 | .umi-production 8 | .umi-test 9 | -------------------------------------------------------------------------------- /car/.umirc.qiankun.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'umi'; 2 | 3 | export default defineConfig({ 4 | publicPath: '/car/', 5 | }) 6 | -------------------------------------------------------------------------------- /foundation/.prettierignore: -------------------------------------------------------------------------------- 1 | **/*.md 2 | **/*.svg 3 | **/*.ejs 4 | **/*.html 5 | package.json 6 | .umi 7 | .umi-production 8 | .umi-test 9 | -------------------------------------------------------------------------------- /home/.umirc.qiankun.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'umi'; 2 | 3 | export default defineConfig({ 4 | publicPath: '/home/', 5 | }) 6 | -------------------------------------------------------------------------------- /account/.umirc.qiankun.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'umi'; 2 | 3 | export default defineConfig({ 4 | publicPath: '/account/', 5 | }) 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | .DS_Store 3 | 4 | # dependencies 5 | node_modules/ 6 | npm-debug.log* 7 | yarn-error.log 8 | yarn.lock 9 | package-lock.json 10 | -------------------------------------------------------------------------------- /car/src/pages/index.less: -------------------------------------------------------------------------------- 1 | .container { 2 | background: #fff; 3 | padding: 20px; 4 | min-height: 100%; 5 | button { 6 | margin: 16px 0; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /account/src/wrappers/clear.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | export default (props: any) => { 4 | localStorage.removeItem('profile') 5 | return props.children 6 | } 7 | -------------------------------------------------------------------------------- /foundation/src/pages/404.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Exception from "@/components/Exception"; 3 | 4 | export default () => { 5 | return 6 | } 7 | -------------------------------------------------------------------------------- /account/src/typings/interface.ts: -------------------------------------------------------------------------------- 1 | export interface ILoginDTO { 2 | principal?: string; 3 | credential?: string; 4 | privileges?: { 5 | checked: string[]; 6 | halfChecked: string[]; 7 | }; 8 | } 9 | -------------------------------------------------------------------------------- /car/README.md: -------------------------------------------------------------------------------- 1 | # umi project 2 | 3 | ## Getting Started 4 | 5 | Install dependencies, 6 | 7 | ```bash 8 | $ yarn 9 | ``` 10 | 11 | Start the dev server, 12 | 13 | ```bash 14 | $ yarn start 15 | ``` 16 | -------------------------------------------------------------------------------- /home/README.md: -------------------------------------------------------------------------------- 1 | # umi project 2 | 3 | ## Getting Started 4 | 5 | Install dependencies, 6 | 7 | ```bash 8 | $ yarn 9 | ``` 10 | 11 | Start the dev server, 12 | 13 | ```bash 14 | $ yarn start 15 | ``` 16 | -------------------------------------------------------------------------------- /home/src/pages/index.less: -------------------------------------------------------------------------------- 1 | .container { 2 | background: #fff; 3 | min-height: 100%; 4 | display: flex; 5 | align-items: center; 6 | img { 7 | width: 50%; 8 | margin: auto; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:12.16.1-alpine 2 | 3 | WORKDIR /app 4 | 5 | # copy code 6 | COPY . . 7 | 8 | RUN npm i 9 | 10 | # Expose is NOT supported by Heroku 11 | # EXPOSE 3000 12 | 13 | CMD ["node", "app.js"] 14 | -------------------------------------------------------------------------------- /account/README.md: -------------------------------------------------------------------------------- 1 | # umi project 2 | 3 | ## Getting Started 4 | 5 | Install dependencies, 6 | 7 | ```bash 8 | $ yarn 9 | ``` 10 | 11 | Start the dev server, 12 | 13 | ```bash 14 | $ yarn start 15 | ``` 16 | -------------------------------------------------------------------------------- /foundation/README.md: -------------------------------------------------------------------------------- 1 | # umi project 2 | 3 | ## Getting Started 4 | 5 | Install dependencies, 6 | 7 | ```bash 8 | $ yarn 9 | ``` 10 | 11 | Start the dev server, 12 | 13 | ```bash 14 | $ yarn start 15 | ``` 16 | -------------------------------------------------------------------------------- /dist/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:12.16.1-alpine 2 | 3 | WORKDIR /app 4 | 5 | # copy code 6 | COPY . . 7 | 8 | RUN npm i 9 | 10 | # Expose is NOT supported by Heroku 11 | # EXPOSE 3000 12 | 13 | CMD ["node", "app.js"] 14 | -------------------------------------------------------------------------------- /car/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "trailingComma": "all", 4 | "printWidth": 80, 5 | "overrides": [ 6 | { 7 | "files": ".prettierrc", 8 | "options": { "parser": "json" } 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /home/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "trailingComma": "all", 4 | "printWidth": 80, 5 | "overrides": [ 6 | { 7 | "files": ".prettierrc", 8 | "options": { "parser": "json" } 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /account/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "trailingComma": "all", 4 | "printWidth": 80, 5 | "overrides": [ 6 | { 7 | "files": ".prettierrc", 8 | "options": { "parser": "json" } 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /foundation/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "trailingComma": "all", 4 | "printWidth": 80, 5 | "overrides": [ 6 | { 7 | "files": ".prettierrc", 8 | "options": { "parser": "json" } 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /foundation/src/components/Account.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Link } from 'umi' 3 | 4 | const Account: React.FC = () => { 5 | return ( 6 | 退出 7 | ) 8 | } 9 | 10 | export default Account 11 | -------------------------------------------------------------------------------- /home/.umirc.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'umi'; 2 | 3 | export default defineConfig({ 4 | routes: [{ path: '/', component: '@/pages/index', title: '首页' }], 5 | base: '/home', 6 | qiankun: { 7 | slave: {}, 8 | }, 9 | hash: true, 10 | }); 11 | -------------------------------------------------------------------------------- /foundation/src/wrappers/brother.tsx: -------------------------------------------------------------------------------- 1 | import React, { PropsWithChildren } from 'react' 2 | 3 | export default (props: PropsWithChildren) => { 4 | return ( 5 |
8 | {props.children} 9 |
10 | ) 11 | } 12 | -------------------------------------------------------------------------------- /account/src/pages/index.less: -------------------------------------------------------------------------------- 1 | .account { 2 | width: 400px; 3 | height: 100vh; 4 | margin: auto; 5 | display: flex; 6 | flex-direction: column; 7 | justify-content: center; 8 | h1 { 9 | text-align: center; 10 | padding-bottom: 20px; 11 | } 12 | .warning { 13 | margin-bottom: 30px; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /car/.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | 15 | [Makefile] 16 | indent_style = tab 17 | -------------------------------------------------------------------------------- /account/.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | 15 | [Makefile] 16 | indent_style = tab 17 | -------------------------------------------------------------------------------- /home/.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | 15 | [Makefile] 16 | indent_style = tab 17 | -------------------------------------------------------------------------------- /foundation/.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | 15 | [Makefile] 16 | indent_style = tab 17 | -------------------------------------------------------------------------------- /foundation/src/app.ts: -------------------------------------------------------------------------------- 1 | import { history } from 'umi'; 2 | import { generatePrivilegesTreeData } from './utils/helpers'; 3 | import { privileges } from './utils/permission'; 4 | 5 | export function useQiankunStateForSlave() { 6 | return { 7 | rootHistory: history, 8 | generatePrivilegesTreeData, 9 | privileges, 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /home/src/pages/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import styles from './index.less'; 3 | 4 | export default () => { 5 | return ( 6 |
7 | ming 11 |
12 | ); 13 | }; 14 | -------------------------------------------------------------------------------- /car/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /npm-debug.log* 6 | /yarn-error.log 7 | /yarn.lock 8 | /package-lock.json 9 | 10 | # production 11 | /dist 12 | 13 | # misc 14 | .DS_Store 15 | 16 | # umi 17 | /src/.umi 18 | /src/.umi-production 19 | /src/.umi-test 20 | /.env.local 21 | -------------------------------------------------------------------------------- /home/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /npm-debug.log* 6 | /yarn-error.log 7 | /yarn.lock 8 | /package-lock.json 9 | 10 | # production 11 | /dist 12 | 13 | # misc 14 | .DS_Store 15 | 16 | # umi 17 | /src/.umi 18 | /src/.umi-production 19 | /src/.umi-test 20 | /.env.local 21 | -------------------------------------------------------------------------------- /account/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /npm-debug.log* 6 | /yarn-error.log 7 | /yarn.lock 8 | /package-lock.json 9 | 10 | # production 11 | /dist 12 | 13 | # misc 14 | .DS_Store 15 | 16 | # umi 17 | /src/.umi 18 | /src/.umi-production 19 | /src/.umi-test 20 | /.env.local 21 | -------------------------------------------------------------------------------- /foundation/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /npm-debug.log* 6 | /yarn-error.log 7 | /yarn.lock 8 | /package-lock.json 9 | 10 | # production 11 | /dist 12 | 13 | # misc 14 | .DS_Store 15 | 16 | # umi 17 | /src/.umi 18 | /src/.umi-production 19 | /src/.umi-test 20 | /.env.local 21 | -------------------------------------------------------------------------------- /foundation/src/global.less: -------------------------------------------------------------------------------- 1 | .spinner-wrapper { 2 | height: 100%; 3 | > .ant-spin { 4 | width: 100%; 5 | height: 100%; 6 | z-index: 0; 7 | display: flex; 8 | align-items: center; 9 | justify-content: center; 10 | } 11 | } 12 | 13 | #root-slave { 14 | background: #fff; 15 | height: 100%; 16 | > * { 17 | position: relative; 18 | z-index: 1; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /account/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "esnext", 4 | "module": "esnext", 5 | "moduleResolution": "node", 6 | "importHelpers": true, 7 | "jsx": "react-jsx", 8 | "esModuleInterop": true, 9 | "sourceMap": true, 10 | "baseUrl": "./", 11 | "strict": true, 12 | "paths": { 13 | "@/*": ["src/*"], 14 | "@@/*": ["src/.umi/*"] 15 | }, 16 | "allowSyntheticDefaultImports": true 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /car/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "esnext", 4 | "module": "esnext", 5 | "moduleResolution": "node", 6 | "importHelpers": true, 7 | "jsx": "react-jsx", 8 | "esModuleInterop": true, 9 | "sourceMap": true, 10 | "baseUrl": "./", 11 | "strict": true, 12 | "paths": { 13 | "@/*": ["src/*"], 14 | "@@/*": ["src/.umi/*"] 15 | }, 16 | "allowSyntheticDefaultImports": true 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /home/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "esnext", 4 | "module": "esnext", 5 | "moduleResolution": "node", 6 | "importHelpers": true, 7 | "jsx": "react-jsx", 8 | "esModuleInterop": true, 9 | "sourceMap": true, 10 | "baseUrl": "./", 11 | "strict": true, 12 | "paths": { 13 | "@/*": ["src/*"], 14 | "@@/*": ["src/.umi/*"] 15 | }, 16 | "allowSyntheticDefaultImports": true 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /foundation/src/components/BreadCrumb.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Breadcrumb } from 'antd'; 3 | import { getCurrentTitleList } from '@/utils/helpers'; 4 | 5 | const BreadCrumb: React.FC = () => { 6 | return ( 7 | 8 | {getCurrentTitleList().map((routeName) => ( 9 | {routeName} 10 | ))} 11 | 12 | ); 13 | }; 14 | 15 | export default BreadCrumb; 16 | -------------------------------------------------------------------------------- /foundation/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "esnext", 4 | "module": "esnext", 5 | "moduleResolution": "node", 6 | "importHelpers": true, 7 | "jsx": "react-jsx", 8 | "esModuleInterop": true, 9 | "sourceMap": true, 10 | "baseUrl": "./", 11 | "strict": true, 12 | "paths": { 13 | "@/*": ["src/*"], 14 | "@@/*": ["src/.umi/*"] 15 | }, 16 | "allowSyntheticDefaultImports": true 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /account/.umirc.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'umi'; 2 | 3 | export default defineConfig({ 4 | routes: [ 5 | { 6 | path: '/login', 7 | component: '@/pages/login', 8 | wrappers: ['@/wrappers/clear'], 9 | title: '登录', 10 | }, 11 | { 12 | path: '/', 13 | redirect: '/login' 14 | } 15 | ], 16 | base: '/account', 17 | qiankun: { 18 | slave: {}, 19 | }, 20 | antd: { 21 | dark: false, 22 | }, 23 | hash: true, 24 | }); 25 | -------------------------------------------------------------------------------- /foundation/src/typings/interface.ts: -------------------------------------------------------------------------------- 1 | import { IRoute } from 'umi'; 2 | 3 | export interface MingRoute extends IRoute { 4 | name?: string; 5 | microApp?: string; 6 | entry?: string; 7 | routes?: Omit[]; 8 | sidebar?: boolean; 9 | privilegeId?: string; 10 | } 11 | 12 | export interface TreeData extends MingRoute { 13 | checkable?: boolean; 14 | disableCheckbox?: boolean; 15 | disabled?: boolean; 16 | key?: string | null; 17 | selectable?: boolean; 18 | children?: TreeData[]; 19 | } 20 | -------------------------------------------------------------------------------- /car/.umirc.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'umi'; 2 | 3 | export default defineConfig({ 4 | routes: [ 5 | { path: '/all', exact: true, component: '@/pages/all', title: '全部车辆' }, 6 | { 7 | path: '/overproof', 8 | exact: true, 9 | component: '@/pages/overproof', 10 | title: '超标车辆', 11 | }, 12 | { 13 | path: '/detail/:id', 14 | exact: true, 15 | component: '@/pages/detail', 16 | title: '车辆详情', 17 | }, 18 | ], 19 | base: '/car', 20 | // 注意下面这项在 umi3.x 中必须配置 21 | qiankun: { 22 | slave: {}, 23 | }, 24 | antd: { 25 | dark: false, 26 | }, 27 | hash: true, 28 | }); 29 | -------------------------------------------------------------------------------- /dist/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 11 | 14 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: Deploy 2 | 3 | on: 4 | push: 5 | branches: 6 | - template 7 | pull_request: 8 | branches: 9 | - master 10 | jobs: 11 | build: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: actions/checkout@v2 15 | - name: Use Node.js 16 | uses: actions/setup-node@v1 17 | with: 18 | node-version: '12.x' 19 | - run: npm run build:all 20 | - uses: akhileshns/heroku-deploy@v3.4.6 21 | with: 22 | heroku_api_key: ${{secrets.HEROKU_API_KEY}} 23 | heroku_app_name: ${{secrets.HEROKU_APP_NAME}} 24 | heroku_email: ${{secrets.HEROKU_USER_NAME}} 25 | appdir: dist 26 | usedocker: true -------------------------------------------------------------------------------- /dist/car/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 13 | 16 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /dist/home/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 13 | 17 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /foundation/src/components/Loading.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Spin } from 'antd' 3 | import { AppstoreTwoTone } from '@ant-design/icons' 4 | 5 | export default (loading: boolean) => { 6 | return ( 7 |
8 | } 12 | tip="模块加载中" 13 | size="large" 14 | /> 15 |
16 | ) 17 | } 18 | 19 | const styles = { 20 | loading: { 21 | width: '100%', 22 | height: '100%', 23 | display: 'flex', 24 | alignItems: 'center', 25 | justifyContent: 'center' 26 | }, 27 | spin: { 28 | height: 'unset' 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /dist/account/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 13 | 17 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /foundation/config/config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'umi'; 2 | import { MingRoute } from "@/typings/interface"; 3 | 4 | export const generateApps = (subApps: MingRoute[]) => 5 | subApps 6 | .filter(subApp => subApp.microApp) 7 | .map(subApp => ({ name: subApp.name, entry: subApp.entry })) 8 | 9 | export const generateRoutes = (subApps: MingRoute[]) => 10 | subApps 11 | .concat([{ component: '@/pages/404' }]) 12 | .map(subApp => ({ 13 | ...subApp, 14 | routes: undefined, 15 | microAppProps: { 16 | autoSetLoading: true, 17 | wrapperClassName: 'spinner-wrapper', 18 | } 19 | })) 20 | 21 | export default defineConfig({ 22 | define: { 23 | 'process.env.UMI_ENV': process.env.UMI_ENV, 24 | }, 25 | favicon: '/favicon.ico', 26 | copy: ['assets'], 27 | }); 28 | -------------------------------------------------------------------------------- /car/src/pages/detail.tsx: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import { useParams } from 'umi' 3 | import { Descriptions } from "antd" 4 | import styles from './index.less' 5 | 6 | export default () => { 7 | const { id } = useParams() 8 | return ( 9 |
10 | 11 | car 12 | 13 | {process.env.NODE_ENV === 'production' ? '/car/index.html' : 'http://localhost:3001'} 14 | 15 | /car/detail/:id 16 | /car/detail/{id} 17 | 查看检测数据 {">"} 查看车辆详情 18 | 19 |
20 | ); 21 | } 22 | -------------------------------------------------------------------------------- /car/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "car", 3 | "private": true, 4 | "scripts": { 5 | "start": "umi dev", 6 | "build": "umi build", 7 | "build:qiankun": "UMI_ENV=qiankun umi build", 8 | "prettier": "prettier --write '**/*.{js,jsx,tsx,ts,less,md,json}'", 9 | "test": "umi-test", 10 | "test:coverage": "umi-test --coverage" 11 | }, 12 | "gitHooks": { 13 | "pre-commit": "lint-staged" 14 | }, 15 | "lint-staged": { 16 | "*.{js,jsx,less,md,json}": [ 17 | "prettier --write" 18 | ], 19 | "*.ts?(x)": [ 20 | "prettier --parser=typescript --write" 21 | ] 22 | }, 23 | "dependencies": { 24 | "@umijs/plugin-qiankun": "^2.25.1", 25 | "@umijs/preset-react": "1.x", 26 | "@umijs/test": "^3.4.25", 27 | "lint-staged": "^11.0.0", 28 | "prettier": "^2.3.1", 29 | "react": "^17.0.2", 30 | "react-dom": "^17.0.2", 31 | "umi": "^3.4.25", 32 | "yorkie": "^2.0.0" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /home/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "home", 3 | "private": true, 4 | "scripts": { 5 | "start": "umi dev", 6 | "build": "umi build", 7 | "build:qiankun": "UMI_ENV=qiankun umi build", 8 | "prettier": "prettier --write '**/*.{js,jsx,tsx,ts,less,md,json}'", 9 | "test": "umi-test", 10 | "test:coverage": "umi-test --coverage" 11 | }, 12 | "gitHooks": { 13 | "pre-commit": "lint-staged" 14 | }, 15 | "lint-staged": { 16 | "*.{js,jsx,less,md,json}": [ 17 | "prettier --write" 18 | ], 19 | "*.ts?(x)": [ 20 | "prettier --parser=typescript --write" 21 | ] 22 | }, 23 | "dependencies": { 24 | "@umijs/plugin-qiankun": "^2.25.1", 25 | "@umijs/preset-react": "1.x", 26 | "@umijs/test": "^3.4.25", 27 | "lint-staged": "^11.0.0", 28 | "prettier": "^2.3.1", 29 | "react": "^17.0.2", 30 | "react-dom": "^17.0.2", 31 | "umi": "^3.4.25", 32 | "yorkie": "^2.0.0" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /account/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "account", 3 | "private": true, 4 | "scripts": { 5 | "start": "umi dev", 6 | "build": "umi build", 7 | "build:qiankun": "UMI_ENV=qiankun umi build", 8 | "prettier": "prettier --write '**/*.{js,jsx,tsx,ts,less,md,json}'", 9 | "test": "umi-test", 10 | "test:coverage": "umi-test --coverage" 11 | }, 12 | "gitHooks": { 13 | "pre-commit": "lint-staged" 14 | }, 15 | "lint-staged": { 16 | "*.{js,jsx,less,md,json}": [ 17 | "prettier --write" 18 | ], 19 | "*.ts?(x)": [ 20 | "prettier --parser=typescript --write" 21 | ] 22 | }, 23 | "dependencies": { 24 | "@umijs/plugin-qiankun": "^2.25.1", 25 | "@umijs/preset-react": "1.x", 26 | "@umijs/test": "^3.4.25", 27 | "lint-staged": "^11.0.0", 28 | "prettier": "^2.3.1", 29 | "react": "^17.0.2", 30 | "react-dom": "^17.0.2", 31 | "umi": "^3.4.25", 32 | "yorkie": "^2.0.0" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /foundation/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "scripts": { 4 | "start": "cross-env UMI_ENV=dev umi dev", 5 | "build": "cross-env UMI_ENV=prod umi build", 6 | "prettier": "prettier --write '**/*.{js,jsx,tsx,ts,less,md,json}'", 7 | "test": "umi-test", 8 | "test:coverage": "umi-test --coverage" 9 | }, 10 | "gitHooks": { 11 | "pre-commit": "lint-staged" 12 | }, 13 | "lint-staged": { 14 | "*.{js,jsx,less,md,json}": [ 15 | "prettier --write" 16 | ], 17 | "*.ts?(x)": [ 18 | "prettier --parser=typescript --write" 19 | ] 20 | }, 21 | "dependencies": { 22 | "@umijs/plugin-qiankun": "^2.25.1", 23 | "@umijs/preset-react": "1.x", 24 | "@umijs/test": "^3.4.25", 25 | "lint-staged": "^11.0.0", 26 | "path-to-regexp": "^6.2.0", 27 | "prettier": "^2.3.1", 28 | "react": "^17.0.2", 29 | "react-dom": "^17.0.2", 30 | "umi": "^3.4.25", 31 | "yorkie": "^2.0.0" 32 | }, 33 | "devDependencies": { 34 | "cross-env": "^7.0.3" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /foundation/src/components/Exception.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { history } from 'umi' 3 | import { Result, Button } from 'antd' 4 | 5 | interface IExceptionProps { 6 | type: "404" | "403" | "500" 7 | } 8 | 9 | const Exception: React.FC = ({ type }) => { 10 | const titleMap = { 11 | 403: { 12 | title: '403 无权访问', 13 | subtitle: '您无权访问此页面,如有疑问请联系管理员' 14 | }, 15 | 404: { 16 | title: '404 页面不存在', 17 | subtitle: '抱歉,您访问的页面不存在' 18 | }, 19 | 500: { 20 | title: '500 错误', 21 | subtitle: '渲染服务器出现问题,请联系开发人员' 22 | } 23 | } 24 | 25 | const backHome = () => { 26 | history.replace('/') 27 | } 28 | 29 | return ( 30 |
36 | 返回首页} 41 | /> 42 |
43 | ) 44 | } 45 | 46 | export default Exception 47 | -------------------------------------------------------------------------------- /foundation/src/wrappers/index.less: -------------------------------------------------------------------------------- 1 | .layout { 2 | height: 100vh; 3 | .sider { 4 | overflow: auto; 5 | height: 100vh; 6 | position: fixed; 7 | left: 0; 8 | .logo { 9 | height: 32px; 10 | background: rgba(255, 255, 255, 0.2); 11 | margin: 16px; 12 | color: #fff; 13 | display: flex; 14 | align-items: center; 15 | justify-content: center; 16 | } 17 | } 18 | 19 | .main { 20 | margin-left: 200px; 21 | .header { 22 | background: #fff; 23 | padding: 0 20px; 24 | display: flex; 25 | align-items: center; 26 | justify-content: space-between; 27 | } 28 | 29 | .content { 30 | padding: 20px; 31 | height: 100%; 32 | overflow: scroll; 33 | .children { 34 | height: 100%; 35 | > div { 36 | height: 100%; 37 | > div { 38 | height: 100%; 39 | > div { 40 | height: 100%; 41 | > div { 42 | height: 100%; 43 | } 44 | } 45 | } 46 | } 47 | } 48 | } 49 | .footer { 50 | width: 100%; 51 | background: rgba(255, 255, 255, 0.3); 52 | display: flex; 53 | align-items: center; 54 | justify-content: center; 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const Hapi = require('@hapi/hapi') 4 | const Inert = require('inert') 5 | 6 | const server = Hapi.server({ 7 | port: process.env.PORT || 3000, 8 | host: '0.0.0.0' 9 | }) 10 | 11 | const start = async () => { 12 | await server.register(Inert) 13 | 14 | server.route({ 15 | method: 'GET', 16 | path: '/', 17 | handler: (request, h) => { 18 | return h.file('index.html') 19 | } 20 | }) 21 | 22 | server.route({ 23 | method: 'GET', 24 | path: '/{micro_app}/{path*}', 25 | handler: (request, h) => { 26 | const micro_app = request.params.micro_app; 27 | const path = request.params.path; 28 | 29 | /* {domain}/*.[js|css] */ 30 | if (micro_app.includes('.')) { return h.file(micro_app) } 31 | /* {domain}/{micro_app} */ 32 | if (!micro_app.includes('.') && !path) { return h.file('index.html') } 33 | /* {domain}/{micro_app}/{path*} */ 34 | if (!micro_app.includes('.') && path && !path.includes('.')) { return h.file('index.html') } 35 | /* {domain}/{micro_app}/*.[js|css] */ 36 | if (!micro_app.includes('.') && path && path.includes('.')) { return h.file(`${micro_app}/${path}`) } 37 | /* 404 fallback to foundation app */ 38 | return h.file('index.html') 39 | } 40 | }) 41 | 42 | await server.start() 43 | 44 | console.log('Server running at:', server.info.uri) 45 | } 46 | 47 | start() 48 | -------------------------------------------------------------------------------- /dist/app.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const Hapi = require('@hapi/hapi') 4 | const Inert = require('inert') 5 | 6 | const server = Hapi.server({ 7 | port: process.env.PORT || 3000, 8 | host: '0.0.0.0' 9 | }) 10 | 11 | const start = async () => { 12 | await server.register(Inert) 13 | 14 | server.route({ 15 | method: 'GET', 16 | path: '/', 17 | handler: (request, h) => { 18 | return h.file('index.html') 19 | } 20 | }) 21 | 22 | server.route({ 23 | method: 'GET', 24 | path: '/{micro_app}/{path*}', 25 | handler: (request, h) => { 26 | const micro_app = request.params.micro_app; 27 | const path = request.params.path; 28 | 29 | /* {domain}/*.[js|css] */ 30 | if (micro_app.includes('.')) { return h.file(micro_app) } 31 | /* {domain}/{micro_app} */ 32 | if (!micro_app.includes('.') && !path) { return h.file('index.html') } 33 | /* {domain}/{micro_app}/{path*} */ 34 | if (!micro_app.includes('.') && path && !path.includes('.')) { return h.file('index.html') } 35 | /* {domain}/{micro_app}/*.[js|css] */ 36 | if (!micro_app.includes('.') && path && path.includes('.')) { return h.file(`${micro_app}/${path}`) } 37 | /* 404 fallback to foundation app */ 38 | return h.file('index.html') 39 | } 40 | }) 41 | 42 | await server.start() 43 | 44 | console.log('Server running at:', server.info.uri) 45 | } 46 | 47 | start() 48 | -------------------------------------------------------------------------------- /car/src/pages/overproof.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { history, useModel } from 'umi'; 3 | import { Descriptions, Button, Divider } from 'antd'; 4 | import styles from './index.less'; 5 | 6 | export default () => { 7 | const { privileges } = useModel('@@qiankunStateFromMaster') 8 | const disabled = privileges._banned().includes('查看车辆详情'); 9 | return ( 10 |
11 | 12 | car 13 | 14 | {process.env.NODE_ENV === 'production' 15 | ? '/car/index.html' 16 | : 'http://localhost:3001'} 17 | 18 | 19 | /car/overproof 20 | 21 | 22 | 查看检测数据 {">"} 查看超标车辆 23 | 24 | 25 | 26 |

下面是一个权限控制的 button

27 | 34 |

如果登录时未勾选「查看车辆详情」的权限,此按钮将不可点击

35 |

即使直接打开车辆详情的 URL,也会看到 403 错误页面:

36 | 37 | {location.host + '/car/detail/1'} 38 | 39 |
40 | ); 41 | }; 42 | -------------------------------------------------------------------------------- /foundation/src/utils/routes.ts: -------------------------------------------------------------------------------- 1 | import { history } from 'umi'; 2 | import { pathToRegexp } from 'path-to-regexp'; 3 | import { MingRoute } from '@/typings/interface'; 4 | import { privileges } from '@/utils/permission'; 5 | import { getCurrentTitleList } from '@/utils/helpers'; 6 | 7 | export const routes = process.env.subApps! as unknown as MingRoute[]; 8 | 9 | export const menu = { 10 | routes, 11 | generateDefaultKeys: () => getCurrentTitleList(), 12 | }; 13 | 14 | export const getApplicationType: () => undefined | string = () => { 15 | let applicationType: undefined | string = undefined; 16 | const privilegeDetection = (route: MingRoute) => { 17 | if ( 18 | route.privilegeId && 19 | privileges._banned() && 20 | privileges._banned().includes(route.privilegeId) 21 | ) { 22 | // 匹配到无权限的路由时 23 | applicationType = '403'; 24 | } 25 | }; 26 | const recursiveSidebarMap = (routes: MingRoute[]) => { 27 | routes.forEach((route) => { 28 | if (route.routes) { 29 | // 有子路由直接继续递归 30 | recursiveSidebarMap(route.routes); 31 | } 32 | if ( 33 | route.path && 34 | pathToRegexp(route.path).exec(history.location.pathname) 35 | ) { 36 | applicationType = 'normal'; 37 | privilegeDetection(route); 38 | } 39 | // 如果什么都匹配不上,说明没有声明这个路由,直接返回 undefined 40 | }); 41 | }; 42 | recursiveSidebarMap(routes); 43 | return applicationType; 44 | }; 45 | 46 | export const checkLogged = () => { 47 | if (!localStorage.getItem('profile')) { 48 | history.replace('/account/login'); 49 | } 50 | }; 51 | -------------------------------------------------------------------------------- /car/src/pages/all.tsx: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from 'react'; 2 | import { history } from 'umi'; 3 | import { Descriptions, Button, Divider } from 'antd'; 4 | import styles from './index.less'; 5 | 6 | export default () => { 7 | const [dynamicButton, setDynamicButton] = useState( 8 | , 9 | ); 10 | 11 | useEffect(() => { 12 | setTimeout(() => { 13 | setDynamicButton( 14 | , 15 | ); 16 | }, 2000); 17 | }, [dynamicButton]); 18 | 19 | return ( 20 |
21 | 22 | car 23 | 24 | {process.env.NODE_ENV === 'production' 25 | ? '/car/index.html' 26 | : 'http://localhost:3001'} 27 | 28 | /car/all 29 | 30 | 查看检测数据 {">"} 查看全部车辆 31 | 32 | 33 | 34 |

下面是一个权限控制的 button

35 | 43 | {dynamicButton} 44 |

如果登录时未勾选「查看车辆详情」的权限,将看不到此按钮

45 |

即使直接打开车辆详情的 URL,也会看到 403 错误页面:

46 | 47 | {location.host + '/car/detail/1'} 48 | 49 |
50 | ); 51 | }; 52 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ming", 3 | "version": "1.1.1", 4 | "description": "Ming means Sun and Moon, A framework worked with qiankun and umi3.x", 5 | "main": "app.js", 6 | "scripts": { 7 | "build:all": "npm run copy && npm run build:foundation & npm run build:account & npm run build:home & npm run build:car", 8 | "build:foundation": "cd foundation && npm install && npm run build && rm -f ../dist/umi.*.js && rm -f ../dist/umi.*.css && cp -rvf dist/. ../dist/", 9 | "build:account": "cd account && npm install && npm run build:qiankun && rm -rf ../dist/account/ && cp -rvf dist ../dist/account", 10 | "build:home": "cd home && npm install && npm run build:qiankun && rm -rf ../dist/home/ && cp -rvf dist ../dist/home", 11 | "build:car": "cd car && npm install && npm run build:qiankun && rm -rf ../dist/car/ && cp -rvf dist ../dist/car", 12 | "copy": "rm -rf dist && mkdir dist && cp app.js dist/ && cp package.json dist/ && cp Dockerfile dist/" 13 | }, 14 | "repository": { 15 | "type": "git", 16 | "url": "git+https://github.com/Vizards/Ming.git" 17 | }, 18 | "keywords": [ 19 | "umijs", 20 | "umi3", 21 | "qiankun", 22 | "micro-frontend" 23 | ], 24 | "author": "Vizards ", 25 | "license": "SEE LICENSE IN LICENSE", 26 | "bugs": { 27 | "url": "https://github.com/Vizards/Ming/issues" 28 | }, 29 | "homepage": "https://github.com/Vizards/Ming#readme", 30 | "dependencies": { 31 | "@hapi/hapi": "^20.0.0", 32 | "inert": "^5.1.3" 33 | }, 34 | "devDependencies": { 35 | "lint-staged": "^10.3.0", 36 | "prettier": "^2.1.1", 37 | "yorkie": "^2.0.0" 38 | }, 39 | "gitHooks": { 40 | "pre-commit": "lint-staged" 41 | }, 42 | "lint-staged": { 43 | "*.{js,jsx,less,md,json}": [ 44 | "prettier --write" 45 | ], 46 | "*.ts?(x)": [ 47 | "prettier --parser=typescript --write" 48 | ] 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /dist/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ming", 3 | "version": "1.1.0", 4 | "description": "Ming means Sun and Moon, A framework worked with qiankun and umi3.x", 5 | "main": "app.js", 6 | "scripts": { 7 | "build:all": "npm run copy && npm run build:foundation & npm run build:account & npm run build:home & npm run build:car", 8 | "build:foundation": "cd foundation && npm install && npm run build && rm -f ../dist/umi.*.js && rm -f ../dist/umi.*.css && cp -rvf dist/. ../dist/", 9 | "build:account": "cd account && npm install && npm run build:qiankun && rm -rf ../dist/account/ && cp -rvf dist ../dist/account", 10 | "build:home": "cd home && npm install && npm run build:qiankun && rm -rf ../dist/home/ && cp -rvf dist ../dist/home", 11 | "build:car": "cd car && npm install && npm run build:qiankun && rm -rf ../dist/car/ && cp -rvf dist ../dist/car", 12 | "copy": "rm -rf dist && mkdir dist && cp app.js dist/ && cp package.json dist/ && cp Dockerfile dist/" 13 | }, 14 | "repository": { 15 | "type": "git", 16 | "url": "git+https://github.com/Vizards/Ming.git" 17 | }, 18 | "keywords": [ 19 | "umijs", 20 | "umi3", 21 | "qiankun", 22 | "micro-frontend" 23 | ], 24 | "author": "Vizards ", 25 | "license": "SEE LICENSE IN LICENSE", 26 | "bugs": { 27 | "url": "https://github.com/Vizards/Ming/issues" 28 | }, 29 | "homepage": "https://github.com/Vizards/Ming#readme", 30 | "dependencies": { 31 | "@hapi/hapi": "^20.0.0", 32 | "inert": "^5.1.3" 33 | }, 34 | "devDependencies": { 35 | "lint-staged": "^10.3.0", 36 | "prettier": "^2.1.1", 37 | "yorkie": "^2.0.0" 38 | }, 39 | "gitHooks": { 40 | "pre-commit": "lint-staged" 41 | }, 42 | "lint-staged": { 43 | "*.{js,jsx,less,md,json}": [ 44 | "prettier --write" 45 | ], 46 | "*.ts?(x)": [ 47 | "prettier --parser=typescript --write" 48 | ] 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The Star And Thank Author License (SATA) 2 | 3 | Copyright © 2020 Vizards 4 | 5 | Project Url: https://github.com/Vizards/Ming 6 | https://microfe.herokuapp.com 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a copy 9 | of this software and associated documentation files (the "Software"), to deal 10 | in the Software without restriction, including without limitation the rights 11 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | copies of the Software, and to permit persons to whom the Software is 13 | furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included in 16 | all copies or substantial portions of the Software. 17 | 18 | And wait, the most important, you shall star/+1/like the project(s) in project url 19 | section above first, and then thank the author(s) in Copyright section. 20 | 21 | Here are some suggested ways: 22 | 23 | - Email the authors a thank-you letter, and make friends with him/her/them. 24 | - Report bugs or issues. 25 | - Tell friends what a wonderful project this is. 26 | - And, sure, you can just express thanks in your mind without telling the world. 27 | 28 | Contributors of this project by forking have the option to add his/her name and 29 | forked project url at copyright and project url sections, but shall not delete 30 | or modify anything else in these two sections. 31 | 32 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 33 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 34 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 35 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 36 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 37 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 38 | THE SOFTWARE. 39 | -------------------------------------------------------------------------------- /foundation/config/config.prod.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'umi'; 2 | import { MingRoute } from "@/typings/interface"; 3 | import { generateApps, generateRoutes } from "./config"; 4 | 5 | const subApps: MingRoute[] = [ 6 | { 7 | path: '/', 8 | redirect: '/home', 9 | sidebar: false, 10 | }, 11 | { 12 | name: 'account', 13 | microApp: 'account', 14 | entry: '/account/index.html', 15 | path: '/account', 16 | title: '账户', 17 | wrappers: ['@/wrappers/brother'], 18 | routes: [ 19 | { 20 | path: '/account/login', 21 | title: '登录', 22 | }, 23 | ], 24 | }, 25 | { 26 | name: 'home', 27 | microApp: 'home', 28 | entry: '/home/index.html', 29 | path: '/home', 30 | title: '首页', 31 | wrappers: ['@/wrappers/children'], 32 | }, 33 | { 34 | name: 'car', 35 | microApp: 'car', 36 | entry: '/car/index.html', 37 | path: '/car', 38 | title: '车辆数据', 39 | privilegeId: '查看车辆数据', 40 | wrappers: ['@/wrappers/children'], 41 | routes: [ 42 | { path: '/car/all', title: '全部车辆', privilegeId: '查看全部车辆' }, 43 | { 44 | path: '/car/overproof', 45 | title: '超标车辆', 46 | privilegeId: '查看超标车辆', 47 | }, 48 | { 49 | path: '/car/detail/:id', 50 | title: '车辆详情', 51 | sidebar: false, 52 | privilegeId: '查看车辆详情', 53 | }, 54 | { 55 | sidebar: false, 56 | title: '异步按钮', 57 | privilegeId: '查看异步渲染的按钮', 58 | }, 59 | ], 60 | }, 61 | { 62 | name: 'oss', 63 | microApp: 'oss', 64 | entry: 'https://cloud.vizards.cc/ming/oss/index.html', 65 | path: '/oss', 66 | title: 'OSS 页面', 67 | privilegeId: '查看OSS页面', 68 | wrappers: ['@/wrappers/children'], 69 | }, 70 | ]; 71 | 72 | export default defineConfig({ 73 | qiankun: { 74 | master: { 75 | apps: generateApps(subApps), 76 | jsSandbox: false, // 是否启用 js 沙箱,默认为 false 77 | prefetch: true, // 是否启用 prefetch 特性,默认为 true 78 | defer: false, // 是否异步渲染,默认为 false 79 | }, 80 | }, 81 | define: { 82 | 'process.env.subApps': subApps, 83 | }, 84 | antd: { 85 | dark: false, 86 | }, 87 | routes: generateRoutes(subApps) 88 | }); 89 | -------------------------------------------------------------------------------- /foundation/config/config.dev.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'umi'; 2 | import { MingRoute } from "@/typings/interface"; 3 | import { generateApps, generateRoutes } from "./config"; 4 | 5 | const subApps: MingRoute[] = [ 6 | { 7 | path: '/', 8 | redirect: '/home', 9 | sidebar: false, 10 | }, 11 | { 12 | name: 'account', 13 | microApp: 'account', 14 | entry: 'http://localhost:3010', 15 | path: '/account', 16 | title: '账户', 17 | wrappers: ['@/wrappers/brother'], 18 | routes: [ 19 | { 20 | path: '/account/login', 21 | title: '登录', 22 | }, 23 | ], 24 | }, 25 | { 26 | name: 'home', 27 | microApp: 'home', 28 | entry: 'http://localhost:3000', 29 | path: '/home', 30 | title: '首页', 31 | wrappers: ['@/wrappers/children'], 32 | }, 33 | { 34 | name: 'car', 35 | microApp: 'car', 36 | entry: 'http://localhost:3001', 37 | path: '/car', 38 | title: '车辆数据', 39 | privilegeId: '查看车辆数据', 40 | wrappers: ['@/wrappers/children'], 41 | routes: [ 42 | { path: '/car/all', title: '全部车辆', privilegeId: '查看全部车辆' }, 43 | { 44 | path: '/car/overproof', 45 | title: '超标车辆', 46 | privilegeId: '查看超标车辆', 47 | }, 48 | { 49 | path: '/car/detail/:id', 50 | title: '车辆详情', 51 | sidebar: false, 52 | privilegeId: '查看车辆详情', 53 | }, 54 | { 55 | sidebar: false, 56 | title: '异步按钮', 57 | privilegeId: '查看异步渲染的按钮', 58 | }, 59 | ], 60 | }, 61 | { 62 | name: 'oss', 63 | microApp: 'oss', 64 | entry: 'https://cloud.vizards.cc/ming/oss/index.html', 65 | path: '/oss', 66 | title: 'OSS 页面', 67 | privilegeId: '查看OSS页面', 68 | wrappers: ['@/wrappers/children'], 69 | }, 70 | ]; 71 | 72 | export default defineConfig({ 73 | qiankun: { 74 | master: { 75 | apps: generateApps(subApps), 76 | jsSandbox: false, // 是否启用 js 沙箱,默认为 false 77 | prefetch: true, // 是否启用 prefetch 特性,默认为 true 78 | defer: false, // 是否异步渲染,默认为 false 79 | }, 80 | }, 81 | define: { 82 | 'process.env.subApps': subApps, 83 | }, 84 | antd: { 85 | dark: false, 86 | }, 87 | routes: generateRoutes(subApps) 88 | }); 89 | -------------------------------------------------------------------------------- /foundation/src/utils/permission.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * 核心逻辑 3 | * @file [permission.ts] DOM 级权限控制 4 | */ 5 | 6 | import { getArrDifference, generatePrivilegesListData } from '@/utils/helpers'; 7 | 8 | export const privileges = { 9 | _data: [] as string[], // 当前用户拥有的权限 10 | _all: () => generatePrivilegesListData(), // 所有权限 11 | _banned: () => getArrDifference(privileges._data, privileges._all()), // 当前用户没有的权限 12 | _nodes: [] as any[], // 被 remove 掉的 DOM 暂存在这里 13 | set: (data: string[]) => (privileges._data = data), 14 | get: () => privileges._data, 15 | }; 16 | 17 | /* 18 | * 获取权限数据并设置 19 | * 实际项目中建议从服务端获取用户权限,而不是从 localStorage 获取,仅为前端项目演示 20 | */ 21 | const setPrivileges = () => { 22 | const profileStr = localStorage.getItem('profile'); 23 | const profile = profileStr ? JSON.parse(profileStr) : null; 24 | if (profile && profile.privileges) { 25 | privileges.set(profile.privileges); 26 | } 27 | }; 28 | 29 | // 根据用户没有的权限和 DOM 上标识的 id, remove 掉对应的 DOM Elements 30 | const hideElements = () => { 31 | privileges._banned().forEach((bannedPrivilege) => { 32 | const nodes = document.querySelectorAll(`#${bannedPrivilege}`); 33 | nodes.forEach((node) => { 34 | const savedNode = { 35 | node, 36 | parentNode: node.parentNode, 37 | }; 38 | if (!privileges._nodes.includes(savedNode)) { 39 | privileges._nodes.push(savedNode); 40 | } 41 | node.parentNode?.removeChild(node); 42 | }); 43 | }); 44 | }; 45 | 46 | /* 47 | * remove 掉的 DOM Elements 暂存,以备在切换用户之后恢复 48 | * 如果从登陆页面跳转到主界面为 window 级跳转,则不需要此 restore 过程 49 | */ 50 | const restoreElements = () => { 51 | privileges._nodes.forEach((removedNode) => { 52 | removedNode.parentNode.appendChild(removedNode.node); 53 | }); 54 | }; 55 | 56 | // let's run it before react render! 57 | export const run = () => { 58 | setPrivileges(); 59 | restoreElements(); 60 | const observer = new MutationObserver(hideElements); 61 | // 监听根 DOM,请保证 masterNode 不会在切换子应用时丢失 62 | const masterNode = document.querySelector(`#root-master`); 63 | if (masterNode) { 64 | observer.observe(masterNode, { 65 | childList: true, 66 | subtree: true, 67 | characterData: true, 68 | attributes: true, 69 | attributeFilter: ['id'], 70 | }); 71 | } 72 | }; 73 | -------------------------------------------------------------------------------- /account/src/pages/login.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { useModel } from 'umi'; 3 | import { Form, Input, Button, Tree } from 'antd'; 4 | import { UserOutlined, LockOutlined } from '@ant-design/icons'; 5 | import { ILoginDTO } from '@/typings/interface'; 6 | 7 | import styles from './index.less'; 8 | 9 | export default () => { 10 | const [form] = Form.useForm(); 11 | const { rootHistory, generatePrivilegesTreeData } = useModel('@@qiankunStateFromMaster') 12 | const onFinish = (values: ILoginDTO) => { 13 | let privileges: string[] = []; 14 | if (values.privileges) { 15 | // 半选的菜单也要展示在左侧菜单里面嗷 16 | privileges = values.privileges.checked.concat( 17 | values.privileges.halfChecked, 18 | ); 19 | } 20 | localStorage.setItem( 21 | 'profile', 22 | JSON.stringify({ 23 | principal: values.principal, 24 | credential: values.credential, 25 | privileges, 26 | }), 27 | ); 28 | rootHistory.push('/home'); 29 | }; 30 | const privilegesTreeData: any = generatePrivilegesTreeData(); 31 | return ( 32 |
33 |

监控系统 - 登入

34 |
35 | 39 | } placeholder="用户名" /> 40 | 41 | 42 | 46 | } placeholder="密码" /> 47 | 48 | 49 | 54 | { 59 | form.setFieldsValue({ 60 | privileges: { 61 | checked: checkedKeys, 62 | halfChecked: e.halfCheckedKeys, 63 | }, 64 | }); 65 | }} 66 | /> 67 | 68 | 69 | 70 | 73 | 74 |
75 |
76 | ); 77 | }; 78 | -------------------------------------------------------------------------------- /foundation/src/utils/helpers.ts: -------------------------------------------------------------------------------- 1 | import { routes } from '@/utils/routes'; 2 | import { TreeData, MingRoute } from '@/typings/interface'; 3 | import { pathToRegexp } from 'path-to-regexp'; 4 | import { history } from '@@/core/history'; 5 | 6 | export const getArrDifference = (arr1: string[], arr2: any[]) => { 7 | return arr1.concat(arr2).filter((v, i, arr) => { 8 | return arr.indexOf(v) === arr.lastIndexOf(v); 9 | }); 10 | }; 11 | 12 | export const generatePrivilegesTreeData = () => { 13 | const recursiveRoutes = (routes: TreeData[]) => { 14 | routes.forEach((route) => { 15 | route.title = route.privilegeId ? route.privilegeId : route.title; 16 | route.key = route.privilegeId 17 | ? route.privilegeId 18 | : Math.random().toString(); 19 | route.checkable = !!route.privilegeId; 20 | if (route.routes) { 21 | route.children = route.routes; 22 | delete route.routes; 23 | recursiveRoutes(route.children); 24 | } 25 | }); 26 | }; 27 | const tree = JSON.parse(JSON.stringify(routes)); 28 | recursiveRoutes(tree); 29 | return tree; 30 | }; 31 | 32 | export const generatePrivilegesListData = () => { 33 | const allPrivileges: string[] = []; 34 | const recursiveRoutes = (routes: TreeData[]) => { 35 | routes.forEach((route) => { 36 | if (route.privilegeId) { 37 | allPrivileges.push(route.privilegeId); 38 | } 39 | if (route.routes) { 40 | recursiveRoutes(route.routes); 41 | } 42 | }); 43 | }; 44 | recursiveRoutes(routes); 45 | return allPrivileges; 46 | }; 47 | 48 | export const generateRouteTitlePathList = () => { 49 | const titlePathArr: { path: string; titleArr: string[] }[] = []; 50 | let tempTitleArr: string[] = []; 51 | 52 | const recursiveRoutes = ( 53 | routes: MingRoute[], 54 | parentTitles: string[] = [], 55 | ) => { 56 | routes.forEach((route) => { 57 | tempTitleArr = parentTitles; 58 | if (route.routes) { 59 | recursiveRoutes(route.routes, parentTitles.concat([route.title!])); 60 | } 61 | if (!route.routes) { 62 | titlePathArr.push({ 63 | path: route.path ? route.path : '', 64 | titleArr: tempTitleArr.concat([route.title!]), 65 | }); 66 | tempTitleArr = []; 67 | } 68 | }); 69 | }; 70 | recursiveRoutes(routes); 71 | return titlePathArr; 72 | }; 73 | 74 | export const getCurrentTitleList = () => { 75 | const titlePathList = generateRouteTitlePathList(); 76 | let currentTitleList: string[] = []; 77 | titlePathList.forEach((obj) => { 78 | if (pathToRegexp(obj.path)?.exec(history.location.pathname)) { 79 | currentTitleList = obj.titleArr; 80 | } 81 | }); 82 | return currentTitleList; 83 | }; 84 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | ming 3 |

4 | 5 | --- 6 | 7 |

📦开箱即用的微前端工程方案,基于 umi3.x + qiankun@next

8 |

🍳从实际中台项目孵化,精简的 开发→构建→部署 全流程应用方案

9 |

🧭Demo Site:microfe.herokuapp.com

10 |
11 | 12 | # 快速开始 13 | 14 | 先分别安装基座应用和子应用的依赖,文件结构如下: 15 | 16 | ```tree 17 | Ming 18 | |-- account/ ·········· 子应用 account 19 | |-- car/ ·············· 子应用 car 20 | |-- dist/ ············· 生产环境目录 21 | |-- foundation/ ······· 基座应用 22 | |-- home/ ············· 子应用 home 23 | |-- Dockerfile 24 | |-- app.js ············ hapi 驱动的简单后端路由 25 | |-- package.json 26 | ``` 27 | 28 | 先启动基座应用: 29 | 30 | ```shell script 31 | Ming/foundation > $ yarn start 32 | ``` 33 | 34 | 再启动对应的子应用 35 | 36 | ```shell script 37 | Ming/account > $ yarn start 38 | Ming/home > $ yarn start 39 | Ming/car > $ yarn start 40 | ``` 41 | 42 | 应用默认运行于 http://localhost:8000 43 | 44 |
45 | 46 | # 本地开发 47 | 48 | 本地开发时,子应用运行在不同的端口,集中配置在基座应用的 `config/config.dev.ts` 中。 49 | 50 | ### 说明文档 51 | 52 | - [开发一个子应用](https://github.com/Vizards/Ming/wiki/01.-开发一个子应用) 53 | - [children 级子应用与 brother 级子应用](https://github.com/Vizards/Ming/wiki/02.-children-级子应用与-brother-级子应用) 54 | - [基座声明式路由](https://github.com/Vizards/Ming/wiki/03.-基座声明式路由) 55 | - [DOM 级权限控制](https://github.com/Vizards/Ming/wiki/04.-DOM-级权限控制) 56 | - [微前端下 BrowserHistory Mode 的 404 问题](https://github.com/Vizards/Ming/wiki/05.-微前端下-BrowserHistory-Mode-的-404-问题) 57 | 58 | ### 开发资源 59 | 60 | - [UmiJS](https://umijs.org) 61 | - [@umijs/plugin-qiankun](https://github.com/umijs/plugins/blob/master/packages/plugin-qiankun) 62 | - [Umi Hooks](https://hooks.umijs.org) 63 | - [Formily](https://formilyjs.org/) 64 | 65 |
66 | 67 | # 生产构建 68 | 69 | 推荐 OSS 托管静态文件式部署子应用。 70 | 71 | ### OSS 托管子应用 72 | 73 | 各个子应用应分别托管到 OSS 后,暴露自己的入口 `index.html` 路径给基座应用。从版本 1.1.0 开始,集中子应用配置项到 74 | `foundation/config/config.prod.ts`: 75 | 76 | ```javascript 77 | const subApps = [ 78 | ... 79 | { 80 | name: 'account', 81 | microApp: 'account', 82 | entry: 'https://oss.myname.cloud.com/micro_subapp/account/index.html', 83 | path: 'account', 84 | title: '账户', 85 | wrappers: ['@/wrappers/brother'], 86 | routes: [ 87 | { 88 | path: '/account/login', 89 | title: '登录', 90 | }, 91 | ], 92 | }, 93 | ... 94 | ] 95 | ``` 96 | 97 | 以上部署方式可以实现子应用单独开发、单独更新、甚至技术栈无关(子应用只需暴露符合 Single-SPA/qiankun 的生命周期方法)。 98 | 99 | ### 全量打包构建 100 | 101 | 参考根目录 `package.json` 的 `scripts`,子应用和基座应用都打包进 `/dist` 后, 102 | 参考 `app.js` 简单处理静态文件与路由冲突导致的 404 问题即可部署。 103 | 104 | ### 生产环境运行 105 | 106 | #### 不使用 Docker,直接运行 Node 服务: 107 | 108 | ```shell script 109 | Ming/dist > $ PORT=3000 node app.js 110 | ``` 111 | 112 | Ming 将会运行在 http://localhost:3000 113 | 114 | #### 使用 Docker: 115 | 116 | 先取消注释 `dist/Dockerfile` 文件中的的端口(PORT)字段 117 | 118 | ```shell script 119 | Ming/dist > $ docker build -t vizards/ming . 120 | Ming/dist > $ docker run -p 12580:3000 -d vizards/ming 121 | ``` 122 | 123 | Ming 将会运行在 http://localhost:12580 124 | 125 |
126 | 127 | # LICENSE 128 | 129 | [The Star And Thank Author License (SATA License)](https://github.com/Vizards/Ming/LICENSE) 130 | -------------------------------------------------------------------------------- /foundation/src/wrappers/children.tsx: -------------------------------------------------------------------------------- 1 | import React, { PropsWithChildren } from 'react'; 2 | import { IRoute, Link } from 'umi'; 3 | import { Layout, Menu } from 'antd'; 4 | import { checkLogged, getApplicationType, menu } from '@/utils/routes'; 5 | import { privileges, run } from '@/utils/permission'; 6 | 7 | import BreadCrumb from '@/components/BreadCrumb'; 8 | import Account from '@/components/Account'; 9 | import Exception from "@/components/Exception"; 10 | 11 | const { Header, Content, Footer, Sider } = Layout; 12 | const { SubMenu } = Menu; 13 | 14 | import styles from './index.less'; 15 | 16 | const recursiveRoutes = (routes: IRoute[]) => { 17 | const menuItemDisplay = (route: IRoute) => 18 | route.sidebar !== false && 19 | !privileges._banned().includes(route.privilegeId); 20 | 21 | const generateMenuItem = (route: IRoute) => 22 | menuItemDisplay(route) && ( 23 | 24 | {route.title} 25 | 26 | ); 27 | 28 | return routes.map((route) => { 29 | if (route.wrappers?.includes('@/wrappers/brother')) { 30 | // brother 级子应用不展示在 sidebar 31 | return null 32 | } 33 | if (route.routes) { 34 | /* 35 | * 如果子路由要么被 ban ,要么 sidebar:false 36 | * 那么自己作为父级菜单也不展示 37 | */ 38 | if ( 39 | route.routes.every( 40 | (route) => 41 | privileges._banned().includes(route.privilegeId) || 42 | route.sidebar === false, 43 | ) 44 | ) { 45 | return null; 46 | } 47 | return ( 48 | /* 49 | * 如果子路由中有展示在 sidebar 的,那么自己作为父级菜单 50 | * 根据 Ant Design 设计规范,父级菜单不应当作导航路由使用 51 | */ 52 | 53 | {recursiveRoutes(route.routes)} 54 | 55 | ); 56 | } 57 | return generateMenuItem(route); // 没有子路由,判断自己展不展示 58 | }); 59 | }; 60 | 61 | export default (props: PropsWithChildren) => { 62 | run() 63 | checkLogged() 64 | switch (getApplicationType()) { 65 | case undefined: 66 | return 67 | case '403': 68 | return 69 | case 'normal': 70 | return ( 71 | 72 | 73 |
这里是标题 Logo
74 | 80 | {recursiveRoutes(menu.routes)} 81 | 82 |
83 | 84 |
85 | 86 | 87 |
88 | 89 |
90 | {props.children} 91 |
92 |
93 |
94 | Copyright © 2020. Powered by 姜饼科技 95 |
96 |
97 |
98 | ); 99 | default: 100 | return 101 | } 102 | }; 103 | -------------------------------------------------------------------------------- /dist/home/umi.80cf52ba.css: -------------------------------------------------------------------------------- 1 | [class*=ant-]::-ms-clear,[class*=ant-] input::-ms-clear,[class*=ant-] input::-ms-reveal,[class^=ant-]::-ms-clear,[class^=ant-] input::-ms-clear,[class^=ant-] input::-ms-reveal{display:none}body,html{width:100%;height:100%}input::-ms-clear,input::-ms-reveal{display:none}*,:after,:before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;-ms-overflow-style:scrollbar;-webkit-tap-highlight-color:rgba(0,0,0,0)}@-ms-viewport{width:device-width}body{margin:0;color:rgba(0,0,0,.85);font-size:14px;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-variant:tabular-nums;line-height:1.5715;background-color:#fff;font-feature-settings:"tnum","tnum"}[tabindex="-1"]:focus{outline:none!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5em;color:rgba(0,0,0,.85);font-weight:500}p{margin-top:0;margin-bottom:1em}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;border-bottom:0;cursor:help}address{margin-bottom:1em;font-style:normal;line-height:inherit}input[type=number],input[type=password],input[type=text],textarea{-webkit-appearance:none}dl,ol,ul{margin-top:0;margin-bottom:1em}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:500}dd{margin-bottom:.5em;margin-left:0}blockquote{margin:0 0 1em}dfn{font-style:italic}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#1890ff;text-decoration:none;background-color:transparent;outline:none;cursor:pointer;transition:color .3s;-webkit-text-decoration-skip:objects}a:hover{color:#40a9ff}a:active{color:#096dd9}a:active,a:hover{text-decoration:none;outline:0}a:focus{text-decoration:none;outline:0}a[disabled]{color:rgba(0,0,0,.25);cursor:not-allowed}code,kbd,pre,samp{font-size:1em;font-family:"SFMono-Regular",Consolas,"Liberation Mono",Menlo,Courier,monospace}pre{margin-top:0;margin-bottom:1em;overflow:auto}figure{margin:0 0 1em}img{vertical-align:middle;border-style:none}svg:not(:root){overflow:hidden}[role=button],a,area,button,input:not([type=range]),label,select,summary,textarea{touch-action:manipulation}table{border-collapse:collapse}caption{padding-top:.75em;padding-bottom:.3em;color:rgba(0,0,0,.45);text-align:left;caption-side:bottom}button,input,optgroup,select,textarea{margin:0;color:inherit;font-size:inherit;font-family:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}[type=reset],[type=submit],button,html [type=button]{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=date],input[type=datetime-local],input[type=month],input[type=time]{-webkit-appearance:listbox}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;margin:0;padding:0;border:0}legend{display:block;width:100%;max-width:100%;margin-bottom:.5em;padding:0;color:inherit;font-size:1.5em;line-height:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item}template{display:none}[hidden]{display:none!important}mark{padding:.2em;background-color:#feffe6}::selection{color:#fff;background:#1890ff}.clearfix:before{display:table;content:""}.clearfix:after{display:table;clear:both;content:""}.anticon{display:inline-block;color:inherit;font-style:normal;line-height:0;text-align:center;text-transform:none;vertical-align:-.125em;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.anticon>*{line-height:1}.anticon svg{display:inline-block}.anticon:before{display:none}.anticon .anticon-icon{display:block}.anticon[tabindex]{cursor:pointer}.anticon-spin:before{display:inline-block;animation:loadingCircle 1s linear infinite}.anticon-spin{display:inline-block;animation:loadingCircle 1s linear infinite}.ant-fade-appear,.ant-fade-enter{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-fade-leave{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-fade-appear.ant-fade-appear-active,.ant-fade-enter.ant-fade-enter-active{animation-name:antFadeIn;animation-play-state:running}.ant-fade-leave.ant-fade-leave-active{animation-name:antFadeOut;animation-play-state:running;pointer-events:none}.ant-fade-appear,.ant-fade-enter{opacity:0;animation-timing-function:linear}.ant-fade-leave{animation-timing-function:linear}@keyframes antFadeIn{0%{opacity:0}to{opacity:1}}@keyframes antFadeOut{0%{opacity:1}to{opacity:0}}.ant-move-up-appear,.ant-move-up-enter{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-move-up-leave{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-move-up-appear.ant-move-up-appear-active,.ant-move-up-enter.ant-move-up-enter-active{animation-name:antMoveUpIn;animation-play-state:running}.ant-move-up-leave.ant-move-up-leave-active{animation-name:antMoveUpOut;animation-play-state:running;pointer-events:none}.ant-move-up-appear,.ant-move-up-enter{opacity:0;animation-timing-function:cubic-bezier(.08,.82,.17,1)}.ant-move-up-leave{animation-timing-function:cubic-bezier(.6,.04,.98,.34)}.ant-move-down-appear,.ant-move-down-enter{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-move-down-leave{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-move-down-appear.ant-move-down-appear-active,.ant-move-down-enter.ant-move-down-enter-active{animation-name:antMoveDownIn;animation-play-state:running}.ant-move-down-leave.ant-move-down-leave-active{animation-name:antMoveDownOut;animation-play-state:running;pointer-events:none}.ant-move-down-appear,.ant-move-down-enter{opacity:0;animation-timing-function:cubic-bezier(.08,.82,.17,1)}.ant-move-down-leave{animation-timing-function:cubic-bezier(.6,.04,.98,.34)}.ant-move-left-appear,.ant-move-left-enter{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-move-left-leave{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-move-left-appear.ant-move-left-appear-active,.ant-move-left-enter.ant-move-left-enter-active{animation-name:antMoveLeftIn;animation-play-state:running}.ant-move-left-leave.ant-move-left-leave-active{animation-name:antMoveLeftOut;animation-play-state:running;pointer-events:none}.ant-move-left-appear,.ant-move-left-enter{opacity:0;animation-timing-function:cubic-bezier(.08,.82,.17,1)}.ant-move-left-leave{animation-timing-function:cubic-bezier(.6,.04,.98,.34)}.ant-move-right-appear,.ant-move-right-enter{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-move-right-leave{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-move-right-appear.ant-move-right-appear-active,.ant-move-right-enter.ant-move-right-enter-active{animation-name:antMoveRightIn;animation-play-state:running}.ant-move-right-leave.ant-move-right-leave-active{animation-name:antMoveRightOut;animation-play-state:running;pointer-events:none}.ant-move-right-appear,.ant-move-right-enter{opacity:0;animation-timing-function:cubic-bezier(.08,.82,.17,1)}.ant-move-right-leave{animation-timing-function:cubic-bezier(.6,.04,.98,.34)}@keyframes antMoveDownIn{0%{transform:translateY(100%);transform-origin:0 0;opacity:0}to{transform:translateY(0);transform-origin:0 0;opacity:1}}@keyframes antMoveDownOut{0%{transform:translateY(0);transform-origin:0 0;opacity:1}to{transform:translateY(100%);transform-origin:0 0;opacity:0}}@keyframes antMoveLeftIn{0%{transform:translateX(-100%);transform-origin:0 0;opacity:0}to{transform:translateX(0);transform-origin:0 0;opacity:1}}@keyframes antMoveLeftOut{0%{transform:translateX(0);transform-origin:0 0;opacity:1}to{transform:translateX(-100%);transform-origin:0 0;opacity:0}}@keyframes antMoveRightIn{0%{transform:translateX(100%);transform-origin:0 0;opacity:0}to{transform:translateX(0);transform-origin:0 0;opacity:1}}@keyframes antMoveRightOut{0%{transform:translateX(0);transform-origin:0 0;opacity:1}to{transform:translateX(100%);transform-origin:0 0;opacity:0}}@keyframes antMoveUpIn{0%{transform:translateY(-100%);transform-origin:0 0;opacity:0}to{transform:translateY(0);transform-origin:0 0;opacity:1}}@keyframes antMoveUpOut{0%{transform:translateY(0);transform-origin:0 0;opacity:1}to{transform:translateY(-100%);transform-origin:0 0;opacity:0}}@keyframes loadingCircle{to{transform:rotate(1turn)}}[ant-click-animating-without-extra-node=true],[ant-click-animating=true]{position:relative}html{--antd-wave-shadow-color:#1890ff;--scroll-bar:0}.ant-click-animating-node,[ant-click-animating-without-extra-node=true]:after{position:absolute;top:0;right:0;bottom:0;left:0;display:block;border-radius:inherit;box-shadow:0 0 0 0 #1890ff;box-shadow:0 0 0 0 var(--antd-wave-shadow-color);opacity:.2;animation:fadeEffect 2s cubic-bezier(.08,.82,.17,1),waveEffect .4s cubic-bezier(.08,.82,.17,1);animation-fill-mode:forwards;content:"";pointer-events:none}@keyframes waveEffect{to{box-shadow:0 0 0 #1890ff;box-shadow:0 0 0 6px #1890ff;box-shadow:0 0 0 6px var(--antd-wave-shadow-color)}}@keyframes fadeEffect{to{opacity:0}}.ant-slide-up-appear,.ant-slide-up-enter{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-slide-up-leave{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-slide-up-appear.ant-slide-up-appear-active,.ant-slide-up-enter.ant-slide-up-enter-active{animation-name:antSlideUpIn;animation-play-state:running}.ant-slide-up-leave.ant-slide-up-leave-active{animation-name:antSlideUpOut;animation-play-state:running;pointer-events:none}.ant-slide-up-appear,.ant-slide-up-enter{opacity:0;animation-timing-function:cubic-bezier(.23,1,.32,1)}.ant-slide-up-leave{animation-timing-function:cubic-bezier(.755,.05,.855,.06)}.ant-slide-down-appear,.ant-slide-down-enter{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-slide-down-leave{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-slide-down-appear.ant-slide-down-appear-active,.ant-slide-down-enter.ant-slide-down-enter-active{animation-name:antSlideDownIn;animation-play-state:running}.ant-slide-down-leave.ant-slide-down-leave-active{animation-name:antSlideDownOut;animation-play-state:running;pointer-events:none}.ant-slide-down-appear,.ant-slide-down-enter{opacity:0;animation-timing-function:cubic-bezier(.23,1,.32,1)}.ant-slide-down-leave{animation-timing-function:cubic-bezier(.755,.05,.855,.06)}.ant-slide-left-appear,.ant-slide-left-enter{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-slide-left-leave{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-slide-left-appear.ant-slide-left-appear-active,.ant-slide-left-enter.ant-slide-left-enter-active{animation-name:antSlideLeftIn;animation-play-state:running}.ant-slide-left-leave.ant-slide-left-leave-active{animation-name:antSlideLeftOut;animation-play-state:running;pointer-events:none}.ant-slide-left-appear,.ant-slide-left-enter{opacity:0;animation-timing-function:cubic-bezier(.23,1,.32,1)}.ant-slide-left-leave{animation-timing-function:cubic-bezier(.755,.05,.855,.06)}.ant-slide-right-appear,.ant-slide-right-enter{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-slide-right-leave{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-slide-right-appear.ant-slide-right-appear-active,.ant-slide-right-enter.ant-slide-right-enter-active{animation-name:antSlideRightIn;animation-play-state:running}.ant-slide-right-leave.ant-slide-right-leave-active{animation-name:antSlideRightOut;animation-play-state:running;pointer-events:none}.ant-slide-right-appear,.ant-slide-right-enter{opacity:0;animation-timing-function:cubic-bezier(.23,1,.32,1)}.ant-slide-right-leave{animation-timing-function:cubic-bezier(.755,.05,.855,.06)}@keyframes antSlideUpIn{0%{transform:scaleY(.8);transform-origin:0 0;opacity:0}to{transform:scaleY(1);transform-origin:0 0;opacity:1}}@keyframes antSlideUpOut{0%{transform:scaleY(1);transform-origin:0 0;opacity:1}to{transform:scaleY(.8);transform-origin:0 0;opacity:0}}@keyframes antSlideDownIn{0%{transform:scaleY(.8);transform-origin:100% 100%;opacity:0}to{transform:scaleY(1);transform-origin:100% 100%;opacity:1}}@keyframes antSlideDownOut{0%{transform:scaleY(1);transform-origin:100% 100%;opacity:1}to{transform:scaleY(.8);transform-origin:100% 100%;opacity:0}}@keyframes antSlideLeftIn{0%{transform:scaleX(.8);transform-origin:0 0;opacity:0}to{transform:scaleX(1);transform-origin:0 0;opacity:1}}@keyframes antSlideLeftOut{0%{transform:scaleX(1);transform-origin:0 0;opacity:1}to{transform:scaleX(.8);transform-origin:0 0;opacity:0}}@keyframes antSlideRightIn{0%{transform:scaleX(.8);transform-origin:100% 0;opacity:0}to{transform:scaleX(1);transform-origin:100% 0;opacity:1}}@keyframes antSlideRightOut{0%{transform:scaleX(1);transform-origin:100% 0;opacity:1}to{transform:scaleX(.8);transform-origin:100% 0;opacity:0}}.ant-zoom-appear,.ant-zoom-enter{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-zoom-leave{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-zoom-appear.ant-zoom-appear-active,.ant-zoom-enter.ant-zoom-enter-active{animation-name:antZoomIn;animation-play-state:running}.ant-zoom-leave.ant-zoom-leave-active{animation-name:antZoomOut;animation-play-state:running;pointer-events:none}.ant-zoom-appear,.ant-zoom-enter{transform:scale(0);opacity:0;animation-timing-function:cubic-bezier(.08,.82,.17,1)}.ant-zoom-appear-prepare,.ant-zoom-enter-prepare{transform:none}.ant-zoom-leave{animation-timing-function:cubic-bezier(.78,.14,.15,.86)}.ant-zoom-big-appear,.ant-zoom-big-enter{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-zoom-big-leave{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-zoom-big-appear.ant-zoom-big-appear-active,.ant-zoom-big-enter.ant-zoom-big-enter-active{animation-name:antZoomBigIn;animation-play-state:running}.ant-zoom-big-leave.ant-zoom-big-leave-active{animation-name:antZoomBigOut;animation-play-state:running;pointer-events:none}.ant-zoom-big-appear,.ant-zoom-big-enter{transform:scale(0);opacity:0;animation-timing-function:cubic-bezier(.08,.82,.17,1)}.ant-zoom-big-appear-prepare,.ant-zoom-big-enter-prepare{transform:none}.ant-zoom-big-leave{animation-timing-function:cubic-bezier(.78,.14,.15,.86)}.ant-zoom-big-fast-appear,.ant-zoom-big-fast-enter{animation-duration:.1s;animation-fill-mode:both;animation-play-state:paused}.ant-zoom-big-fast-leave{animation-duration:.1s;animation-fill-mode:both;animation-play-state:paused}.ant-zoom-big-fast-appear.ant-zoom-big-fast-appear-active,.ant-zoom-big-fast-enter.ant-zoom-big-fast-enter-active{animation-name:antZoomBigIn;animation-play-state:running}.ant-zoom-big-fast-leave.ant-zoom-big-fast-leave-active{animation-name:antZoomBigOut;animation-play-state:running;pointer-events:none}.ant-zoom-big-fast-appear,.ant-zoom-big-fast-enter{transform:scale(0);opacity:0;animation-timing-function:cubic-bezier(.08,.82,.17,1)}.ant-zoom-big-fast-appear-prepare,.ant-zoom-big-fast-enter-prepare{transform:none}.ant-zoom-big-fast-leave{animation-timing-function:cubic-bezier(.78,.14,.15,.86)}.ant-zoom-up-appear,.ant-zoom-up-enter{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-zoom-up-leave{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-zoom-up-appear.ant-zoom-up-appear-active,.ant-zoom-up-enter.ant-zoom-up-enter-active{animation-name:antZoomUpIn;animation-play-state:running}.ant-zoom-up-leave.ant-zoom-up-leave-active{animation-name:antZoomUpOut;animation-play-state:running;pointer-events:none}.ant-zoom-up-appear,.ant-zoom-up-enter{transform:scale(0);opacity:0;animation-timing-function:cubic-bezier(.08,.82,.17,1)}.ant-zoom-up-appear-prepare,.ant-zoom-up-enter-prepare{transform:none}.ant-zoom-up-leave{animation-timing-function:cubic-bezier(.78,.14,.15,.86)}.ant-zoom-down-appear,.ant-zoom-down-enter{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-zoom-down-leave{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-zoom-down-appear.ant-zoom-down-appear-active,.ant-zoom-down-enter.ant-zoom-down-enter-active{animation-name:antZoomDownIn;animation-play-state:running}.ant-zoom-down-leave.ant-zoom-down-leave-active{animation-name:antZoomDownOut;animation-play-state:running;pointer-events:none}.ant-zoom-down-appear,.ant-zoom-down-enter{transform:scale(0);opacity:0;animation-timing-function:cubic-bezier(.08,.82,.17,1)}.ant-zoom-down-appear-prepare,.ant-zoom-down-enter-prepare{transform:none}.ant-zoom-down-leave{animation-timing-function:cubic-bezier(.78,.14,.15,.86)}.ant-zoom-left-appear,.ant-zoom-left-enter{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-zoom-left-leave{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-zoom-left-appear.ant-zoom-left-appear-active,.ant-zoom-left-enter.ant-zoom-left-enter-active{animation-name:antZoomLeftIn;animation-play-state:running}.ant-zoom-left-leave.ant-zoom-left-leave-active{animation-name:antZoomLeftOut;animation-play-state:running;pointer-events:none}.ant-zoom-left-appear,.ant-zoom-left-enter{transform:scale(0);opacity:0;animation-timing-function:cubic-bezier(.08,.82,.17,1)}.ant-zoom-left-appear-prepare,.ant-zoom-left-enter-prepare{transform:none}.ant-zoom-left-leave{animation-timing-function:cubic-bezier(.78,.14,.15,.86)}.ant-zoom-right-appear,.ant-zoom-right-enter{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-zoom-right-leave{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-zoom-right-appear.ant-zoom-right-appear-active,.ant-zoom-right-enter.ant-zoom-right-enter-active{animation-name:antZoomRightIn;animation-play-state:running}.ant-zoom-right-leave.ant-zoom-right-leave-active{animation-name:antZoomRightOut;animation-play-state:running;pointer-events:none}.ant-zoom-right-appear,.ant-zoom-right-enter{transform:scale(0);opacity:0;animation-timing-function:cubic-bezier(.08,.82,.17,1)}.ant-zoom-right-appear-prepare,.ant-zoom-right-enter-prepare{transform:none}.ant-zoom-right-leave{animation-timing-function:cubic-bezier(.78,.14,.15,.86)}@keyframes antZoomIn{0%{transform:scale(.2);opacity:0}to{transform:scale(1);opacity:1}}@keyframes antZoomOut{0%{transform:scale(1)}to{transform:scale(.2);opacity:0}}@keyframes antZoomBigIn{0%{transform:scale(.8);opacity:0}to{transform:scale(1);opacity:1}}@keyframes antZoomBigOut{0%{transform:scale(1)}to{transform:scale(.8);opacity:0}}@keyframes antZoomUpIn{0%{transform:scale(.8);transform-origin:50% 0;opacity:0}to{transform:scale(1);transform-origin:50% 0}}@keyframes antZoomUpOut{0%{transform:scale(1);transform-origin:50% 0}to{transform:scale(.8);transform-origin:50% 0;opacity:0}}@keyframes antZoomLeftIn{0%{transform:scale(.8);transform-origin:0 50%;opacity:0}to{transform:scale(1);transform-origin:0 50%}}@keyframes antZoomLeftOut{0%{transform:scale(1);transform-origin:0 50%}to{transform:scale(.8);transform-origin:0 50%;opacity:0}}@keyframes antZoomRightIn{0%{transform:scale(.8);transform-origin:100% 50%;opacity:0}to{transform:scale(1);transform-origin:100% 50%}}@keyframes antZoomRightOut{0%{transform:scale(1);transform-origin:100% 50%}to{transform:scale(.8);transform-origin:100% 50%;opacity:0}}@keyframes antZoomDownIn{0%{transform:scale(.8);transform-origin:50% 100%;opacity:0}to{transform:scale(1);transform-origin:50% 100%}}@keyframes antZoomDownOut{0%{transform:scale(1);transform-origin:50% 100%}to{transform:scale(.8);transform-origin:50% 100%;opacity:0}}.ant-motion-collapse-legacy{overflow:hidden}.ant-motion-collapse-legacy-active{transition:height .2s cubic-bezier(.645,.045,.355,1),opacity .2s cubic-bezier(.645,.045,.355,1)!important}.ant-motion-collapse{overflow:hidden;transition:height .2s cubic-bezier(.645,.045,.355,1),opacity .2s cubic-bezier(.645,.045,.355,1)!important}.ant-message{box-sizing:border-box;margin:0;padding:0;color:rgba(0,0,0,.85);font-size:14px;font-variant:tabular-nums;line-height:1.5715;list-style:none;font-feature-settings:"tnum","tnum";position:fixed;top:8px;left:0;z-index:1010;width:100%;pointer-events:none}.ant-message-notice{padding:8px;text-align:center}.ant-message-notice-content{display:inline-block;padding:10px 16px;background:#fff;border-radius:2px;box-shadow:0 3px 6px -4px rgba(0,0,0,.12),0 6px 16px 0 rgba(0,0,0,.08),0 9px 28px 8px rgba(0,0,0,.05);pointer-events:all}.ant-message-success .anticon{color:#52c41a}.ant-message-error .anticon{color:#ff4d4f}.ant-message-warning .anticon{color:#faad14}.ant-message-info .anticon,.ant-message-loading .anticon{color:#1890ff}.ant-message .anticon{position:relative;top:1px;margin-right:8px;font-size:16px}.ant-message-notice.ant-move-up-leave.ant-move-up-leave-active{animation-name:MessageMoveOut;animation-duration:.3s}@keyframes MessageMoveOut{0%{max-height:150px;padding:8px;opacity:1}to{max-height:0;padding:0;opacity:0}}.ant-message-rtl{direction:rtl}.ant-message-rtl span{direction:rtl}.ant-message-rtl .anticon{margin-right:0;margin-left:8px}.ant-notification{box-sizing:border-box;padding:0;color:rgba(0,0,0,.85);font-size:14px;font-variant:tabular-nums;line-height:1.5715;list-style:none;font-feature-settings:"tnum","tnum";position:fixed;z-index:1010;margin:0 24px 0 0}.ant-notification-bottomLeft,.ant-notification-topLeft{margin-right:0;margin-left:24px}.ant-notification-bottomLeft .ant-notification-fade-appear.ant-notification-fade-appear-active,.ant-notification-bottomLeft .ant-notification-fade-enter.ant-notification-fade-enter-active,.ant-notification-topLeft .ant-notification-fade-appear.ant-notification-fade-appear-active,.ant-notification-topLeft .ant-notification-fade-enter.ant-notification-fade-enter-active{animation-name:NotificationLeftFadeIn}.ant-notification-close-icon{font-size:14px;cursor:pointer}.ant-notification-hook-holder{position:relative}.ant-notification-notice{position:relative;width:384px;max-width:calc(100vw - 48px);margin-bottom:16px;margin-left:auto;padding:16px 24px;overflow:hidden;line-height:1.5715;word-wrap:break-word;background:#fff;border-radius:2px;box-shadow:0 3px 6px -4px rgba(0,0,0,.12),0 6px 16px 0 rgba(0,0,0,.08),0 9px 28px 8px rgba(0,0,0,.05)}.ant-notification-bottomLeft .ant-notification-notice,.ant-notification-topLeft .ant-notification-notice{margin-right:auto;margin-left:0}.ant-notification-notice-message{margin-bottom:8px;color:rgba(0,0,0,.85);font-size:16px;line-height:24px}.ant-notification-notice-message-single-line-auto-margin{display:block;width:calc(264px - 100%);max-width:4px;background-color:transparent;pointer-events:none}.ant-notification-notice-message-single-line-auto-margin:before{display:block;content:""}.ant-notification-notice-description{font-size:14px}.ant-notification-notice-closable .ant-notification-notice-message{padding-right:24px}.ant-notification-notice-with-icon .ant-notification-notice-message{margin-bottom:4px;margin-left:48px;font-size:16px}.ant-notification-notice-with-icon .ant-notification-notice-description{margin-left:48px;font-size:14px}.ant-notification-notice-icon{position:absolute;margin-left:4px;font-size:24px;line-height:24px}.anticon.ant-notification-notice-icon-success{color:#52c41a}.anticon.ant-notification-notice-icon-info{color:#1890ff}.anticon.ant-notification-notice-icon-warning{color:#faad14}.anticon.ant-notification-notice-icon-error{color:#ff4d4f}.ant-notification-notice-close{position:absolute;top:16px;right:22px;color:rgba(0,0,0,.45);outline:none}.ant-notification-notice-close:hover{color:rgba(0,0,0,.67)}.ant-notification-notice-btn{float:right;margin-top:16px}.ant-notification .notification-fade-effect{animation-duration:.24s;animation-timing-function:cubic-bezier(.645,.045,.355,1);animation-fill-mode:both}.ant-notification-fade-appear,.ant-notification-fade-enter{animation-duration:.24s;animation-timing-function:cubic-bezier(.645,.045,.355,1);animation-fill-mode:both;opacity:0;animation-play-state:paused}.ant-notification-fade-leave{animation-duration:.24s;animation-timing-function:cubic-bezier(.645,.045,.355,1);animation-fill-mode:both;animation-duration:.2s;animation-play-state:paused}.ant-notification-fade-appear.ant-notification-fade-appear-active,.ant-notification-fade-enter.ant-notification-fade-enter-active{animation-name:NotificationFadeIn;animation-play-state:running}.ant-notification-fade-leave.ant-notification-fade-leave-active{animation-name:NotificationFadeOut;animation-play-state:running}@keyframes NotificationFadeIn{0%{left:384px;opacity:0}to{left:0;opacity:1}}@keyframes NotificationLeftFadeIn{0%{right:384px;opacity:0}to{right:0;opacity:1}}@keyframes NotificationFadeOut{0%{max-height:150px;margin-bottom:16px;opacity:1}to{max-height:0;margin-bottom:0;padding-top:0;padding-bottom:0;opacity:0}}.ant-notification-rtl{direction:rtl}.ant-notification-rtl .ant-notification-notice-closable .ant-notification-notice-message{padding-right:0;padding-left:24px}.ant-notification-rtl .ant-notification-notice-with-icon .ant-notification-notice-message{margin-right:48px;margin-left:0}.ant-notification-rtl .ant-notification-notice-with-icon .ant-notification-notice-description{margin-right:48px;margin-left:0}.ant-notification-rtl .ant-notification-notice-icon{margin-right:4px;margin-left:0}.ant-notification-rtl .ant-notification-notice-close{right:auto;left:22px}.ant-notification-rtl .ant-notification-notice-btn{float:left}.container___rRDCW{background:#fff;min-height:100%;display:flex;align-items:center}.container___rRDCW img{width:50%;margin:auto} -------------------------------------------------------------------------------- /dist/car/umi.9ec2f624.css: -------------------------------------------------------------------------------- 1 | [class*=ant-]::-ms-clear,[class*=ant-] input::-ms-clear,[class*=ant-] input::-ms-reveal,[class^=ant-]::-ms-clear,[class^=ant-] input::-ms-clear,[class^=ant-] input::-ms-reveal{display:none}body,html{width:100%;height:100%}input::-ms-clear,input::-ms-reveal{display:none}*,:after,:before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;-ms-overflow-style:scrollbar;-webkit-tap-highlight-color:rgba(0,0,0,0)}@-ms-viewport{width:device-width}body{margin:0;color:rgba(0,0,0,.85);font-size:14px;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-variant:tabular-nums;line-height:1.5715;background-color:#fff;font-feature-settings:"tnum","tnum"}[tabindex="-1"]:focus{outline:none!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5em;color:rgba(0,0,0,.85);font-weight:500}p{margin-top:0;margin-bottom:1em}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;border-bottom:0;cursor:help}address{margin-bottom:1em;font-style:normal;line-height:inherit}input[type=number],input[type=password],input[type=text],textarea{-webkit-appearance:none}dl,ol,ul{margin-top:0;margin-bottom:1em}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:500}dd{margin-bottom:.5em;margin-left:0}blockquote{margin:0 0 1em}dfn{font-style:italic}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#1890ff;text-decoration:none;background-color:transparent;outline:none;cursor:pointer;transition:color .3s;-webkit-text-decoration-skip:objects}a:hover{color:#40a9ff}a:active{color:#096dd9}a:active,a:hover{text-decoration:none;outline:0}a:focus{text-decoration:none;outline:0}a[disabled]{color:rgba(0,0,0,.25);cursor:not-allowed}code,kbd,pre,samp{font-size:1em;font-family:"SFMono-Regular",Consolas,"Liberation Mono",Menlo,Courier,monospace}pre{margin-top:0;margin-bottom:1em;overflow:auto}figure{margin:0 0 1em}img{vertical-align:middle;border-style:none}svg:not(:root){overflow:hidden}[role=button],a,area,button,input:not([type=range]),label,select,summary,textarea{touch-action:manipulation}table{border-collapse:collapse}caption{padding-top:.75em;padding-bottom:.3em;color:rgba(0,0,0,.45);text-align:left;caption-side:bottom}button,input,optgroup,select,textarea{margin:0;color:inherit;font-size:inherit;font-family:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}[type=reset],[type=submit],button,html [type=button]{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=date],input[type=datetime-local],input[type=month],input[type=time]{-webkit-appearance:listbox}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;margin:0;padding:0;border:0}legend{display:block;width:100%;max-width:100%;margin-bottom:.5em;padding:0;color:inherit;font-size:1.5em;line-height:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item}template{display:none}[hidden]{display:none!important}mark{padding:.2em;background-color:#feffe6}::selection{color:#fff;background:#1890ff}.clearfix:before{display:table;content:""}.clearfix:after{display:table;clear:both;content:""}.anticon{display:inline-block;color:inherit;font-style:normal;line-height:0;text-align:center;text-transform:none;vertical-align:-.125em;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.anticon>*{line-height:1}.anticon svg{display:inline-block}.anticon:before{display:none}.anticon .anticon-icon{display:block}.anticon[tabindex]{cursor:pointer}.anticon-spin:before{display:inline-block;animation:loadingCircle 1s linear infinite}.anticon-spin{display:inline-block;animation:loadingCircle 1s linear infinite}.ant-fade-appear,.ant-fade-enter{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-fade-leave{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-fade-appear.ant-fade-appear-active,.ant-fade-enter.ant-fade-enter-active{animation-name:antFadeIn;animation-play-state:running}.ant-fade-leave.ant-fade-leave-active{animation-name:antFadeOut;animation-play-state:running;pointer-events:none}.ant-fade-appear,.ant-fade-enter{opacity:0;animation-timing-function:linear}.ant-fade-leave{animation-timing-function:linear}@keyframes antFadeIn{0%{opacity:0}to{opacity:1}}@keyframes antFadeOut{0%{opacity:1}to{opacity:0}}.ant-move-up-appear,.ant-move-up-enter{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-move-up-leave{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-move-up-appear.ant-move-up-appear-active,.ant-move-up-enter.ant-move-up-enter-active{animation-name:antMoveUpIn;animation-play-state:running}.ant-move-up-leave.ant-move-up-leave-active{animation-name:antMoveUpOut;animation-play-state:running;pointer-events:none}.ant-move-up-appear,.ant-move-up-enter{opacity:0;animation-timing-function:cubic-bezier(.08,.82,.17,1)}.ant-move-up-leave{animation-timing-function:cubic-bezier(.6,.04,.98,.34)}.ant-move-down-appear,.ant-move-down-enter{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-move-down-leave{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-move-down-appear.ant-move-down-appear-active,.ant-move-down-enter.ant-move-down-enter-active{animation-name:antMoveDownIn;animation-play-state:running}.ant-move-down-leave.ant-move-down-leave-active{animation-name:antMoveDownOut;animation-play-state:running;pointer-events:none}.ant-move-down-appear,.ant-move-down-enter{opacity:0;animation-timing-function:cubic-bezier(.08,.82,.17,1)}.ant-move-down-leave{animation-timing-function:cubic-bezier(.6,.04,.98,.34)}.ant-move-left-appear,.ant-move-left-enter{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-move-left-leave{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-move-left-appear.ant-move-left-appear-active,.ant-move-left-enter.ant-move-left-enter-active{animation-name:antMoveLeftIn;animation-play-state:running}.ant-move-left-leave.ant-move-left-leave-active{animation-name:antMoveLeftOut;animation-play-state:running;pointer-events:none}.ant-move-left-appear,.ant-move-left-enter{opacity:0;animation-timing-function:cubic-bezier(.08,.82,.17,1)}.ant-move-left-leave{animation-timing-function:cubic-bezier(.6,.04,.98,.34)}.ant-move-right-appear,.ant-move-right-enter{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-move-right-leave{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-move-right-appear.ant-move-right-appear-active,.ant-move-right-enter.ant-move-right-enter-active{animation-name:antMoveRightIn;animation-play-state:running}.ant-move-right-leave.ant-move-right-leave-active{animation-name:antMoveRightOut;animation-play-state:running;pointer-events:none}.ant-move-right-appear,.ant-move-right-enter{opacity:0;animation-timing-function:cubic-bezier(.08,.82,.17,1)}.ant-move-right-leave{animation-timing-function:cubic-bezier(.6,.04,.98,.34)}@keyframes antMoveDownIn{0%{transform:translateY(100%);transform-origin:0 0;opacity:0}to{transform:translateY(0);transform-origin:0 0;opacity:1}}@keyframes antMoveDownOut{0%{transform:translateY(0);transform-origin:0 0;opacity:1}to{transform:translateY(100%);transform-origin:0 0;opacity:0}}@keyframes antMoveLeftIn{0%{transform:translateX(-100%);transform-origin:0 0;opacity:0}to{transform:translateX(0);transform-origin:0 0;opacity:1}}@keyframes antMoveLeftOut{0%{transform:translateX(0);transform-origin:0 0;opacity:1}to{transform:translateX(-100%);transform-origin:0 0;opacity:0}}@keyframes antMoveRightIn{0%{transform:translateX(100%);transform-origin:0 0;opacity:0}to{transform:translateX(0);transform-origin:0 0;opacity:1}}@keyframes antMoveRightOut{0%{transform:translateX(0);transform-origin:0 0;opacity:1}to{transform:translateX(100%);transform-origin:0 0;opacity:0}}@keyframes antMoveUpIn{0%{transform:translateY(-100%);transform-origin:0 0;opacity:0}to{transform:translateY(0);transform-origin:0 0;opacity:1}}@keyframes antMoveUpOut{0%{transform:translateY(0);transform-origin:0 0;opacity:1}to{transform:translateY(-100%);transform-origin:0 0;opacity:0}}@keyframes loadingCircle{to{transform:rotate(1turn)}}[ant-click-animating-without-extra-node=true],[ant-click-animating=true]{position:relative}html{--antd-wave-shadow-color:#1890ff;--scroll-bar:0}.ant-click-animating-node,[ant-click-animating-without-extra-node=true]:after{position:absolute;top:0;right:0;bottom:0;left:0;display:block;border-radius:inherit;box-shadow:0 0 0 0 #1890ff;box-shadow:0 0 0 0 var(--antd-wave-shadow-color);opacity:.2;animation:fadeEffect 2s cubic-bezier(.08,.82,.17,1),waveEffect .4s cubic-bezier(.08,.82,.17,1);animation-fill-mode:forwards;content:"";pointer-events:none}@keyframes waveEffect{to{box-shadow:0 0 0 #1890ff;box-shadow:0 0 0 6px #1890ff;box-shadow:0 0 0 6px var(--antd-wave-shadow-color)}}@keyframes fadeEffect{to{opacity:0}}.ant-slide-up-appear,.ant-slide-up-enter{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-slide-up-leave{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-slide-up-appear.ant-slide-up-appear-active,.ant-slide-up-enter.ant-slide-up-enter-active{animation-name:antSlideUpIn;animation-play-state:running}.ant-slide-up-leave.ant-slide-up-leave-active{animation-name:antSlideUpOut;animation-play-state:running;pointer-events:none}.ant-slide-up-appear,.ant-slide-up-enter{opacity:0;animation-timing-function:cubic-bezier(.23,1,.32,1)}.ant-slide-up-leave{animation-timing-function:cubic-bezier(.755,.05,.855,.06)}.ant-slide-down-appear,.ant-slide-down-enter{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-slide-down-leave{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-slide-down-appear.ant-slide-down-appear-active,.ant-slide-down-enter.ant-slide-down-enter-active{animation-name:antSlideDownIn;animation-play-state:running}.ant-slide-down-leave.ant-slide-down-leave-active{animation-name:antSlideDownOut;animation-play-state:running;pointer-events:none}.ant-slide-down-appear,.ant-slide-down-enter{opacity:0;animation-timing-function:cubic-bezier(.23,1,.32,1)}.ant-slide-down-leave{animation-timing-function:cubic-bezier(.755,.05,.855,.06)}.ant-slide-left-appear,.ant-slide-left-enter{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-slide-left-leave{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-slide-left-appear.ant-slide-left-appear-active,.ant-slide-left-enter.ant-slide-left-enter-active{animation-name:antSlideLeftIn;animation-play-state:running}.ant-slide-left-leave.ant-slide-left-leave-active{animation-name:antSlideLeftOut;animation-play-state:running;pointer-events:none}.ant-slide-left-appear,.ant-slide-left-enter{opacity:0;animation-timing-function:cubic-bezier(.23,1,.32,1)}.ant-slide-left-leave{animation-timing-function:cubic-bezier(.755,.05,.855,.06)}.ant-slide-right-appear,.ant-slide-right-enter{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-slide-right-leave{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-slide-right-appear.ant-slide-right-appear-active,.ant-slide-right-enter.ant-slide-right-enter-active{animation-name:antSlideRightIn;animation-play-state:running}.ant-slide-right-leave.ant-slide-right-leave-active{animation-name:antSlideRightOut;animation-play-state:running;pointer-events:none}.ant-slide-right-appear,.ant-slide-right-enter{opacity:0;animation-timing-function:cubic-bezier(.23,1,.32,1)}.ant-slide-right-leave{animation-timing-function:cubic-bezier(.755,.05,.855,.06)}@keyframes antSlideUpIn{0%{transform:scaleY(.8);transform-origin:0 0;opacity:0}to{transform:scaleY(1);transform-origin:0 0;opacity:1}}@keyframes antSlideUpOut{0%{transform:scaleY(1);transform-origin:0 0;opacity:1}to{transform:scaleY(.8);transform-origin:0 0;opacity:0}}@keyframes antSlideDownIn{0%{transform:scaleY(.8);transform-origin:100% 100%;opacity:0}to{transform:scaleY(1);transform-origin:100% 100%;opacity:1}}@keyframes antSlideDownOut{0%{transform:scaleY(1);transform-origin:100% 100%;opacity:1}to{transform:scaleY(.8);transform-origin:100% 100%;opacity:0}}@keyframes antSlideLeftIn{0%{transform:scaleX(.8);transform-origin:0 0;opacity:0}to{transform:scaleX(1);transform-origin:0 0;opacity:1}}@keyframes antSlideLeftOut{0%{transform:scaleX(1);transform-origin:0 0;opacity:1}to{transform:scaleX(.8);transform-origin:0 0;opacity:0}}@keyframes antSlideRightIn{0%{transform:scaleX(.8);transform-origin:100% 0;opacity:0}to{transform:scaleX(1);transform-origin:100% 0;opacity:1}}@keyframes antSlideRightOut{0%{transform:scaleX(1);transform-origin:100% 0;opacity:1}to{transform:scaleX(.8);transform-origin:100% 0;opacity:0}}.ant-zoom-appear,.ant-zoom-enter{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-zoom-leave{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-zoom-appear.ant-zoom-appear-active,.ant-zoom-enter.ant-zoom-enter-active{animation-name:antZoomIn;animation-play-state:running}.ant-zoom-leave.ant-zoom-leave-active{animation-name:antZoomOut;animation-play-state:running;pointer-events:none}.ant-zoom-appear,.ant-zoom-enter{transform:scale(0);opacity:0;animation-timing-function:cubic-bezier(.08,.82,.17,1)}.ant-zoom-appear-prepare,.ant-zoom-enter-prepare{transform:none}.ant-zoom-leave{animation-timing-function:cubic-bezier(.78,.14,.15,.86)}.ant-zoom-big-appear,.ant-zoom-big-enter{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-zoom-big-leave{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-zoom-big-appear.ant-zoom-big-appear-active,.ant-zoom-big-enter.ant-zoom-big-enter-active{animation-name:antZoomBigIn;animation-play-state:running}.ant-zoom-big-leave.ant-zoom-big-leave-active{animation-name:antZoomBigOut;animation-play-state:running;pointer-events:none}.ant-zoom-big-appear,.ant-zoom-big-enter{transform:scale(0);opacity:0;animation-timing-function:cubic-bezier(.08,.82,.17,1)}.ant-zoom-big-appear-prepare,.ant-zoom-big-enter-prepare{transform:none}.ant-zoom-big-leave{animation-timing-function:cubic-bezier(.78,.14,.15,.86)}.ant-zoom-big-fast-appear,.ant-zoom-big-fast-enter{animation-duration:.1s;animation-fill-mode:both;animation-play-state:paused}.ant-zoom-big-fast-leave{animation-duration:.1s;animation-fill-mode:both;animation-play-state:paused}.ant-zoom-big-fast-appear.ant-zoom-big-fast-appear-active,.ant-zoom-big-fast-enter.ant-zoom-big-fast-enter-active{animation-name:antZoomBigIn;animation-play-state:running}.ant-zoom-big-fast-leave.ant-zoom-big-fast-leave-active{animation-name:antZoomBigOut;animation-play-state:running;pointer-events:none}.ant-zoom-big-fast-appear,.ant-zoom-big-fast-enter{transform:scale(0);opacity:0;animation-timing-function:cubic-bezier(.08,.82,.17,1)}.ant-zoom-big-fast-appear-prepare,.ant-zoom-big-fast-enter-prepare{transform:none}.ant-zoom-big-fast-leave{animation-timing-function:cubic-bezier(.78,.14,.15,.86)}.ant-zoom-up-appear,.ant-zoom-up-enter{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-zoom-up-leave{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-zoom-up-appear.ant-zoom-up-appear-active,.ant-zoom-up-enter.ant-zoom-up-enter-active{animation-name:antZoomUpIn;animation-play-state:running}.ant-zoom-up-leave.ant-zoom-up-leave-active{animation-name:antZoomUpOut;animation-play-state:running;pointer-events:none}.ant-zoom-up-appear,.ant-zoom-up-enter{transform:scale(0);opacity:0;animation-timing-function:cubic-bezier(.08,.82,.17,1)}.ant-zoom-up-appear-prepare,.ant-zoom-up-enter-prepare{transform:none}.ant-zoom-up-leave{animation-timing-function:cubic-bezier(.78,.14,.15,.86)}.ant-zoom-down-appear,.ant-zoom-down-enter{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-zoom-down-leave{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-zoom-down-appear.ant-zoom-down-appear-active,.ant-zoom-down-enter.ant-zoom-down-enter-active{animation-name:antZoomDownIn;animation-play-state:running}.ant-zoom-down-leave.ant-zoom-down-leave-active{animation-name:antZoomDownOut;animation-play-state:running;pointer-events:none}.ant-zoom-down-appear,.ant-zoom-down-enter{transform:scale(0);opacity:0;animation-timing-function:cubic-bezier(.08,.82,.17,1)}.ant-zoom-down-appear-prepare,.ant-zoom-down-enter-prepare{transform:none}.ant-zoom-down-leave{animation-timing-function:cubic-bezier(.78,.14,.15,.86)}.ant-zoom-left-appear,.ant-zoom-left-enter{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-zoom-left-leave{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-zoom-left-appear.ant-zoom-left-appear-active,.ant-zoom-left-enter.ant-zoom-left-enter-active{animation-name:antZoomLeftIn;animation-play-state:running}.ant-zoom-left-leave.ant-zoom-left-leave-active{animation-name:antZoomLeftOut;animation-play-state:running;pointer-events:none}.ant-zoom-left-appear,.ant-zoom-left-enter{transform:scale(0);opacity:0;animation-timing-function:cubic-bezier(.08,.82,.17,1)}.ant-zoom-left-appear-prepare,.ant-zoom-left-enter-prepare{transform:none}.ant-zoom-left-leave{animation-timing-function:cubic-bezier(.78,.14,.15,.86)}.ant-zoom-right-appear,.ant-zoom-right-enter{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-zoom-right-leave{animation-duration:.2s;animation-fill-mode:both;animation-play-state:paused}.ant-zoom-right-appear.ant-zoom-right-appear-active,.ant-zoom-right-enter.ant-zoom-right-enter-active{animation-name:antZoomRightIn;animation-play-state:running}.ant-zoom-right-leave.ant-zoom-right-leave-active{animation-name:antZoomRightOut;animation-play-state:running;pointer-events:none}.ant-zoom-right-appear,.ant-zoom-right-enter{transform:scale(0);opacity:0;animation-timing-function:cubic-bezier(.08,.82,.17,1)}.ant-zoom-right-appear-prepare,.ant-zoom-right-enter-prepare{transform:none}.ant-zoom-right-leave{animation-timing-function:cubic-bezier(.78,.14,.15,.86)}@keyframes antZoomIn{0%{transform:scale(.2);opacity:0}to{transform:scale(1);opacity:1}}@keyframes antZoomOut{0%{transform:scale(1)}to{transform:scale(.2);opacity:0}}@keyframes antZoomBigIn{0%{transform:scale(.8);opacity:0}to{transform:scale(1);opacity:1}}@keyframes antZoomBigOut{0%{transform:scale(1)}to{transform:scale(.8);opacity:0}}@keyframes antZoomUpIn{0%{transform:scale(.8);transform-origin:50% 0;opacity:0}to{transform:scale(1);transform-origin:50% 0}}@keyframes antZoomUpOut{0%{transform:scale(1);transform-origin:50% 0}to{transform:scale(.8);transform-origin:50% 0;opacity:0}}@keyframes antZoomLeftIn{0%{transform:scale(.8);transform-origin:0 50%;opacity:0}to{transform:scale(1);transform-origin:0 50%}}@keyframes antZoomLeftOut{0%{transform:scale(1);transform-origin:0 50%}to{transform:scale(.8);transform-origin:0 50%;opacity:0}}@keyframes antZoomRightIn{0%{transform:scale(.8);transform-origin:100% 50%;opacity:0}to{transform:scale(1);transform-origin:100% 50%}}@keyframes antZoomRightOut{0%{transform:scale(1);transform-origin:100% 50%}to{transform:scale(.8);transform-origin:100% 50%;opacity:0}}@keyframes antZoomDownIn{0%{transform:scale(.8);transform-origin:50% 100%;opacity:0}to{transform:scale(1);transform-origin:50% 100%}}@keyframes antZoomDownOut{0%{transform:scale(1);transform-origin:50% 100%}to{transform:scale(.8);transform-origin:50% 100%;opacity:0}}.ant-motion-collapse-legacy{overflow:hidden}.ant-motion-collapse-legacy-active{transition:height .2s cubic-bezier(.645,.045,.355,1),opacity .2s cubic-bezier(.645,.045,.355,1)!important}.ant-motion-collapse{overflow:hidden;transition:height .2s cubic-bezier(.645,.045,.355,1),opacity .2s cubic-bezier(.645,.045,.355,1)!important}.ant-message{box-sizing:border-box;margin:0;padding:0;color:rgba(0,0,0,.85);font-size:14px;font-variant:tabular-nums;line-height:1.5715;list-style:none;font-feature-settings:"tnum","tnum";position:fixed;top:8px;left:0;z-index:1010;width:100%;pointer-events:none}.ant-message-notice{padding:8px;text-align:center}.ant-message-notice-content{display:inline-block;padding:10px 16px;background:#fff;border-radius:2px;box-shadow:0 3px 6px -4px rgba(0,0,0,.12),0 6px 16px 0 rgba(0,0,0,.08),0 9px 28px 8px rgba(0,0,0,.05);pointer-events:all}.ant-message-success .anticon{color:#52c41a}.ant-message-error .anticon{color:#ff4d4f}.ant-message-warning .anticon{color:#faad14}.ant-message-info .anticon,.ant-message-loading .anticon{color:#1890ff}.ant-message .anticon{position:relative;top:1px;margin-right:8px;font-size:16px}.ant-message-notice.ant-move-up-leave.ant-move-up-leave-active{animation-name:MessageMoveOut;animation-duration:.3s}@keyframes MessageMoveOut{0%{max-height:150px;padding:8px;opacity:1}to{max-height:0;padding:0;opacity:0}}.ant-message-rtl{direction:rtl}.ant-message-rtl span{direction:rtl}.ant-message-rtl .anticon{margin-right:0;margin-left:8px}.ant-notification{box-sizing:border-box;padding:0;color:rgba(0,0,0,.85);font-size:14px;font-variant:tabular-nums;line-height:1.5715;list-style:none;font-feature-settings:"tnum","tnum";position:fixed;z-index:1010;margin:0 24px 0 0}.ant-notification-bottomLeft,.ant-notification-topLeft{margin-right:0;margin-left:24px}.ant-notification-bottomLeft .ant-notification-fade-appear.ant-notification-fade-appear-active,.ant-notification-bottomLeft .ant-notification-fade-enter.ant-notification-fade-enter-active,.ant-notification-topLeft .ant-notification-fade-appear.ant-notification-fade-appear-active,.ant-notification-topLeft .ant-notification-fade-enter.ant-notification-fade-enter-active{animation-name:NotificationLeftFadeIn}.ant-notification-close-icon{font-size:14px;cursor:pointer}.ant-notification-hook-holder{position:relative}.ant-notification-notice{position:relative;width:384px;max-width:calc(100vw - 48px);margin-bottom:16px;margin-left:auto;padding:16px 24px;overflow:hidden;line-height:1.5715;word-wrap:break-word;background:#fff;border-radius:2px;box-shadow:0 3px 6px -4px rgba(0,0,0,.12),0 6px 16px 0 rgba(0,0,0,.08),0 9px 28px 8px rgba(0,0,0,.05)}.ant-notification-bottomLeft .ant-notification-notice,.ant-notification-topLeft .ant-notification-notice{margin-right:auto;margin-left:0}.ant-notification-notice-message{margin-bottom:8px;color:rgba(0,0,0,.85);font-size:16px;line-height:24px}.ant-notification-notice-message-single-line-auto-margin{display:block;width:calc(264px - 100%);max-width:4px;background-color:transparent;pointer-events:none}.ant-notification-notice-message-single-line-auto-margin:before{display:block;content:""}.ant-notification-notice-description{font-size:14px}.ant-notification-notice-closable .ant-notification-notice-message{padding-right:24px}.ant-notification-notice-with-icon .ant-notification-notice-message{margin-bottom:4px;margin-left:48px;font-size:16px}.ant-notification-notice-with-icon .ant-notification-notice-description{margin-left:48px;font-size:14px}.ant-notification-notice-icon{position:absolute;margin-left:4px;font-size:24px;line-height:24px}.anticon.ant-notification-notice-icon-success{color:#52c41a}.anticon.ant-notification-notice-icon-info{color:#1890ff}.anticon.ant-notification-notice-icon-warning{color:#faad14}.anticon.ant-notification-notice-icon-error{color:#ff4d4f}.ant-notification-notice-close{position:absolute;top:16px;right:22px;color:rgba(0,0,0,.45);outline:none}.ant-notification-notice-close:hover{color:rgba(0,0,0,.67)}.ant-notification-notice-btn{float:right;margin-top:16px}.ant-notification .notification-fade-effect{animation-duration:.24s;animation-timing-function:cubic-bezier(.645,.045,.355,1);animation-fill-mode:both}.ant-notification-fade-appear,.ant-notification-fade-enter{animation-duration:.24s;animation-timing-function:cubic-bezier(.645,.045,.355,1);animation-fill-mode:both;opacity:0;animation-play-state:paused}.ant-notification-fade-leave{animation-duration:.24s;animation-timing-function:cubic-bezier(.645,.045,.355,1);animation-fill-mode:both;animation-duration:.2s;animation-play-state:paused}.ant-notification-fade-appear.ant-notification-fade-appear-active,.ant-notification-fade-enter.ant-notification-fade-enter-active{animation-name:NotificationFadeIn;animation-play-state:running}.ant-notification-fade-leave.ant-notification-fade-leave-active{animation-name:NotificationFadeOut;animation-play-state:running}@keyframes NotificationFadeIn{0%{left:384px;opacity:0}to{left:0;opacity:1}}@keyframes NotificationLeftFadeIn{0%{right:384px;opacity:0}to{right:0;opacity:1}}@keyframes NotificationFadeOut{0%{max-height:150px;margin-bottom:16px;opacity:1}to{max-height:0;margin-bottom:0;padding-top:0;padding-bottom:0;opacity:0}}.ant-notification-rtl{direction:rtl}.ant-notification-rtl .ant-notification-notice-closable .ant-notification-notice-message{padding-right:0;padding-left:24px}.ant-notification-rtl .ant-notification-notice-with-icon .ant-notification-notice-message{margin-right:48px;margin-left:0}.ant-notification-rtl .ant-notification-notice-with-icon .ant-notification-notice-description{margin-right:48px;margin-left:0}.ant-notification-rtl .ant-notification-notice-icon{margin-right:4px;margin-left:0}.ant-notification-rtl .ant-notification-notice-close{right:auto;left:22px}.ant-notification-rtl .ant-notification-notice-btn{float:left}.ant-divider{box-sizing:border-box;margin:0;padding:0;color:rgba(0,0,0,.85);font-size:14px;font-variant:tabular-nums;line-height:1.5715;list-style:none;font-feature-settings:"tnum","tnum";border-top:1px solid rgba(0,0,0,.06)}.ant-divider-vertical{position:relative;top:-.06em;display:inline-block;height:.9em;margin:0 8px;vertical-align:middle;border-top:0;border-left:1px solid rgba(0,0,0,.06)}.ant-divider-horizontal{display:flex;clear:both;width:100%;min-width:100%;margin:24px 0}.ant-divider-horizontal.ant-divider-with-text{display:flex;margin:16px 0;color:rgba(0,0,0,.85);font-weight:500;font-size:16px;white-space:nowrap;text-align:center;border-top:0;border-top-color:rgba(0,0,0,.06)}.ant-divider-horizontal.ant-divider-with-text:after,.ant-divider-horizontal.ant-divider-with-text:before{position:relative;top:50%;width:50%;border-top:1px solid transparent;border-top-color:inherit;border-bottom:0;transform:translateY(50%);content:""}.ant-divider-horizontal.ant-divider-with-text-left:before{top:50%;width:5%}.ant-divider-horizontal.ant-divider-with-text-left:after{top:50%;width:95%}.ant-divider-horizontal.ant-divider-with-text-right:before{top:50%;width:95%}.ant-divider-horizontal.ant-divider-with-text-right:after{top:50%;width:5%}.ant-divider-inner-text{display:inline-block;padding:0 1em}.ant-divider-dashed{background:none;border:dashed rgba(0,0,0,.06);border-width:1px 0 0}.ant-divider-horizontal.ant-divider-with-text.ant-divider-dashed{border-top:0}.ant-divider-horizontal.ant-divider-with-text.ant-divider-dashed:after,.ant-divider-horizontal.ant-divider-with-text.ant-divider-dashed:before{border-style:dashed none none}.ant-divider-vertical.ant-divider-dashed{border-width:0 0 0 1px}.ant-divider-plain.ant-divider-with-text{color:rgba(0,0,0,.85);font-weight:400;font-size:14px}.ant-divider-rtl{direction:rtl}.ant-divider-rtl.ant-divider-horizontal.ant-divider-with-text-left:before{width:95%}.ant-divider-rtl.ant-divider-horizontal.ant-divider-with-text-left:after{width:5%}.ant-divider-rtl.ant-divider-horizontal.ant-divider-with-text-right:before{width:5%}.ant-divider-rtl.ant-divider-horizontal.ant-divider-with-text-right:after{width:95%}.ant-descriptions-header{display:flex;align-items:center;margin-bottom:20px}.ant-descriptions-title{flex:auto;overflow:hidden;color:rgba(0,0,0,.85);font-weight:700;font-size:16px;line-height:1.5715;white-space:nowrap;text-overflow:ellipsis}.ant-descriptions-extra{margin-left:auto;color:rgba(0,0,0,.85);font-size:14px}.ant-descriptions-view{width:100%;overflow:hidden;border-radius:2px}.ant-descriptions-view table{width:100%;table-layout:fixed}.ant-descriptions-row>td,.ant-descriptions-row>th{padding-bottom:16px}.ant-descriptions-row:last-child{border-bottom:none}.ant-descriptions-item-label{color:rgba(0,0,0,.85);font-weight:400;font-size:14px;line-height:1.5715;text-align:start}.ant-descriptions-item-label:after{content:":";position:relative;top:-.5px;margin:0 8px 0 2px}.ant-descriptions-item-label.ant-descriptions-item-no-colon:after{content:" "}.ant-descriptions-item-no-label:after{margin:0;content:""}.ant-descriptions-item-content{display:table-cell;flex:1 1;color:rgba(0,0,0,.85);font-size:14px;line-height:1.5715;word-break:break-word;overflow-wrap:break-word}.ant-descriptions-item{padding-bottom:0;vertical-align:top}.ant-descriptions-item-container{display:flex}.ant-descriptions-item-container .ant-descriptions-item-content,.ant-descriptions-item-container .ant-descriptions-item-label{display:inline-flex;align-items:baseline}.ant-descriptions-middle .ant-descriptions-row>td,.ant-descriptions-middle .ant-descriptions-row>th{padding-bottom:12px}.ant-descriptions-small .ant-descriptions-row>td,.ant-descriptions-small .ant-descriptions-row>th{padding-bottom:8px}.ant-descriptions-bordered .ant-descriptions-view{border:1px solid #f0f0f0}.ant-descriptions-bordered .ant-descriptions-view>table{table-layout:auto}.ant-descriptions-bordered .ant-descriptions-item-content,.ant-descriptions-bordered .ant-descriptions-item-label{padding:16px 24px;border-right:1px solid #f0f0f0}.ant-descriptions-bordered .ant-descriptions-item-content:last-child,.ant-descriptions-bordered .ant-descriptions-item-label:last-child{border-right:none}.ant-descriptions-bordered .ant-descriptions-item-label{background-color:#fafafa}.ant-descriptions-bordered .ant-descriptions-item-label:after{display:none}.ant-descriptions-bordered .ant-descriptions-row{border-bottom:1px solid #f0f0f0}.ant-descriptions-bordered .ant-descriptions-row:last-child{border-bottom:none}.ant-descriptions-bordered.ant-descriptions-middle .ant-descriptions-item-content,.ant-descriptions-bordered.ant-descriptions-middle .ant-descriptions-item-label{padding:12px 24px}.ant-descriptions-bordered.ant-descriptions-small .ant-descriptions-item-content,.ant-descriptions-bordered.ant-descriptions-small .ant-descriptions-item-label{padding:8px 16px}.ant-descriptions-rtl{direction:rtl}.ant-descriptions-rtl .ant-descriptions-item-label:after{margin:0 2px 0 8px}.ant-descriptions-rtl.ant-descriptions-bordered .ant-descriptions-item-content,.ant-descriptions-rtl.ant-descriptions-bordered .ant-descriptions-item-label{border-right:none;border-left:1px solid #f0f0f0}.ant-descriptions-rtl.ant-descriptions-bordered .ant-descriptions-item-content:last-child,.ant-descriptions-rtl.ant-descriptions-bordered .ant-descriptions-item-label:last-child{border-left:none}.ant-btn{line-height:1.5715;position:relative;display:inline-block;font-weight:400;white-space:nowrap;text-align:center;background-image:none;box-shadow:0 2px 0 rgba(0,0,0,.015);cursor:pointer;transition:all .3s cubic-bezier(.645,.045,.355,1);-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;touch-action:manipulation;height:32px;padding:4px 15px;font-size:14px;border-radius:2px;color:rgba(0,0,0,.85);background:#fff;border:1px solid #d9d9d9}.ant-btn>.anticon{line-height:1}.ant-btn,.ant-btn:active,.ant-btn:focus{outline:0}.ant-btn:not([disabled]):hover{text-decoration:none}.ant-btn:not([disabled]):active{outline:0;box-shadow:none}.ant-btn[disabled]{cursor:not-allowed}.ant-btn[disabled]>*{pointer-events:none}.ant-btn-lg{height:40px;padding:6.4px 15px;font-size:16px;border-radius:2px}.ant-btn-sm{height:24px;padding:0 7px;font-size:14px;border-radius:2px}.ant-btn>a:only-child{color:currentColor}.ant-btn>a:only-child:after{position:absolute;top:0;right:0;bottom:0;left:0;background:transparent;content:""}.ant-btn:focus,.ant-btn:hover{color:#40a9ff;background:#fff;border-color:#40a9ff}.ant-btn:focus>a:only-child,.ant-btn:hover>a:only-child{color:currentColor}.ant-btn:focus>a:only-child:after,.ant-btn:hover>a:only-child:after{position:absolute;top:0;right:0;bottom:0;left:0;background:transparent;content:""}.ant-btn:active{color:#096dd9;background:#fff;border-color:#096dd9}.ant-btn:active>a:only-child{color:currentColor}.ant-btn:active>a:only-child:after{position:absolute;top:0;right:0;bottom:0;left:0;background:transparent;content:""}.ant-btn[disabled],.ant-btn[disabled]:active,.ant-btn[disabled]:focus,.ant-btn[disabled]:hover{color:rgba(0,0,0,.25);background:#f5f5f5;border-color:#d9d9d9;text-shadow:none;box-shadow:none}.ant-btn[disabled]:active>a:only-child,.ant-btn[disabled]:focus>a:only-child,.ant-btn[disabled]:hover>a:only-child,.ant-btn[disabled]>a:only-child{color:currentColor}.ant-btn[disabled]:active>a:only-child:after,.ant-btn[disabled]:focus>a:only-child:after,.ant-btn[disabled]:hover>a:only-child:after,.ant-btn[disabled]>a:only-child:after{position:absolute;top:0;right:0;bottom:0;left:0;background:transparent;content:""}.ant-btn:active,.ant-btn:focus,.ant-btn:hover{text-decoration:none;background:#fff}.ant-btn>span{display:inline-block}.ant-btn-primary{color:#fff;background:#1890ff;border-color:#1890ff;text-shadow:0 -1px 0 rgba(0,0,0,.12);box-shadow:0 2px 0 rgba(0,0,0,.045)}.ant-btn-primary>a:only-child{color:currentColor}.ant-btn-primary>a:only-child:after{position:absolute;top:0;right:0;bottom:0;left:0;background:transparent;content:""}.ant-btn-primary:focus,.ant-btn-primary:hover{color:#fff;background:#40a9ff;border-color:#40a9ff}.ant-btn-primary:focus>a:only-child,.ant-btn-primary:hover>a:only-child{color:currentColor}.ant-btn-primary:focus>a:only-child:after,.ant-btn-primary:hover>a:only-child:after{position:absolute;top:0;right:0;bottom:0;left:0;background:transparent;content:""}.ant-btn-primary:active{color:#fff;background:#096dd9;border-color:#096dd9}.ant-btn-primary:active>a:only-child{color:currentColor}.ant-btn-primary:active>a:only-child:after{position:absolute;top:0;right:0;bottom:0;left:0;background:transparent;content:""}.ant-btn-primary[disabled],.ant-btn-primary[disabled]:active,.ant-btn-primary[disabled]:focus,.ant-btn-primary[disabled]:hover{color:rgba(0,0,0,.25);background:#f5f5f5;border-color:#d9d9d9;text-shadow:none;box-shadow:none}.ant-btn-primary[disabled]:active>a:only-child,.ant-btn-primary[disabled]:focus>a:only-child,.ant-btn-primary[disabled]:hover>a:only-child,.ant-btn-primary[disabled]>a:only-child{color:currentColor}.ant-btn-primary[disabled]:active>a:only-child:after,.ant-btn-primary[disabled]:focus>a:only-child:after,.ant-btn-primary[disabled]:hover>a:only-child:after,.ant-btn-primary[disabled]>a:only-child:after{position:absolute;top:0;right:0;bottom:0;left:0;background:transparent;content:""}.ant-btn-group .ant-btn-primary:not(:first-child):not(:last-child){border-right-color:#40a9ff;border-left-color:#40a9ff}.ant-btn-group .ant-btn-primary:not(:first-child):not(:last-child):disabled{border-color:#d9d9d9}.ant-btn-group .ant-btn-primary:first-child:not(:last-child){border-right-color:#40a9ff}.ant-btn-group .ant-btn-primary:first-child:not(:last-child)[disabled]{border-right-color:#d9d9d9}.ant-btn-group .ant-btn-primary+.ant-btn-primary,.ant-btn-group .ant-btn-primary:last-child:not(:first-child){border-left-color:#40a9ff}.ant-btn-group .ant-btn-primary+.ant-btn-primary[disabled],.ant-btn-group .ant-btn-primary:last-child:not(:first-child)[disabled]{border-left-color:#d9d9d9}.ant-btn-ghost{color:rgba(0,0,0,.85);background:transparent;border-color:#d9d9d9}.ant-btn-ghost>a:only-child{color:currentColor}.ant-btn-ghost>a:only-child:after{position:absolute;top:0;right:0;bottom:0;left:0;background:transparent;content:""}.ant-btn-ghost:focus,.ant-btn-ghost:hover{color:#40a9ff;background:transparent;border-color:#40a9ff}.ant-btn-ghost:focus>a:only-child,.ant-btn-ghost:hover>a:only-child{color:currentColor}.ant-btn-ghost:focus>a:only-child:after,.ant-btn-ghost:hover>a:only-child:after{position:absolute;top:0;right:0;bottom:0;left:0;background:transparent;content:""}.ant-btn-ghost:active{color:#096dd9;background:transparent;border-color:#096dd9}.ant-btn-ghost:active>a:only-child{color:currentColor}.ant-btn-ghost:active>a:only-child:after{position:absolute;top:0;right:0;bottom:0;left:0;background:transparent;content:""}.ant-btn-ghost[disabled],.ant-btn-ghost[disabled]:active,.ant-btn-ghost[disabled]:focus,.ant-btn-ghost[disabled]:hover{color:rgba(0,0,0,.25);background:#f5f5f5;border-color:#d9d9d9;text-shadow:none;box-shadow:none}.ant-btn-ghost[disabled]:active>a:only-child,.ant-btn-ghost[disabled]:focus>a:only-child,.ant-btn-ghost[disabled]:hover>a:only-child,.ant-btn-ghost[disabled]>a:only-child{color:currentColor}.ant-btn-ghost[disabled]:active>a:only-child:after,.ant-btn-ghost[disabled]:focus>a:only-child:after,.ant-btn-ghost[disabled]:hover>a:only-child:after,.ant-btn-ghost[disabled]>a:only-child:after{position:absolute;top:0;right:0;bottom:0;left:0;background:transparent;content:""}.ant-btn-dashed{color:rgba(0,0,0,.85);background:#fff;border-color:#d9d9d9;border-style:dashed}.ant-btn-dashed>a:only-child{color:currentColor}.ant-btn-dashed>a:only-child:after{position:absolute;top:0;right:0;bottom:0;left:0;background:transparent;content:""}.ant-btn-dashed:focus,.ant-btn-dashed:hover{color:#40a9ff;background:#fff;border-color:#40a9ff}.ant-btn-dashed:focus>a:only-child,.ant-btn-dashed:hover>a:only-child{color:currentColor}.ant-btn-dashed:focus>a:only-child:after,.ant-btn-dashed:hover>a:only-child:after{position:absolute;top:0;right:0;bottom:0;left:0;background:transparent;content:""}.ant-btn-dashed:active{color:#096dd9;background:#fff;border-color:#096dd9}.ant-btn-dashed:active>a:only-child{color:currentColor}.ant-btn-dashed:active>a:only-child:after{position:absolute;top:0;right:0;bottom:0;left:0;background:transparent;content:""}.ant-btn-dashed[disabled],.ant-btn-dashed[disabled]:active,.ant-btn-dashed[disabled]:focus,.ant-btn-dashed[disabled]:hover{color:rgba(0,0,0,.25);background:#f5f5f5;border-color:#d9d9d9;text-shadow:none;box-shadow:none}.ant-btn-dashed[disabled]:active>a:only-child,.ant-btn-dashed[disabled]:focus>a:only-child,.ant-btn-dashed[disabled]:hover>a:only-child,.ant-btn-dashed[disabled]>a:only-child{color:currentColor}.ant-btn-dashed[disabled]:active>a:only-child:after,.ant-btn-dashed[disabled]:focus>a:only-child:after,.ant-btn-dashed[disabled]:hover>a:only-child:after,.ant-btn-dashed[disabled]>a:only-child:after{position:absolute;top:0;right:0;bottom:0;left:0;background:transparent;content:""}.ant-btn-danger{color:#fff;background:#ff4d4f;border-color:#ff4d4f;text-shadow:0 -1px 0 rgba(0,0,0,.12);box-shadow:0 2px 0 rgba(0,0,0,.045)}.ant-btn-danger>a:only-child{color:currentColor}.ant-btn-danger>a:only-child:after{position:absolute;top:0;right:0;bottom:0;left:0;background:transparent;content:""}.ant-btn-danger:focus,.ant-btn-danger:hover{color:#fff;background:#ff7875;border-color:#ff7875}.ant-btn-danger:focus>a:only-child,.ant-btn-danger:hover>a:only-child{color:currentColor}.ant-btn-danger:focus>a:only-child:after,.ant-btn-danger:hover>a:only-child:after{position:absolute;top:0;right:0;bottom:0;left:0;background:transparent;content:""}.ant-btn-danger:active{color:#fff;background:#d9363e;border-color:#d9363e}.ant-btn-danger:active>a:only-child{color:currentColor}.ant-btn-danger:active>a:only-child:after{position:absolute;top:0;right:0;bottom:0;left:0;background:transparent;content:""}.ant-btn-danger[disabled],.ant-btn-danger[disabled]:active,.ant-btn-danger[disabled]:focus,.ant-btn-danger[disabled]:hover{color:rgba(0,0,0,.25);background:#f5f5f5;border-color:#d9d9d9;text-shadow:none;box-shadow:none}.ant-btn-danger[disabled]:active>a:only-child,.ant-btn-danger[disabled]:focus>a:only-child,.ant-btn-danger[disabled]:hover>a:only-child,.ant-btn-danger[disabled]>a:only-child{color:currentColor}.ant-btn-danger[disabled]:active>a:only-child:after,.ant-btn-danger[disabled]:focus>a:only-child:after,.ant-btn-danger[disabled]:hover>a:only-child:after,.ant-btn-danger[disabled]>a:only-child:after{position:absolute;top:0;right:0;bottom:0;left:0;background:transparent;content:""}.ant-btn-link{color:#1890ff;background:transparent;border-color:transparent;box-shadow:none}.ant-btn-link>a:only-child{color:currentColor}.ant-btn-link>a:only-child:after{position:absolute;top:0;right:0;bottom:0;left:0;background:transparent;content:""}.ant-btn-link:focus,.ant-btn-link:hover{color:#40a9ff;background:transparent;border-color:#40a9ff}.ant-btn-link:focus>a:only-child,.ant-btn-link:hover>a:only-child{color:currentColor}.ant-btn-link:focus>a:only-child:after,.ant-btn-link:hover>a:only-child:after{position:absolute;top:0;right:0;bottom:0;left:0;background:transparent;content:""}.ant-btn-link:active{color:#096dd9;background:transparent;border-color:#096dd9}.ant-btn-link:active>a:only-child{color:currentColor}.ant-btn-link:active>a:only-child:after{position:absolute;top:0;right:0;bottom:0;left:0;background:transparent;content:""}.ant-btn-link[disabled],.ant-btn-link[disabled]:active,.ant-btn-link[disabled]:focus,.ant-btn-link[disabled]:hover{background:#f5f5f5;border-color:#d9d9d9}.ant-btn-link:hover{background:transparent}.ant-btn-link:active,.ant-btn-link:focus,.ant-btn-link:hover{border-color:transparent}.ant-btn-link[disabled],.ant-btn-link[disabled]:active,.ant-btn-link[disabled]:focus,.ant-btn-link[disabled]:hover{color:rgba(0,0,0,.25);background:transparent;border-color:transparent;text-shadow:none;box-shadow:none}.ant-btn-link[disabled]:active>a:only-child,.ant-btn-link[disabled]:focus>a:only-child,.ant-btn-link[disabled]:hover>a:only-child,.ant-btn-link[disabled]>a:only-child{color:currentColor}.ant-btn-link[disabled]:active>a:only-child:after,.ant-btn-link[disabled]:focus>a:only-child:after,.ant-btn-link[disabled]:hover>a:only-child:after,.ant-btn-link[disabled]>a:only-child:after{position:absolute;top:0;right:0;bottom:0;left:0;background:transparent;content:""}.ant-btn-text{color:rgba(0,0,0,.85);background:transparent;border-color:transparent;box-shadow:none}.ant-btn-text>a:only-child{color:currentColor}.ant-btn-text>a:only-child:after{position:absolute;top:0;right:0;bottom:0;left:0;background:transparent;content:""}.ant-btn-text:focus,.ant-btn-text:hover{color:#40a9ff;background:transparent;border-color:#40a9ff}.ant-btn-text:focus>a:only-child,.ant-btn-text:hover>a:only-child{color:currentColor}.ant-btn-text:focus>a:only-child:after,.ant-btn-text:hover>a:only-child:after{position:absolute;top:0;right:0;bottom:0;left:0;background:transparent;content:""}.ant-btn-text:active{color:#096dd9;background:transparent;border-color:#096dd9}.ant-btn-text:active>a:only-child{color:currentColor}.ant-btn-text:active>a:only-child:after{position:absolute;top:0;right:0;bottom:0;left:0;background:transparent;content:""}.ant-btn-text[disabled],.ant-btn-text[disabled]:active,.ant-btn-text[disabled]:focus,.ant-btn-text[disabled]:hover{background:#f5f5f5;border-color:#d9d9d9}.ant-btn-text:focus,.ant-btn-text:hover{color:rgba(0,0,0,.85);background:rgba(0,0,0,.018);border-color:transparent}.ant-btn-text:active{color:rgba(0,0,0,.85);background:rgba(0,0,0,.028);border-color:transparent}.ant-btn-text[disabled],.ant-btn-text[disabled]:active,.ant-btn-text[disabled]:focus,.ant-btn-text[disabled]:hover{color:rgba(0,0,0,.25);background:transparent;border-color:transparent;text-shadow:none;box-shadow:none}.ant-btn-text[disabled]:active>a:only-child,.ant-btn-text[disabled]:focus>a:only-child,.ant-btn-text[disabled]:hover>a:only-child,.ant-btn-text[disabled]>a:only-child{color:currentColor}.ant-btn-text[disabled]:active>a:only-child:after,.ant-btn-text[disabled]:focus>a:only-child:after,.ant-btn-text[disabled]:hover>a:only-child:after,.ant-btn-text[disabled]>a:only-child:after{position:absolute;top:0;right:0;bottom:0;left:0;background:transparent;content:""}.ant-btn-dangerous{color:#ff4d4f;background:#fff;border-color:#ff4d4f}.ant-btn-dangerous>a:only-child{color:currentColor}.ant-btn-dangerous>a:only-child:after{position:absolute;top:0;right:0;bottom:0;left:0;background:transparent;content:""}.ant-btn-dangerous:focus,.ant-btn-dangerous:hover{color:#ff7875;background:#fff;border-color:#ff7875}.ant-btn-dangerous:focus>a:only-child,.ant-btn-dangerous:hover>a:only-child{color:currentColor}.ant-btn-dangerous:focus>a:only-child:after,.ant-btn-dangerous:hover>a:only-child:after{position:absolute;top:0;right:0;bottom:0;left:0;background:transparent;content:""}.ant-btn-dangerous:active{color:#d9363e;background:#fff;border-color:#d9363e}.ant-btn-dangerous:active>a:only-child{color:currentColor}.ant-btn-dangerous:active>a:only-child:after{position:absolute;top:0;right:0;bottom:0;left:0;background:transparent;content:""}.ant-btn-dangerous[disabled],.ant-btn-dangerous[disabled]:active,.ant-btn-dangerous[disabled]:focus,.ant-btn-dangerous[disabled]:hover{color:rgba(0,0,0,.25);background:#f5f5f5;border-color:#d9d9d9;text-shadow:none;box-shadow:none}.ant-btn-dangerous[disabled]:active>a:only-child,.ant-btn-dangerous[disabled]:focus>a:only-child,.ant-btn-dangerous[disabled]:hover>a:only-child,.ant-btn-dangerous[disabled]>a:only-child{color:currentColor}.ant-btn-dangerous[disabled]:active>a:only-child:after,.ant-btn-dangerous[disabled]:focus>a:only-child:after,.ant-btn-dangerous[disabled]:hover>a:only-child:after,.ant-btn-dangerous[disabled]>a:only-child:after{position:absolute;top:0;right:0;bottom:0;left:0;background:transparent;content:""}.ant-btn-dangerous.ant-btn-primary{color:#fff;background:#ff4d4f;border-color:#ff4d4f;text-shadow:0 -1px 0 rgba(0,0,0,.12);box-shadow:0 2px 0 rgba(0,0,0,.045)}.ant-btn-dangerous.ant-btn-primary>a:only-child{color:currentColor}.ant-btn-dangerous.ant-btn-primary>a:only-child:after{position:absolute;top:0;right:0;bottom:0;left:0;background:transparent;content:""}.ant-btn-dangerous.ant-btn-primary:focus,.ant-btn-dangerous.ant-btn-primary:hover{color:#fff;background:#ff7875;border-color:#ff7875}.ant-btn-dangerous.ant-btn-primary:focus>a:only-child,.ant-btn-dangerous.ant-btn-primary:hover>a:only-child{color:currentColor}.ant-btn-dangerous.ant-btn-primary:focus>a:only-child:after,.ant-btn-dangerous.ant-btn-primary:hover>a:only-child:after{position:absolute;top:0;right:0;bottom:0;left:0;background:transparent;content:""}.ant-btn-dangerous.ant-btn-primary:active{color:#fff;background:#d9363e;border-color:#d9363e}.ant-btn-dangerous.ant-btn-primary:active>a:only-child{color:currentColor}.ant-btn-dangerous.ant-btn-primary:active>a:only-child:after{position:absolute;top:0;right:0;bottom:0;left:0;background:transparent;content:""}.ant-btn-dangerous.ant-btn-primary[disabled],.ant-btn-dangerous.ant-btn-primary[disabled]:active,.ant-btn-dangerous.ant-btn-primary[disabled]:focus,.ant-btn-dangerous.ant-btn-primary[disabled]:hover{color:rgba(0,0,0,.25);background:#f5f5f5;border-color:#d9d9d9;text-shadow:none;box-shadow:none}.ant-btn-dangerous.ant-btn-primary[disabled]:active>a:only-child,.ant-btn-dangerous.ant-btn-primary[disabled]:focus>a:only-child,.ant-btn-dangerous.ant-btn-primary[disabled]:hover>a:only-child,.ant-btn-dangerous.ant-btn-primary[disabled]>a:only-child{color:currentColor}.ant-btn-dangerous.ant-btn-primary[disabled]:active>a:only-child:after,.ant-btn-dangerous.ant-btn-primary[disabled]:focus>a:only-child:after,.ant-btn-dangerous.ant-btn-primary[disabled]:hover>a:only-child:after,.ant-btn-dangerous.ant-btn-primary[disabled]>a:only-child:after{position:absolute;top:0;right:0;bottom:0;left:0;background:transparent;content:""}.ant-btn-dangerous.ant-btn-link{color:#ff4d4f;background:transparent;border-color:transparent;box-shadow:none}.ant-btn-dangerous.ant-btn-link>a:only-child{color:currentColor}.ant-btn-dangerous.ant-btn-link>a:only-child:after{position:absolute;top:0;right:0;bottom:0;left:0;background:transparent;content:""}.ant-btn-dangerous.ant-btn-link:focus,.ant-btn-dangerous.ant-btn-link:hover{color:#40a9ff;border-color:#40a9ff}.ant-btn-dangerous.ant-btn-link:active{color:#096dd9;border-color:#096dd9}.ant-btn-dangerous.ant-btn-link[disabled],.ant-btn-dangerous.ant-btn-link[disabled]:active,.ant-btn-dangerous.ant-btn-link[disabled]:focus,.ant-btn-dangerous.ant-btn-link[disabled]:hover{background:#f5f5f5;border-color:#d9d9d9}.ant-btn-dangerous.ant-btn-link:focus,.ant-btn-dangerous.ant-btn-link:hover{color:#ff7875;background:transparent;border-color:transparent}.ant-btn-dangerous.ant-btn-link:focus>a:only-child,.ant-btn-dangerous.ant-btn-link:hover>a:only-child{color:currentColor}.ant-btn-dangerous.ant-btn-link:focus>a:only-child:after,.ant-btn-dangerous.ant-btn-link:hover>a:only-child:after{position:absolute;top:0;right:0;bottom:0;left:0;background:transparent;content:""}.ant-btn-dangerous.ant-btn-link:active{color:#d9363e;background:transparent;border-color:transparent}.ant-btn-dangerous.ant-btn-link:active>a:only-child{color:currentColor}.ant-btn-dangerous.ant-btn-link:active>a:only-child:after{position:absolute;top:0;right:0;bottom:0;left:0;background:transparent;content:""}.ant-btn-dangerous.ant-btn-link[disabled],.ant-btn-dangerous.ant-btn-link[disabled]:active,.ant-btn-dangerous.ant-btn-link[disabled]:focus,.ant-btn-dangerous.ant-btn-link[disabled]:hover{color:rgba(0,0,0,.25);background:transparent;border-color:transparent;text-shadow:none;box-shadow:none}.ant-btn-dangerous.ant-btn-link[disabled]:active>a:only-child,.ant-btn-dangerous.ant-btn-link[disabled]:focus>a:only-child,.ant-btn-dangerous.ant-btn-link[disabled]:hover>a:only-child,.ant-btn-dangerous.ant-btn-link[disabled]>a:only-child{color:currentColor}.ant-btn-dangerous.ant-btn-link[disabled]:active>a:only-child:after,.ant-btn-dangerous.ant-btn-link[disabled]:focus>a:only-child:after,.ant-btn-dangerous.ant-btn-link[disabled]:hover>a:only-child:after,.ant-btn-dangerous.ant-btn-link[disabled]>a:only-child:after{position:absolute;top:0;right:0;bottom:0;left:0;background:transparent;content:""}.ant-btn-dangerous.ant-btn-text{color:#ff4d4f;background:transparent;border-color:transparent;box-shadow:none}.ant-btn-dangerous.ant-btn-text>a:only-child{color:currentColor}.ant-btn-dangerous.ant-btn-text>a:only-child:after{position:absolute;top:0;right:0;bottom:0;left:0;background:transparent;content:""}.ant-btn-dangerous.ant-btn-text:focus,.ant-btn-dangerous.ant-btn-text:hover{color:#40a9ff;background:transparent;border-color:#40a9ff}.ant-btn-dangerous.ant-btn-text:active{color:#096dd9;background:transparent;border-color:#096dd9}.ant-btn-dangerous.ant-btn-text[disabled],.ant-btn-dangerous.ant-btn-text[disabled]:active,.ant-btn-dangerous.ant-btn-text[disabled]:focus,.ant-btn-dangerous.ant-btn-text[disabled]:hover{background:#f5f5f5;border-color:#d9d9d9}.ant-btn-dangerous.ant-btn-text:focus,.ant-btn-dangerous.ant-btn-text:hover{color:#ff7875;background:rgba(0,0,0,.018);border-color:transparent}.ant-btn-dangerous.ant-btn-text:focus>a:only-child,.ant-btn-dangerous.ant-btn-text:hover>a:only-child{color:currentColor}.ant-btn-dangerous.ant-btn-text:focus>a:only-child:after,.ant-btn-dangerous.ant-btn-text:hover>a:only-child:after{position:absolute;top:0;right:0;bottom:0;left:0;background:transparent;content:""}.ant-btn-dangerous.ant-btn-text:active{color:#d9363e;background:rgba(0,0,0,.028);border-color:transparent}.ant-btn-dangerous.ant-btn-text:active>a:only-child{color:currentColor}.ant-btn-dangerous.ant-btn-text:active>a:only-child:after{position:absolute;top:0;right:0;bottom:0;left:0;background:transparent;content:""}.ant-btn-dangerous.ant-btn-text[disabled],.ant-btn-dangerous.ant-btn-text[disabled]:active,.ant-btn-dangerous.ant-btn-text[disabled]:focus,.ant-btn-dangerous.ant-btn-text[disabled]:hover{color:rgba(0,0,0,.25);background:transparent;border-color:transparent;text-shadow:none;box-shadow:none}.ant-btn-dangerous.ant-btn-text[disabled]:active>a:only-child,.ant-btn-dangerous.ant-btn-text[disabled]:focus>a:only-child,.ant-btn-dangerous.ant-btn-text[disabled]:hover>a:only-child,.ant-btn-dangerous.ant-btn-text[disabled]>a:only-child{color:currentColor}.ant-btn-dangerous.ant-btn-text[disabled]:active>a:only-child:after,.ant-btn-dangerous.ant-btn-text[disabled]:focus>a:only-child:after,.ant-btn-dangerous.ant-btn-text[disabled]:hover>a:only-child:after,.ant-btn-dangerous.ant-btn-text[disabled]>a:only-child:after{position:absolute;top:0;right:0;bottom:0;left:0;background:transparent;content:""}.ant-btn-icon-only{width:32px;height:32px;padding:2.4px 0;font-size:16px;border-radius:2px;vertical-align:-1px}.ant-btn-icon-only>*{font-size:16px}.ant-btn-icon-only.ant-btn-lg{width:40px;height:40px;padding:4.9px 0;font-size:18px;border-radius:2px}.ant-btn-icon-only.ant-btn-lg>*{font-size:18px}.ant-btn-icon-only.ant-btn-sm{width:24px;height:24px;padding:0;font-size:14px;border-radius:2px}.ant-btn-icon-only.ant-btn-sm>*{font-size:14px}.ant-btn-round{height:32px;padding:4px 16px;font-size:14px;border-radius:32px}.ant-btn-round.ant-btn-lg{height:40px;padding:6.4px 20px;font-size:16px;border-radius:40px}.ant-btn-round.ant-btn-sm{height:24px;padding:0 12px;font-size:14px;border-radius:24px}.ant-btn-round.ant-btn-icon-only{width:auto}.ant-btn-circle{min-width:32px;padding-right:0;padding-left:0;text-align:center;border-radius:50%}.ant-btn-circle.ant-btn-lg{min-width:40px;border-radius:50%}.ant-btn-circle.ant-btn-sm{min-width:24px;border-radius:50%}.ant-btn:before{position:absolute;top:-1px;right:-1px;bottom:-1px;left:-1px;z-index:1;display:none;background:#fff;border-radius:inherit;opacity:.35;transition:opacity .2s;content:"";pointer-events:none}.ant-btn .anticon{transition:margin-left .3s cubic-bezier(.645,.045,.355,1)}.ant-btn .anticon.anticon-minus>svg,.ant-btn .anticon.anticon-plus>svg{shape-rendering:optimizeSpeed}.ant-btn.ant-btn-loading{position:relative}.ant-btn.ant-btn-loading:not([disabled]){pointer-events:none}.ant-btn.ant-btn-loading:before{display:block}.ant-btn>.ant-btn-loading-icon{transition:all .3s cubic-bezier(.645,.045,.355,1)}.ant-btn>.ant-btn-loading-icon .anticon{padding-right:8px;animation:none}.ant-btn>.ant-btn-loading-icon .anticon svg{animation:loadingCircle 1s linear infinite}.ant-btn-group{position:relative;display:inline-flex}.ant-btn-group>.ant-btn,.ant-btn-group>span>.ant-btn{position:relative}.ant-btn-group>.ant-btn:active,.ant-btn-group>.ant-btn:focus,.ant-btn-group>.ant-btn:hover,.ant-btn-group>span>.ant-btn:active,.ant-btn-group>span>.ant-btn:focus,.ant-btn-group>span>.ant-btn:hover{z-index:2}.ant-btn-group>.ant-btn[disabled],.ant-btn-group>span>.ant-btn[disabled]{z-index:0}.ant-btn-group .ant-btn-icon-only{font-size:14px}.ant-btn-group-lg>.ant-btn,.ant-btn-group-lg>span>.ant-btn{height:40px;padding:6.4px 15px;font-size:16px;border-radius:0}.ant-btn-group-lg .ant-btn.ant-btn-icon-only{width:40px;height:40px;padding-right:0;padding-left:0}.ant-btn-group-sm>.ant-btn,.ant-btn-group-sm>span>.ant-btn{height:24px;padding:0 7px;font-size:14px;border-radius:0}.ant-btn-group-sm>.ant-btn>.anticon,.ant-btn-group-sm>span>.ant-btn>.anticon{font-size:14px}.ant-btn-group-sm .ant-btn.ant-btn-icon-only{width:24px;height:24px;padding-right:0;padding-left:0}.ant-btn+.ant-btn-group,.ant-btn-group+.ant-btn,.ant-btn-group+.ant-btn-group,.ant-btn-group .ant-btn+.ant-btn,.ant-btn-group .ant-btn+span,.ant-btn-group>span+span,.ant-btn-group span+.ant-btn{margin-left:-1px}.ant-btn-group .ant-btn-primary+.ant-btn:not(.ant-btn-primary):not([disabled]){border-left-color:transparent}.ant-btn-group .ant-btn{border-radius:0}.ant-btn-group>.ant-btn:first-child,.ant-btn-group>span:first-child>.ant-btn{margin-left:0}.ant-btn-group>.ant-btn:only-child{border-radius:2px}.ant-btn-group>span:only-child>.ant-btn{border-radius:2px}.ant-btn-group>.ant-btn:first-child:not(:last-child),.ant-btn-group>span:first-child:not(:last-child)>.ant-btn{border-top-left-radius:2px;border-bottom-left-radius:2px}.ant-btn-group>.ant-btn:last-child:not(:first-child),.ant-btn-group>span:last-child:not(:first-child)>.ant-btn{border-top-right-radius:2px;border-bottom-right-radius:2px}.ant-btn-group-sm>.ant-btn:only-child{border-radius:2px}.ant-btn-group-sm>span:only-child>.ant-btn{border-radius:2px}.ant-btn-group-sm>.ant-btn:first-child:not(:last-child),.ant-btn-group-sm>span:first-child:not(:last-child)>.ant-btn{border-top-left-radius:2px;border-bottom-left-radius:2px}.ant-btn-group-sm>.ant-btn:last-child:not(:first-child),.ant-btn-group-sm>span:last-child:not(:first-child)>.ant-btn{border-top-right-radius:2px;border-bottom-right-radius:2px}.ant-btn-group>.ant-btn-group{float:left}.ant-btn-group>.ant-btn-group:not(:first-child):not(:last-child)>.ant-btn{border-radius:0}.ant-btn-group>.ant-btn-group:first-child:not(:last-child)>.ant-btn:last-child{padding-right:8px;border-top-right-radius:0;border-bottom-right-radius:0}.ant-btn-group>.ant-btn-group:last-child:not(:first-child)>.ant-btn:first-child{padding-left:8px;border-top-left-radius:0;border-bottom-left-radius:0}.ant-btn-group-rtl.ant-btn+.ant-btn-group,.ant-btn-group-rtl.ant-btn-group+.ant-btn,.ant-btn-group-rtl.ant-btn-group+.ant-btn-group,.ant-btn-group-rtl.ant-btn-group .ant-btn+.ant-btn,.ant-btn-group-rtl.ant-btn-group .ant-btn+span,.ant-btn-group-rtl.ant-btn-group>span+span,.ant-btn-group-rtl.ant-btn-group span+.ant-btn,.ant-btn-rtl.ant-btn+.ant-btn-group,.ant-btn-rtl.ant-btn-group+.ant-btn,.ant-btn-rtl.ant-btn-group+.ant-btn-group,.ant-btn-rtl.ant-btn-group .ant-btn+.ant-btn,.ant-btn-rtl.ant-btn-group .ant-btn+span,.ant-btn-rtl.ant-btn-group>span+span,.ant-btn-rtl.ant-btn-group span+.ant-btn{margin-right:-1px;margin-left:auto}.ant-btn-group.ant-btn-group-rtl{direction:rtl}.ant-btn-group-rtl.ant-btn-group>.ant-btn:first-child:not(:last-child),.ant-btn-group-rtl.ant-btn-group>span:first-child:not(:last-child)>.ant-btn{border-top-left-radius:0;border-top-right-radius:2px;border-bottom-right-radius:2px;border-bottom-left-radius:0}.ant-btn-group-rtl.ant-btn-group>.ant-btn:last-child:not(:first-child),.ant-btn-group-rtl.ant-btn-group>span:last-child:not(:first-child)>.ant-btn{border-top-left-radius:2px;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:2px}.ant-btn-group-rtl.ant-btn-group-sm>.ant-btn:first-child:not(:last-child),.ant-btn-group-rtl.ant-btn-group-sm>span:first-child:not(:last-child)>.ant-btn{border-top-left-radius:0;border-top-right-radius:2px;border-bottom-right-radius:2px;border-bottom-left-radius:0}.ant-btn-group-rtl.ant-btn-group-sm>.ant-btn:last-child:not(:first-child),.ant-btn-group-rtl.ant-btn-group-sm>span:last-child:not(:first-child)>.ant-btn{border-top-left-radius:2px;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:2px}.ant-btn:active>span,.ant-btn:focus>span{position:relative}.ant-btn>.anticon+span,.ant-btn>span+.anticon{margin-left:8px}.ant-btn-background-ghost{color:#fff;background:transparent!important;border-color:#fff}.ant-btn-background-ghost.ant-btn-primary{color:#1890ff;background:transparent;border-color:#1890ff;text-shadow:none}.ant-btn-background-ghost.ant-btn-primary>a:only-child{color:currentColor}.ant-btn-background-ghost.ant-btn-primary>a:only-child:after{position:absolute;top:0;right:0;bottom:0;left:0;background:transparent;content:""}.ant-btn-background-ghost.ant-btn-primary:focus,.ant-btn-background-ghost.ant-btn-primary:hover{color:#40a9ff;background:transparent;border-color:#40a9ff}.ant-btn-background-ghost.ant-btn-primary:focus>a:only-child,.ant-btn-background-ghost.ant-btn-primary:hover>a:only-child{color:currentColor}.ant-btn-background-ghost.ant-btn-primary:focus>a:only-child:after,.ant-btn-background-ghost.ant-btn-primary:hover>a:only-child:after{position:absolute;top:0;right:0;bottom:0;left:0;background:transparent;content:""}.ant-btn-background-ghost.ant-btn-primary:active{color:#096dd9;background:transparent;border-color:#096dd9}.ant-btn-background-ghost.ant-btn-primary:active>a:only-child{color:currentColor}.ant-btn-background-ghost.ant-btn-primary:active>a:only-child:after{position:absolute;top:0;right:0;bottom:0;left:0;background:transparent;content:""}.ant-btn-background-ghost.ant-btn-primary[disabled],.ant-btn-background-ghost.ant-btn-primary[disabled]:active,.ant-btn-background-ghost.ant-btn-primary[disabled]:focus,.ant-btn-background-ghost.ant-btn-primary[disabled]:hover{color:rgba(0,0,0,.25);background:#f5f5f5;border-color:#d9d9d9;text-shadow:none;box-shadow:none}.ant-btn-background-ghost.ant-btn-primary[disabled]:active>a:only-child,.ant-btn-background-ghost.ant-btn-primary[disabled]:focus>a:only-child,.ant-btn-background-ghost.ant-btn-primary[disabled]:hover>a:only-child,.ant-btn-background-ghost.ant-btn-primary[disabled]>a:only-child{color:currentColor}.ant-btn-background-ghost.ant-btn-primary[disabled]:active>a:only-child:after,.ant-btn-background-ghost.ant-btn-primary[disabled]:focus>a:only-child:after,.ant-btn-background-ghost.ant-btn-primary[disabled]:hover>a:only-child:after,.ant-btn-background-ghost.ant-btn-primary[disabled]>a:only-child:after{position:absolute;top:0;right:0;bottom:0;left:0;background:transparent;content:""}.ant-btn-background-ghost.ant-btn-danger{color:#ff4d4f;background:transparent;border-color:#ff4d4f;text-shadow:none}.ant-btn-background-ghost.ant-btn-danger>a:only-child{color:currentColor}.ant-btn-background-ghost.ant-btn-danger>a:only-child:after{position:absolute;top:0;right:0;bottom:0;left:0;background:transparent;content:""}.ant-btn-background-ghost.ant-btn-danger:focus,.ant-btn-background-ghost.ant-btn-danger:hover{color:#ff7875;background:transparent;border-color:#ff7875}.ant-btn-background-ghost.ant-btn-danger:focus>a:only-child,.ant-btn-background-ghost.ant-btn-danger:hover>a:only-child{color:currentColor}.ant-btn-background-ghost.ant-btn-danger:focus>a:only-child:after,.ant-btn-background-ghost.ant-btn-danger:hover>a:only-child:after{position:absolute;top:0;right:0;bottom:0;left:0;background:transparent;content:""}.ant-btn-background-ghost.ant-btn-danger:active{color:#d9363e;background:transparent;border-color:#d9363e}.ant-btn-background-ghost.ant-btn-danger:active>a:only-child{color:currentColor}.ant-btn-background-ghost.ant-btn-danger:active>a:only-child:after{position:absolute;top:0;right:0;bottom:0;left:0;background:transparent;content:""}.ant-btn-background-ghost.ant-btn-danger[disabled],.ant-btn-background-ghost.ant-btn-danger[disabled]:active,.ant-btn-background-ghost.ant-btn-danger[disabled]:focus,.ant-btn-background-ghost.ant-btn-danger[disabled]:hover{color:rgba(0,0,0,.25);background:#f5f5f5;border-color:#d9d9d9;text-shadow:none;box-shadow:none}.ant-btn-background-ghost.ant-btn-danger[disabled]:active>a:only-child,.ant-btn-background-ghost.ant-btn-danger[disabled]:focus>a:only-child,.ant-btn-background-ghost.ant-btn-danger[disabled]:hover>a:only-child,.ant-btn-background-ghost.ant-btn-danger[disabled]>a:only-child{color:currentColor}.ant-btn-background-ghost.ant-btn-danger[disabled]:active>a:only-child:after,.ant-btn-background-ghost.ant-btn-danger[disabled]:focus>a:only-child:after,.ant-btn-background-ghost.ant-btn-danger[disabled]:hover>a:only-child:after,.ant-btn-background-ghost.ant-btn-danger[disabled]>a:only-child:after{position:absolute;top:0;right:0;bottom:0;left:0;background:transparent;content:""}.ant-btn-background-ghost.ant-btn-dangerous{color:#ff4d4f;background:transparent;border-color:#ff4d4f;text-shadow:none}.ant-btn-background-ghost.ant-btn-dangerous>a:only-child{color:currentColor}.ant-btn-background-ghost.ant-btn-dangerous>a:only-child:after{position:absolute;top:0;right:0;bottom:0;left:0;background:transparent;content:""}.ant-btn-background-ghost.ant-btn-dangerous:focus,.ant-btn-background-ghost.ant-btn-dangerous:hover{color:#ff7875;background:transparent;border-color:#ff7875}.ant-btn-background-ghost.ant-btn-dangerous:focus>a:only-child,.ant-btn-background-ghost.ant-btn-dangerous:hover>a:only-child{color:currentColor}.ant-btn-background-ghost.ant-btn-dangerous:focus>a:only-child:after,.ant-btn-background-ghost.ant-btn-dangerous:hover>a:only-child:after{position:absolute;top:0;right:0;bottom:0;left:0;background:transparent;content:""}.ant-btn-background-ghost.ant-btn-dangerous:active{color:#d9363e;background:transparent;border-color:#d9363e}.ant-btn-background-ghost.ant-btn-dangerous:active>a:only-child{color:currentColor}.ant-btn-background-ghost.ant-btn-dangerous:active>a:only-child:after{position:absolute;top:0;right:0;bottom:0;left:0;background:transparent;content:""}.ant-btn-background-ghost.ant-btn-dangerous[disabled],.ant-btn-background-ghost.ant-btn-dangerous[disabled]:active,.ant-btn-background-ghost.ant-btn-dangerous[disabled]:focus,.ant-btn-background-ghost.ant-btn-dangerous[disabled]:hover{color:rgba(0,0,0,.25);background:#f5f5f5;border-color:#d9d9d9;text-shadow:none;box-shadow:none}.ant-btn-background-ghost.ant-btn-dangerous[disabled]:active>a:only-child,.ant-btn-background-ghost.ant-btn-dangerous[disabled]:focus>a:only-child,.ant-btn-background-ghost.ant-btn-dangerous[disabled]:hover>a:only-child,.ant-btn-background-ghost.ant-btn-dangerous[disabled]>a:only-child{color:currentColor}.ant-btn-background-ghost.ant-btn-dangerous[disabled]:active>a:only-child:after,.ant-btn-background-ghost.ant-btn-dangerous[disabled]:focus>a:only-child:after,.ant-btn-background-ghost.ant-btn-dangerous[disabled]:hover>a:only-child:after,.ant-btn-background-ghost.ant-btn-dangerous[disabled]>a:only-child:after{position:absolute;top:0;right:0;bottom:0;left:0;background:transparent;content:""}.ant-btn-background-ghost.ant-btn-dangerous.ant-btn-link{color:#ff4d4f;background:transparent;border-color:transparent;text-shadow:none}.ant-btn-background-ghost.ant-btn-dangerous.ant-btn-link>a:only-child{color:currentColor}.ant-btn-background-ghost.ant-btn-dangerous.ant-btn-link>a:only-child:after{position:absolute;top:0;right:0;bottom:0;left:0;background:transparent;content:""}.ant-btn-background-ghost.ant-btn-dangerous.ant-btn-link:focus,.ant-btn-background-ghost.ant-btn-dangerous.ant-btn-link:hover{color:#ff7875;background:transparent;border-color:transparent}.ant-btn-background-ghost.ant-btn-dangerous.ant-btn-link:focus>a:only-child,.ant-btn-background-ghost.ant-btn-dangerous.ant-btn-link:hover>a:only-child{color:currentColor}.ant-btn-background-ghost.ant-btn-dangerous.ant-btn-link:focus>a:only-child:after,.ant-btn-background-ghost.ant-btn-dangerous.ant-btn-link:hover>a:only-child:after{position:absolute;top:0;right:0;bottom:0;left:0;background:transparent;content:""}.ant-btn-background-ghost.ant-btn-dangerous.ant-btn-link:active{color:#d9363e;background:transparent;border-color:transparent}.ant-btn-background-ghost.ant-btn-dangerous.ant-btn-link:active>a:only-child{color:currentColor}.ant-btn-background-ghost.ant-btn-dangerous.ant-btn-link:active>a:only-child:after{position:absolute;top:0;right:0;bottom:0;left:0;background:transparent;content:""}.ant-btn-background-ghost.ant-btn-dangerous.ant-btn-link[disabled],.ant-btn-background-ghost.ant-btn-dangerous.ant-btn-link[disabled]:active,.ant-btn-background-ghost.ant-btn-dangerous.ant-btn-link[disabled]:focus,.ant-btn-background-ghost.ant-btn-dangerous.ant-btn-link[disabled]:hover{color:rgba(0,0,0,.25);background:#f5f5f5;border-color:#d9d9d9;text-shadow:none;box-shadow:none}.ant-btn-background-ghost.ant-btn-dangerous.ant-btn-link[disabled]:active>a:only-child,.ant-btn-background-ghost.ant-btn-dangerous.ant-btn-link[disabled]:focus>a:only-child,.ant-btn-background-ghost.ant-btn-dangerous.ant-btn-link[disabled]:hover>a:only-child,.ant-btn-background-ghost.ant-btn-dangerous.ant-btn-link[disabled]>a:only-child{color:currentColor}.ant-btn-background-ghost.ant-btn-dangerous.ant-btn-link[disabled]:active>a:only-child:after,.ant-btn-background-ghost.ant-btn-dangerous.ant-btn-link[disabled]:focus>a:only-child:after,.ant-btn-background-ghost.ant-btn-dangerous.ant-btn-link[disabled]:hover>a:only-child:after,.ant-btn-background-ghost.ant-btn-dangerous.ant-btn-link[disabled]>a:only-child:after{position:absolute;top:0;right:0;bottom:0;left:0;background:transparent;content:""}.ant-btn-two-chinese-chars:first-letter{letter-spacing:.34em}.ant-btn-two-chinese-chars>:not(.anticon){margin-right:-.34em;letter-spacing:.34em}.ant-btn-block{width:100%}.ant-btn:empty{display:inline-block;width:0;visibility:hidden;content:"\a0"}a.ant-btn{padding-top:.01px!important;line-height:30px}a.ant-btn-lg{line-height:38px}a.ant-btn-sm{line-height:22px}.ant-btn-rtl{direction:rtl}.ant-btn-group-rtl.ant-btn-group .ant-btn-primary+.ant-btn-primary,.ant-btn-group-rtl.ant-btn-group .ant-btn-primary:last-child:not(:first-child){border-right-color:#40a9ff;border-left-color:#d9d9d9}.ant-btn-group-rtl.ant-btn-group .ant-btn-primary+.ant-btn-primary[disabled],.ant-btn-group-rtl.ant-btn-group .ant-btn-primary:last-child:not(:first-child)[disabled]{border-right-color:#d9d9d9;border-left-color:#40a9ff}.ant-btn-rtl.ant-btn>.ant-btn-loading-icon .anticon{padding-right:0;padding-left:8px}.ant-btn>.ant-btn-loading-icon:only-child .anticon{padding-right:0;padding-left:0}.ant-btn-rtl.ant-btn>.anticon+span,.ant-btn-rtl.ant-btn>span+.anticon{margin-right:8px;margin-left:0}.container___rRDCW{background:#fff;padding:20px;min-height:100%}.container___rRDCW button{margin:16px 0} --------------------------------------------------------------------------------