├── logs
├── app-err.log
└── app-out.log
├── public
├── images
│ ├── demo.png
│ ├── meta.png
│ ├── _meta.png
│ ├── cover.jpg
│ ├── image4.svg
│ ├── image3.svg
│ ├── image1.svg
│ ├── image2.svg
│ └── share.svg
├── icons
│ ├── favicon.ico
│ ├── favicon-16x16.png
│ ├── favicon-32x32.png
│ ├── mstile-150x150.png
│ ├── apple-touch-icon.png
│ ├── android-chrome-192x192.png
│ ├── android-chrome-512x512.png
│ ├── browserconfig.xml
│ ├── site.webmanifest
│ └── safari-pinned-tab.svg
├── static
│ └── locales
│ │ ├── cn
│ │ ├── header.json
│ │ ├── moreFeature.json
│ │ ├── mainFeature.json
│ │ ├── faq.json
│ │ ├── common.json
│ │ └── log.json
│ │ └── en
│ │ ├── header.json
│ │ ├── moreFeature.json
│ │ ├── mainFeature.json
│ │ ├── faq.json
│ │ ├── common.json
│ │ └── log.json
├── manifest.json
└── lib
│ ├── aos.js
│ └── aos.css
├── index.js
├── configs
├── moreFeature.js
├── faq.js
├── download.js
├── logs.js
└── share.js
├── next.config.js
├── i18n.js
├── .gitignore
├── pages
├── _app.js
├── index.js
├── download.js
├── _error.js
├── faq.js
├── support.js
├── _document.js
└── log.js
├── README.md
├── package.json
├── pm2.json
├── server.js
├── components
├── footer.js
├── share.js
├── downloadOption.js
├── moreFeature.js
├── headerOption.js
├── ready.js
├── mainFeature.js
├── cover.js
└── header.js
├── styles
├── global.css
└── reset.css
└── nginx.conf
/logs/app-err.log:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/logs/app-out.log:
--------------------------------------------------------------------------------
1 | 2020-05-24 09:43:14: > Ready on http://localhost:3000
2 |
--------------------------------------------------------------------------------
/public/images/demo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/daosonit/website-for-koodo-reader/HEAD/public/images/demo.png
--------------------------------------------------------------------------------
/public/images/meta.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/daosonit/website-for-koodo-reader/HEAD/public/images/meta.png
--------------------------------------------------------------------------------
/public/icons/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/daosonit/website-for-koodo-reader/HEAD/public/icons/favicon.ico
--------------------------------------------------------------------------------
/public/images/_meta.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/daosonit/website-for-koodo-reader/HEAD/public/images/_meta.png
--------------------------------------------------------------------------------
/public/images/cover.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/daosonit/website-for-koodo-reader/HEAD/public/images/cover.jpg
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | const { setConfig } = require('next/config')
2 | setConfig(require('./next.config'))
3 |
4 | require('./server')
5 |
--------------------------------------------------------------------------------
/public/icons/favicon-16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/daosonit/website-for-koodo-reader/HEAD/public/icons/favicon-16x16.png
--------------------------------------------------------------------------------
/public/icons/favicon-32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/daosonit/website-for-koodo-reader/HEAD/public/icons/favicon-32x32.png
--------------------------------------------------------------------------------
/public/icons/mstile-150x150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/daosonit/website-for-koodo-reader/HEAD/public/icons/mstile-150x150.png
--------------------------------------------------------------------------------
/public/icons/apple-touch-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/daosonit/website-for-koodo-reader/HEAD/public/icons/apple-touch-icon.png
--------------------------------------------------------------------------------
/public/icons/android-chrome-192x192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/daosonit/website-for-koodo-reader/HEAD/public/icons/android-chrome-192x192.png
--------------------------------------------------------------------------------
/public/icons/android-chrome-512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/daosonit/website-for-koodo-reader/HEAD/public/icons/android-chrome-512x512.png
--------------------------------------------------------------------------------
/public/static/locales/cn/header.json:
--------------------------------------------------------------------------------
1 | {
2 | "faq": "帮助",
3 | "log": "更新日志",
4 | "donate": "捐赠",
5 | "lang": "English",
6 | "download": "下载",
7 | "support": "客户支持"
8 | }
9 |
--------------------------------------------------------------------------------
/public/static/locales/en/header.json:
--------------------------------------------------------------------------------
1 | {
2 | "faq": "FAQ",
3 | "log": "Changelogs",
4 | "donate": "Donate",
5 | "lang": "简体中文",
6 | "download": "Download",
7 | "support": "Support"
8 | }
9 |
--------------------------------------------------------------------------------
/configs/moreFeature.js:
--------------------------------------------------------------------------------
1 | export const moreFeature = [
2 | { id: 1, icon: "zu9" },
3 | { id: 2, icon: "zu11" },
4 | { id: 3, icon: "zu16" },
5 | { id: 4, icon: "zu12" },
6 | { id: 5, icon: "zu14" },
7 | { id: 6, icon: "zu13" },
8 | ];
9 |
--------------------------------------------------------------------------------
/next.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | distDir: "_next",
3 | publicRuntimeConfig: {
4 | localeSubpaths:
5 | typeof process.env.LOCALE_SUBPATHS === "string"
6 | ? process.env.LOCALE_SUBPATHS
7 | : "none",
8 | },
9 | };
10 |
--------------------------------------------------------------------------------
/configs/faq.js:
--------------------------------------------------------------------------------
1 | export const aboutInfo = [
2 | { id: 1, icon: "zu54", color1: "#1D2FFD", color2: "#3282FA" },
3 | { id: 2, icon: "zu56", color1: "#FE7326", color2: "#FFD547" },
4 | { id: 3, icon: "sync", color1: "#FF5050", color2: "#D83BE2" },
5 | { id: 4, icon: "zu57", color1: "#24C4CC", color2: "#4AC22A" },
6 | ];
7 |
--------------------------------------------------------------------------------
/public/icons/browserconfig.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | #da532c
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/i18n.js:
--------------------------------------------------------------------------------
1 | const NextI18Next = require("next-i18next").default;
2 |
3 | module.exports = new NextI18Next({
4 | defaultLanguage: "cn",
5 | otherLanguages: ["en"],
6 | browserLanguageDetection: true,
7 | detection: {
8 | lookupCookie: "next-i18next",
9 | order: ["cookie", "querystring", "localStorage", "path", "subdomain"],
10 | caches: ["cookie"],
11 | },
12 | });
13 |
--------------------------------------------------------------------------------
/public/icons/site.webmanifest:
--------------------------------------------------------------------------------
1 | {
2 | "name": "",
3 | "short_name": "",
4 | "icons": [
5 | {
6 | "src": "/icons/android-chrome-192x192.png",
7 | "sizes": "192x192",
8 | "type": "image/png"
9 | },
10 | {
11 | "src": "/icons/android-chrome-512x512.png",
12 | "sizes": "512x512",
13 | "type": "image/png"
14 | }
15 | ],
16 | "theme_color": "#ffffff",
17 | "background_color": "#ffffff",
18 | "display": "standalone"
19 | }
20 |
--------------------------------------------------------------------------------
/public/static/locales/cn/moreFeature.json:
--------------------------------------------------------------------------------
1 | {
2 | "title1": "跨平台",
3 | "title2": "搜索功能",
4 | "title3": "书摘功能",
5 | "title4": "书签功能",
6 | "title5": "永久免费",
7 | "title6": "面板模式",
8 | "subtitle1": "Koodo Reader 完美支持跨平台的阅读体验",
9 | "subtitle2": "从上千本书中快速搜索到你寻找的图书",
10 | "subtitle3": "一键将你喜欢的文字添加到书摘中永久保存",
11 | "subtitle4": "使用书签标记你的阅读进度,快速定位到之前的位置",
12 | "subtitle5": "Koodo Reader 将永久免费,并不断添加更多功能",
13 | "subtitle6": "随意缩放软件大小,以节省屏幕空间",
14 | "question": "更多"
15 | }
16 |
--------------------------------------------------------------------------------
/public/static/locales/cn/mainFeature.json:
--------------------------------------------------------------------------------
1 | {
2 | "title1": "强大笔记功能",
3 | "title2": "跨平台的阅读体验",
4 | "title3": "备份恢复功能",
5 | "title4": "多端同步功能",
6 | "subtitle1": "简单易用的 EPUB 笔记系统,让你在学习时效率倍增,充分体验电子化学习的乐趣。当然,您还可以导出笔记,存在任何地方,方便日后查阅",
7 | "subtitle2": "Koodo Reader 完美支持Windows,macOS 和 网页版,无论是任何类型的图书,都能完美展现,提供最佳阅读效果",
8 | "subtitle3": "备份自己的图书、笔记、进度,以及所有你能想到的一切!永远不用担心数据丢失,只需打开应用,轻轻一点,继续享受阅读",
9 | "subtitle4": "Koodo Reader 率先在业界实现了主流平台的全面支持,让你无需再在各个软件间来回切换,真正实现了无拘无束,随时随地阅读体验。"
10 | }
11 |
--------------------------------------------------------------------------------
/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "next-pwa",
3 | "short_name": "next-pwa",
4 | "display": "standalone",
5 | "orientation": "portrait",
6 | "theme_color": "#FFFFFF",
7 | "background_color": "#FFFFFF",
8 | "start_url": "/",
9 | "icons": [
10 | {
11 | "src": "/icons/android-chrome-192x192.png",
12 | "sizes": "192x192",
13 | "type": "image/png"
14 | },
15 | {
16 | "src": "/icons/icon-512x512.png",
17 | "sizes": "512x512",
18 | "type": "image/png"
19 | }
20 | ]
21 | }
22 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # next.js
12 | /.next/
13 | /out/
14 | /cache/
15 | /_next/
16 | # production
17 | #/build
18 |
19 | # misc
20 | .DS_Store
21 |
22 | # debug
23 | npm-debug.log*
24 | yarn-debug.log*
25 | yarn-error.log*
26 |
27 | # local env files
28 | .env.local
29 | .env.development.local
30 | .env.test.local
31 | .env.production.local
32 |
33 | .now
--------------------------------------------------------------------------------
/public/static/locales/cn/faq.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "帮助",
3 | "subtitle": "关于 Koodo Reader 您可能关心的东西",
4 | "question1": "Koodo Reader 是什么?",
5 | "answer1": "Koodo Reader 是一个免费开源的 Epub 阅读器,诞生于2020年春,因为当时正在爆发新冠病毒,停工停学,开发者才有时间开发这个软件",
6 | "question2": "Koodo Reader 对系统有什么要求?",
7 | "answer2": "对于 Mac, Koodo Reader 要求 macOS 10.10 (Yosemite) 及以上系统. 对于 Windows, 要求 Windows 7 及以上系统",
8 | "question3": "如何备份和恢复数据?",
9 | "answer3": "点击右上角的 “备份和恢复” 按钮按照提示一步步操作就可以了,备份的文件以 zip 的形式保存,文件名为备份日期。",
10 | "question4": "我要如何联系你?",
11 | "answer4": "对于问题咨询,功能改进和 bug 反馈请前往客户支持页面,您也可以直接通过邮箱的方式与开发者取得联系。"
12 | }
13 |
--------------------------------------------------------------------------------
/pages/_app.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import App from "next/app";
3 | import { appWithTranslation } from "../i18n";
4 | import Head from "next/head";
5 | import "../styles/global.css";
6 | import "../styles/reset.css";
7 | class MyApp extends App {
8 | render() {
9 | const { Component, pageProps } = this.props;
10 | return (
11 | <>
12 |
13 |
14 | Koodo Reader - Free Epub Reader for Windows, Mac and Web
15 |
16 |
17 |
18 | >
19 | );
20 | }
21 | }
22 |
23 | export default appWithTranslation(MyApp);
24 |
--------------------------------------------------------------------------------
/configs/download.js:
--------------------------------------------------------------------------------
1 | const changeLogs = require("./logs");
2 | const version = changeLogs[0].version;
3 | const downloadOptions = [
4 | {
5 | id: 1,
6 | icon: "windows",
7 | title: "Windows",
8 | url: `https://github.com/troyeguo/koodo-reader/releases/download/v${version}/Koodo-Reader-Web-Setup-${version}.exe`,
9 | },
10 | {
11 | id: 2,
12 | icon: "mac",
13 | title: "macOS",
14 | url: `https://github.com/troyeguo/koodo-reader/releases/download/v${version}/Koodo-Reader-${version}.dmg`,
15 | },
16 | {
17 | id: 3,
18 | icon: "web",
19 | title: "Web",
20 | url: "https://reader.960960.xyz",
21 | },
22 | ];
23 | module.exports = downloadOptions;
24 |
--------------------------------------------------------------------------------
/public/static/locales/en/moreFeature.json:
--------------------------------------------------------------------------------
1 | {
2 | "title1": "Cross-platform",
3 | "title2": "Search",
4 | "title3": "Digest",
5 | "title4": "Bookmark",
6 | "title5": "Free Forever",
7 | "title6": "Panel Mode",
8 | "subtitle1": "Koodo Reader works great on all mainstream platform",
9 | "subtitle2": "Lightning fast seach inside thousands of books at once.",
10 | "subtitle3": "Easily save any sentences into digests with one click",
11 | "subtitle4": "Use bookmarks to flag your reading progress",
12 | "subtitle5": "Koodo Reader will always be free to use, with frequent updates.",
13 | "subtitle6": "Resize window to panel size to save screen space.",
14 | "question": "What's more?"
15 | }
16 |
--------------------------------------------------------------------------------
/configs/logs.js:
--------------------------------------------------------------------------------
1 | const changeLogs = [
2 | {
3 | version: "1.1.1",
4 | versionTag: "1-1-1",
5 | date: "13 July, 2020",
6 | fix: 3,
7 | new: 0,
8 | },
9 | {
10 | version: "1.1.0",
11 | versionTag: "1-1-0",
12 | date: "2 July, 2020",
13 | fix: 0,
14 | new: 3,
15 | },
16 | {
17 | version: "1.0.9",
18 | versionTag: "1-0-9",
19 | date: "21 June, 2020",
20 | fix: 3,
21 | new: 2,
22 | },
23 | {
24 | version: "1.0.8",
25 | versionTag: "1-0-8",
26 | date: "8 June, 2020",
27 | fix: 3,
28 | new: 2,
29 | },
30 | {
31 | version: "1.0.7",
32 | versionTag: "1-0-7",
33 | date: "27 Apr, 2020",
34 | fix: 4,
35 | new: 2,
36 | },
37 | ];
38 | module.exports = changeLogs;
39 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Koodo Reader 官网
2 |
3 | ### 预览
4 |
5 |
6 |
7 |
8 |
9 |
10 | ### 技术栈
11 |
12 | 使用 **Next.js** 实现服务端渲染,使用 **Bootstrap** 实现响应式,使用 **next-i18next** 实现国际化,使用 **aos** 实现页面动画
13 |
14 | ### 网站地址
15 |
16 | 网站托管在 **Heroku** 上,由于免费应用的限制,网站需要 10s 左右的启动时间,请耐心等待
17 |
18 | [点我前往](https://koodo.960960.xyz)
19 |
20 | ### 运行源码
21 |
22 | ```bash
23 | git clone https://github.com/troyeguo/website-for-koodo-reader.git
24 | cd website-for-koodo-reader
25 | yarn
26 | yarn dev
27 | ```
28 |
29 | ### 帮助与反馈
30 |
31 | 您可以在 **issue** 区提问,我会在力所能及的范围内提供帮助
32 |
--------------------------------------------------------------------------------
/public/static/locales/en/mainFeature.json:
--------------------------------------------------------------------------------
1 | {
2 | "title1": "Take notes while reading",
3 | "title2": "Reader Books on any devices",
4 | "title3": "Backup and restore your data",
5 | "title4": "Sync data between multiple devices",
6 | "subtitle1": "Add annotations and notes to improve reading efficiency. Export notes and have them anywhere, so you can check them on the go",
7 | "subtitle2": "Powerful parsing engine that perfectly supports ePub2 and ePub3, Koodo Reader support Window, macOS and Web",
8 | "subtitle3": "Export book files, notes, reading progress, and anything to a .zip file! and people could use our icon manager app to import it with one click.",
9 | "subtitle4": "No matter on a browser or a desktop app, we try our best to provide you with refreshing and comfortable reading experience."
10 | }
11 |
--------------------------------------------------------------------------------
/public/static/locales/en/faq.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "FAQ",
3 | "subtitle": "What you should know about Koodo Reader?",
4 | "question1": "What is Koodo Reader?",
5 | "answer1": "Koodo Reader is a free and powerful epub reader, born in 2020 spring during the outbreak of Coronavirus COVID-19.",
6 | "question2": "What are the system requirements?",
7 | "answer2": "For Mac, Koodo Reader requires macOS 10.10 (Yosemite) or later. For Windows, Windows 7 and later are supported.",
8 | "question3": "How to backup and restore data?",
9 | "answer3": "To backup and restore data, just click the Backup and Restore button in the top-right corner and follow the instruction",
10 | "question4": "How do I contact you?",
11 | "answer4": "For general inquiries, suggesting new features and improvements, or to report bugs, visit the support page."
12 | }
13 |
--------------------------------------------------------------------------------
/public/static/locales/cn/common.json:
--------------------------------------------------------------------------------
1 | {
2 | "ready": "还在等什么?",
3 | "ads": "快使用 Koodo Reader 来管理你的电子书吧!",
4 | "download": "下载",
5 | "preview": "网页版",
6 | "title": "开启全新 Epub 阅读体验",
7 | "subtitle": "Koodo Reader 是一个免费开源的 Epub 阅读器,支持 Windows, Mac和网页版",
8 | "share-title": "分享给更多朋友",
9 | "share-subtitle": "把你对 Koodo Reader 的喜爱分享给更多的人",
10 | "twitter": "推特",
11 | "facebook": "脸书",
12 | "weibo": "微博",
13 | "support": "客户支持",
14 | "support-subtitle": "您可以通过以下方式与开发者取得联系",
15 | "feedback": "反馈",
16 | "feedback-subtitle": "对于问题咨询,功能改进和 bug 反馈,请前往本项目在github上的issue区提交。",
17 | "email": "邮箱",
18 | "email-subtitle": "您也可以直接通过邮箱 guo362429@gmail.com 与开发者取得联系。",
19 | "error": "你来到了没有知识的荒原",
20 | "back": "返回首页",
21 | "privacy": "隐私策略",
22 | "terms": "服务条款",
23 | "download-on-pc": "请在电脑上下载本应用",
24 | "click-me-to-go": "点我前往"
25 | }
26 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "-",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "license": "MIT",
6 | "engines": {
7 | "node": ">=10.13.0"
8 | },
9 | "scripts": {
10 | "dev": "node index.js",
11 | "build": "next build",
12 | "prestart": "next build",
13 | "export": "next export",
14 | "preexport": "next build",
15 | "start": "cross-env NODE_ENV=production node index.js",
16 | "pm2": "pm2 start pm2.json"
17 | },
18 | "devDependencies": {},
19 | "dependencies": {
20 | "compression": "^1.7.4",
21 | "cors": "^2.8.5",
22 | "cross-env": "^7.0.2",
23 | "express": "^4.17.1",
24 | "i18next": "^19.4.4",
25 | "next": "^9.3.6",
26 | "next-i18next": "^4.4.1",
27 | "pm2": "^4.4.0",
28 | "react": "^16.13.1",
29 | "react-device-detect": "^1.12.1",
30 | "react-dom": "^16.13.1"
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/configs/share.js:
--------------------------------------------------------------------------------
1 | export const shareOptions = [
2 | {
3 | id: 1,
4 | icon: "twitter",
5 | url:
6 | "https://twitter.com/intent/tweet?text=Koodo+Reader+-+Free+Epub+Reader+for+Windows%2C+Mac%2Cand+Web+&url=https%3A%2F%2Fkoodo.960960.xyz",
7 | color: "rgba(29, 162, 242, 1)",
8 | },
9 | {
10 | id: 2,
11 | icon: "facebook",
12 | url:
13 | "https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Fkoodo.960960.xyz",
14 | color: "rgba(60, 88, 151, 1)",
15 | },
16 | {
17 | id: 3,
18 | icon: "weibo",
19 | url:
20 | "https://service.weibo.com/share/share.php?url=https%3A%2F%2Fkoodo.960960.xyz&title=Koodo+Reader+%E4%B8%80%E4%B8%AA%E5%85%8D%E8%B4%B9%E5%BC%BA%E5%A4%A7%E7%9A%84+Epub+%E9%98%85%E8%AF%BB%E5%99%A8%EF%BC%8C%E6%94%AF%E6%8C%81+Windows%2C+Mac%2C+%E5%92%8C+%E7%BD%91%E9%A1%B5%E7%89%88",
21 | color: "rgba(230, 22, 45, 1)",
22 | },
23 | ];
24 |
--------------------------------------------------------------------------------
/pm2.json:
--------------------------------------------------------------------------------
1 | {
2 | "apps": {
3 | "name": "Koodo Reader",
4 | "script": "index.js",
5 | "cwd": "./",
6 | "args": "",
7 | "interpreter": "",
8 | "interpreter_args": "",
9 | "watch": true,
10 | "ignore_watch": ["node_modules", "logs"],
11 | "exec_mode": "fork",
12 | "instances": 1,
13 | "max_memory_restart": "500M",
14 | "error_file": "./logs/app-err.log",
15 | "out_file": "./logs/app-out.log",
16 | "merge_logs": true,
17 | "log_date_format": "YYYY-MM-DD HH:mm:ss",
18 | "min_uptime": "60s",
19 | "max_restarts": 30,
20 | "autorestart": true,
21 | "cron_restart": "",
22 | "restart_delay": 10,
23 | "env": {
24 | "NODE_ENV": "production",
25 | "REMOTE_ADDR": ""
26 | },
27 | "env_dev": {
28 | "NODE_ENV": "development",
29 | "REMOTE_ADDR": ""
30 | },
31 | "env_test": {
32 | "NODE_ENV": "test",
33 | "REMOTE_ADDR": ""
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/pages/index.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import PropTypes from "prop-types";
3 |
4 | import { withTranslation } from "../i18n";
5 |
6 | import Header from "../components/header";
7 | import Footer from "../components/footer";
8 | import MainFeature from "../components/mainFeature";
9 | import MoreFeature from "../components/moreFeature";
10 | import Ready from "../components/ready";
11 | import Cover from "../components/cover";
12 | const Homepage = ({ t }) => (
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 | );
24 |
25 | Homepage.getInitialProps = async () => ({
26 | namespacesRequired: ["common", "header", "moreFeature", "mainFeature"],
27 | });
28 |
29 | Homepage.propTypes = {
30 | t: PropTypes.func.isRequired,
31 | };
32 |
33 | export default withTranslation("common")(Homepage);
34 |
--------------------------------------------------------------------------------
/public/static/locales/cn/log.json:
--------------------------------------------------------------------------------
1 | {
2 | "log-title": "更新日志",
3 | "log-subtitle": "每个版本 Koodo Reader 的更新日志",
4 | "fix1-1-0-7": "修复备份恢复后白屏的问题",
5 | "fix2-1-0-7": "删除多余的测试代码",
6 | "fix3-1-0-7": "去除页边距设置选项",
7 | "fix4-1-0-7": "部分选项标题加粗显示",
8 | "new1-1-0-7": "整个项目使用 TypeScript 重构",
9 | "new2-1-0-7": "原代码保存在 JavaScript分支 ",
10 | "fix1-1-0-8": "修复logo字体问题",
11 | "fix2-1-0-8": "修复高亮显示异常的问题",
12 | "fix3-1-0-8": "字体选择替换为更加常用的字体,如宋体,黑体,Times New Roman",
13 | "new1-1-0-8": "现在 Koodo Reader 支持英文啦!非中文操作系统会自动显示为英文界面",
14 | "new2-1-0-8": "支持拖拽添加图书,把图书拖拽到导入图书的按钮上就可以实现添加图书 ",
15 | "fix1-1-0-9": "修复字体调节bug",
16 | "fix2-1-0-9": "修复语言切换无法保存的bug",
17 | "fix3-1-0-9": "修复设置面板异常退出问题",
18 | "new1-1-0-9": "代码重构,增加代码可读性,将源代码的xxx.js拆分为index.js, component.js,interface.js三个文件",
19 | "new2-1-0-9": "使用Google Font统一字体为Source Sans Pro",
20 | "new1-1-1-0": "现在 Koodo Reader 支持绑定 Dropbox 实现多端同步啦,更多网盘会在后续更新中支持",
21 | "new2-1-1-0": "书签,高亮,笔记和书摘支持删除啦",
22 | "new3-1-1-0": "支持批量添加图书",
23 | "fix1-1-1-1": "修复卡片模式和列表模式图标和文字不居中对齐的问题",
24 | "fix2-1-1-1": "修复ESC退出全屏后,无法在此进入全屏的问题",
25 | "fix3-1-1-1": "修复删除按钮多处显示的问题"
26 | }
27 |
--------------------------------------------------------------------------------
/server.js:
--------------------------------------------------------------------------------
1 | const express = require("express");
2 | const next = require("next");
3 | const nextI18NextMiddleware = require("next-i18next/middleware").default;
4 | const compression = require("compression");
5 | const nextI18next = require("./i18n");
6 | const download = require("./configs/download");
7 | const logs = require("./configs/logs");
8 | const port = process.env.LEANCLOUD_APP_PORT || process.env.PORT || 3001;
9 | const app = next({ dev: process.env.NODE_ENV !== "production" });
10 | const handle = app.getRequestHandler();
11 | const cors = require("cors");
12 | (async () => {
13 | await app.prepare();
14 | const server = express();
15 | server.use(cors());
16 | await nextI18next.initPromise;
17 | server.use(nextI18NextMiddleware(nextI18next));
18 | server.use(compression());
19 | server.get("/update", (req, res) => {
20 | res.send({ download: download, log: logs[0] });
21 | });
22 | server.get("*", (req, res) => handle(req, res));
23 | server.post("/alipay", (req, res) => {
24 | res.send({ accountVerified: true, orderVerified: true });
25 | });
26 |
27 | await server.listen(port);
28 | console.log(`> Ready on http://localhost:${port}`); // eslint-disable-line no-console
29 | })();
30 |
--------------------------------------------------------------------------------
/public/static/locales/en/common.json:
--------------------------------------------------------------------------------
1 | {
2 | "ready": "Ready to get started ?",
3 | "ads": "All your books in one place, organized and safely stored",
4 | "download": "Download",
5 | "preview": "Web Version",
6 | "title": "Read Epub books with Koodo Reader",
7 | "subtitle": "Koodo Reader is a open-source epub reader with backup and restore support, runs on Windows, Mac and Web",
8 | "share-title": "Share your love with the world",
9 | "share-subtitle": "Share this free Epub Reader and help us spread the word!",
10 | "twitter": "Twitter",
11 | "facebook": "Facebook",
12 | "weibo": "Weibo",
13 | "feedback": "Feedback",
14 | "feedback-subtitle": "For general inquiries, bug reports or feature requests, please open an issue on our github page",
15 | "email": "Email to us",
16 | "email-subtitle": "Any other questions? Drop us a line to guo362429@gmail.com and we’ll get in touch with you soon.",
17 | "error": "You're lost in the wasteland of knowledge",
18 | "back": "Back to Home Page",
19 | "privacy": "Privacy",
20 | "terms": "Terms",
21 | "support": "SUPPORT",
22 | "support-subtitle": "You can contact the developer through the following methods",
23 | "download-on-pc": "Please download this app on PC",
24 | "click-me-to-go": "Click Me"
25 | }
26 |
--------------------------------------------------------------------------------
/components/footer.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import PropTypes from "prop-types";
3 |
4 | import { withTranslation, Link } from "../i18n";
5 |
6 | const Footer = ({ t }) => (
7 |
8 |
13 |
18 |
19 |
20 | © 2020 App by Troye. All rights reserved.
21 |
22 |
23 |
40 |
41 | );
42 | Footer.getInitialProps = async () => ({
43 | namespacesRequired: ["common"],
44 | });
45 | Footer.propTypes = {
46 | t: PropTypes.func.isRequired,
47 | };
48 |
49 | export default withTranslation("common")(Footer);
50 |
--------------------------------------------------------------------------------
/public/icons/safari-pinned-tab.svg:
--------------------------------------------------------------------------------
1 |
2 |
4 |
26 |
--------------------------------------------------------------------------------
/pages/download.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import PropTypes from "prop-types";
3 | import { withTranslation } from "../i18n";
4 | import Header from "../components/header";
5 | import Footer from "../components/footer";
6 | import DownloadOption from "../components/downloadOption";
7 | import Share from "../components/share";
8 | const Homepage = ({ t }) => (
9 |
10 |
11 |
12 |
13 |
14 |
Koodo Reader
15 |

21 |
22 |
23 |
24 |
25 |
26 |
43 |
44 |
45 | );
46 |
47 | Homepage.getInitialProps = async () => ({
48 | namespacesRequired: ["common", "header"],
49 | });
50 |
51 | Homepage.propTypes = {
52 | t: PropTypes.func.isRequired,
53 | };
54 |
55 | export default withTranslation("common")(Homepage);
56 |
--------------------------------------------------------------------------------
/public/static/locales/en/log.json:
--------------------------------------------------------------------------------
1 | {
2 | "log-title": "CHANGELOG",
3 | "log-subtitle": "What's new about each version of Koodo Reader",
4 | "fix1-1-0-7": "Fix the bug causing blank screen after importing backup file",
5 | "fix2-1-0-7": "Delete extra testing code from source code",
6 | "fix3-1-0-7": "Remove the padding setting from setting panel",
7 | "fix4-1-0-7": "Bolden some options' title",
8 | "new1-1-0-7": "Refactor the whole project with TypeScript",
9 | "new2-1-0-7": "The orignal JavaScript code is kept in JavaScript branch ",
10 | "fix1-1-0-8": "Change svg logo to png logo",
11 | "fix2-1-0-8": "Fix the bug showing highlighter in every chapter",
12 | "fix3-1-0-8": "Change the alternative font family",
13 | "new1-1-0-8": "Add English support for non-Chinese system",
14 | "new2-1-0-8": "Drag epub file on Import-From-Local button to add books",
15 | "fix1-1-0-9": "Fix the bug causing font-size switch failure",
16 | "fix2-1-0-9": "Fix the language switch bug",
17 | "fix3-1-0-9": "Fix the bug causing setting panel to exit unusually",
18 | "new1-1-0-9": "refact the code to increase readability",
19 | "new2-1-0-9": "Set Source Sans Pro as the default font",
20 | "new1-1-1-0": "Add support to Dropbox, Now you can sync data from multiple devices",
21 | "new2-1-1-0": "Now you can delete notes, bookmarks, digests and highlighters as you want",
22 | "new3-1-1-0": "Now you can add multiple epubs simultaneously",
23 | "fix1-1-1-1": "Make the icon and text of card-mode and list-mode align center",
24 | "fix2-1-1-1": "Fix the fullscreen issue after pressing Esc button",
25 | "fix3-1-1-1": "Fix the render issue of delete icon"
26 | }
27 |
--------------------------------------------------------------------------------
/styles/global.css:
--------------------------------------------------------------------------------
1 | .icon {
2 | width: 1em;
3 | height: 1em;
4 | vertical-align: -0.15em;
5 | fill: currentColor;
6 | overflow: hidden;
7 | }
8 | .divider {
9 | width: 100%;
10 | height: 30px;
11 | }
12 | .download-button {
13 | width: 175px;
14 | height: 46px;
15 | background: rgba(255, 226, 183, 1);
16 | opacity: 1;
17 | border-radius: 23px;
18 | cursor: pointer;
19 | font-weight: 600;
20 | }
21 | .bg-dynamic {
22 | margin-top: 93px;
23 | }
24 | .page-title {
25 | font-size: calc(1rem + 1.62vw);
26 | font-weight: bold;
27 | line-height: 53px;
28 | color: rgba(0, 0, 0, 1);
29 | opacity: 0.75;
30 | text-align: center;
31 | margin-top: 40px;
32 | }
33 | .page-subtitle {
34 | font-size: calc(0.7rem + 0.6vw);
35 | font-weight: 500;
36 | line-height: 27px;
37 | color: rgba(0, 0, 0, 1);
38 | opacity: 0.46;
39 | text-align: center;
40 | }
41 | .bg-dynamic {
42 | margin-top: 93px;
43 | }
44 | .h1 {
45 | font-size: calc(1rem + 1.5vw);
46 | font-weight: bold;
47 | line-height: 1.25;
48 | color: rgba(0, 0, 0, 1);
49 | opacity: 1;
50 | }
51 | .lead {
52 | font-size: 1.1rem;
53 | font-weight: 500;
54 | line-height: 1.5;
55 | color: rgba(0, 0, 0, 1);
56 | opacity: 0.55;
57 | margin-top: 15px;
58 | }
59 | @media (max-width: 992px) {
60 | .download-button {
61 | /* display: none; */
62 | }
63 | .preview-button {
64 | /* display: none; */
65 | }
66 | .h1,
67 | .lead {
68 | text-align: center;
69 | }
70 | .lead {
71 | font-size: 0.8rem;
72 | }
73 | .divider {
74 | height: 0px;
75 | }
76 | .feature-image {
77 | padding: 0px 60px;
78 | }
79 | }
80 | .share-button {
81 | width: 116px;
82 | height: 48px;
83 | opacity: 1;
84 | border-radius: 24px;
85 | color: white;
86 | font-size: 1rem;
87 | cursor: pointer;
88 | }
89 |
--------------------------------------------------------------------------------
/components/share.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import PropTypes from "prop-types";
3 | import { shareOptions } from "../configs/share";
4 | import { withTranslation } from "../i18n";
5 |
6 | const Share = ({ t }) => {
7 | const renderShare = () => {
8 | return shareOptions.map((item) => {
9 | return (
10 |
17 |
21 |
24 |
25 | {t(item.icon)}
26 |
27 |
28 | );
29 | });
30 | };
31 | return (
32 |
33 |
34 |
35 |
36 |
{t("share-title")}
37 |
{t("share-subtitle")}
38 |
39 |
40 | {renderShare()}
41 |
42 |
43 |
47 |

52 |
53 |
54 |
55 |
56 |
57 | );
58 | };
59 | Share.getInitialProps = async () => ({
60 | namespacesRequired: ["common"],
61 | });
62 | Share.propTypes = {
63 | t: PropTypes.func.isRequired,
64 | };
65 |
66 | export default withTranslation("common")(Share);
67 |
--------------------------------------------------------------------------------
/styles/reset.css:
--------------------------------------------------------------------------------
1 | html,
2 | body,
3 | div,
4 | span,
5 | applet,
6 | object,
7 | iframe,
8 | h1,
9 | h2,
10 | h3,
11 | h4,
12 | h5,
13 | h6,
14 | p,
15 | blockquote,
16 | pre,
17 | a,
18 | abbr,
19 | acronym,
20 | address,
21 | big,
22 | cite,
23 | code,
24 | del,
25 | dfn,
26 | em,
27 | img,
28 | ins,
29 | kbd,
30 | q,
31 | s,
32 | samp,
33 | small,
34 | strike,
35 | strong,
36 | sub,
37 | sup,
38 | tt,
39 | var,
40 | b,
41 | u,
42 | i,
43 | center,
44 | dl,
45 | dt,
46 | dd,
47 | ol,
48 | ul,
49 | li,
50 | fieldset,
51 | form,
52 | label,
53 | legend,
54 | table,
55 | caption,
56 | tbody,
57 | tfoot,
58 | thead,
59 | tr,
60 | th,
61 | td,
62 | article,
63 | aside,
64 | canvas,
65 | details,
66 | embed,
67 | figure,
68 | figcaption,
69 | footer,
70 | header,
71 | hgroup,
72 | menu,
73 | nav,
74 | output,
75 | ruby,
76 | section,
77 | summary,
78 | time,
79 | mark,
80 | audio,
81 | video {
82 | margin: 0;
83 | padding: 0;
84 | border: 0;
85 | font-size: 100%;
86 | font: inherit;
87 | vertical-align: baseline;
88 | }
89 |
90 | /* HTML5 display-role reset for older browsers */
91 | article,
92 | aside,
93 | details,
94 | figcaption,
95 | figure,
96 | footer,
97 | header,
98 | hgroup,
99 | menu,
100 | nav,
101 | section {
102 | display: block;
103 | }
104 |
105 | body {
106 | line-height: 1;
107 | }
108 |
109 | ol,
110 | ul {
111 | list-style: none;
112 | }
113 |
114 | blockquote,
115 | q {
116 | quotes: none;
117 | }
118 |
119 | blockquote:before,
120 | blockquote:after,
121 | q:before,
122 | q:after {
123 | content: "";
124 | content: none;
125 | }
126 |
127 | table {
128 | border-collapse: collapse;
129 | border-spacing: 0;
130 | }
131 |
132 | a {
133 | text-decoration: none;
134 | -webkit-backface-visibility: hidden;
135 | color: rgba(0, 0, 0, 0.9);
136 | }
137 |
138 | li {
139 | list-style: none;
140 | }
141 |
142 | html,
143 | body {
144 | width: 100%;
145 | user-select: text;
146 | }
147 | html,
148 | body {
149 | padding: 0;
150 | margin: 0;
151 | font-family: "Source Sans Pro", -apple-system, BlinkMacSystemFont, "Segoe UI",
152 | Roboto, Oxygen, Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue,
153 | sans-serif !important;
154 | }
155 |
--------------------------------------------------------------------------------
/components/downloadOption.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import PropTypes from "prop-types";
3 | import downloadOptions from "../configs/download";
4 | import { withTranslation } from "../i18n";
5 | import { isMobile } from "react-device-detect";
6 | const DownloadDemo = ({ t }) => {
7 | const handleClick = (url) => {
8 | if (isMobile) {
9 | alert(t("download-on-pc"));
10 | return;
11 | }
12 | window.location.href = url;
13 | };
14 | const renderDownload = () => {
15 | return downloadOptions.map((item) => {
16 | return (
17 |
37 | );
38 | });
39 | };
40 | return (
41 |
42 |
{renderDownload()}
43 |
61 |
62 | );
63 | };
64 | DownloadDemo.getInitialProps = async () => ({
65 | namespacesRequired: ["common"],
66 | });
67 | DownloadDemo.propTypes = {
68 | t: PropTypes.func.isRequired,
69 | };
70 |
71 | export default withTranslation("common")(DownloadDemo);
72 |
--------------------------------------------------------------------------------
/components/moreFeature.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import PropTypes from "prop-types";
3 | import { moreFeature } from "../configs/moreFeature";
4 | import { withTranslation } from "../i18n";
5 |
6 | const MoreFeature = ({ t }) => {
7 | const renderFeature = () => {
8 | return moreFeature.map((item) => {
9 | return (
10 |
16 |
17 |
20 |
{t(`title${item.id}`)}
21 |
{t(`subtitle${item.id}`)}
22 |
23 |
24 | );
25 | });
26 | };
27 | return (
28 |
29 | {t("question")}
30 | {renderFeature()}
31 |
32 |
69 |
70 | );
71 | };
72 | MoreFeature.getInitialProps = async () => ({
73 | namespacesRequired: ["moreFeature"],
74 | });
75 | MoreFeature.propTypes = {
76 | t: PropTypes.func.isRequired,
77 | };
78 |
79 | export default withTranslation("moreFeature")(MoreFeature);
80 |
--------------------------------------------------------------------------------
/components/headerOption.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import PropTypes from "prop-types";
3 | import { withRouter } from "next/router";
4 | import { i18n, Link, withTranslation } from "../i18n";
5 |
6 | const HeaderOption = ({ t, router, theme }) => {
7 | const routeName = router.pathname;
8 | return (
9 |
68 | );
69 | };
70 | HeaderOption.getInitialProps = async () => ({
71 | namespacesRequired: ["header"],
72 | });
73 | HeaderOption.propTypes = {
74 | t: PropTypes.func.isRequired,
75 | };
76 | export default withTranslation("header")(withRouter(HeaderOption));
77 |
--------------------------------------------------------------------------------
/pages/_error.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import PropTypes from "prop-types";
3 |
4 | import { withTranslation, Link } from "../i18n";
5 |
6 | const Error = ({ statusCode, t }) => (
7 |
8 |
9 |
10 |
11 |

15 |
16 |
27 |
28 |
64 |
65 |
66 | );
67 |
68 | Error.getInitialProps = async ({ res, err }) => {
69 | let statusCode = null;
70 | if (res) {
71 | ({ statusCode } = res);
72 | } else if (err) {
73 | ({ statusCode } = err);
74 | }
75 | return {
76 | namespacesRequired: ["common"],
77 | statusCode,
78 | };
79 | };
80 |
81 | Error.defaultProps = {
82 | statusCode: null,
83 | };
84 |
85 | Error.propTypes = {
86 | statusCode: PropTypes.number,
87 | t: PropTypes.func.isRequired,
88 | };
89 |
90 | export default withTranslation("common")(Error);
91 |
--------------------------------------------------------------------------------
/nginx.conf:
--------------------------------------------------------------------------------
1 |
2 |
3 | #user nobody;
4 | worker_processes 4;
5 |
6 | #error_log logs/error.log;
7 | #error_log logs/error.log notice;
8 | #error_log logs/error.log info;
9 |
10 | #pid logs/nginx.pid;
11 |
12 |
13 | events {
14 | worker_connections 40960;
15 | }
16 |
17 | http {
18 | include mime.types;
19 | default_type application/octet-stream;
20 |
21 | #log_format main '$remote_addr - $remote_user [$time_local] "$request" '
22 | # '$status $body_bytes_sent "$http_referer" '
23 | # '"$http_user_agent" "$http_x_forwarded_for"';
24 |
25 | #access_log logs/access.log main;
26 | sendfile on;
27 | #tcp_nopush on;
28 |
29 | #keepalive_timeout 0;
30 | keepalive_timeout 65;
31 |
32 | #gzip on;
33 |
34 |
35 |
36 | # another virtual host using mix of IP-, name-, and port-based configuration
37 | #
38 | server {
39 | listen 80;
40 | server_name koodo.960960.xyz;
41 |
42 | location / {
43 | proxy_set_header X-Real-IP $remote_addr;
44 | proxy_set_header X-Forward-For $proxy_add_x_forwarded_for;
45 | proxy_set_header Host $http_host;
46 | proxy_set_header X-Nginx-Proxy true;
47 |
48 | proxy_pass http://localhost:3000;
49 | proxy_redirect off;
50 | }
51 | location /_next/ {
52 | alias /.next;
53 | expires 30d;
54 | access_log on;
55 | }
56 | location /_next/static {
57 | proxy_cache STATIC;
58 | proxy_pass https://localhost:3000;
59 |
60 | # For testing cache - remove before deploying to production
61 | add_header X-Cache-Status $upstream_cache_status;
62 | }
63 | }
64 | #include vhosts.conf;
65 | map $time_iso8601 $logdate {
66 | '~^(?\\d{4}-\\d{2}-\\d{2})' $ymd;
67 | default 'date-not-found';
68 | }
69 | include vhosts/*.conf;
70 | # HTTPS server
71 | #
72 | #server {
73 | # listen 443 ssl;
74 | # server_name localhost;
75 |
76 | # ssl_certificate cert.pem;
77 | # ssl_certificate_key cert.key;
78 |
79 | # ssl_session_cache shared:SSL:1m;
80 | # ssl_session_timeout 5m;
81 |
82 | # ssl_ciphers HIGH:!aNULL:!MD5;
83 | # ssl_prefer_server_ciphers on;
84 |
85 | # location / {
86 | # root html;
87 | # index index.html index.htm;
88 | # }
89 | #}
90 |
91 | client_max_body_size 50m;
92 | client_body_buffer_size 60k;
93 | client_body_timeout 60;
94 | client_header_buffer_size 64k;
95 | client_header_timeout 60;
96 | error_page 400 error/400.html;
97 | error_page 403 error/403.html;
98 | error_page 404 error/404.html;
99 | error_page 500 error/500.html;
100 | error_page 501 error/501.html;
101 | error_page 502 error/502.html;
102 | error_page 503 error/503.html;
103 | error_page 504 error/504.html;
104 | error_page 505 error/505.html;
105 | error_page 506 error/506.html;
106 | error_page 507 error/507.html;
107 | error_page 509 error/509.html;
108 | error_page 510 error/510.html;
109 |
110 | keepalive_requests 100;
111 | large_client_header_buffers 4 64k;
112 | reset_timedout_connection on;
113 | send_timeout 60;
114 | sendfile_max_chunk 512k;
115 | server_names_hash_bucket_size 256;
116 | }
117 | worker_rlimit_nofile 100000;
118 |
--------------------------------------------------------------------------------
/components/ready.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import PropTypes from "prop-types";
3 |
4 | import { withTranslation, Link } from "../i18n";
5 |
6 | const Ready = ({ t }) => (
7 |
8 |
9 |
10 |
11 |
12 | {t("ready")}
13 |
14 |
15 | {t("ads")}
16 |
17 |
18 |
23 |
24 |
25 |
26 |
{t("download")}
27 |
28 |
29 |
30 |
39 |
40 |
41 |
42 |
43 |
103 |
104 | );
105 | Ready.getInitialProps = async () => ({
106 | namespacesRequired: ["common"],
107 | });
108 | Ready.propTypes = {
109 | t: PropTypes.func.isRequired,
110 | };
111 |
112 | export default withTranslation("common")(Ready);
113 |
--------------------------------------------------------------------------------
/pages/faq.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import PropTypes from "prop-types";
3 | import { withTranslation } from "../i18n";
4 | import Header from "../components/header";
5 | import Footer from "../components/footer";
6 | import { aboutInfo } from "../configs/faq";
7 | const FAQ = ({ t }) => {
8 | const renderFaq = () => {
9 | return aboutInfo.map((item) => {
10 | return (
11 |
17 |
18 |
24 |
27 |
28 |
29 |
{t(`question${item.id}`)}
30 |
{t(`answer${item.id}`)}
31 |
32 |
33 |
34 | );
35 | });
36 | };
37 | return (
38 |
39 |
40 |
41 |
42 |
43 |
44 |
{t("title")}
45 |
{t("subtitle")}
46 |
47 |
48 |
{renderFaq()}
49 |
50 |
51 |
96 |
97 |
98 | );
99 | };
100 | FAQ.getInitialProps = async () => ({
101 | namespacesRequired: ["common", "header", "faq"],
102 | });
103 | FAQ.propTypes = {
104 | t: PropTypes.func.isRequired,
105 | };
106 |
107 | export default withTranslation("faq")(FAQ);
108 |
--------------------------------------------------------------------------------
/components/mainFeature.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import PropTypes from "prop-types";
3 |
4 | import { withTranslation } from "../i18n";
5 |
6 | const MainFeature = ({ t }) => {
7 | return (
8 |
9 |
10 |
11 |
12 |
{t("title1")}
13 |
{t("subtitle1")}
14 |
15 |
19 |

24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
{t("title2")}
33 |
{t("subtitle2")}
34 |
35 |
36 |
40 |

45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
{t("title3")}
53 |
{t("subtitle3")}
54 |
55 |
59 |

64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
{t("title4")}
73 |
{t("subtitle4")}
74 |
75 |
76 |
80 |

85 |
86 |
87 |
88 |
89 |
90 | );
91 | };
92 | MainFeature.getInitialProps = async () => ({
93 | namespacesRequired: ["mainFeature"],
94 | });
95 | MainFeature.propTypes = {
96 | t: PropTypes.func.isRequired,
97 | };
98 |
99 | export default withTranslation("mainFeature")(MainFeature);
100 |
--------------------------------------------------------------------------------
/pages/support.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import PropTypes from "prop-types";
3 | import { withTranslation } from "../i18n";
4 | import Header from "../components/header";
5 | import Footer from "../components/footer";
6 | const Support = ({ t }) => {
7 | return (
8 |
9 |
10 |
11 |
12 |
13 |
14 |
{t("support")}
15 |
{t("support-subtitle")}
16 |
17 |
18 |
22 |
23 |
24 |
25 |
28 |
29 |
42 |
43 |
44 |
45 |
48 |
49 |
50 |
{t("email")}
51 |
{t("email-subtitle")}
52 |
53 |
54 |
55 |
56 |
57 |
58 |
94 |
95 |
96 | );
97 | };
98 | Support.getInitialProps = async () => ({
99 | namespacesRequired: ["common", "header"],
100 | });
101 | Support.propTypes = {
102 | t: PropTypes.func.isRequired,
103 | };
104 |
105 | export default withTranslation("common")(Support);
106 |
--------------------------------------------------------------------------------
/components/cover.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import PropTypes from "prop-types";
3 |
4 | import { withTranslation, Link } from "../i18n";
5 | const Cover = ({ t }) => (
6 |
7 |

8 |
9 |
10 |
14 |
18 |
{t("title")}
19 |
{t("subtitle")}
20 |
25 |
26 |
27 |
28 |
{t("download")}
29 |
30 |
31 |
32 |
41 |
42 |
43 |
44 |
45 |
46 |
52 |
58 |
59 |
60 |
139 |
140 | );
141 | Cover.getInitialProps = async () => ({
142 | namespacesRequired: ["common"],
143 | });
144 | Cover.propTypes = {
145 | t: PropTypes.func.isRequired,
146 | };
147 |
148 | export default withTranslation("common")(Cover);
149 |
--------------------------------------------------------------------------------
/pages/_document.js:
--------------------------------------------------------------------------------
1 | /* eslint react/no-danger: 0 */
2 | import React from "react";
3 | import Document, { Html, Head, Main, NextScript } from "next/document";
4 |
5 | class CustomDocument extends Document {
6 | setGoogleTags() {
7 | return {
8 | __html: `
9 | window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);};gtag('js', new Date());gtag('config', 'UA-149740367-1')
10 | `,
11 | };
12 | }
13 | render() {
14 | return (
15 |
16 |
17 |
18 |
19 |
23 |
24 |
28 |
32 |
33 |
34 |
38 |
42 |
46 |
47 |
48 |
52 |
56 |
60 |
64 |
68 |
73 |
79 |
85 |
86 |
91 |
92 |
93 |
97 |
98 | {" "}
99 |
100 |
101 |
102 |
103 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 | );
116 | }
117 | }
118 |
119 | export default CustomDocument;
120 |
--------------------------------------------------------------------------------
/pages/log.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import PropTypes from "prop-types";
3 | import { withTranslation } from "../i18n";
4 | import Header from "../components/header";
5 | import Footer from "../components/footer";
6 | import changeLogs from "../configs/logs";
7 | const Log = ({ t }) => {
8 | const generateLogsInfo = (isNew, item) => {
9 | let arr = new Array();
10 | let num = isNew ? item.new : item.fix;
11 | for (let i = 1; i <= num; i++) {
12 | arr.push(`${isNew ? "new" : "fix"}${i}-${item.versionTag}`);
13 | }
14 | return arr;
15 | };
16 | const renderFix = (fixLogs) => {
17 | return fixLogs.map((item) => {
18 | return (
19 |
20 |
FIX
21 |
22 | {t(item)}
23 |
24 |
25 | );
26 | });
27 | };
28 | const renderNew = (newLogs) => {
29 | return newLogs.map((item) => {
30 | return (
31 |
32 |
NEW
33 |
34 | {t(item)}
35 |
36 |
37 | );
38 | });
39 | };
40 | const renderLogs = () => {
41 | return changeLogs.map((item, index) => {
42 | return (
43 |
49 |
50 |
51 |
52 |
53 |
54 | {"Version" + " " + item.version}
55 |
56 |
{item.date}
57 |
58 |
59 |
🎉🎉🎉
60 |
61 |
62 |
63 |
64 |
65 | {renderNew(generateLogsInfo(true, item))}
66 | {renderFix(generateLogsInfo(false, item))}
67 |
68 |
69 |
70 | );
71 | });
72 | };
73 | return (
74 |
75 |
76 |
77 |
78 |
79 |
{t("log-title")}
80 |
{t("log-subtitle")}
81 |
82 |
83 | {renderLogs()}
84 |
85 |
162 |
163 |
164 | );
165 | };
166 |
167 | Log.getInitialProps = async () => ({
168 | namespacesRequired: ["common", "header", "log"],
169 | });
170 |
171 | Log.propTypes = {
172 | t: PropTypes.func.isRequired,
173 | };
174 |
175 | export default withTranslation("log")(Log);
176 |
--------------------------------------------------------------------------------
/components/header.js:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useState } from "react";
2 | import PropTypes from "prop-types";
3 | import { withRouter } from "next/router";
4 | import { i18n, Link, withTranslation } from "../i18n";
5 | import HeaderOption from "./headerOption";
6 | const Header = ({ t, router }) => {
7 | const [theme, setTheme] = useState("dark");
8 | const routeName = router.pathname;
9 | const [collapse, setCollapse] = useState(true);
10 | useEffect(() => {
11 | var scrollFunc = function (e) {
12 | e = e || window.event;
13 | if (e.wheelDelta) {
14 | let offsetHeight =
15 | document.body.scrollTop || document.documentElement.scrollTop;
16 | if (offsetHeight > 150) {
17 | setTheme("light");
18 | } else {
19 | setTheme("dark");
20 | }
21 | } else if (e.detail) {
22 | //Firefox滑轮事件
23 | let offsetHeight =
24 | document.body.scrollTop || document.documentElement.scrollTop;
25 | console.log(offsetHeight);
26 | if (offsetHeight > 150) {
27 | setTheme("light");
28 | } else {
29 | setTheme("dark");
30 | }
31 | }
32 | };
33 | //给页面绑定滑轮滚动事件
34 | if (document.addEventListener) {
35 | //firefox
36 | document.addEventListener("DOMMouseScroll", scrollFunc, false);
37 | }
38 | //滚动滑轮触发scrollFunc方法 //ie 谷歌
39 | window.onmousewheel = document.onmousewheel = scrollFunc;
40 | }, []);
41 | useEffect(() => {
42 | console.log(theme);
43 | }, [theme]);
44 | return (
45 |
195 | );
196 | };
197 | Header.getInitialProps = async () => ({
198 | namespacesRequired: ["header"],
199 | });
200 | Header.propTypes = {
201 | t: PropTypes.func.isRequired,
202 | };
203 | export default withTranslation("header")(withRouter(Header));
204 |
--------------------------------------------------------------------------------
/public/images/image4.svg:
--------------------------------------------------------------------------------
1 |
58 |
--------------------------------------------------------------------------------
/public/images/image3.svg:
--------------------------------------------------------------------------------
1 |
44 |
--------------------------------------------------------------------------------
/public/images/image1.svg:
--------------------------------------------------------------------------------
1 |
37 |
--------------------------------------------------------------------------------
/public/lib/aos.js:
--------------------------------------------------------------------------------
1 | !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.AOS=t()}(this,function(){"use strict";var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},t="Expected a function",n=NaN,o="[object Symbol]",i=/^\s+|\s+$/g,a=/^[-+]0x[0-9a-f]+$/i,r=/^0b[01]+$/i,c=/^0o[0-7]+$/i,s=parseInt,u="object"==typeof e&&e&&e.Object===Object&&e,d="object"==typeof self&&self&&self.Object===Object&&self,l=u||d||Function("return this")(),f=Object.prototype.toString,m=Math.max,p=Math.min,b=function(){return l.Date.now()};function v(e,n,o){var i,a,r,c,s,u,d=0,l=!1,f=!1,v=!0;if("function"!=typeof e)throw new TypeError(t);function y(t){var n=i,o=a;return i=a=void 0,d=t,c=e.apply(o,n)}function h(e){var t=e-u;return void 0===u||t>=n||t<0||f&&e-d>=r}function k(){var e=b();if(h(e))return x(e);s=setTimeout(k,function(e){var t=n-(e-u);return f?p(t,r-(e-d)):t}(e))}function x(e){return s=void 0,v&&i?y(e):(i=a=void 0,c)}function O(){var e=b(),t=h(e);if(i=arguments,a=this,u=e,t){if(void 0===s)return function(e){return d=e,s=setTimeout(k,n),l?y(e):c}(u);if(f)return s=setTimeout(k,n),y(u)}return void 0===s&&(s=setTimeout(k,n)),c}return n=w(n)||0,g(o)&&(l=!!o.leading,r=(f="maxWait"in o)?m(w(o.maxWait)||0,n):r,v="trailing"in o?!!o.trailing:v),O.cancel=function(){void 0!==s&&clearTimeout(s),d=0,i=u=a=s=void 0},O.flush=function(){return void 0===s?c:x(b())},O}function g(e){var t=typeof e;return!!e&&("object"==t||"function"==t)}function w(e){if("number"==typeof e)return e;if(function(e){return"symbol"==typeof e||function(e){return!!e&&"object"==typeof e}(e)&&f.call(e)==o}(e))return n;if(g(e)){var t="function"==typeof e.valueOf?e.valueOf():e;e=g(t)?t+"":t}if("string"!=typeof e)return 0===e?e:+e;e=e.replace(i,"");var u=r.test(e);return u||c.test(e)?s(e.slice(2),u?2:8):a.test(e)?n:+e}var y=function(e,n,o){var i=!0,a=!0;if("function"!=typeof e)throw new TypeError(t);return g(o)&&(i="leading"in o?!!o.leading:i,a="trailing"in o?!!o.trailing:a),v(e,n,{leading:i,maxWait:n,trailing:a})},h="Expected a function",k=NaN,x="[object Symbol]",O=/^\s+|\s+$/g,j=/^[-+]0x[0-9a-f]+$/i,E=/^0b[01]+$/i,N=/^0o[0-7]+$/i,z=parseInt,C="object"==typeof e&&e&&e.Object===Object&&e,A="object"==typeof self&&self&&self.Object===Object&&self,q=C||A||Function("return this")(),L=Object.prototype.toString,T=Math.max,M=Math.min,S=function(){return q.Date.now()};function D(e){var t=typeof e;return!!e&&("object"==t||"function"==t)}function H(e){if("number"==typeof e)return e;if(function(e){return"symbol"==typeof e||function(e){return!!e&&"object"==typeof e}(e)&&L.call(e)==x}(e))return k;if(D(e)){var t="function"==typeof e.valueOf?e.valueOf():e;e=D(t)?t+"":t}if("string"!=typeof e)return 0===e?e:+e;e=e.replace(O,"");var n=E.test(e);return n||N.test(e)?z(e.slice(2),n?2:8):j.test(e)?k:+e}var $=function(e,t,n){var o,i,a,r,c,s,u=0,d=!1,l=!1,f=!0;if("function"!=typeof e)throw new TypeError(h);function m(t){var n=o,a=i;return o=i=void 0,u=t,r=e.apply(a,n)}function p(e){var n=e-s;return void 0===s||n>=t||n<0||l&&e-u>=a}function b(){var e=S();if(p(e))return v(e);c=setTimeout(b,function(e){var n=t-(e-s);return l?M(n,a-(e-u)):n}(e))}function v(e){return c=void 0,f&&o?m(e):(o=i=void 0,r)}function g(){var e=S(),n=p(e);if(o=arguments,i=this,s=e,n){if(void 0===c)return function(e){return u=e,c=setTimeout(b,t),d?m(e):r}(s);if(l)return c=setTimeout(b,t),m(s)}return void 0===c&&(c=setTimeout(b,t)),r}return t=H(t)||0,D(n)&&(d=!!n.leading,a=(l="maxWait"in n)?T(H(n.maxWait)||0,t):a,f="trailing"in n?!!n.trailing:f),g.cancel=function(){void 0!==c&&clearTimeout(c),u=0,o=s=i=c=void 0},g.flush=function(){return void 0===c?r:v(S())},g},W=function(){};function P(e){e&&e.forEach(function(e){var t=Array.prototype.slice.call(e.addedNodes),n=Array.prototype.slice.call(e.removedNodes);if(function e(t){var n=void 0,o=void 0;for(n=0;n=o.out&&!n.once?a():t>=o.in?e.animated||(function(e,t){t&&t.forEach(function(t){return e.classList.add(t)})}(i,n.animatedClassNames),V("aos:in",i),e.options.id&&V("aos:in:"+e.options.id,i),e.animated=!0):e.animated&&!n.once&&a()}(e,window.pageYOffset)})},Z=function(e){for(var t=0,n=0;e&&!isNaN(e.offsetLeft)&&!isNaN(e.offsetTop);)t+=e.offsetLeft-("BODY"!=e.tagName?e.scrollLeft:0),n+=e.offsetTop-("BODY"!=e.tagName?e.scrollTop:0),e=e.offsetParent;return{top:n,left:t}},ee=function(e,t,n){var o=e.getAttribute("data-aos-"+t);if(void 0!==o){if("true"===o)return!0;if("false"===o)return!1}return o||n},te=function(e,t){return e.forEach(function(e,n){var o=ee(e.node,"mirror",t.mirror),i=ee(e.node,"once",t.once),a=ee(e.node,"id"),r=t.useClassNames&&e.node.getAttribute("data-aos"),c=[t.animatedClassName].concat(r?r.split(" "):[]).filter(function(e){return"string"==typeof e});t.initClassName&&e.node.classList.add(t.initClassName),e.position={in:function(e,t,n){var o=window.innerHeight,i=ee(e,"anchor"),a=ee(e,"anchor-placement"),r=Number(ee(e,"offset",a?0:t)),c=a||n,s=e;i&&document.querySelectorAll(i)&&(s=document.querySelectorAll(i)[0]);var u=Z(s).top-o;switch(c){case"top-bottom":break;case"center-bottom":u+=s.offsetHeight/2;break;case"bottom-bottom":u+=s.offsetHeight;break;case"top-center":u+=o/2;break;case"center-center":u+=o/2+s.offsetHeight/2;break;case"bottom-center":u+=o/2+s.offsetHeight;break;case"top-top":u+=o;break;case"bottom-top":u+=o+s.offsetHeight;break;case"center-top":u+=o+s.offsetHeight/2}return u+r}(e.node,t.offset,t.anchorPlacement),out:o&&function(e,t){window.innerHeight;var n=ee(e,"anchor"),o=ee(e,"offset",t),i=e;return n&&document.querySelectorAll(n)&&(i=document.querySelectorAll(n)[0]),Z(i).top+i.offsetHeight-o}(e.node,t.offset)},e.options={once:i,mirror:o,animatedClassNames:c,id:a}}),e},ne=function(){var e=document.querySelectorAll("[data-aos]");return Array.prototype.map.call(e,function(e){return{node:e}})},oe=[],ie=!1,ae={offset:120,delay:0,easing:"ease",duration:400,disable:!1,once:!1,mirror:!1,anchorPlacement:"top-bottom",startEvent:"DOMContentLoaded",animatedClassName:"aos-animate",initClassName:"aos-init",useClassNames:!1,disableMutationObserver:!1,throttleDelay:99,debounceDelay:50},re=function(){return document.all&&!window.atob},ce=function(){arguments.length>0&&void 0!==arguments[0]&&arguments[0]&&(ie=!0),ie&&(oe=te(oe,ae),X(oe),window.addEventListener("scroll",y(function(){X(oe,ae.once)},ae.throttleDelay)))},se=function(){if(oe=ne(),de(ae.disable)||re())return ue();ce()},ue=function(){oe.forEach(function(e,t){e.node.removeAttribute("data-aos"),e.node.removeAttribute("data-aos-easing"),e.node.removeAttribute("data-aos-duration"),e.node.removeAttribute("data-aos-delay"),ae.initClassName&&e.node.classList.remove(ae.initClassName),ae.animatedClassName&&e.node.classList.remove(ae.animatedClassName)})},de=function(e){return!0===e||"mobile"===e&&U.mobile()||"phone"===e&&U.phone()||"tablet"===e&&U.tablet()||"function"==typeof e&&!0===e()};return{init:function(e){return ae=I(ae,e),oe=ne(),ae.disableMutationObserver||_.isSupported()||(console.info('\n aos: MutationObserver is not supported on this browser,\n code mutations observing has been disabled.\n You may have to call "refreshHard()" by yourself.\n '),ae.disableMutationObserver=!0),ae.disableMutationObserver||_.ready("[data-aos]",se),de(ae.disable)||re()?ue():(document.querySelector("body").setAttribute("data-aos-easing",ae.easing),document.querySelector("body").setAttribute("data-aos-duration",ae.duration),document.querySelector("body").setAttribute("data-aos-delay",ae.delay),-1===["DOMContentLoaded","load"].indexOf(ae.startEvent)?document.addEventListener(ae.startEvent,function(){ce(!0)}):window.addEventListener("load",function(){ce(!0)}),"DOMContentLoaded"===ae.startEvent&&["complete","interactive"].indexOf(document.readyState)>-1&&ce(!0),window.addEventListener("resize",$(ce,ae.debounceDelay,!0)),window.addEventListener("orientationchange",$(ce,ae.debounceDelay,!0)),oe)},refresh:ce,refreshHard:se}});
2 |
--------------------------------------------------------------------------------
/public/images/image2.svg:
--------------------------------------------------------------------------------
1 |
97 |
--------------------------------------------------------------------------------
/public/lib/aos.css:
--------------------------------------------------------------------------------
1 | [data-aos][data-aos][data-aos-duration="50"],body[data-aos-duration="50"] [data-aos]{transition-duration:50ms}[data-aos][data-aos][data-aos-delay="50"],body[data-aos-delay="50"] [data-aos]{transition-delay:0s}[data-aos][data-aos][data-aos-delay="50"].aos-animate,body[data-aos-delay="50"] [data-aos].aos-animate{transition-delay:50ms}[data-aos][data-aos][data-aos-duration="100"],body[data-aos-duration="100"] [data-aos]{transition-duration:.1s}[data-aos][data-aos][data-aos-delay="100"],body[data-aos-delay="100"] [data-aos]{transition-delay:0s}[data-aos][data-aos][data-aos-delay="100"].aos-animate,body[data-aos-delay="100"] [data-aos].aos-animate{transition-delay:.1s}[data-aos][data-aos][data-aos-duration="150"],body[data-aos-duration="150"] [data-aos]{transition-duration:.15s}[data-aos][data-aos][data-aos-delay="150"],body[data-aos-delay="150"] [data-aos]{transition-delay:0s}[data-aos][data-aos][data-aos-delay="150"].aos-animate,body[data-aos-delay="150"] [data-aos].aos-animate{transition-delay:.15s}[data-aos][data-aos][data-aos-duration="200"],body[data-aos-duration="200"] [data-aos]{transition-duration:.2s}[data-aos][data-aos][data-aos-delay="200"],body[data-aos-delay="200"] [data-aos]{transition-delay:0s}[data-aos][data-aos][data-aos-delay="200"].aos-animate,body[data-aos-delay="200"] [data-aos].aos-animate{transition-delay:.2s}[data-aos][data-aos][data-aos-duration="250"],body[data-aos-duration="250"] [data-aos]{transition-duration:.25s}[data-aos][data-aos][data-aos-delay="250"],body[data-aos-delay="250"] [data-aos]{transition-delay:0s}[data-aos][data-aos][data-aos-delay="250"].aos-animate,body[data-aos-delay="250"] [data-aos].aos-animate{transition-delay:.25s}[data-aos][data-aos][data-aos-duration="300"],body[data-aos-duration="300"] [data-aos]{transition-duration:.3s}[data-aos][data-aos][data-aos-delay="300"],body[data-aos-delay="300"] [data-aos]{transition-delay:0s}[data-aos][data-aos][data-aos-delay="300"].aos-animate,body[data-aos-delay="300"] [data-aos].aos-animate{transition-delay:.3s}[data-aos][data-aos][data-aos-duration="350"],body[data-aos-duration="350"] [data-aos]{transition-duration:.35s}[data-aos][data-aos][data-aos-delay="350"],body[data-aos-delay="350"] [data-aos]{transition-delay:0s}[data-aos][data-aos][data-aos-delay="350"].aos-animate,body[data-aos-delay="350"] [data-aos].aos-animate{transition-delay:.35s}[data-aos][data-aos][data-aos-duration="400"],body[data-aos-duration="400"] [data-aos]{transition-duration:.4s}[data-aos][data-aos][data-aos-delay="400"],body[data-aos-delay="400"] [data-aos]{transition-delay:0s}[data-aos][data-aos][data-aos-delay="400"].aos-animate,body[data-aos-delay="400"] [data-aos].aos-animate{transition-delay:.4s}[data-aos][data-aos][data-aos-duration="450"],body[data-aos-duration="450"] [data-aos]{transition-duration:.45s}[data-aos][data-aos][data-aos-delay="450"],body[data-aos-delay="450"] [data-aos]{transition-delay:0s}[data-aos][data-aos][data-aos-delay="450"].aos-animate,body[data-aos-delay="450"] [data-aos].aos-animate{transition-delay:.45s}[data-aos][data-aos][data-aos-duration="500"],body[data-aos-duration="500"] [data-aos]{transition-duration:.5s}[data-aos][data-aos][data-aos-delay="500"],body[data-aos-delay="500"] [data-aos]{transition-delay:0s}[data-aos][data-aos][data-aos-delay="500"].aos-animate,body[data-aos-delay="500"] [data-aos].aos-animate{transition-delay:.5s}[data-aos][data-aos][data-aos-duration="550"],body[data-aos-duration="550"] [data-aos]{transition-duration:.55s}[data-aos][data-aos][data-aos-delay="550"],body[data-aos-delay="550"] [data-aos]{transition-delay:0s}[data-aos][data-aos][data-aos-delay="550"].aos-animate,body[data-aos-delay="550"] [data-aos].aos-animate{transition-delay:.55s}[data-aos][data-aos][data-aos-duration="600"],body[data-aos-duration="600"] [data-aos]{transition-duration:.6s}[data-aos][data-aos][data-aos-delay="600"],body[data-aos-delay="600"] [data-aos]{transition-delay:0s}[data-aos][data-aos][data-aos-delay="600"].aos-animate,body[data-aos-delay="600"] [data-aos].aos-animate{transition-delay:.6s}[data-aos][data-aos][data-aos-duration="650"],body[data-aos-duration="650"] [data-aos]{transition-duration:.65s}[data-aos][data-aos][data-aos-delay="650"],body[data-aos-delay="650"] [data-aos]{transition-delay:0s}[data-aos][data-aos][data-aos-delay="650"].aos-animate,body[data-aos-delay="650"] [data-aos].aos-animate{transition-delay:.65s}[data-aos][data-aos][data-aos-duration="700"],body[data-aos-duration="700"] [data-aos]{transition-duration:.7s}[data-aos][data-aos][data-aos-delay="700"],body[data-aos-delay="700"] [data-aos]{transition-delay:0s}[data-aos][data-aos][data-aos-delay="700"].aos-animate,body[data-aos-delay="700"] [data-aos].aos-animate{transition-delay:.7s}[data-aos][data-aos][data-aos-duration="750"],body[data-aos-duration="750"] [data-aos]{transition-duration:.75s}[data-aos][data-aos][data-aos-delay="750"],body[data-aos-delay="750"] [data-aos]{transition-delay:0s}[data-aos][data-aos][data-aos-delay="750"].aos-animate,body[data-aos-delay="750"] [data-aos].aos-animate{transition-delay:.75s}[data-aos][data-aos][data-aos-duration="800"],body[data-aos-duration="800"] [data-aos]{transition-duration:.8s}[data-aos][data-aos][data-aos-delay="800"],body[data-aos-delay="800"] [data-aos]{transition-delay:0s}[data-aos][data-aos][data-aos-delay="800"].aos-animate,body[data-aos-delay="800"] [data-aos].aos-animate{transition-delay:.8s}[data-aos][data-aos][data-aos-duration="850"],body[data-aos-duration="850"] [data-aos]{transition-duration:.85s}[data-aos][data-aos][data-aos-delay="850"],body[data-aos-delay="850"] [data-aos]{transition-delay:0s}[data-aos][data-aos][data-aos-delay="850"].aos-animate,body[data-aos-delay="850"] [data-aos].aos-animate{transition-delay:.85s}[data-aos][data-aos][data-aos-duration="900"],body[data-aos-duration="900"] [data-aos]{transition-duration:.9s}[data-aos][data-aos][data-aos-delay="900"],body[data-aos-delay="900"] [data-aos]{transition-delay:0s}[data-aos][data-aos][data-aos-delay="900"].aos-animate,body[data-aos-delay="900"] [data-aos].aos-animate{transition-delay:.9s}[data-aos][data-aos][data-aos-duration="950"],body[data-aos-duration="950"] [data-aos]{transition-duration:.95s}[data-aos][data-aos][data-aos-delay="950"],body[data-aos-delay="950"] [data-aos]{transition-delay:0s}[data-aos][data-aos][data-aos-delay="950"].aos-animate,body[data-aos-delay="950"] [data-aos].aos-animate{transition-delay:.95s}[data-aos][data-aos][data-aos-duration="1000"],body[data-aos-duration="1000"] [data-aos]{transition-duration:1s}[data-aos][data-aos][data-aos-delay="1000"],body[data-aos-delay="1000"] [data-aos]{transition-delay:0s}[data-aos][data-aos][data-aos-delay="1000"].aos-animate,body[data-aos-delay="1000"] [data-aos].aos-animate{transition-delay:1s}[data-aos][data-aos][data-aos-duration="1050"],body[data-aos-duration="1050"] [data-aos]{transition-duration:1.05s}[data-aos][data-aos][data-aos-delay="1050"],body[data-aos-delay="1050"] [data-aos]{transition-delay:0s}[data-aos][data-aos][data-aos-delay="1050"].aos-animate,body[data-aos-delay="1050"] [data-aos].aos-animate{transition-delay:1.05s}[data-aos][data-aos][data-aos-duration="1100"],body[data-aos-duration="1100"] [data-aos]{transition-duration:1.1s}[data-aos][data-aos][data-aos-delay="1100"],body[data-aos-delay="1100"] [data-aos]{transition-delay:0s}[data-aos][data-aos][data-aos-delay="1100"].aos-animate,body[data-aos-delay="1100"] [data-aos].aos-animate{transition-delay:1.1s}[data-aos][data-aos][data-aos-duration="1150"],body[data-aos-duration="1150"] [data-aos]{transition-duration:1.15s}[data-aos][data-aos][data-aos-delay="1150"],body[data-aos-delay="1150"] [data-aos]{transition-delay:0s}[data-aos][data-aos][data-aos-delay="1150"].aos-animate,body[data-aos-delay="1150"] [data-aos].aos-animate{transition-delay:1.15s}[data-aos][data-aos][data-aos-duration="1200"],body[data-aos-duration="1200"] [data-aos]{transition-duration:1.2s}[data-aos][data-aos][data-aos-delay="1200"],body[data-aos-delay="1200"] [data-aos]{transition-delay:0s}[data-aos][data-aos][data-aos-delay="1200"].aos-animate,body[data-aos-delay="1200"] [data-aos].aos-animate{transition-delay:1.2s}[data-aos][data-aos][data-aos-duration="1250"],body[data-aos-duration="1250"] [data-aos]{transition-duration:1.25s}[data-aos][data-aos][data-aos-delay="1250"],body[data-aos-delay="1250"] [data-aos]{transition-delay:0s}[data-aos][data-aos][data-aos-delay="1250"].aos-animate,body[data-aos-delay="1250"] [data-aos].aos-animate{transition-delay:1.25s}[data-aos][data-aos][data-aos-duration="1300"],body[data-aos-duration="1300"] [data-aos]{transition-duration:1.3s}[data-aos][data-aos][data-aos-delay="1300"],body[data-aos-delay="1300"] [data-aos]{transition-delay:0s}[data-aos][data-aos][data-aos-delay="1300"].aos-animate,body[data-aos-delay="1300"] [data-aos].aos-animate{transition-delay:1.3s}[data-aos][data-aos][data-aos-duration="1350"],body[data-aos-duration="1350"] [data-aos]{transition-duration:1.35s}[data-aos][data-aos][data-aos-delay="1350"],body[data-aos-delay="1350"] [data-aos]{transition-delay:0s}[data-aos][data-aos][data-aos-delay="1350"].aos-animate,body[data-aos-delay="1350"] [data-aos].aos-animate{transition-delay:1.35s}[data-aos][data-aos][data-aos-duration="1400"],body[data-aos-duration="1400"] [data-aos]{transition-duration:1.4s}[data-aos][data-aos][data-aos-delay="1400"],body[data-aos-delay="1400"] [data-aos]{transition-delay:0s}[data-aos][data-aos][data-aos-delay="1400"].aos-animate,body[data-aos-delay="1400"] [data-aos].aos-animate{transition-delay:1.4s}[data-aos][data-aos][data-aos-duration="1450"],body[data-aos-duration="1450"] [data-aos]{transition-duration:1.45s}[data-aos][data-aos][data-aos-delay="1450"],body[data-aos-delay="1450"] [data-aos]{transition-delay:0s}[data-aos][data-aos][data-aos-delay="1450"].aos-animate,body[data-aos-delay="1450"] [data-aos].aos-animate{transition-delay:1.45s}[data-aos][data-aos][data-aos-duration="1500"],body[data-aos-duration="1500"] [data-aos]{transition-duration:1.5s}[data-aos][data-aos][data-aos-delay="1500"],body[data-aos-delay="1500"] [data-aos]{transition-delay:0s}[data-aos][data-aos][data-aos-delay="1500"].aos-animate,body[data-aos-delay="1500"] [data-aos].aos-animate{transition-delay:1.5s}[data-aos][data-aos][data-aos-duration="1550"],body[data-aos-duration="1550"] [data-aos]{transition-duration:1.55s}[data-aos][data-aos][data-aos-delay="1550"],body[data-aos-delay="1550"] [data-aos]{transition-delay:0s}[data-aos][data-aos][data-aos-delay="1550"].aos-animate,body[data-aos-delay="1550"] [data-aos].aos-animate{transition-delay:1.55s}[data-aos][data-aos][data-aos-duration="1600"],body[data-aos-duration="1600"] [data-aos]{transition-duration:1.6s}[data-aos][data-aos][data-aos-delay="1600"],body[data-aos-delay="1600"] [data-aos]{transition-delay:0s}[data-aos][data-aos][data-aos-delay="1600"].aos-animate,body[data-aos-delay="1600"] [data-aos].aos-animate{transition-delay:1.6s}[data-aos][data-aos][data-aos-duration="1650"],body[data-aos-duration="1650"] [data-aos]{transition-duration:1.65s}[data-aos][data-aos][data-aos-delay="1650"],body[data-aos-delay="1650"] [data-aos]{transition-delay:0s}[data-aos][data-aos][data-aos-delay="1650"].aos-animate,body[data-aos-delay="1650"] [data-aos].aos-animate{transition-delay:1.65s}[data-aos][data-aos][data-aos-duration="1700"],body[data-aos-duration="1700"] [data-aos]{transition-duration:1.7s}[data-aos][data-aos][data-aos-delay="1700"],body[data-aos-delay="1700"] [data-aos]{transition-delay:0s}[data-aos][data-aos][data-aos-delay="1700"].aos-animate,body[data-aos-delay="1700"] [data-aos].aos-animate{transition-delay:1.7s}[data-aos][data-aos][data-aos-duration="1750"],body[data-aos-duration="1750"] [data-aos]{transition-duration:1.75s}[data-aos][data-aos][data-aos-delay="1750"],body[data-aos-delay="1750"] [data-aos]{transition-delay:0s}[data-aos][data-aos][data-aos-delay="1750"].aos-animate,body[data-aos-delay="1750"] [data-aos].aos-animate{transition-delay:1.75s}[data-aos][data-aos][data-aos-duration="1800"],body[data-aos-duration="1800"] [data-aos]{transition-duration:1.8s}[data-aos][data-aos][data-aos-delay="1800"],body[data-aos-delay="1800"] [data-aos]{transition-delay:0s}[data-aos][data-aos][data-aos-delay="1800"].aos-animate,body[data-aos-delay="1800"] [data-aos].aos-animate{transition-delay:1.8s}[data-aos][data-aos][data-aos-duration="1850"],body[data-aos-duration="1850"] [data-aos]{transition-duration:1.85s}[data-aos][data-aos][data-aos-delay="1850"],body[data-aos-delay="1850"] [data-aos]{transition-delay:0s}[data-aos][data-aos][data-aos-delay="1850"].aos-animate,body[data-aos-delay="1850"] [data-aos].aos-animate{transition-delay:1.85s}[data-aos][data-aos][data-aos-duration="1900"],body[data-aos-duration="1900"] [data-aos]{transition-duration:1.9s}[data-aos][data-aos][data-aos-delay="1900"],body[data-aos-delay="1900"] [data-aos]{transition-delay:0s}[data-aos][data-aos][data-aos-delay="1900"].aos-animate,body[data-aos-delay="1900"] [data-aos].aos-animate{transition-delay:1.9s}[data-aos][data-aos][data-aos-duration="1950"],body[data-aos-duration="1950"] [data-aos]{transition-duration:1.95s}[data-aos][data-aos][data-aos-delay="1950"],body[data-aos-delay="1950"] [data-aos]{transition-delay:0s}[data-aos][data-aos][data-aos-delay="1950"].aos-animate,body[data-aos-delay="1950"] [data-aos].aos-animate{transition-delay:1.95s}[data-aos][data-aos][data-aos-duration="2000"],body[data-aos-duration="2000"] [data-aos]{transition-duration:2s}[data-aos][data-aos][data-aos-delay="2000"],body[data-aos-delay="2000"] [data-aos]{transition-delay:0s}[data-aos][data-aos][data-aos-delay="2000"].aos-animate,body[data-aos-delay="2000"] [data-aos].aos-animate{transition-delay:2s}[data-aos][data-aos][data-aos-duration="2050"],body[data-aos-duration="2050"] [data-aos]{transition-duration:2.05s}[data-aos][data-aos][data-aos-delay="2050"],body[data-aos-delay="2050"] [data-aos]{transition-delay:0s}[data-aos][data-aos][data-aos-delay="2050"].aos-animate,body[data-aos-delay="2050"] [data-aos].aos-animate{transition-delay:2.05s}[data-aos][data-aos][data-aos-duration="2100"],body[data-aos-duration="2100"] [data-aos]{transition-duration:2.1s}[data-aos][data-aos][data-aos-delay="2100"],body[data-aos-delay="2100"] [data-aos]{transition-delay:0s}[data-aos][data-aos][data-aos-delay="2100"].aos-animate,body[data-aos-delay="2100"] [data-aos].aos-animate{transition-delay:2.1s}[data-aos][data-aos][data-aos-duration="2150"],body[data-aos-duration="2150"] [data-aos]{transition-duration:2.15s}[data-aos][data-aos][data-aos-delay="2150"],body[data-aos-delay="2150"] [data-aos]{transition-delay:0s}[data-aos][data-aos][data-aos-delay="2150"].aos-animate,body[data-aos-delay="2150"] [data-aos].aos-animate{transition-delay:2.15s}[data-aos][data-aos][data-aos-duration="2200"],body[data-aos-duration="2200"] [data-aos]{transition-duration:2.2s}[data-aos][data-aos][data-aos-delay="2200"],body[data-aos-delay="2200"] [data-aos]{transition-delay:0s}[data-aos][data-aos][data-aos-delay="2200"].aos-animate,body[data-aos-delay="2200"] [data-aos].aos-animate{transition-delay:2.2s}[data-aos][data-aos][data-aos-duration="2250"],body[data-aos-duration="2250"] [data-aos]{transition-duration:2.25s}[data-aos][data-aos][data-aos-delay="2250"],body[data-aos-delay="2250"] [data-aos]{transition-delay:0s}[data-aos][data-aos][data-aos-delay="2250"].aos-animate,body[data-aos-delay="2250"] [data-aos].aos-animate{transition-delay:2.25s}[data-aos][data-aos][data-aos-duration="2300"],body[data-aos-duration="2300"] [data-aos]{transition-duration:2.3s}[data-aos][data-aos][data-aos-delay="2300"],body[data-aos-delay="2300"] [data-aos]{transition-delay:0s}[data-aos][data-aos][data-aos-delay="2300"].aos-animate,body[data-aos-delay="2300"] [data-aos].aos-animate{transition-delay:2.3s}[data-aos][data-aos][data-aos-duration="2350"],body[data-aos-duration="2350"] [data-aos]{transition-duration:2.35s}[data-aos][data-aos][data-aos-delay="2350"],body[data-aos-delay="2350"] [data-aos]{transition-delay:0s}[data-aos][data-aos][data-aos-delay="2350"].aos-animate,body[data-aos-delay="2350"] [data-aos].aos-animate{transition-delay:2.35s}[data-aos][data-aos][data-aos-duration="2400"],body[data-aos-duration="2400"] [data-aos]{transition-duration:2.4s}[data-aos][data-aos][data-aos-delay="2400"],body[data-aos-delay="2400"] [data-aos]{transition-delay:0s}[data-aos][data-aos][data-aos-delay="2400"].aos-animate,body[data-aos-delay="2400"] [data-aos].aos-animate{transition-delay:2.4s}[data-aos][data-aos][data-aos-duration="2450"],body[data-aos-duration="2450"] [data-aos]{transition-duration:2.45s}[data-aos][data-aos][data-aos-delay="2450"],body[data-aos-delay="2450"] [data-aos]{transition-delay:0s}[data-aos][data-aos][data-aos-delay="2450"].aos-animate,body[data-aos-delay="2450"] [data-aos].aos-animate{transition-delay:2.45s}[data-aos][data-aos][data-aos-duration="2500"],body[data-aos-duration="2500"] [data-aos]{transition-duration:2.5s}[data-aos][data-aos][data-aos-delay="2500"],body[data-aos-delay="2500"] [data-aos]{transition-delay:0s}[data-aos][data-aos][data-aos-delay="2500"].aos-animate,body[data-aos-delay="2500"] [data-aos].aos-animate{transition-delay:2.5s}[data-aos][data-aos][data-aos-duration="2550"],body[data-aos-duration="2550"] [data-aos]{transition-duration:2.55s}[data-aos][data-aos][data-aos-delay="2550"],body[data-aos-delay="2550"] [data-aos]{transition-delay:0s}[data-aos][data-aos][data-aos-delay="2550"].aos-animate,body[data-aos-delay="2550"] [data-aos].aos-animate{transition-delay:2.55s}[data-aos][data-aos][data-aos-duration="2600"],body[data-aos-duration="2600"] [data-aos]{transition-duration:2.6s}[data-aos][data-aos][data-aos-delay="2600"],body[data-aos-delay="2600"] [data-aos]{transition-delay:0s}[data-aos][data-aos][data-aos-delay="2600"].aos-animate,body[data-aos-delay="2600"] [data-aos].aos-animate{transition-delay:2.6s}[data-aos][data-aos][data-aos-duration="2650"],body[data-aos-duration="2650"] [data-aos]{transition-duration:2.65s}[data-aos][data-aos][data-aos-delay="2650"],body[data-aos-delay="2650"] [data-aos]{transition-delay:0s}[data-aos][data-aos][data-aos-delay="2650"].aos-animate,body[data-aos-delay="2650"] [data-aos].aos-animate{transition-delay:2.65s}[data-aos][data-aos][data-aos-duration="2700"],body[data-aos-duration="2700"] [data-aos]{transition-duration:2.7s}[data-aos][data-aos][data-aos-delay="2700"],body[data-aos-delay="2700"] [data-aos]{transition-delay:0s}[data-aos][data-aos][data-aos-delay="2700"].aos-animate,body[data-aos-delay="2700"] [data-aos].aos-animate{transition-delay:2.7s}[data-aos][data-aos][data-aos-duration="2750"],body[data-aos-duration="2750"] [data-aos]{transition-duration:2.75s}[data-aos][data-aos][data-aos-delay="2750"],body[data-aos-delay="2750"] [data-aos]{transition-delay:0s}[data-aos][data-aos][data-aos-delay="2750"].aos-animate,body[data-aos-delay="2750"] [data-aos].aos-animate{transition-delay:2.75s}[data-aos][data-aos][data-aos-duration="2800"],body[data-aos-duration="2800"] [data-aos]{transition-duration:2.8s}[data-aos][data-aos][data-aos-delay="2800"],body[data-aos-delay="2800"] [data-aos]{transition-delay:0s}[data-aos][data-aos][data-aos-delay="2800"].aos-animate,body[data-aos-delay="2800"] [data-aos].aos-animate{transition-delay:2.8s}[data-aos][data-aos][data-aos-duration="2850"],body[data-aos-duration="2850"] [data-aos]{transition-duration:2.85s}[data-aos][data-aos][data-aos-delay="2850"],body[data-aos-delay="2850"] [data-aos]{transition-delay:0s}[data-aos][data-aos][data-aos-delay="2850"].aos-animate,body[data-aos-delay="2850"] [data-aos].aos-animate{transition-delay:2.85s}[data-aos][data-aos][data-aos-duration="2900"],body[data-aos-duration="2900"] [data-aos]{transition-duration:2.9s}[data-aos][data-aos][data-aos-delay="2900"],body[data-aos-delay="2900"] [data-aos]{transition-delay:0s}[data-aos][data-aos][data-aos-delay="2900"].aos-animate,body[data-aos-delay="2900"] [data-aos].aos-animate{transition-delay:2.9s}[data-aos][data-aos][data-aos-duration="2950"],body[data-aos-duration="2950"] [data-aos]{transition-duration:2.95s}[data-aos][data-aos][data-aos-delay="2950"],body[data-aos-delay="2950"] [data-aos]{transition-delay:0s}[data-aos][data-aos][data-aos-delay="2950"].aos-animate,body[data-aos-delay="2950"] [data-aos].aos-animate{transition-delay:2.95s}[data-aos][data-aos][data-aos-duration="3000"],body[data-aos-duration="3000"] [data-aos]{transition-duration:3s}[data-aos][data-aos][data-aos-delay="3000"],body[data-aos-delay="3000"] [data-aos]{transition-delay:0s}[data-aos][data-aos][data-aos-delay="3000"].aos-animate,body[data-aos-delay="3000"] [data-aos].aos-animate{transition-delay:3s}[data-aos]{pointer-events:none}[data-aos].aos-animate{pointer-events:auto}[data-aos][data-aos][data-aos-easing=linear],body[data-aos-easing=linear] [data-aos]{transition-timing-function:cubic-bezier(.25,.25,.75,.75)}[data-aos][data-aos][data-aos-easing=ease],body[data-aos-easing=ease] [data-aos]{transition-timing-function:ease}[data-aos][data-aos][data-aos-easing=ease-in],body[data-aos-easing=ease-in] [data-aos]{transition-timing-function:ease-in}[data-aos][data-aos][data-aos-easing=ease-out],body[data-aos-easing=ease-out] [data-aos]{transition-timing-function:ease-out}[data-aos][data-aos][data-aos-easing=ease-in-out],body[data-aos-easing=ease-in-out] [data-aos]{transition-timing-function:ease-in-out}[data-aos][data-aos][data-aos-easing=ease-in-back],body[data-aos-easing=ease-in-back] [data-aos]{transition-timing-function:cubic-bezier(.6,-.28,.735,.045)}[data-aos][data-aos][data-aos-easing=ease-out-back],body[data-aos-easing=ease-out-back] [data-aos]{transition-timing-function:cubic-bezier(.175,.885,.32,1.275)}[data-aos][data-aos][data-aos-easing=ease-in-out-back],body[data-aos-easing=ease-in-out-back] [data-aos]{transition-timing-function:cubic-bezier(.68,-.55,.265,1.55)}[data-aos][data-aos][data-aos-easing=ease-in-sine],body[data-aos-easing=ease-in-sine] [data-aos]{transition-timing-function:cubic-bezier(.47,0,.745,.715)}[data-aos][data-aos][data-aos-easing=ease-out-sine],body[data-aos-easing=ease-out-sine] [data-aos]{transition-timing-function:cubic-bezier(.39,.575,.565,1)}[data-aos][data-aos][data-aos-easing=ease-in-out-sine],body[data-aos-easing=ease-in-out-sine] [data-aos]{transition-timing-function:cubic-bezier(.445,.05,.55,.95)}[data-aos][data-aos][data-aos-easing=ease-in-quad],body[data-aos-easing=ease-in-quad] [data-aos]{transition-timing-function:cubic-bezier(.55,.085,.68,.53)}[data-aos][data-aos][data-aos-easing=ease-out-quad],body[data-aos-easing=ease-out-quad] [data-aos]{transition-timing-function:cubic-bezier(.25,.46,.45,.94)}[data-aos][data-aos][data-aos-easing=ease-in-out-quad],body[data-aos-easing=ease-in-out-quad] [data-aos]{transition-timing-function:cubic-bezier(.455,.03,.515,.955)}[data-aos][data-aos][data-aos-easing=ease-in-cubic],body[data-aos-easing=ease-in-cubic] [data-aos]{transition-timing-function:cubic-bezier(.55,.085,.68,.53)}[data-aos][data-aos][data-aos-easing=ease-out-cubic],body[data-aos-easing=ease-out-cubic] [data-aos]{transition-timing-function:cubic-bezier(.25,.46,.45,.94)}[data-aos][data-aos][data-aos-easing=ease-in-out-cubic],body[data-aos-easing=ease-in-out-cubic] [data-aos]{transition-timing-function:cubic-bezier(.455,.03,.515,.955)}[data-aos][data-aos][data-aos-easing=ease-in-quart],body[data-aos-easing=ease-in-quart] [data-aos]{transition-timing-function:cubic-bezier(.55,.085,.68,.53)}[data-aos][data-aos][data-aos-easing=ease-out-quart],body[data-aos-easing=ease-out-quart] [data-aos]{transition-timing-function:cubic-bezier(.25,.46,.45,.94)}[data-aos][data-aos][data-aos-easing=ease-in-out-quart],body[data-aos-easing=ease-in-out-quart] [data-aos]{transition-timing-function:cubic-bezier(.455,.03,.515,.955)}@media screen{html:not(.no-js) [data-aos^=fade][data-aos^=fade]{opacity:0;transition-property:opacity,-webkit-transform;transition-property:opacity,transform;transition-property:opacity,transform,-webkit-transform}html:not(.no-js) [data-aos^=fade][data-aos^=fade].aos-animate{opacity:1;-webkit-transform:none;transform:none}html:not(.no-js) [data-aos=fade-up]{-webkit-transform:translate3d(0,100px,0);transform:translate3d(0,100px,0)}html:not(.no-js) [data-aos=fade-down]{-webkit-transform:translate3d(0,-100px,0);transform:translate3d(0,-100px,0)}html:not(.no-js) [data-aos=fade-right]{-webkit-transform:translate3d(-100px,0,0);transform:translate3d(-100px,0,0)}html:not(.no-js) [data-aos=fade-left]{-webkit-transform:translate3d(100px,0,0);transform:translate3d(100px,0,0)}html:not(.no-js) [data-aos=fade-up-right]{-webkit-transform:translate3d(-100px,100px,0);transform:translate3d(-100px,100px,0)}html:not(.no-js) [data-aos=fade-up-left]{-webkit-transform:translate3d(100px,100px,0);transform:translate3d(100px,100px,0)}html:not(.no-js) [data-aos=fade-down-right]{-webkit-transform:translate3d(-100px,-100px,0);transform:translate3d(-100px,-100px,0)}html:not(.no-js) [data-aos=fade-down-left]{-webkit-transform:translate3d(100px,-100px,0);transform:translate3d(100px,-100px,0)}html:not(.no-js) [data-aos^=zoom][data-aos^=zoom]{opacity:0;transition-property:opacity,-webkit-transform;transition-property:opacity,transform;transition-property:opacity,transform,-webkit-transform}html:not(.no-js) [data-aos^=zoom][data-aos^=zoom].aos-animate{opacity:1;-webkit-transform:translateZ(0) scale(1);transform:translateZ(0) scale(1)}html:not(.no-js) [data-aos=zoom-in]{-webkit-transform:scale(.6);transform:scale(.6)}html:not(.no-js) [data-aos=zoom-in-up]{-webkit-transform:translate3d(0,100px,0) scale(.6);transform:translate3d(0,100px,0) scale(.6)}html:not(.no-js) [data-aos=zoom-in-down]{-webkit-transform:translate3d(0,-100px,0) scale(.6);transform:translate3d(0,-100px,0) scale(.6)}html:not(.no-js) [data-aos=zoom-in-right]{-webkit-transform:translate3d(-100px,0,0) scale(.6);transform:translate3d(-100px,0,0) scale(.6)}html:not(.no-js) [data-aos=zoom-in-left]{-webkit-transform:translate3d(100px,0,0) scale(.6);transform:translate3d(100px,0,0) scale(.6)}html:not(.no-js) [data-aos=zoom-out]{-webkit-transform:scale(1.2);transform:scale(1.2)}html:not(.no-js) [data-aos=zoom-out-up]{-webkit-transform:translate3d(0,100px,0) scale(1.2);transform:translate3d(0,100px,0) scale(1.2)}html:not(.no-js) [data-aos=zoom-out-down]{-webkit-transform:translate3d(0,-100px,0) scale(1.2);transform:translate3d(0,-100px,0) scale(1.2)}html:not(.no-js) [data-aos=zoom-out-right]{-webkit-transform:translate3d(-100px,0,0) scale(1.2);transform:translate3d(-100px,0,0) scale(1.2)}html:not(.no-js) [data-aos=zoom-out-left]{-webkit-transform:translate3d(100px,0,0) scale(1.2);transform:translate3d(100px,0,0) scale(1.2)}html:not(.no-js) [data-aos^=slide][data-aos^=slide]{transition-property:-webkit-transform;transition-property:transform;transition-property:transform,-webkit-transform;visibility:hidden}html:not(.no-js) [data-aos^=slide][data-aos^=slide].aos-animate{visibility:visible;-webkit-transform:translateZ(0);transform:translateZ(0)}html:not(.no-js) [data-aos=slide-up]{-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}html:not(.no-js) [data-aos=slide-down]{-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}html:not(.no-js) [data-aos=slide-right]{-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}html:not(.no-js) [data-aos=slide-left]{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}html:not(.no-js) [data-aos^=flip][data-aos^=flip]{-webkit-backface-visibility:hidden;backface-visibility:hidden;transition-property:-webkit-transform;transition-property:transform;transition-property:transform,-webkit-transform}html:not(.no-js) [data-aos=flip-left]{-webkit-transform:perspective(2500px) rotateY(-100deg);transform:perspective(2500px) rotateY(-100deg)}html:not(.no-js) [data-aos=flip-left].aos-animate{-webkit-transform:perspective(2500px) rotateY(0);transform:perspective(2500px) rotateY(0)}html:not(.no-js) [data-aos=flip-right]{-webkit-transform:perspective(2500px) rotateY(100deg);transform:perspective(2500px) rotateY(100deg)}html:not(.no-js) [data-aos=flip-right].aos-animate{-webkit-transform:perspective(2500px) rotateY(0);transform:perspective(2500px) rotateY(0)}html:not(.no-js) [data-aos=flip-up]{-webkit-transform:perspective(2500px) rotateX(-100deg);transform:perspective(2500px) rotateX(-100deg)}html:not(.no-js) [data-aos=flip-up].aos-animate{-webkit-transform:perspective(2500px) rotateX(0);transform:perspective(2500px) rotateX(0)}html:not(.no-js) [data-aos=flip-down]{-webkit-transform:perspective(2500px) rotateX(100deg);transform:perspective(2500px) rotateX(100deg)}html:not(.no-js) [data-aos=flip-down].aos-animate{-webkit-transform:perspective(2500px) rotateX(0);transform:perspective(2500px) rotateX(0)}}
--------------------------------------------------------------------------------
/public/images/share.svg:
--------------------------------------------------------------------------------
1 |
186 |
--------------------------------------------------------------------------------