diff --git a/package.json b/package.json index 54330ab8..200d1669 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,6 @@ "devDependencies": { "algoliasearch": "^4.2.0", "vuepress": "^1.4.1", - "vuepress-theme-reco": "^1.4.5", "vuepress-plugin-autobar": "github:boboidream/vuepress-bar" }, "description": "易懂的算法教程", diff --git a/website/.vuepress/config.js b/website/.vuepress/config.js index 131a9a4a..fbf43a88 100644 --- a/website/.vuepress/config.js +++ b/website/.vuepress/config.js @@ -1,38 +1,56 @@ module.exports = { - title: "小浩算法", - plugins: [require('../../lib/autobar.js'), require('../../lib/Notification.js')], - description: '和小浩一起学算法', - // root : "./hell-algorithm", - theme: "reco", - themeConfig: { - logo: '/logo.png', - sidebar: "auto", - searchPlaceholder: "搜索:KMP", - nav: [ - {text: 'GitHub', link: 'https://github.com/geekxh/hello-algorithm', icon: 'reco-github'} - ], - head: [ - ['link', {rel: 'shortcut icon', href: '/favicon.ico'}] - ], - type: 'blog', - search: true, - searchMaxSuggestions: 10, - lastUpdated: '文章修订于', - author: '程序员小浩', - authorAvatar: '/code.png', - startYear: '2019', - valineConfig: { - visitor: false, - enable: true, - placeholder: "留下你的问题,或者你想要的资源...", - avatar: "wavatar", - requiredFields: ['nick'], - appId: 'sINkW5sfpPxoqDyBqbpvTN79-gzGzoHsz', - appKey: '5tkDVulRNyjuAbCUekxU6zHW', + title: "和小浩学编程", + plugins: [ + require('../../lib/autobar.js'), + require('../../lib/Notification.js')], + description: '编程是一件有趣的事情', + // root : "./hell-algorithm", + theme: "reco", + themeConfig: { + logo: '/logo.png', + sidebar: "auto", + searchPlaceholder: "搜索:KMP", + nav: [ + { + text: 'GitHub', + link: 'https://githubd.com/geekxh/hello-algorithm', + icon: 'reco-github' + }, + { + text: 'TimeLine', + link: '/timeline/', + icon: 'reco-date' + } + ], + // 博客配置 + blogConfig: { + tag: { + location: 3, // 在导航栏菜单中所占的位置,默认3 + text: 'Tag' // 默认文案 “标签” + } + }, + head: [ + ['link', {rel: 'shortcut icon', href: '/favicon.ico'}] + ], + type: 'blog', + search: true, + searchMaxSuggestions: 10, + lastUpdated: '文章修订于', + author: '程序员小浩', + authorAvatar: '/code.png', + startYear: '2019', + valineConfig: { + visitor: false, + enable: true, + placeholder: "留下你的问题,或者你想要的资源...", + avatar: "wavatar", + requiredFields: ['nick'], + appId: 'sINkW5sfpPxoqDyBqbpvTN79-gzGzoHsz', + appKey: '5tkDVulRNyjuAbCUekxU6zHW', + }, + noFoundPageByTencent: false }, - noFoundPageByTencent: false - }, - markdown: { - lineNumbers: true, - } + markdown: { + lineNumbers: true, + } } \ No newline at end of file diff --git a/website/.vuepress/theme/LICENSE b/website/.vuepress/theme/LICENSE new file mode 100644 index 00000000..84b7cce6 --- /dev/null +++ b/website/.vuepress/theme/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 reco_luan + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/website/.vuepress/theme/README.md b/website/.vuepress/theme/README.md new file mode 100644 index 00000000..2b6d41e4 --- /dev/null +++ b/website/.vuepress/theme/README.md @@ -0,0 +1,88 @@ +

Vue logo

+ +

+ + + + +

+ +## Introduce + +1. 这是一个vuepress主题,旨在添加博客所需的分类、标签墙、分页、评论等功能; +2. 主题追求极简,根据 vuepress 的默认主题修改而成,官方的主题配置仍然适用; +3. 效果:[午后南杂](https://www.recoluan.com) +4. 文档:[vuepress-theme-reco-doc](https://vuepress-theme-reco.recoluan.com) + +## Quick start + +**npx** + +``` +npx @vuepress-reco/theme-cli init my-blog +``` + +**npm** + +```bash +# init +npm install @vuepress-reco/theme-cli -g +theme-cli init my-blog + +# install +cd my-blog +npm install + +# run +npm run dev + +# build +npm run build +``` + +**yarn** + +```bash +# init +yarn global add @vuepress-reco/theme-cli +theme-cli init my-blog + +# install +cd my-blog +yarn install + +# run +yarn dev + +# build +yarn build +``` + +## Preview + +![size.png](https://i.loli.net/2020/01/13/nCbXp13lRG2TNeD.png) + +![style.png](https://i.loli.net/2020/01/13/ke1VirShQRLnEd7.png) + +![dark.png](https://i.loli.net/2020/01/13/Lj6XbwdmDFCYH9k.png) + +![home.png](https://i.loli.net/2020/01/13/nra3kbYSlxojmw4.png) + +## Contributors + +**衷心感谢为此项目贡献过宝贵代码的朋友们** + +|昵称|贡献记录| +|:-:|-| +|[kangxu](https://github.com/kangxukangxu)|[vuepress-theme-reco@0.x](https://github.com/recoluan/vuepress-theme-reco/commit/ec7426a88d50cf8d9f90a7ad9b731a10da7f438b)| +|[Ekko](https://github.com/danranVm)|[vuepress-theme-reco-demo@1.x](https://github.com/recoluan/vuepress-theme-reco-demo/commit/6d2bbe919e7f6564b8c8173558d197e38e024dc5)| + +**衷心感谢美女设计师** + +|昵称|贡献内容| +|:-:|-| +|[Zoey]()|主题图标调整定稿| +|冰冰|主题图标初稿| + +## License +[MIT](https://github.com/recoluan/vuepress-theme-reco/blob/master/LICENSE) diff --git a/website/.vuepress/theme/components/AlgoliaSearchBox.vue b/website/.vuepress/theme/components/AlgoliaSearchBox.vue new file mode 100644 index 00000000..5add0002 --- /dev/null +++ b/website/.vuepress/theme/components/AlgoliaSearchBox.vue @@ -0,0 +1,170 @@ + + + + + diff --git a/website/.vuepress/theme/components/Common.vue b/website/.vuepress/theme/components/Common.vue new file mode 100644 index 00000000..bfcd929d --- /dev/null +++ b/website/.vuepress/theme/components/Common.vue @@ -0,0 +1,268 @@ + + + + + diff --git a/website/.vuepress/theme/components/DropdownLink.vue b/website/.vuepress/theme/components/DropdownLink.vue new file mode 100644 index 00000000..058b3bf5 --- /dev/null +++ b/website/.vuepress/theme/components/DropdownLink.vue @@ -0,0 +1,183 @@ + + + + + diff --git a/website/.vuepress/theme/components/DropdownTransition.vue b/website/.vuepress/theme/components/DropdownTransition.vue new file mode 100644 index 00000000..8c711a15 --- /dev/null +++ b/website/.vuepress/theme/components/DropdownTransition.vue @@ -0,0 +1,33 @@ + + + + + diff --git a/website/.vuepress/theme/components/Footer.vue b/website/.vuepress/theme/components/Footer.vue new file mode 100644 index 00000000..74a98809 --- /dev/null +++ b/website/.vuepress/theme/components/Footer.vue @@ -0,0 +1,81 @@ + + + + + diff --git a/website/.vuepress/theme/components/FriendLink.vue b/website/.vuepress/theme/components/FriendLink.vue new file mode 100644 index 00000000..9d730e5e --- /dev/null +++ b/website/.vuepress/theme/components/FriendLink.vue @@ -0,0 +1,196 @@ + + + + + diff --git a/website/.vuepress/theme/components/Home.vue b/website/.vuepress/theme/components/Home.vue new file mode 100644 index 00000000..4e31d2ce --- /dev/null +++ b/website/.vuepress/theme/components/Home.vue @@ -0,0 +1,241 @@ + + + + + diff --git a/website/.vuepress/theme/components/HomeBlog.vue b/website/.vuepress/theme/components/HomeBlog.vue new file mode 100644 index 00000000..a4ec2dfa --- /dev/null +++ b/website/.vuepress/theme/components/HomeBlog.vue @@ -0,0 +1,350 @@ + + + + + diff --git a/website/.vuepress/theme/components/MobShare.vue b/website/.vuepress/theme/components/MobShare.vue new file mode 100644 index 00000000..afb81e4a --- /dev/null +++ b/website/.vuepress/theme/components/MobShare.vue @@ -0,0 +1,30 @@ + + + + diff --git a/website/.vuepress/theme/components/Mode/ModePicker.vue b/website/.vuepress/theme/components/Mode/ModePicker.vue new file mode 100644 index 00000000..60880d2a --- /dev/null +++ b/website/.vuepress/theme/components/Mode/ModePicker.vue @@ -0,0 +1,102 @@ + + + + + diff --git a/website/.vuepress/theme/components/Mode/applyMode.js b/website/.vuepress/theme/components/Mode/applyMode.js new file mode 100644 index 00000000..a4a0037e --- /dev/null +++ b/website/.vuepress/theme/components/Mode/applyMode.js @@ -0,0 +1,35 @@ +import modeOptions from './modeOptions' + +function render (mode) { + const rootElement = document.querySelector(':root') + const options = modeOptions[mode] + + for (const k in options) { + rootElement.style.setProperty(k, options[k]) + } +} + +/** + * Sets a color scheme for the website. + * If browser supports "prefers-color-scheme", 'auto' mode will respect the setting for light or dark mode + * otherwise it will set a dark theme during night time + */ +export default function applyMode (mode) { + if (mode !== 'auto') { + render(mode) + return + } + + const isDarkMode = window.matchMedia('(prefers-color-scheme: dark)').matches + const isLightMode = window.matchMedia('(prefers-color-scheme: light)').matches + + if (isDarkMode) render('dark') + if (isLightMode) render('light') + + if (!isDarkMode && !isLightMode) { + console.log('You specified no preference for a color scheme or your browser does not support it. I schedule dark mode during night time.') + const hour = new Date().getHours() + if (hour < 6 || hour >= 18) render('dark') + else render('light') + } +} diff --git a/website/.vuepress/theme/components/Mode/index.vue b/website/.vuepress/theme/components/Mode/index.vue new file mode 100755 index 00000000..5f11859e --- /dev/null +++ b/website/.vuepress/theme/components/Mode/index.vue @@ -0,0 +1,114 @@ + + + + + diff --git a/website/.vuepress/theme/components/Mode/modeOptions.js b/website/.vuepress/theme/components/Mode/modeOptions.js new file mode 100644 index 00000000..fe48e9ee --- /dev/null +++ b/website/.vuepress/theme/components/Mode/modeOptions.js @@ -0,0 +1,44 @@ +const modeOptions = { + light: { + '--default-color-10': 'rgba(255, 255, 255, 1)', + '--default-color-9': 'rgba(255, 255, 255, .9)', + '--default-color-8': 'rgba(255, 255, 255, .8)', + '--default-color-7': 'rgba(255, 255, 255, .7)', + '--default-color-6': 'rgba(255, 255, 255, .6)', + '--default-color-5': 'rgba(255, 255, 255, .5)', + '--default-color-4': 'rgba(255, 255, 255, .4)', + '--default-color-3': 'rgba(255, 255, 255, .3)', + '--default-color-2': 'rgba(255, 255, 255, .2)', + '--default-color-1': 'rgba(255, 255, 255, .1)', + '--background-color': '#fff', + '--box-shadow': '0 1px 6px 0 rgba(0, 0, 0, 0.2)', + '--box-shadow-hover': '0 2px 16px 0 rgba(0, 0, 0, 0.2)', + '--text-color': '#242424', + '--text-color-sub': '#7F7F7F', + '--border-color': '#eaecef', + '--code-color': 'rgba(27, 31, 35, 0.05)', + '--mask-color': '#888' + }, + dark: { + '--default-color-10': 'rgba(0, 0, 0, 1)', + '--default-color-9': 'rgba(0, 0, 0, .9)', + '--default-color-8': 'rgba(0, 0, 0, .8)', + '--default-color-7': 'rgba(0, 0, 0, .7)', + '--default-color-6': 'rgba(0, 0, 0, .6)', + '--default-color-5': 'rgba(0, 0, 0, .5)', + '--default-color-4': 'rgba(0, 0, 0, .4)', + '--default-color-3': 'rgba(0, 0, 0, .3)', + '--default-color-2': 'rgba(0, 0, 0, .2)', + '--default-color-1': 'rgba(0, 0, 0, .1)', + '--background-color': '#181818', + '--box-shadow': '0 1px 6px 0 rgba(0, 0, 0, .9)', + '--box-shadow-hover': '0 2px 26px 0 rgba(0, 0, 0, .9)', + '--text-color': 'rgba(255, 255, 255, .8)', + '--text-color-sub': '#8B8B8B', + '--border-color': 'rgba(0, 0, 0, .3)', + '--code-color': 'rgba(0, 0, 0, .3)', + '--mask-color': '#000' + } +} + +export default modeOptions diff --git a/website/.vuepress/theme/components/ModuleTransition.vue b/website/.vuepress/theme/components/ModuleTransition.vue new file mode 100644 index 00000000..5b114f54 --- /dev/null +++ b/website/.vuepress/theme/components/ModuleTransition.vue @@ -0,0 +1,45 @@ + + + + + diff --git a/website/.vuepress/theme/components/NavLink.vue b/website/.vuepress/theme/components/NavLink.vue new file mode 100644 index 00000000..40621a23 --- /dev/null +++ b/website/.vuepress/theme/components/NavLink.vue @@ -0,0 +1,52 @@ + + + diff --git a/website/.vuepress/theme/components/NavLinks.vue b/website/.vuepress/theme/components/NavLinks.vue new file mode 100644 index 00000000..00b52d53 --- /dev/null +++ b/website/.vuepress/theme/components/NavLinks.vue @@ -0,0 +1,188 @@ + + + + + diff --git a/website/.vuepress/theme/components/Navbar.vue b/website/.vuepress/theme/components/Navbar.vue new file mode 100644 index 00000000..ccc87b3c --- /dev/null +++ b/website/.vuepress/theme/components/Navbar.vue @@ -0,0 +1,131 @@ + + + + + diff --git a/website/.vuepress/theme/components/NoteAbstract.vue b/website/.vuepress/theme/components/NoteAbstract.vue new file mode 100644 index 00000000..a6d31b61 --- /dev/null +++ b/website/.vuepress/theme/components/NoteAbstract.vue @@ -0,0 +1,31 @@ + + + + + diff --git a/website/.vuepress/theme/components/NoteAbstractItem.vue b/website/.vuepress/theme/components/NoteAbstractItem.vue new file mode 100644 index 00000000..9e066cfa --- /dev/null +++ b/website/.vuepress/theme/components/NoteAbstractItem.vue @@ -0,0 +1,86 @@ + + + + + diff --git a/website/.vuepress/theme/components/Page.vue b/website/.vuepress/theme/components/Page.vue new file mode 100644 index 00000000..6bf13041 --- /dev/null +++ b/website/.vuepress/theme/components/Page.vue @@ -0,0 +1,282 @@ + + + + + diff --git a/website/.vuepress/theme/components/PageInfo.vue b/website/.vuepress/theme/components/PageInfo.vue new file mode 100644 index 00000000..9caa2b76 --- /dev/null +++ b/website/.vuepress/theme/components/PageInfo.vue @@ -0,0 +1,114 @@ + + + + + diff --git a/website/.vuepress/theme/components/Password.vue b/website/.vuepress/theme/components/Password.vue new file mode 100644 index 00000000..523f75a3 --- /dev/null +++ b/website/.vuepress/theme/components/Password.vue @@ -0,0 +1,327 @@ + + + + + diff --git a/website/.vuepress/theme/components/PersonalInfo.vue b/website/.vuepress/theme/components/PersonalInfo.vue new file mode 100644 index 00000000..036ea1ab --- /dev/null +++ b/website/.vuepress/theme/components/PersonalInfo.vue @@ -0,0 +1,75 @@ + + + + + diff --git a/website/.vuepress/theme/components/SearchBox.vue b/website/.vuepress/theme/components/SearchBox.vue new file mode 100644 index 00000000..365c308c --- /dev/null +++ b/website/.vuepress/theme/components/SearchBox.vue @@ -0,0 +1,238 @@ + + + + + diff --git a/website/.vuepress/theme/components/Sidebar.vue b/website/.vuepress/theme/components/Sidebar.vue new file mode 100644 index 00000000..57f34d7e --- /dev/null +++ b/website/.vuepress/theme/components/Sidebar.vue @@ -0,0 +1,65 @@ + + + + + diff --git a/website/.vuepress/theme/components/SidebarButton.vue b/website/.vuepress/theme/components/SidebarButton.vue new file mode 100644 index 00000000..b8fb4150 --- /dev/null +++ b/website/.vuepress/theme/components/SidebarButton.vue @@ -0,0 +1,27 @@ + + + diff --git a/website/.vuepress/theme/components/SidebarGroup.vue b/website/.vuepress/theme/components/SidebarGroup.vue new file mode 100644 index 00000000..5f726a97 --- /dev/null +++ b/website/.vuepress/theme/components/SidebarGroup.vue @@ -0,0 +1,129 @@ + + + + + diff --git a/website/.vuepress/theme/components/SidebarLink.vue b/website/.vuepress/theme/components/SidebarLink.vue new file mode 100644 index 00000000..7ad741a5 --- /dev/null +++ b/website/.vuepress/theme/components/SidebarLink.vue @@ -0,0 +1,115 @@ + + + diff --git a/website/.vuepress/theme/components/SidebarLinks.vue b/website/.vuepress/theme/components/SidebarLinks.vue new file mode 100644 index 00000000..9d45bfe3 --- /dev/null +++ b/website/.vuepress/theme/components/SidebarLinks.vue @@ -0,0 +1,141 @@ + + + diff --git a/website/.vuepress/theme/components/TagList.vue b/website/.vuepress/theme/components/TagList.vue new file mode 100644 index 00000000..55e3e956 --- /dev/null +++ b/website/.vuepress/theme/components/TagList.vue @@ -0,0 +1,58 @@ + + + + + diff --git a/website/.vuepress/theme/enhanceApp.js b/website/.vuepress/theme/enhanceApp.js new file mode 100644 index 00000000..e325e2bb --- /dev/null +++ b/website/.vuepress/theme/enhanceApp.js @@ -0,0 +1,9 @@ +import postMixin from '@theme/mixins/posts' +import localMixin from '@theme/mixins/locals' + +export default ({ + Vue +}) => { + Vue.mixin(postMixin) + Vue.mixin(localMixin) +} diff --git a/website/.vuepress/theme/global-components/Badge.vue b/website/.vuepress/theme/global-components/Badge.vue new file mode 100644 index 00000000..019ba4d6 --- /dev/null +++ b/website/.vuepress/theme/global-components/Badge.vue @@ -0,0 +1,45 @@ + + + diff --git a/website/.vuepress/theme/helpers/other.js b/website/.vuepress/theme/helpers/other.js new file mode 100644 index 00000000..be543189 --- /dev/null +++ b/website/.vuepress/theme/helpers/other.js @@ -0,0 +1,18 @@ +export function getOneColor () { + const tagColorArr = [ + '#e15b64', + '#f47e60', + '#f8b26a', + '#abbd81', + '#849b87', + '#e15b64', + '#f47e60', + '#f8b26a', + '#f26d6d', + '#67cc86', + '#fb9b5f', + '#3498db' + ] + const index = Math.floor(Math.random() * tagColorArr.length) + return tagColorArr[index] +} diff --git a/website/.vuepress/theme/helpers/postData.js b/website/.vuepress/theme/helpers/postData.js new file mode 100644 index 00000000..95748e29 --- /dev/null +++ b/website/.vuepress/theme/helpers/postData.js @@ -0,0 +1,41 @@ +import { compareDate } from '@theme/helpers/utils' + +// 过滤博客数据 +export function filterPosts (posts, isTimeline) { + posts = posts.filter((item, index) => { + const { title, frontmatter: { home, date, publish }} = item + // 过滤多个分类时产生的重复数据 + if (posts.indexOf(item) !== index) { + return false + } else { + const someConditions = home == true || title == undefined || publish === false + const boo = isTimeline === true + ? !(someConditions || date === undefined) + : !someConditions + return boo + } + }) + return posts +} + +// 排序博客数据 +export function sortPostsByStickyAndDate (posts) { + posts.sort((prev, next) => { + const prevSticky = prev.frontmatter.sticky + const nextSticky = next.frontmatter.sticky + if (prevSticky && nextSticky) { + return prevSticky == nextSticky ? compareDate(prev, next) : (prevSticky - nextSticky) + } else if (prevSticky && !nextSticky) { + return -1 + } else if (!prevSticky && nextSticky) { + return 1 + } + return compareDate(prev, next) + }) +} + +export function sortPostsByDate (posts) { + posts.sort((prev, next) => { + return compareDate(prev, next) + }) +} diff --git a/website/.vuepress/theme/helpers/utils.js b/website/.vuepress/theme/helpers/utils.js new file mode 100644 index 00000000..80c3efcb --- /dev/null +++ b/website/.vuepress/theme/helpers/utils.js @@ -0,0 +1,273 @@ +export const hashRE = /#.*$/ +export const extRE = /\.(md|html)$/ +export const endingSlashRE = /\/$/ +export const outboundRE = /^(https?:|mailto:|tel:)/ + +export function normalize (path) { + return decodeURI(path) + .replace(hashRE, '') + .replace(extRE, '') +} + +export function getHash (path) { + const match = path.match(hashRE) + if (match) { + return match[0] + } +} + +export function isExternal (path) { + return outboundRE.test(path) +} + +export function isMailto (path) { + return /^mailto:/.test(path) +} + +export function isTel (path) { + return /^tel:/.test(path) +} + +export function ensureExt (path) { + if (isExternal(path)) { + return path + } + const hashMatch = path.match(hashRE) + const hash = hashMatch ? hashMatch[0] : '' + const normalized = normalize(path) + + if (endingSlashRE.test(normalized)) { + return path + } + return normalized + '.html' + hash +} + +export function isActive (route, path) { + const routeHash = route.hash + const linkHash = getHash(path) + if (linkHash && routeHash !== linkHash) { + return false + } + const routePath = normalize(route.path) + const pagePath = normalize(path) + return routePath === pagePath +} + +export function resolvePage (pages, rawPath, base) { + if (base) { + rawPath = resolvePath(rawPath, base) + } + const path = normalize(rawPath) + for (let i = 0; i < pages.length; i++) { + if (normalize(pages[i].regularPath) === path) { + return Object.assign({}, pages[i], { + type: 'page', + path: ensureExt(pages[i].path) + }) + } + } + console.error(`[vuepress] No matching page found for sidebar item "${rawPath}"`) + return {} +} + +function resolvePath (relative, base, append) { + const firstChar = relative.charAt(0) + if (firstChar === '/') { + return relative + } + + if (firstChar === '?' || firstChar === '#') { + return base + relative + } + + const stack = base.split('/') + + // remove trailing segment if: + // - not appending + // - appending to trailing slash (last segment is empty) + if (!append || !stack[stack.length - 1]) { + stack.pop() + } + + // resolve relative path + const segments = relative.replace(/^\//, '').split('/') + for (let i = 0; i < segments.length; i++) { + const segment = segments[i] + if (segment === '..') { + stack.pop() + } else if (segment !== '.') { + stack.push(segment) + } + } + + // ensure leading slash + if (stack[0] !== '') { + stack.unshift('') + } + + return stack.join('/') +} + +/** + * @param { Page } page + * @param { string } regularPath + * @param { SiteData } site + * @param { string } localePath + * @returns { SidebarGroup } + */ +export function resolveSidebarItems (page, regularPath, site, localePath) { + const { pages, themeConfig } = site + + const localeConfig = localePath && themeConfig.locales + ? themeConfig.locales[localePath] || themeConfig + : themeConfig + + const pageSidebarConfig = page.frontmatter.sidebar || localeConfig.sidebar || themeConfig.sidebar + if (pageSidebarConfig === 'auto') { + return resolveHeaders(page) + } + + const sidebarConfig = localeConfig.sidebar || themeConfig.sidebar + if (!sidebarConfig) { + return [] + } else { + const { base, config } = resolveMatchingConfig(regularPath, sidebarConfig) + return config + ? config.map(item => resolveItem(item, pages, base)) + : [] + } +} + +/** + * @param { Page } page + * @returns { SidebarGroup } + */ +function resolveHeaders (page) { + const headers = groupHeaders(page.headers || []) + return [{ + type: 'group', + collapsable: false, + title: page.title, + path: null, + children: headers.map(h => ({ + type: 'auto', + title: h.title, + basePath: page.path, + path: page.path + '#' + h.slug, + children: h.children || [] + })) + }] +} + +export function groupHeaders (headers) { + // group h3s under h2 + headers = headers.map(h => Object.assign({}, h)) + let lastH2 + headers.forEach(h => { + if (h.level === 2) { + lastH2 = h + } else if (lastH2) { + (lastH2.children || (lastH2.children = [])).push(h) + } + }) + return headers.filter(h => h.level === 2) +} + +export function resolveNavLinkItem (linkItem) { + return Object.assign(linkItem, { + type: linkItem.items && linkItem.items.length ? 'links' : 'link' + }) +} + +/** + * @param { Route } route + * @param { Array | Array | [link: string]: SidebarConfig } config + * @returns { base: string, config: SidebarConfig } + */ +export function resolveMatchingConfig (regularPath, config) { + if (Array.isArray(config)) { + return { + base: '/', + config: config + } + } + for (const base in config) { + if (ensureEndingSlash(regularPath).indexOf(encodeURI(base)) === 0) { + return { + base, + config: config[base] + } + } + } + return {} +} + +export function formatDate (time, fmt = 'yyyy-MM-dd hh:mm:ss') { + time = time.replace(/-/g, '/') + const date = new Date(time) + if (/(y+)/.test(fmt)) { + fmt = fmt.replace(RegExp.$1, date.getFullYear() + '').substr(4 - RegExp.$1.length) + } + + const o = { + 'M+': date.getMonth() + 1, + 'd+': date.getDate(), + 'h+': date.getHours(), + 'm+': date.getMinutes(), + 's+': date.getSeconds() + } + + for (const key in o) { + if (RegExp(`(${key})`).test(fmt)) { + const str = o[key] + '' + fmt = fmt.replace(RegExp.$1, str.length === 2 ? str : '0' + str) + } + } + return fmt +} + +// 获取时间的数字类型 +export function getTimeNum (date) { + return new Date(date.frontmatter.date).getTime() +} + +// 比对时间 +export function compareDate (a, b) { + return getTimeNum(b) - getTimeNum(a) +} + +function ensureEndingSlash (path) { + return /(\.html|\/)$/.test(path) + ? path + : path + '/' +} + +function resolveItem (item, pages, base, groupDepth = 1) { + if (typeof item === 'string') { + return resolvePage(pages, item, base) + } else if (Array.isArray(item)) { + return Object.assign(resolvePage(pages, item[0], base), { + title: item[1] + }) + } else { + if (groupDepth > 3) { + console.error( + '[vuepress] detected a too deep nested sidebar group.' + ) + } + const children = item.children || [] + if (children.length === 0 && item.path) { + return Object.assign(resolvePage(pages, item.path, base), { + title: item.title + }) + } + return { + type: 'group', + path: item.path, + title: item.title, + sidebarDepth: item.sidebarDepth, + children: children.map(child => resolveItem(child, pages, base, groupDepth + 1)), + collapsable: item.collapsable !== false + } + } +} diff --git a/website/.vuepress/theme/images/home-bg.jpg b/website/.vuepress/theme/images/home-bg.jpg new file mode 100644 index 00000000..02d4a81b Binary files /dev/null and b/website/.vuepress/theme/images/home-bg.jpg differ diff --git a/website/.vuepress/theme/images/home-head.png b/website/.vuepress/theme/images/home-head.png new file mode 100644 index 00000000..72247268 Binary files /dev/null and b/website/.vuepress/theme/images/home-head.png differ diff --git a/website/.vuepress/theme/images/icon_vuepress_reco.png b/website/.vuepress/theme/images/icon_vuepress_reco.png new file mode 100644 index 00000000..ac012529 Binary files /dev/null and b/website/.vuepress/theme/images/icon_vuepress_reco.png differ diff --git a/website/.vuepress/theme/index.js b/website/.vuepress/theme/index.js new file mode 100644 index 00000000..6835f6d7 --- /dev/null +++ b/website/.vuepress/theme/index.js @@ -0,0 +1,97 @@ +const path = require('path') + +// Theme API. +module.exports = (options, ctx) => ({ + alias () { + const { themeConfig, siteConfig } = ctx + // resolve algolia + const isAlgoliaSearch = ( + themeConfig.algolia || + Object.keys(siteConfig.locales && themeConfig.locales || {}) + .some(base => themeConfig.locales[base].algolia) + ) + return { + '@AlgoliaSearchBox': isAlgoliaSearch + ? path.resolve(__dirname, 'components/AlgoliaSearchBox.vue') + : path.resolve(__dirname, 'noopModule.js'), + '@SearchBox': path.resolve(__dirname, 'components/SearchBox.vue') + } + }, + + plugins: [ + '@vuepress-reco/back-to-top', + '@vuepress-reco/loading-page', + '@vuepress-reco/pagation', + '@vuepress-reco/comments', + '@vuepress/active-header-links', + ['@vuepress/medium-zoom', { + selector: '.theme-reco-content :not(a) > img' + }], + '@vuepress/plugin-nprogress', + ['@vuepress/plugin-blog', { + permalink: '/:regular', + frontmatters: [ + { + id: 'tags', + keys: ['tags'], + path: '/tag/', + layout: 'Tags', + scopeLayout: 'Tag' + }, + { + id: 'categories', + keys: ['categories'], + path: '/categories/', + layout: 'Categories', + scopeLayout: 'Category' + }, + { + id: 'timeline', + keys: ['timeline'], + path: '/timeline/', + layout: 'TimeLines', + scopeLayout: 'TimeLine' + } + ] + }], + ['container', { + type: 'tip', + defaultTitle: { + '/': '', + '/zh/': '提示' + } + }], + ['container', { + type: 'warning', + defaultTitle: { + '/': '', + '/zh/': '注意' + } + }], + ['container', { + type: 'danger', + defaultTitle: { + '/': '', + '/zh/': '警告' + } + }], + ['container', { + type: 'right', + defaultTitle: '' + }], + ['container', { + type: 'theorem', + before: info => `

${info}

`, + after: '
' + }], + ['container', { + type: 'details', + before: info => `
${info ? `${info}` : ''}\n`, + after: () => '
\n', + defaultTitle: { + '/': 'See More', + '/zh/': '更多' + } + }] + ] +}) diff --git a/website/.vuepress/theme/layouts/404.vue b/website/.vuepress/theme/layouts/404.vue new file mode 100644 index 00000000..3b3a22fc --- /dev/null +++ b/website/.vuepress/theme/layouts/404.vue @@ -0,0 +1,69 @@ + + + + + + + + diff --git a/website/.vuepress/theme/layouts/Category.vue b/website/.vuepress/theme/layouts/Category.vue new file mode 100644 index 00000000..71fb8153 --- /dev/null +++ b/website/.vuepress/theme/layouts/Category.vue @@ -0,0 +1,169 @@ + + + + + + + + diff --git a/website/.vuepress/theme/layouts/Layout.vue b/website/.vuepress/theme/layouts/Layout.vue new file mode 100644 index 00000000..8123cbf8 --- /dev/null +++ b/website/.vuepress/theme/layouts/Layout.vue @@ -0,0 +1,41 @@ + + + + + + diff --git a/website/.vuepress/theme/layouts/Tag.vue b/website/.vuepress/theme/layouts/Tag.vue new file mode 100644 index 00000000..7f761c1d --- /dev/null +++ b/website/.vuepress/theme/layouts/Tag.vue @@ -0,0 +1,111 @@ + + + + + + + + diff --git a/website/.vuepress/theme/layouts/Tags.vue b/website/.vuepress/theme/layouts/Tags.vue new file mode 100644 index 00000000..aecf550c --- /dev/null +++ b/website/.vuepress/theme/layouts/Tags.vue @@ -0,0 +1,100 @@ + + + + + + + + diff --git a/website/.vuepress/theme/layouts/TimeLines.vue b/website/.vuepress/theme/layouts/TimeLines.vue new file mode 100644 index 00000000..30dd5f2a --- /dev/null +++ b/website/.vuepress/theme/layouts/TimeLines.vue @@ -0,0 +1,153 @@ + + + + + + + diff --git a/website/.vuepress/theme/lib/vuepress-theme-reco.js b/website/.vuepress/theme/lib/vuepress-theme-reco.js new file mode 100644 index 00000000..ee7a9c3c --- /dev/null +++ b/website/.vuepress/theme/lib/vuepress-theme-reco.js @@ -0,0 +1,7 @@ +'use strict' + +module.exports = vuepressThemeReco + +function vuepressThemeReco () { + // TODO +} diff --git a/website/.vuepress/theme/locals/en.js b/website/.vuepress/theme/locals/en.js new file mode 100644 index 00000000..1d917f24 --- /dev/null +++ b/website/.vuepress/theme/locals/en.js @@ -0,0 +1,8 @@ +export default { + homeBlog: { + article: 'Article', + tag: 'Tag', + category: 'Category', + friendLink: 'Friend Link' + } +} diff --git a/website/.vuepress/theme/locals/index.js b/website/.vuepress/theme/locals/index.js new file mode 100644 index 00000000..05f22191 --- /dev/null +++ b/website/.vuepress/theme/locals/index.js @@ -0,0 +1,7 @@ +import zhHans from './zh-hans.js' +import zhHant from './zh-hant.js' +import en from './en.js' +import ja from './ja.js' +import ko from './ko.js' + +export { zhHans, zhHant, en, ja, ko } diff --git a/website/.vuepress/theme/locals/ja.js b/website/.vuepress/theme/locals/ja.js new file mode 100644 index 00000000..c5b81f8f --- /dev/null +++ b/website/.vuepress/theme/locals/ja.js @@ -0,0 +1,8 @@ +export default { + homeBlog: { + article: '文章', + tag: 'ラベル', + category: '分類', + friendLink: '友情リンク' + } +} diff --git a/website/.vuepress/theme/locals/ko.js b/website/.vuepress/theme/locals/ko.js new file mode 100644 index 00000000..7b53fe35 --- /dev/null +++ b/website/.vuepress/theme/locals/ko.js @@ -0,0 +1,8 @@ +export default { + homeBlog: { + article: '글', + tag: '태그', + category: '분류', + friendLink: '링크 참조' + } +} diff --git a/website/.vuepress/theme/locals/zh-hans.js b/website/.vuepress/theme/locals/zh-hans.js new file mode 100644 index 00000000..adf34dba --- /dev/null +++ b/website/.vuepress/theme/locals/zh-hans.js @@ -0,0 +1,8 @@ +export default { + homeBlog: { + article: '文章', + tag: '标签', + category: '分类', + friendLink: '友情链接' + } +} diff --git a/website/.vuepress/theme/locals/zh-hant.js b/website/.vuepress/theme/locals/zh-hant.js new file mode 100644 index 00000000..e84913f2 --- /dev/null +++ b/website/.vuepress/theme/locals/zh-hant.js @@ -0,0 +1,8 @@ +export default { + homeBlog: { + article: '文章', + tag: '標簽', + category: '分類', + friendLink: '友情鏈接' + } +} diff --git a/website/.vuepress/theme/mixins/index.js b/website/.vuepress/theme/mixins/index.js new file mode 100644 index 00000000..5afa78a9 --- /dev/null +++ b/website/.vuepress/theme/mixins/index.js @@ -0,0 +1,26 @@ +export default { + methods: { + _tagColor () { + const tagColorArr = ['#e15b64', '#f47e60', '#f8b26a', '#abbd81', '#849b87', '#e15b64', '#f47e60', '#f8b26a', '#f26d6d', '#67cc86', '#fb9b5f', '#3498db'] + const index = Math.floor(Math.random() * tagColorArr.length) + return tagColorArr[index] + }, + // 获取当前页码 + _getStoragePage () { + const path = window.location.pathname + const currentPage = JSON.parse(sessionStorage.getItem('currentPage')) + + if (currentPage === null || path !== currentPage.path) { + sessionStorage.setItem('currentPage', { page: 1, path: '' }) + return 1 + } + + return parseInt(currentPage.page) + }, + // 设置当前页码 + _setStoragePage (page) { + const path = window.location.pathname + sessionStorage.setItem('currentPage', JSON.stringify({ page, path })) + } + } +} diff --git a/website/.vuepress/theme/mixins/locals.js b/website/.vuepress/theme/mixins/locals.js new file mode 100644 index 00000000..58abc458 --- /dev/null +++ b/website/.vuepress/theme/mixins/locals.js @@ -0,0 +1,25 @@ +import { zhHans, zhHant, en, ja, ko } from '../locals/index' + +export default { + computed: { + $recoLocals () { + const recoLocals = this.$themeLocaleConfig.recoLocals + if (recoLocals) { + return recoLocals + } + if (/^zh\-(CN|SG)$/.test(this.$lang)) { + return zhHans + } + if (/^zh\-(HK|MO|TW)$/.test(this.$lang)) { + return zhHant + } + if (/^ja\-JP$/.test(this.$lang)) { + return ja + } + if (/^ko\-KR$/.test(this.$lang)) { + return ko + } + return en + } + } +} diff --git a/website/.vuepress/theme/mixins/moduleTransiton.js b/website/.vuepress/theme/mixins/moduleTransiton.js new file mode 100644 index 00000000..42cf101a --- /dev/null +++ b/website/.vuepress/theme/mixins/moduleTransiton.js @@ -0,0 +1,13 @@ +export default { + data () { + return { + recoShowModule: false + } + }, + mounted () { + this.recoShowModule = true + }, + destroyed () { + this.recoShowModule = false + } +} diff --git a/website/.vuepress/theme/mixins/pagination.js b/website/.vuepress/theme/mixins/pagination.js new file mode 100644 index 00000000..dbefecc7 --- /dev/null +++ b/website/.vuepress/theme/mixins/pagination.js @@ -0,0 +1,21 @@ +export default { + methods: { + // 获取当前页码 + _getStoragePage () { + const path = window.location.pathname + const currentPage = JSON.parse(sessionStorage.getItem('currentPage')) + + if (currentPage === null || path !== currentPage.path) { + sessionStorage.setItem('currentPage', { page: 1, path: '' }) + return 1 + } + + return parseInt(currentPage.page) + }, + // 设置当前页码 + _setStoragePage (page) { + const path = window.location.pathname + sessionStorage.setItem('currentPage', JSON.stringify({ page, path })) + } + } +} diff --git a/website/.vuepress/theme/mixins/posts.js b/website/.vuepress/theme/mixins/posts.js new file mode 100644 index 00000000..4c71405b --- /dev/null +++ b/website/.vuepress/theme/mixins/posts.js @@ -0,0 +1,60 @@ +import { filterPosts, sortPostsByStickyAndDate, sortPostsByDate } from '../helpers/postData' + +export default { + computed: { + $recoPosts () { + const { + $categories: { list: articles } + } = this + + let posts = articles.reduce((allData, currentData) => { + return [...allData, ...currentData.pages] + }, []) + + posts = filterPosts(posts, false) + sortPostsByStickyAndDate(posts) + + return posts + }, + $recoPostsForTimeline () { + let pages = this.$recoPosts + const formatPages = {} + const formatPagesArr = [] + pages = filterPosts(pages, true) + this.pages = pages.length == 0 ? [] : pages + for (let i = 0, length = pages.length; i < length; i++) { + const page = pages[i] + const pageDateYear = dateFormat(page.frontmatter.date, 'year') + if (formatPages[pageDateYear]) formatPages[pageDateYear].push(page) + else { + formatPages[pageDateYear] = [page] + } + } + + for (const key in formatPages) { + const data = formatPages[key] + sortPostsByDate(data) + formatPagesArr.unshift({ + year: key, + data + }) + } + + return formatPagesArr + } + } +} + +function renderTime (date) { + var dateee = new Date(date).toJSON() + return new Date(+new Date(dateee) + 8 * 3600 * 1000).toISOString().replace(/T/g, ' ').replace(/\.[\d]{3}Z/, '').replace(/-/g, '/') +} +function dateFormat (date, type) { + date = renderTime(date) + const dateObj = new Date(date) + const year = dateObj.getFullYear() + const mon = dateObj.getMonth() + 1 + const day = dateObj.getDate() + if (type == 'year') return year + else return `${mon}-${day}` +} diff --git a/website/.vuepress/theme/noopModule.js b/website/.vuepress/theme/noopModule.js new file mode 100644 index 00000000..b1c6ea43 --- /dev/null +++ b/website/.vuepress/theme/noopModule.js @@ -0,0 +1 @@ +export default {} diff --git a/website/.vuepress/theme/package.json b/website/.vuepress/theme/package.json new file mode 100644 index 00000000..650d415e --- /dev/null +++ b/website/.vuepress/theme/package.json @@ -0,0 +1,65 @@ +{ + "_args": [ + [ + "vuepress-theme-reco@1.4.5", + "/Users/haolin3/Project/hello-algorithm" + ] + ], + "_development": true, + "_from": "vuepress-theme-reco@1.4.5", + "_id": "vuepress-theme-reco@1.4.5", + "_inBundle": false, + "_integrity": "sha512-6PUIzDIzfs8ZCdnUiPdYuCc1IHpRDuNXvD0RuBCbw8N6LsBsPSJy7aiffcDebjDyOpFFkEzTBDNH1EtVGkbExg==", + "_location": "/vuepress-theme-reco", + "_phantomChildren": {}, + "_requested": { + "type": "version", + "registry": true, + "raw": "vuepress-theme-reco@1.4.5", + "name": "vuepress-theme-reco", + "escapedName": "vuepress-theme-reco", + "rawSpec": "1.4.5", + "saveSpec": null, + "fetchSpec": "1.4.5" + }, + "_requiredBy": [ + "#DEV:/" + ], + "_resolved": "https://registry.npmjs.org/vuepress-theme-reco/-/vuepress-theme-reco-1.4.5.tgz", + "_spec": "1.4.5", + "_where": "/Users/haolin3/Project/hello-algorithm", + "author": { + "name": "reco_luan" + }, + "bugs": { + "url": "https://github.com/vuepress-reco/vuepress-theme-reco/issues" + }, + "dependencies": { + "@vuepress-reco/vuepress-plugin-back-to-top": "^1.4.0", + "@vuepress-reco/vuepress-plugin-comments": "^1.4.3", + "@vuepress-reco/vuepress-plugin-loading-page": "^1.4.0", + "@vuepress-reco/vuepress-plugin-pagation": "^1.4.0", + "@vuepress/plugin-blog": "1.9.2", + "@vuepress/plugin-medium-zoom": "1.4.1", + "docsearch.js": "2.6.3", + "md5": "2.2.1", + "valine": "1.4.4", + "vue-click-outside": "1.1.0" + }, + "description": "A simple and beautiful vuepress Blog & Doc theme.", + "gitHead": "44f9d0eb140fed40ba3cce815213c978a06faee0", + "homepage": "https://vuepress-theme-reco.recoluan.com/", + "keywords": [ + "vuepress", + "vue", + "theme" + ], + "license": "MIT", + "main": "index.js", + "name": "vuepress-theme-reco", + "repository": { + "type": "git", + "url": "git+https://github.com/vuepress-reco/vuepress-theme-reco.git" + }, + "version": "1.4.5" +} diff --git a/website/.vuepress/theme/styles/arrow.styl b/website/.vuepress/theme/styles/arrow.styl new file mode 100644 index 00000000..d116e1cc --- /dev/null +++ b/website/.vuepress/theme/styles/arrow.styl @@ -0,0 +1,22 @@ +@require './config' + +.arrow + display inline-block + width 0 + height 0 + &.up + border-left 4px solid transparent + border-right 4px solid transparent + border-bottom 6px solid var(--text-color-sub) + &.down + border-left 4px solid transparent + border-right 4px solid transparent + border-top 6px solid var(--text-color-sub) + &.right + border-top 4px solid transparent + border-bottom 4px solid transparent + border-left 6px solid var(--text-color-sub) + &.left + border-top 4px solid transparent + border-bottom 4px solid transparent + border-right 6px solid var(--text-color-sub) diff --git a/website/.vuepress/theme/styles/code.styl b/website/.vuepress/theme/styles/code.styl new file mode 100644 index 00000000..0cfa3c1d --- /dev/null +++ b/website/.vuepress/theme/styles/code.styl @@ -0,0 +1,135 @@ +.content__default + code + color lighten($textColor, 20%) + padding 0.25rem 0.5rem + margin 0 + font-size 0.85em + background-color var(--code-color) + border-radius 3px + .token + &.deleted + color #EC5975 + &.inserted + color $accentColor + +.content__default + pre, pre[class*="language-"] + line-height 1.4 + padding 1.25rem 1.5rem + margin 0.85rem 0 + background-color $codeBgColor + border-radius 6px + overflow auto + code + color #fff + padding 0 + background-color transparent + border-radius 0 + +div[class*="language-"] + position relative + background-color $codeBgColor + border-radius 6px + .highlight-lines + user-select none + padding-top 1.3rem + position absolute + top 0 + left 0 + width 100% + line-height 1.4 + .highlighted + background-color rgba(0, 0, 0, 66%) + pre, pre[class*="language-"] + background transparent + position relative + z-index 1 + &::before + position absolute + z-index 3 + top 0.8em + right 1em + font-size 0.75rem + color rgba(255, 255, 255, 0.4) + &:not(.line-numbers-mode) + .line-numbers-wrapper + display none + &.line-numbers-mode + .highlight-lines .highlighted + position relative + &:before + content ' ' + position absolute + z-index 3 + left 0 + top 0 + display block + width $lineNumbersWrapperWidth + height 100% + background-color rgba(0, 0, 0, 66%) + pre + padding-left $lineNumbersWrapperWidth + 1 rem + vertical-align middle + .line-numbers-wrapper + position absolute + top 0 + width $lineNumbersWrapperWidth + text-align center + color rgba(255, 255, 255, 0.3) + padding 1.25rem 0 + line-height 1.4 + br + user-select none + .line-number + position relative + z-index 4 + user-select none + font-size 0.85em + &::after + content '' + position absolute + z-index 2 + top 0 + left 0 + width $lineNumbersWrapperWidth + height 100% + border-radius 6px 0 0 6px + border-right 1px solid rgba(0, 0, 0, 66%) + background-color $codeBgColor + + +for lang in $codeLang + div{'[class~="language-' + lang + '"]'} + &:before + content ('' + lang) + +div[class~="language-javascript"] + &:before + content "js" + +div[class~="language-typescript"] + &:before + content "ts" + +div[class~="language-markup"] + &:before + content "html" + +div[class~="language-markdown"] + &:before + content "md" + +div[class~="language-json"]:before + content "json" + +div[class~="language-ruby"]:before + content "rb" + +div[class~="language-python"]:before + content "py" + +div[class~="language-bash"]:before + content "sh" + +div[class~="language-php"]:before + content "php" diff --git a/website/.vuepress/theme/styles/custom-blocks.styl b/website/.vuepress/theme/styles/custom-blocks.styl new file mode 100644 index 00000000..54c564ec --- /dev/null +++ b/website/.vuepress/theme/styles/custom-blocks.styl @@ -0,0 +1,51 @@ +.custom-block + .custom-block-title + font-weight 600 + margin-bottom -0.4rem + &.tip, &.warning, &.danger + padding .1rem 1.5rem + border-left-width .5rem + border-left-style solid + margin 1rem 0 + &.tip + background-color var(--code-color) + border-color #67cc86 + .custom-block-title + color #67cc86 + &.warning + background-color var(--code-color) + border-color #fb9b5f + .custom-block-title + color #fb9b5f + &.danger + background-color var(--code-color) + border-color #f26d6d + .custom-block-title + color #f26d6d + &.right + color transparentify($textColor, 0.4) + font-size 0.9rem + text-align right + &.theorem + margin 1rem 0 + padding .1rem 1.5rem + border-radius 0.4rem + background-color var(--code-color) + .title + font-weight bold + &.details + display block + position relative + border-radius 2px + margin 1em 0 + padding 1rem + background-color var(--code-color) + h4 + margin-top 0 + figure, p + &:last-child + margin-bottom 0 + padding-bottom 0 + summary + outline none + cursor pointer diff --git a/website/.vuepress/theme/styles/iconfont.css b/website/.vuepress/theme/styles/iconfont.css new file mode 100644 index 00000000..63028ad1 --- /dev/null +++ b/website/.vuepress/theme/styles/iconfont.css @@ -0,0 +1,174 @@ +@font-face { + font-family:"iconfont"; + src: url('http://at.alicdn.com/t/font_1030519_ookn0nnv0z8.eot?t=1574737898757'); + /* IE9 */ + src: url('http://at.alicdn.com/t/font_1030519_ookn0nnv0z8.eot?t=1574737898757#iefix') format('embedded-opentype'), + /* IE6-IE8 */ + url('data:application/x-font-woff2;charset=utf-8;base64,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') format('woff2'), url('http://at.alicdn.com/t/font_1030519_ookn0nnv0z8.woff?t=1574737898757') format('woff'), url('http://at.alicdn.com/t/font_1030519_ookn0nnv0z8.ttf?t=1574737898757') format('truetype'), + /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */ + url('http://at.alicdn.com/t/font_1030519_ookn0nnv0z8.svg?t=1574737898757#iconfont') format('svg'); + /* iOS 4.1- */ +} +.iconfont { + font-family:"iconfont" !important; + font-size: 16px; + font-style: normal; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} +.reco-douban:before { + content:"\e603"; +} +.reco-wechat:before { + content:"\e720"; +} +.reco-color:before { + content:"\eae9"; +} +.reco-blog:before { + content:"\e61d"; +} +.reco-sf:before { + content:"\e610"; +} +.reco-message:before { + content:"\e634"; +} +.reco-eye:before { + content:"\e669"; +} +.reco-search:before { + content:"\e611"; +} +.reco-category:before { + content:"\e61e"; +} +.reco-npm:before { + content:"\e88d"; +} +.reco-menu:before { + content:"\e67c"; +} +.reco-suggestion:before { + content:"\e608"; +} +.reco-coding:before { + content:"\e601"; +} +.reco-github:before { + content:"\e628"; +} +.reco-mail:before { + content:"\e624"; +} +.reco-other:before { + content:"\e60e"; +} +.reco-home:before { + content:"\e65b"; +} +.reco-document:before { + content:"\e67a"; +} +.reco-huawei:before { + content:"\e6b9"; +} +.reco-up:before { + content:"\e68b"; +} +.reco-weibo:before { + content:"\e612"; +} +.reco-lock:before { + content:"\e60f"; +} +.reco-fullscreen:before { + content:"\e602"; +} +.reco-tag:before { + content:"\e633"; +} +.reco-date:before { + content:"\e63b"; +} +.reco-jianshu:before { + content:"\e60c"; +} +.reco-friend:before { + content:"\e62f"; +} +.reco-bokeyuan:before { + content:"\e626"; +} +.reco-beian:before { + content:"\e667"; +} +.reco-copyright:before { + content:"\ef87"; +} +.reco-rss:before { + content:"\f09d"; +} +.reco-bilibili:before { + content:"\e630"; +} +.reco-account:before { + content:"\e607"; +} +.reco-qq:before { + content:"\e67b"; +} +.reco-theme:before { + content:"\e7e8"; +} +.reco-three:before { + content:"\e644"; +} +.reco-gitlab:before { + content:"\e63c"; +} +.reco-api:before { + content:"\e662"; +} +.reco-mayun:before { + content:"\e6d0"; +} +.reco-zhihu:before { + content:"\e605"; +} +.reco-facebook:before { + content:"\e606"; +} +.reco-taobao:before { + content:"\e6a5"; +} +.reco-tongzhi:before { + content:"\e764"; +} +.reco-douyin:before { + content:"\e654"; +} +.reco-v2ex:before { + content:"\e62a"; +} +.reco-sticky:before { + content:"\e62b"; +} +.reco-toutiao:before { + content:"\e6b7"; +} +.reco-linkedin:before { + content:"\e668"; +} +.reco-faq:before { + content:"\e643"; +} +.reco-twitter:before { + content:"\e60b"; +} +.reco-csdn:before { + content:"\e609"; +} +.reco-juejin:before { + content:"\e613"; +} diff --git a/website/.vuepress/theme/styles/mobile.styl b/website/.vuepress/theme/styles/mobile.styl new file mode 100644 index 00000000..cb44a7d7 --- /dev/null +++ b/website/.vuepress/theme/styles/mobile.styl @@ -0,0 +1,39 @@ +// @require './config' + +$mobileSidebarWidth = $sidebarWidth * 0.82 + +// narrow desktop / iPad +@media (max-width: $MQNarrow) + .sidebar + font-size 15px + width $mobileSidebarWidth + .page, .password-wrapper-in + margin-left $mobileSidebarWidth + +// wide mobile +@media (max-width: $MQMobile) + .sidebar + top 0 + padding-top $navbarHeight + transform translateX(-100%) + transition transform .2s ease + .page, .password-wrapper-in + margin-left 0 + .theme-container + &.sidebar-open + .sidebar + transform translateX(0) + &.no-navbar + .sidebar + padding-top: 0 + .password-shadow + padding-left 0 + +// narrow mobile +@media (max-width: $MQMobileNarrow) + h1 + font-size 1.9rem + .content__default + div[class*="language-"] + margin 0.85rem -1.5rem + border-radius 0 diff --git a/website/.vuepress/theme/styles/mode.styl b/website/.vuepress/theme/styles/mode.styl new file mode 100644 index 00000000..c74ac858 --- /dev/null +++ b/website/.vuepress/theme/styles/mode.styl @@ -0,0 +1,38 @@ +:root + --default-color-10 $lightColor10 + --default-color-9 $lightColor9 + --default-color-8 $lightColor8 + --default-color-7 $lightColor7 + --default-color-6 $lightColor6 + --default-color-5 $lightColor5 + --default-color-4 $lightColor4 + --default-color-3 $lightColor3 + --default-color-2 $lightColor2 + --default-color-1 $lightColor1 + --background-color $backgroundColor + --box-shadow $boxShadow + --box-shadow-hover $boxShadowHover + --text-color $textColor + --text-color-sub $textColorSub + --border-color $borderColor + --code-color $codeColor + --mask-color $maskColor + @media (prefers-color-scheme: dark) + --default-color-10 $darkColor10 + --default-color-9 $darkColor9 + --default-color-8 $darkColor8 + --default-color-7 $darkColor7 + --default-color-6 $darkColor6 + --default-color-5 $darkColor5 + --default-color-4 $darkColor4 + --default-color-3 $darkColor3 + --default-color-2 $darkColor2 + --default-color-1 $darkColor1 + --background-color $backgroundColorDark + --box-shadow $boxShadowDark + --box-shadow-hover $boxShadowHoverDark + --text-color $textColorDark + --text-color-sub $textColorSubDark + --border-color $borderColorDark + --code-color $codeColorDark + --mask-color $maskColorDark diff --git a/website/.vuepress/theme/styles/palette.styl b/website/.vuepress/theme/styles/palette.styl new file mode 100644 index 00000000..a0dfaa83 --- /dev/null +++ b/website/.vuepress/theme/styles/palette.styl @@ -0,0 +1,47 @@ +$darkColor10 = rgba(0, 0, 0, 1) +$darkColor9 = rgba(0, 0, 0, .9) +$darkColor8 = rgba(0, 0, 0, .8) +$darkColor7 = rgba(0, 0, 0, .7) +$darkColor6 = rgba(0, 0, 0, .6) +$darkColor5 = rgba(0, 0, 0, .5) +$darkColor4 = rgba(0, 0, 0, .4) +$darkColor3 = rgba(0, 0, 0, .3) +$darkColor2 = rgba(0, 0, 0, .2) +$darkColor1 = rgba(0, 0, 0, .1) + +$lightColor10 = rgba(255, 255, 255, 1) +$lightColor9 = rgba(255, 255, 255, .9) +$lightColor8 = rgba(255, 255, 255, .8) +$lightColor7 = rgba(255, 255, 255, .7) +$lightColor6 = rgba(255, 255, 255, .6) +$lightColor5 = rgba(255, 255, 255, .5) +$lightColor4 = rgba(255, 255, 255, .4) +$lightColor3 = rgba(255, 255, 255, .3) +$lightColor2 = rgba(255, 255, 255, .2) +$lightColor1 = rgba(255, 255, 255, .1) + +$textShadow = 0 2px 4px $darkColor1; +$borderRadius = .25rem +$lineNumbersWrapperWidth = 2.5rem + +$backgroundColor ?= #fff +$backgroundColorDark ?= #181818 + +$boxShadow = 0 1px 6px 0 $darkColor2 +$boxShadowHover = 0 2px 16px 0 $darkColor2 +$boxShadowDark = 0 1px 6px 0 $darkColor6 +$boxShadowHoverDark = 0 2px 16px 0 $darkColor6 + +$textColor ?= #242424 +$textColorDark ?= $lightColor8 +$textColorSub = #7F7F7F +$textColorSubDark = #8B8B8B + +$borderColor ?= #eaecef +$borderColorDark ?= $darkColor3 + +$codeColor ?= rgba(27, 31, 35, 0.05) +$codeColorDark ?= $darkColor3 + +$maskColor ?= #888 +$maskColorDark ?= #000 diff --git a/website/.vuepress/theme/styles/theme.styl b/website/.vuepress/theme/styles/theme.styl new file mode 100644 index 00000000..535eb7e3 --- /dev/null +++ b/website/.vuepress/theme/styles/theme.styl @@ -0,0 +1,226 @@ +@require './mode' +@require './code' +@require './custom-blocks' +@require './arrow' +@require './wrapper' +@require './toc' +@require './iconfont.css' + +html, body + padding 0 + margin 0 +body + font-family Ubuntu, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif + -webkit-font-smoothing antialiased + -moz-osx-font-smoothing grayscale + font-size 15px + color var(--text-color) + background-color var(--background-color) + +.page, .password-wrapper-in + overflow-x: hidden + margin-left $sidebarWidth + +.navbar + position fixed + z-index 20 + top 0 + left 0 + right 0 + height $navbarHeight + box-sizing border-box + +.sidebar-mask + position fixed + z-index 9 + top 0 + left 0 + width 100vw + height 100vh + display none + background-color: rgba(0,0,0,.65); + +.sidebar + font-size 16px + background-color var(--background-color) + width $sidebarWidth + position fixed + z-index 10 + margin 0 + top $navbarHeight + left 0 + bottom 0 + box-sizing border-box + border-right 1px solid var(--border-color) + overflow-y auto + +.content__default:not(.custom) + @extend $wrapper + // > *:first-child + // margin-top 1.6rem + a:hover + text-decoration underline + p.demo + padding 1rem 1.5rem + border 1px solid #ddd + border-radius 4px + img + max-width 100% + +.content__default.custom + padding 0 + margin 0 + img + max-width 100% + +a + font-weight 500 + color $accentColor + text-decoration none + +p a code + font-weight 400 + color $accentColor + +kbd + background #eee + border solid 0.15rem #ddd + border-bottom solid 0.25rem #ddd + border-radius 0.15rem + padding 0 0.15em + +blockquote + font-size .9rem + color #999 + border-left .25rem solid #999 + background-color var(--code-color) + margin 0.5rem 0 + padding .25rem 0 .25rem 1rem + & > p + margin 0 + +ul, ol + padding-left 1.2em + +strong + font-weight 600 + +h1, h2, h3, h4, h5, h6 + font-weight 500 + line-height 1.25 + .content__default:not(.custom) > & + margin-top (0.5rem - $navbarHeight) + padding-top ($navbarHeight + 1rem) + margin-bottom 0 + &:first-child + margin-top -3.5rem + margin-bottom 1rem + + p, + pre, + .custom-block + margin-top 2rem + &:hover .header-anchor + opacity: 1 + +h1 + font-size 1.6rem + +h2 + font-size 1.4rem + padding-bottom .3rem + border-bottom 1px solid var(--border-color) + +h3 + font-size 1.2rem + +a.header-anchor + font-size 0.85em + float left + margin-left -0.87em + padding-right 0.23em + margin-top 0.125em + opacity 0 + &:hover + text-decoration none + +code, kbd, .line-number + font-family source-code-pro, Menlo, Monaco, Consolas, "Courier New", monospace + +p, ul, ol + line-height 1.7 + +hr + border 0 + border-top 1px solid var(--border-color) + +table + border-collapse collapse + margin 1rem 0 + display: block + overflow-x: auto + +tr + border-top 1px solid var(--border-color) + &:nth-child(2n) + background-color var(--code-color) + +th, td + border 1px solid var(--border-color) + padding .6em 1em + +.theme-container + &.sidebar-open + .sidebar-mask + display: block + &.no-navbar + .content__default:not(.custom) > h1, h2, h3, h4, h5, h6 + margin-top 1.5rem + padding-top 0 + .sidebar + top 0 + +@media (min-width: ($MQMobile + 1px)) + .theme-container.no-sidebar + .sidebar + display none + .page, .password-wrapper-in + margin-left 0 + +@require 'mobile.styl' + +.iconfont + font-size: 0.9rem; + color: var(--text-color-sub); + +/************** 滚动条 **************/ +::-webkit-scrollbar + width: 5px; + height: 5px; + +::-webkit-scrollbar-track-piece + // background-color: rgba(0, 0, 0, 0.2); + +::-webkit-scrollbar-thumb:vertical + height: 5px; + background-color: $accentColor; + +::-webkit-scrollbar-thumb:horizontal + width: 5px; + background-color: $accentColor; + +/************** 流程图的滚动条 **************/ +.vuepress-flowchart + overflow: auto + +/************** SW-Update Popup **************/ + +.sw-update-popup + border-radius: $borderRadius!important; + box-shadow: var(--box-shadow)!important; + color: var(--text-color)!important; + background: var(--background-color)!important; + border: none!important; + > button + background: $accentColor; + border-radius: $borderRadius; + color: #fff; + -webkit-tap-highlight-color:rgba(0, 0, 0, 0) + border: none; diff --git a/website/.vuepress/theme/styles/toc.styl b/website/.vuepress/theme/styles/toc.styl new file mode 100644 index 00000000..d3e71069 --- /dev/null +++ b/website/.vuepress/theme/styles/toc.styl @@ -0,0 +1,3 @@ +.table-of-contents + .badge + vertical-align middle diff --git a/website/.vuepress/theme/styles/wrapper.styl b/website/.vuepress/theme/styles/wrapper.styl new file mode 100644 index 00000000..a99262c7 --- /dev/null +++ b/website/.vuepress/theme/styles/wrapper.styl @@ -0,0 +1,9 @@ +$wrapper + max-width $contentWidth + margin 0 auto + padding 2rem 2.5rem + @media (max-width: $MQNarrow) + padding 2rem + @media (max-width: $MQMobileNarrow) + padding 1.5rem + diff --git a/website/README.md b/website/README.md index a03eab9e..c5f7a3d5 100644 --- a/website/README.md +++ b/website/README.md @@ -1,5 +1,13 @@ ---- -title: 奥利给 ---- +# 这是你的主页 -这是一个彩蛋。 \ No newline at end of file +--- +home: true +heroImage: /hero.png +heroImageStyle: { + maxHeight: '200px', + display: block, + margin: '6rem auto 1.5rem', + borderRadius: '50%', + boxShadow: '0 5px 18px rgba(0,0,0,0.2)' +} +--- \ No newline at end of file