diff --git a/.gitignore b/.gitignore index 587c07503..063b0e4ce 100644 --- a/.gitignore +++ b/.gitignore @@ -1,19 +1,7 @@ .DS_Store -.idea/ +Thumbs.db +db.json *.log -*.iml -yarn.lock -package-lock.json node_modules/ - -# Ignore optional external libraries -source/lib/* - -# Track internal libraries & Ignore unused verdors files -source/lib/font-awesome/less/ -source/lib/font-awesome/scss/ -!source/lib/font-awesome/ - -!source/lib/anime.min.js - -!source/lib/velocity/ +public/ +.deploy*/ \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index 9591f0b23..74b71d1d3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,18 +1,30 @@ -language: node_js -#node_js: node -node_js: lts/* - +language: node_js # 设置语言 +node_js: stable # 设置相应的版本 cache: - directories: - - node_modules - -install: npm install - + directories: + - node_modules # 据说可以减少travis构建时间 +before_install: + - npm install -g hexo + - npm install -g hexo-cli +install: + - npm install # 安装hexo及插件 before_script: - - npm install -g gulp - -addons: - browserstack: - username: "ivannginx1" - access_key: - secure: "NutOhdgtUdBUXMPZhy8X1F1Jq+tan1LeNOV0FArBt15SNlxtNArqhiyTi4XnG9MPruX4306aGF2RBrKso+OiGNRdGtRGngH613Q0GWNtlC/boMqnI7fHqLIyCs6S12y2uA8PK4Ifxg9bZ0VtCTYYbMy+p1KvBM//L12vmtfdnby8z5Qvex3tB3dLoPOR50CKkINHJVDLm+iVRFrdz4/83oDsulZSRRGIaxu5taDWPIcp3fYZtre2Nc+RXcsyFDyjN7U0Hvr5tKBbloJxXEQEBv2xLkMOtp85nmCPD06s1Il8Wus1ux3raVsfUyaW5FpNX37Jeb5e00RQUM1wgU5m75H6qiGwDvQswbugJG0i/a2nNfsgVmbrSZdMnkHcx2Uxmrw4ejyEP5NSrJSBi05Ck1fQ4UsZ4Qkdf1fd04SI0LpLWt43eoNO/7rHKsQoP4LCX9gxKUuC075NEBLODyJ529RYfA6dKKwwH6o0ZbOgASmCoAWaM65g4+FHRnJcKL/Kj9ZWklQtRa7/ynlHaA65jefFS2lB8Ut6d3rXDDBih9mIrwV1uUaEH96xgAN42bgU/vY6FGzNkDOYZqj4YfsepDM0wbOsslFie7JZq7iFjsYvrXqLvYUMk37AZwQ2Sb6uH4tIT4Qw/4oZfDzA1En3/8HdZJ28nKW/lzjwMSqheIY=" + - npm install -g mocha + - git clone --branch master https://github.com/BladeCode/BladeCode.github.io.git public +script: + - hexo cl # 清除 + - hexo g # 生成 +after_script: + - cd ./public + - git init + - git config user.name "BladeCode" # 修改成自己的github用户名 + - git config user.email "Jerry.x@outlook.com" # 修改成自己的GitHub邮箱 + - git add . + - git commit -m "update by Travis-CI" + - git push --force --quiet "https://${GH_TOKEN}@${GH_REF}" master:master # GH_token就是在travis中设置的token +branches: + only: + - dev # 只监测这个分支,一有动静就开始构建 +env: + global: + - GH_REF: github.com/BladeCode/BladeCode.github.io.git \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 000000000..80f46a893 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 Jerry xu + +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/README.md b/README.md index 740251b2a..545862920 100644 --- a/README.md +++ b/README.md @@ -1,93 +1,10 @@ -
官方文档: -:cn: -:ru:
+

+ BladeCode +

-#
e x T
+![BladeCode](https://travis-ci.com/BladeCode/BladeCode.github.io.svg?branch=dev) -

«NexT» is a high quality elegant Hexo theme. It is crafted from scratch, with love.

- -

- - - - - - - - -

- -## 前言 -这是一个fork项目,在[源项目](https://github.com/theme-next/hexo-theme-next)的基础上,集成了以下第三方常用的工具库 -* ~~[theme-next-algolia-instant-search](https://github.com/theme-next/theme-next-algolia-instant-search):即时搜索~~ -* ~~[theme-next-bookmark](https://github.com/theme-next/theme-next-bookmark):书签,用户可以保存他们的阅读位置~~ -* ~~[theme-next-fancybox3](https://github.com/theme-next/theme-next-fancybox3):图片预览~~ -* ~~[theme-next-reading-progress](https://github.com/theme-next/theme-next-reading-progress):页面阅读进度加载~~ -* ~~[theme-next-pace](https://github.com/theme-next/theme-next-pace):顶部装载栏~~ -* ~~[theme-next-pangu](https://github.com/theme-next/theme-next-pangu):字符间空格处理~~ -* [theme-next-pdf](https://github.com/theme-next/theme-next-pdf):PDF文件预览支持 - -## 使用 - -### 安装主题 -在你的hexo项目中,安装已集成好的[NexT](https://github.com/RootCluster/hexo-theme-next)主题 -```bash -# 在你的 blog 根目录下执行 -git clone https://github.com/RootCluster/hexo-theme-next.git themes/next -``` - -### 个性化配置 -在你的 blog 项目的根目录 `source/_data`中,创建`next.yml` - -copy`/themes/next/`路径下`_config.yml`的内容到`/source/_data/`路径的`next.yml`文件中 - -以下配置均在`next.yml`文件中 -* algolia-instant-search -``` -algolia_search: -enable: true -``` -* bookmark -``` -bookmark: true -``` -* fancybox -``` -fancybox: true -``` -* reading_progress -``` -reading_progress: -enable: true -color: "#37c6c0" -height: 2px -``` -* pace -``` -pace: true -``` -* pangu -``` -pangu: true -``` -* pdf -``` -# PDF Support -pdf: -enable: true - -# Default(true) will load PDFObject/PDF.js script on demand -# That is it only render those page who has 'pdf: true' in Front Matter. -# If you set it to false, it will load PDFObject/PDF.js srcipt EVERY PAGE. -per_page: true - -height: 500px - -pdfobject: -# Use 2.1.1 as default, cloudflare as default CDN -cdn: //cdnjs.cloudflare.com/ajax/libs/pdfobject/2.1.1/pdfobject.min.js -``` - -## 更新 -* 具体操作查看[Git 子仓库管理](https://incoder.org/2018/05/17/git-sub/#git-subtree-%E5%B8%B8%E7%94%A8%E6%93%8D%E4%BD%9C-%E9%87%8D%E7%82%B9) -* [Github上fork项目后保持与源项目更新](https://segmentfault.com/a/1190000008401427) \ No newline at end of file +### Thanks +1. [Node](https://nodejs.org) +2. [Hexo](https://hexo.io) +3. [Next](https://github.com/theme-next/hexo-theme-next) \ No newline at end of file diff --git a/_config.yml b/_config.yml index 699b2ea42..cf256f56d 100644 --- a/_config.yml +++ b/_config.yml @@ -1,1121 +1,161 @@ -# --------------------------------------------------------------- -# Theme Core Configuration Settings -# See: https://theme-next.org/docs/theme-settings/ -# --------------------------------------------------------------- - -# If false, merge configs from `_data/next.yml` into default configuration (rewrite). -# If true, will fully override default configuration by options from `_data/next.yml` (override). Only for NexT settings. -# And if true, all config from default NexT `_config.yml` must be copied into `next.yml`. Use if you know what you are doing. -# Useful if you want to comment some options from NexT `_config.yml` by `next.yml` without editing default config. -override: false - -# Console reminder if new version released. -reminder: false - -# Allow to cache content generation. Introduced in NexT v6.0.0. -cache: +# Hexo Configuration +## Docs: https://hexo.io/docs/configuration.html +## Source: https://github.com/hexojs/hexo/ + +# Site +title: BladeCode +subtitle: Life's a struggle! +description: +keywords: incoder BladeCode +author: Jerry xu +language: zh-CN +timezone: + +# URL +## If your site is put in a subdirectory, set url as 'http://yoursite.com/child' and root as '/child/' +url: https://incoder.org +root: / +permalink: :year/:month/:day/:title/ +permalink_defaults: + +# Directory +source_dir: source +public_dir: public +tag_dir: tags +archive_dir: archives +category_dir: categories +code_dir: downloads/code +i18n_dir: :lang +skip_render: README.md + +# Writing +new_post_name: :title.md # File name of new posts +default_layout: post +titlecase: false # Transform title into titlecase +external_link: true # Open external links in new tab +filename_case: 0 +render_drafts: false +post_asset_folder: false +relative_link: false +future: true +highlight: enable: true - -# Remove unnecessary files after hexo generate. -minify: false - -# Define custom file paths. -# Create your custom files in site directory `source/_data` and uncomment needed files below. -custom_file_path: - #head: source/_data/head.swig - #header: source/_data/header.swig - #sidebar: source/_data/sidebar.swig - #postMeta: source/_data/post-meta.swig - #postBodyEnd: source/_data/post-body-end.swig - #footer: source/_data/footer.swig - #bodyEnd: source/_data/body-end.swig - #variable: source/_data/variables.styl - #mixin: source/_data/mixins.styl - #style: source/_data/styles.styl - - -# --------------------------------------------------------------- -# Site Information Settings -# See: https://theme-next.org/docs/getting-started/ -# --------------------------------------------------------------- - -favicon: - small: /images/favicon-16x16-next.png - medium: /images/favicon-32x32-next.png - apple_touch_icon: /images/apple-touch-icon-next.png - safari_pinned_tab: /images/logo.svg - #android_manifest: /images/manifest.json - #ms_browserconfig: /images/browserconfig.xml - -# hexo-generator-feed required for rss support. Leave rss as blank to use site's feed link. -# Set rss to false to disable feed link. Set rss to specific value if you have burned your feed already. -rss: - -footer: - # Specify the date when the site was setup. If not defined, current year will be used. - #since: 2015 - - # Icon between year and copyright info. - icon: - # Icon name in Font Awesome. See: https://fontawesome.com/v4.7.0/icons/ - # `heart` is recommended with animation in red (#ff0000). - name: user - # If you want to animate the icon, set it to true. - animated: false - # Change the color of icon, using Hex Code. - color: "#808080" - - # If not defined, `author` from Hexo `_config.yml` will be used. - copyright: - - powered: - # Hexo link (Powered by Hexo). - enable: true - # Version info of Hexo after Hexo link (vX.X.X). - version: true - - theme: - # Theme & scheme info link (Theme - NexT.scheme). - enable: true - # Version info of NexT after scheme info (vX.X.X). - version: true - - # Beian ICP and gongan information for Chinese users. See: http://www.beian.miit.gov.cn, http://www.beian.gov.cn - beian: - enable: false - icp: - # The digit in the num of gongan beian. - gongan_id: - # The full num of gongan beian. - gongan_num: - # The icon for gongan beian. See: http://www.beian.gov.cn/portal/download - gongan_icon_url: - -# Creative Commons 4.0 International License. -# See: https://creativecommons.org/share-your-work/licensing-types-examples -# Available values of license: by | by-nc | by-nc-nd | by-nc-sa | by-nd | by-sa | zero -# You can set a language value if you prefer a translated version of CC license, e.g. deed.zh -# CC licenses are available in 39 languages, you can find the specific and correct abbreviation you need on https://creativecommons.org -creative_commons: - license: by-nc-sa - sidebar: false - post: false - language: - - -# --------------------------------------------------------------- -# Scheme Settings -# --------------------------------------------------------------- - -# Schemes -scheme: Muse -#scheme: Mist -#scheme: Pisces -#scheme: Gemini - - -# --------------------------------------------------------------- -# Menu Settings -# --------------------------------------------------------------- - -# Usage: `Key: /link/ || icon` -# Key is the name of menu item. If the translation for this item is available, the translated text will be loaded, otherwise the Key name will be used. Key is case-senstive. -# Value before `||` delimiter is the target link. -# Value after `||` delimiter is the name of Font Awesome icon. If icon (with or without delimiter) is not specified, question icon will be loaded. -# When running the site in a subdirectory (e.g. domain.tld/blog), remove the leading slash from link value (/archives -> archives). -# External url should start with http:// or https:// -menu: - home: / || home - #about: /about/ || user - #tags: /tags/ || tags - #categories: /categories/ || th - archives: /archives/ || archive - #schedule: /schedule/ || calendar - #sitemap: /sitemap.xml || sitemap - #commonweal: /404/ || heartbeat - -# Enable / Disable menu icons / item badges. -menu_settings: - icons: true - badges: false - - -# --------------------------------------------------------------- -# Sidebar Settings -# See: https://theme-next.org/docs/theme-settings/sidebar -# --------------------------------------------------------------- - -sidebar: - # Sidebar Position. - position: left - #position: right - - # Manual define the sidebar width. If commented, will be default for: - # Muse | Mist: 320 - # Pisces | Gemini: 240 - #width: 300 - - # Sidebar Display (only for Muse | Mist), available values: - # - post expand on posts automatically. Default. - # - always expand for all pages automatically. - # - hide expand only when click on the sidebar toggle icon. - # - remove totally remove sidebar including sidebar toggle. - display: post - - # Sidebar offset from top menubar in pixels (only for Pisces | Gemini). - offset: 12 - # Enable sidebar on narrow view (only for Muse | Mist). - onmobile: false - -# Sidebar Avatar -avatar: - # In theme directory (source/images): /images/avatar.gif - # In site directory (source/uploads): /uploads/avatar.gif - # You can also use other linking images. - url: #/images/avatar.gif - # If true, the avatar would be dispalyed in circle. - rounded: false - # If true, the avatar would be rotated with the cursor. - rotated: false - -# Posts / Categories / Tags in sidebar. -site_state: true - -# Social Links -# Usage: `Key: permalink || icon` -# Key is the link label showing to end users. -# Value before `||` delimiter is the target permalink. -# Value after `||` delimiter is the name of Font Awesome icon. If icon (with or without delimiter) is not specified, globe icon will be loaded. -social: - #GitHub: https://github.com/yourname || github - #E-Mail: mailto:yourname@gmail.com || envelope - #Weibo: https://weibo.com/yourname || weibo - #Google: https://plus.google.com/yourname || google - #Twitter: https://twitter.com/yourname || twitter - #FB Page: https://www.facebook.com/yourname || facebook - #VK Group: https://vk.com/yourname || vk - #StackOverflow: https://stackoverflow.com/yourname || stack-overflow - #YouTube: https://youtube.com/yourname || youtube - #Instagram: https://instagram.com/yourname || instagram - #Skype: skype:yourname?call|chat || skype - -social_icons: - enable: true - icons_only: false - transition: false - -# Blog rolls -links_settings: - icon: link - title: Links - # Available values: block | inline - layout: block - -links: - #Title: http://example.com - -# Table Of Contents in the Sidebar -toc: - enable: true - # Automatically add list number to toc. - number: true - # If true, all words will placed on next lines if header width longer then sidebar width. - wrap: false - # If true, all level of TOC in a post will be displayed, rather than the activated part of it. - expand_all: false - # Maximum heading depth of generated toc. You can set it in one post through `toc_max_depth` in Front-matter. - max_depth: 6 - -# A button to open designated chat widget in sidebar. -# Firstly, you need enable the chat service you want to activate its sidebar button. -chat: - enable: false - #service: chatra - #service: tidio - icon: comment # Icon name in Font Awesome, set false to disable icon. - text: Chat # Button text, change it as you wish. - - -# --------------------------------------------------------------- -# Post Settings -# See: https://theme-next.org/docs/theme-settings/posts -# --------------------------------------------------------------- - -# Automatically scroll page to section which is under mark. -scroll_to_more: true - -# Automatically excerpt description in homepage as preamble text. -excerpt_description: true - -# Automatically excerpt (Not recommend). -# Use in the post to control excerpt accurately. -auto_excerpt: - enable: false - length: 150 - -# Read more button -# If true, the read more button would be displayed in excerpt section. -read_more_btn: true - -# Post meta display settings -post_meta: - item_text: true - created_at: true - updated_at: - enable: true - another_day: true - categories: true - -# Post wordcount display settings -# Dependencies: https://github.com/theme-next/hexo-symbols-count-time + line_number: true + auto_detect: false + tab_replace: + +# Home page setting +# path: Root path for your blogs index page. (default = '') +# per_page: Posts displayed per page. (0 = disable pagination) +# order_by: Posts order. (Order by date descending by default) +index_generator: + path: '' + per_page: 10 + order_by: -date + +# Category & Tag +default_category: uncategorized +category_map: +tag_map: + +# Date / Time format +## Hexo uses Moment.js to parse and display date +## You can customize the date format as defined in +## http://momentjs.com/docs/#/displaying/format/ +date_format: YYYY-MM-DD +time_format: HH:mm:ss + +# Pagination +## Set per_page to 0 to disable pagination +per_page: 10 +pagination_dir: page + +# Extensions +## Plugins: https://hexo.io/plugins/ + +# RSS订阅支持 +plugin: +- hexo-generator-feed +# Feed Atom +feed: + type: atom + path: atom.xml + limit: 20 + +## Themes: https://hexo.io/themes/ +theme: next + +# Deployment +## Docs: https://hexo.io/docs/deployment.html +deploy: +- type: git +# - type: leancloud_counter_security_sync + repo: https://github.com/BladeCode/BladeCode.github.io.git + branch: master + +# hexo-symbols-count-time symbols_count_time: - separated_meta: true - item_text_post: true - item_text_total: false - awl: 4 - wpm: 275 - -# Use icon instead of the symbol # to indicate the tag at the bottom of the post -tag_icon: false - -# Wechat Subscriber -wechat_subscriber: - enable: false - qcode: #/uploads/wechat-qcode.jpg - #description: Subscribe to my blog by scanning my public wechat account. - -# Reward (Donate) -reward_settings: - # If true, reward would be displayed in every article by default. - # You can show or hide reward in a specific article throuth `reward: true | false` in Front-matter. - enable: false - animation: false - #comment: Donate comment here. - -reward: - #wechatpay: /images/wechatpay.png - #alipay: /images/alipay.png - #bitcoin: /images/bitcoin.png - -# Related popular posts -# Dependencies: https://github.com/tea3/hexo-related-popular-posts -related_posts: - enable: false - title: # Custom header, leave empty to use the default one - display_in_home: false - params: - maxCount: 5 - #PPMixingRate: 0.0 - #isDate: false - #isImage: false - #isExcerpt: false - -# Post edit -# Dependencies: https://github.com/hexojs/hexo-deployer-git -post_edit: - enable: false - url: https://github.com/user-name/repo-name/tree/branch-name/subdirectory-name # Link for view source - #url: https://github.com/user-name/repo-name/edit/branch-name/subdirectory-name # Link for fork & edit - - -# --------------------------------------------------------------- -# Custom Page Settings -# See: https://theme-next.org/docs/theme-settings/custom-pages -# --------------------------------------------------------------- - -# Enable "cheers" for archive page. -cheers: true - -# TagCloud settings for tags page. -tagcloud: - # All values below are same as default, change them by yourself - min: 12 # Minimun font size in px - max: 30 # Maxium font size in px - start: "#ccc" # Start color (hex, rgba, hsla or color keywords) - end: "#111" # End color (hex, rgba, hsla or color keywords) - amount: 200 # Amount of tags, change it if you have more than 200 tags - -# Google Calendar -# Share your recent schedule to others via calendar page. -# API Documentation: https://developers.google.com/google-apps/calendar/v3/reference/events/list -# To get api_key: https://console.developers.google.com -# Create & manage a public Google calendar: https://support.google.com/calendar/answer/37083 -calendar: - calendar_id: # Your Google account E-Mail - api_key: - orderBy: startTime - offsetMax: 24 # Time Range - offsetMin: 4 # Time Range - showDeleted: false - singleEvents: true - maxResults: 250 - - -# --------------------------------------------------------------- -# Misc Theme Settings -# --------------------------------------------------------------- - -# Set the text alignment in posts / pages. -text_align: - # Available values: start | end | left | right | center | justify | justify-all | match-parent - desktop: justify - mobile: justify - -# Reduce padding / margin indents on devices with narrow width. -mobile_layout_economy: false - -# Android Chrome header panel color ($brand-bg / $headband-bg => $black-deep). -android_chrome_color: "#222" - -# Hide sticky headers and color the menu bar on Safari (iOS / macOS). -safari_rainbow: false - -# Optimize the display of scrollbars on webkit based browsers. -custom_scrollbar: false - -# Custom Logo (Do not support scheme Mist) -custom_logo: #/uploads/custom-logo.jpg - -codeblock: - # Code Highlight theme - # Available values: normal | night | night eighties | night blue | night bright | solarized | solarized dark | galactic - # See: https://github.com/chriskempson/tomorrow-theme - highlight_theme: normal - # Add copy button on codeblock - copy_button: - enable: false - # Show text copy result. - show_result: false - # Available values: default | flat | mac - style: - -back2top: - enable: true - # Back to top in sidebar. - sidebar: false - # Scroll percent label in b2t button. - scrollpercent: false - -# Reading progress bar -reading_progress: - enable: false - # Available values: top | bottom - position: top - color: "#37c6c0" - height: 2px - -# Bookmark Support -bookmark: - enable: false - # Customize the color of the bookmark. - color: "#222" - # If auto, save the reading progress when closing the page or clicking the bookmark-icon. - # If manual, only save it by clicking the bookmark-icon. - save: auto - -# `Follow me on GitHub` banner in the top-right corner. -github_banner: - enable: false - permalink: https://github.com/yourname - title: Follow me on GitHub - - -# --------------------------------------------------------------- -# Font Settings -# See: https://theme-next.org/docs/theme-settings/#Fonts-Customization -# --------------------------------------------------------------- -# Find fonts on Google Fonts (https://www.google.com/fonts) -# All fonts set here will have the following styles: -# light | light italic | normal | normal italic | bold | bold italic -# Be aware that setting too much fonts will cause site running slowly -# --------------------------------------------------------------- -# To avoid space between header and sidebar in scheme Pisces / Gemini, Web Safe fonts are recommended for `global` (and `title`): -# Arial | Tahoma | Helvetica | Times New Roman | Courier New | Verdana | Georgia | Palatino | Garamond | Comic Sans MS | Trebuchet MS -# --------------------------------------------------------------- - -font: - # Use custom fonts families or not. - # Depended options: `external` and `family`. - enable: false - - # Uri of fonts host, e.g. //fonts.googleapis.com (Default). - host: - - # Font options: - # `external: true` will load this font family from `host` above. - # `family: Times New Roman`. Without any quotes. - # `size: x.x`. Use `em` as unit. Default: 1 (16px) - - # Global font settings used for all elements inside . - global: - external: true - family: Lato - size: - - # Font settings for site title (.site-title). - title: - external: true - family: - size: - - # Font settings for headlines (

to

). - headings: - external: true - family: - size: - - # Font settings for posts (.post-body). - posts: - external: true - family: - - # Font settings for and code blocks. - codes: - external: true - family: - - -# --------------------------------------------------------------- -# SEO Settings -# --------------------------------------------------------------- - -# Disable Baidu transformation on mobile devices. -disable_baidu_transformation: false - -# Set a canonical link tag in your hexo, you could use it for your SEO of blog. -# See: https://support.google.com/webmasters/answer/139066 -# Remember to set up your URL in Hexo `_config.yml` (e.g. url: http://yourdomain.com) -canonical: true - -# Change headers hierarchy on site-subtitle (will be main site description) and on all post / page titles for better SEO-optimization. -seo: false - -# If true, will add site-subtitle to index page. -# Remember to set up your site-subtitle in Hexo `_config.yml` (e.g. subtitle: Subtitle) -index_with_subtitle: false - -# Automatically add external URL with Base64 encrypt & decrypt. -exturl: false - -# Google Webmaster tools verification. -# See: https://www.google.com/webmasters -google_site_verification: - -# Bing Webmaster tools verification. -# See: https://www.bing.com/webmaster -bing_site_verification: - -# Yandex Webmaster tools verification. -# See: https://webmaster.yandex.ru -yandex_site_verification: - -# Baidu Webmaster tools verification. -# See: https://ziyuan.baidu.com/site -baidu_site_verification: - -# Enable baidu push so that the blog will push the url to baidu automatically which is very helpful for SEO. -baidu_push: false - - -# --------------------------------------------------------------- -# Third Party Plugins & Services Settings -# See: https://theme-next.org/docs/third-party-services/ -# You may need to install dependencies or set CDN URLs in `vendors` -# There are two different CDN providers by default: -# - jsDelivr (cdn.jsdelivr.net), works everywhere even in China -# - CDNJS (cdnjs.cloudflare.com), provided by cloudflare -# --------------------------------------------------------------- - -# Math Formulas Render Support -math: - enable: false - - # Default (true) will load mathjax / katex script on demand. - # That is it only render those page which has `mathjax: true` in Front-matter. - # If you set it to false, it will load mathjax / katex srcipt EVERY PAGE. - per_page: true - - # hexo-renderer-pandoc (or hexo-renderer-kramed) required for full MathJax support. - mathjax: - enable: false - # See: https://mhchem.github.io/MathJax-mhchem/ - mhchem: false - - # hexo-renderer-markdown-it-plus (or hexo-renderer-markdown-it with markdown-it-katex plugin) required for full Katex support. - katex: - enable: false - # See: https://github.com/KaTeX/KaTeX/tree/master/contrib/copy-tex - copy_tex: false - -# Easily enable fast Ajax navigation on your website. -# Dependencies: https://github.com/theme-next/theme-next-pjax -# For moreinformation: https://github.com/MoOx/pjax -pjax: false - -# FancyBox is a tool that offers a nice and elegant way to add zooming functionality for images. -# For more information: https://fancyapps.com/fancybox -fancybox: false - -# A JavaScript library for zooming images like Medium. -# Do not enable both `fancybox` and `mediumzoom`. -# For more information: https://github.com/francoischalifour/medium-zoom -mediumzoom: false - -# Vanilla JavaScript plugin for lazyloading images. -# For more information: https://github.com/ApoorvSaxena/lozad.js -lazyload: false - -# Pangu Support -# For more information: https://github.com/vinta/pangu.js -pangu: false - -# Quicklink Support -# For more information: https://github.com/GoogleChromeLabs/quicklink -quicklink: - enable: false - - # Quicklink (quicklink.umd.js script) is loaded on demand. - # Add `quicklink: true` in Front-matter of the page or post you need. - # Home page and archive page can be controlled through home and archive options below. - home: true - archive: true - - # Default (true) will initialize quicklink after the load event fires. - delay: true - # Custom a time in milliseconds by which the browser must execute prefetching. - timeout: 3000 - # Default (true) will enable fetch() or falls back to XHR. - priority: true - - # For more flexibility you can add some patterns (RegExp, Function, or Array) to ignores. - # See: https://github.com/GoogleChromeLabs/quicklink#custom-ignore-patterns - ignores: - - -# --------------------------------------------------------------- -# Comments Settings -# See: https://theme-next.org/docs/third-party-services/comments -# --------------------------------------------------------------- - -# Multiple Comment System Support -comments: - # Available values: tabs | buttons - style: tabs - # Choose a comment system to be displayed by default. - # Available values: changyan | disqus | disqusjs | facebook_comments_plugin | gitalk | livere | valine | vkontakte - active: - # Setting `true` means remembering the comment system selected by the visitor. - storage: true - # Modify texts or order for any navs, here are some examples. - nav: - #disqus: - # text: Load Disqus - # order: -1 - #facebook_comments_plugin: - # text: facebook - #gitalk: - # order: -2 - -# Disqus -disqus: - enable: false - shortname: - count: true - lazyload: false - #post_meta_order: 0 - -# DisqusJS -# Alternative Disqus - Render comment component using Disqus API. -# Demo: https://suka.js.org/DisqusJS/ -# For more information: https://github.com/SukkaW/DisqusJS -disqusjs: - enable: false - # API Endpoint of Disqus API (https://disqus.com/api/). - # Leave api empty if you are able to connect to Disqus API. - # Otherwise you need a reverse proxy for Disqus API. - # For example: - # api: https://disqus.skk.moe/disqus/ - api: - apikey: # Register new application from https://disqus.com/api/applications/ - shortname: # See: https://disqus.com/admin/settings/general/ - -# Changyan -changyan: - enable: false - appid: - appkey: - #post_meta_order: 0 - -# Valine -# You can get your appid and appkey from https://leancloud.cn -# For more information: https://valine.js.org, https://github.com/xCss/Valine -valine: - enable: false # When enable is set to be true, leancloud_visitors is recommended to be closed for the re-initialization problem within different leancloud adk version - appid: # Your leancloud application appid - appkey: # Your leancloud application appkey - notify: false # Mail notifier. See: https://github.com/xCss/Valine/wiki - verify: false # Verification code - placeholder: Just go go # Comment box placeholder - avatar: mm # Gravatar style - guest_info: nick,mail,link # Custom comment header - pageSize: 10 # Pagination size - language: # Language, available values: en, zh-cn - visitor: false # leancloud-counter-security is not supported for now. When visitor is set to be true, appid and appkey are recommended to be the same as leancloud_visitors' for counter compatibility. Article reading statistic https://valine.js.org/visitor.html - comment_count: true # If false, comment count will only be displayed in post page, not in home page - recordIP: false # Whether to record the commenter IP - serverURLs: # When the custom domain name is enabled, fill it in here (it will be detected automatically by default, no need to fill in) - #post_meta_order: 0 - -# LiveRe comments system -# You can get your uid from https://livere.com/insight/myCode (General web site) -livere_uid: # - -# Gitalk -# Demo: https://gitalk.github.io -# For more information: https://github.com/gitalk/gitalk -gitalk: - enable: false - github_id: # GitHub repo owner - repo: # Repository name to store issues - client_id: # GitHub Application Client ID - client_secret: # GitHub Application Client Secret - admin_user: # GitHub repo owner and collaborators, only these guys can initialize gitHub issues - distraction_free_mode: true # Facebook-like distraction free mode - # Gitalk's display language depends on user's browser or system environment - # If you want everyone visiting your site to see a uniform language, you can set a force language value - # Available values: en | es-ES | fr | ru | zh-CN | zh-TW - language: - - -# --------------------------------------------------------------- -# Post Widgets & Content Sharing Services -# See: https://theme-next.org/docs/third-party-services/post-widgets -# --------------------------------------------------------------- - -# Facebook SDK Support -facebook_sdk: - enable: false - app_id: # - fb_admin: # - like_button: # true - webmaster: # true - -# Facebook comments plugin -# This plugin depends on Facebook SDK. -# If facebook_sdk.enable is false, Facebook comments plugin is unavailable. -facebook_comments_plugin: - enable: false - num_of_posts: 10 # Minimum posts num is 1 - width: 100% # Default width is 550px - scheme: light # Default scheme is light (light or dark) - #post_meta_order: 0 - -# VKontakte API Support -# To get your AppID visit https://vk.com/editapp?act=create -vkontakte_api: - enable: false - app_id: # - like: true - comments: true - num_of_posts: 10 - -# Star rating support to each article. -# To get your ID visit https://widgetpack.com -rating: - enable: false - id: # - color: fc6423 - -# AddThis Share. See: https://www.addthis.com -# Go to https://www.addthis.com/dashboard to customize your tools. -add_this_id: - - -# --------------------------------------------------------------- -# Statistics and Analytics -# See: https://theme-next.org/docs/third-party-services/statistics-and-analytics -# --------------------------------------------------------------- - -# Baidu Analytics -baidu_analytics: # - -# Growingio Analytics -# Copyright 2015-2018 GrowingIO, Inc. More info available at https://www.growingio.com -growingio_analytics: # - -# Google Analytics -google_analytics: - tracking_id: # - localhost_ignored: true - -# CNZZ count -cnzz_siteid: - -# Application Insights -# See: https://azure.microsoft.com/en-us/services/application-insights -application_insights: - -# Show number of visitors to each article. -# You can visit https://leancloud.cn to get AppID and AppKey. -leancloud_visitors: - enable: false - app_id: # - app_key: # - # Dependencies: https://github.com/theme-next/hexo-leancloud-counter-security - # If you don't care about security in leancloud counter and just want to use it directly - # (without hexo-leancloud-counter-security plugin), set `security` to `false`. - security: true - betterPerformance: false - -# Another tool to show number of visitors to each article. -# Visit https://console.firebase.google.com/u/0/ to get apiKey and projectId. -# Visit https://firebase.google.com/docs/firestore/ to get more information about firestore. -firestore: - enable: false - collection: articles # Required, a string collection name to access firestore database - apiKey: # Required - projectId: # Required - -# Show Views / Visitors of the website / page with busuanzi. -# Get more information on http://ibruce.info/2015/04/04/busuanzi -busuanzi_count: - enable: false - total_visitors: true - total_visitors_icon: user - total_views: true - total_views_icon: eye - post_views: true - post_views_icon: eye - -# Tencent analytics -tencent_analytics: # - -# Tencent MTA -tencent_mta: # - - -# --------------------------------------------------------------- -# Search Services -# See: https://theme-next.org/docs/third-party-services/search-services -# --------------------------------------------------------------- - -# Algolia Search -# For more information: https://www.algolia.com -algolia_search: - enable: false - hits: - per_page: 10 - labels: - input_placeholder: Search for Posts - hits_empty: "We didn't find any results for the search: ${query}" - hits_stats: "${hits} results found in ${time} ms" - -# Local Search -# Dependencies: https://github.com/wzpan/hexo-generator-search -local_search: - enable: false - # If auto, trigger search by changing input. - # If manual, trigger search by pressing enter key or search button. - trigger: auto - # Show top n results per article, show all results by setting to -1 - top_n_per_article: 1 - # Unescape html strings to the readable one. - unescape: false - # Preload the search data when the page loads. - preload: false - -# Swiftype Search API Key -swiftype_key: - - -# --------------------------------------------------------------- -# Chat Services -# See: https://theme-next.org/docs/third-party-services/chat-services -# --------------------------------------------------------------- - -# Chatra Support -# See: https://chatra.io -# Dashboard: https://app.chatra.io/settings/general -chatra: - enable: false - async: true - id: # Visit Dashboard to get your ChatraID - #embed: # Unfinished experimental feature for developers. See: https://chatra.io/help/api/#injectto - -# Tidio Support -# See: https://www.tidiochat.com -# Dashboard: https://www.tidiochat.com/panel/dashboard -tidio: - enable: false - key: # Public Key, get it from dashboard. See: https://www.tidiochat.com/panel/settings/developer - - -# --------------------------------------------------------------- -# Tags Settings -# See: https://theme-next.org/docs/tag-plugins/ -# --------------------------------------------------------------- - -# Note tag (bs-callout) -note: - # Note tag style values: - # - simple bs-callout old alert style. Default. - # - modern bs-callout new (v2-v3) alert style. - # - flat flat callout style with background, like on Mozilla or StackOverflow. - # - disabled disable all CSS styles import of note tag. - style: simple - icons: false - border_radius: 3 - # Offset lighter of background in % for modern and flat styles (modern: -12 | 12; flat: -18 | 6). - # Offset also applied to label tag variables. This option can work with disabled note tag. - light_bg_offset: 0 - -# Tabs tag -tabs: - transition: - tabs: false - labels: true - border_radius: 0 - -# PDF tag, requires two plugins: pdfObject and pdf.js -# pdfObject will try to load pdf files natively, if failed, pdf.js will be used. -# The following `cdn` setting is only for pdfObject, because cdn for pdf.js might be blocked by CORS policy. -# So, you must install the dependency of pdf.js if you want to use pdf tag and make it available to all browsers. -# See: https://github.com/theme-next/theme-next-pdf -pdf: - enable: false - # Default height - height: 500px - -# Mermaid tag -mermaid: - enable: false - # Available themes: default | dark | forest | neutral - theme: forest - - -# --------------------------------------------------------------- -# Animation Settings -# --------------------------------------------------------------- - -# Use velocity to animate everything. -# For more information: http://velocityjs.org -motion: - enable: true - async: false - transition: - # Transition variants: - # fadeIn | fadeOut | flipXIn | flipXOut | flipYIn | flipYOut | flipBounceXIn | flipBounceXOut | flipBounceYIn | flipBounceYOut - # swoopIn | swoopOut | whirlIn | whirlOut | shrinkIn | shrinkOut | expandIn | expandOut - # bounceIn | bounceOut | bounceUpIn | bounceUpOut | bounceDownIn | bounceDownOut | bounceLeftIn | bounceLeftOut | bounceRightIn | bounceRightOut - # slideUpIn | slideUpOut | slideDownIn | slideDownOut | slideLeftIn | slideLeftOut | slideRightIn | slideRightOut - # slideUpBigIn | slideUpBigOut | slideDownBigIn | slideDownBigOut | slideLeftBigIn | slideLeftBigOut | slideRightBigIn | slideRightBigOut - # perspectiveUpIn | perspectiveUpOut | perspectiveDownIn | perspectiveDownOut | perspectiveLeftIn | perspectiveLeftOut | perspectiveRightIn | perspectiveRightOut - post_block: fadeIn - post_header: slideDownIn - post_body: slideDownIn - coll_header: slideLeftIn - # Only for Pisces | Gemini. - sidebar: slideUpIn - -# Progress bar in the top during page loading. -# Dependencies: https://github.com/theme-next/theme-next-pace -# For more information: https://github.com/HubSpot/pace -pace: - enable: false - # Themes list: - # big-counter | bounce | barber-shop | center-atom | center-circle | center-radar | center-simple - # corner-indicator | fill-left | flat-top | flash | loading-bar | mac-osx | material | minimal - theme: minimal - -# JavaScript 3D library. -# Dependencies: https://github.com/theme-next/theme-next-three -three: - enable: false - three_waves: false - canvas_lines: false - canvas_sphere: false - -# Canvas-nest -# Dependencies: https://github.com/theme-next/theme-next-canvas-nest -# For more information: https://github.com/hustcc/canvas-nest.js -canvas_nest: - enable: false - onmobile: true # Display on mobile or not - color: "0,0,255" # RGB values, use `,` to separate - opacity: 0.5 # The opacity of line: 0~1 - zIndex: -1 # z-index property of the background - count: 99 # The number of lines - -# Canvas-ribbon -# Dependencies: https://github.com/theme-next/theme-next-canvas-ribbon -# For more information: https://github.com/zproo/canvas-ribbon -canvas_ribbon: - enable: false - size: 300 # The width of the ribbon - alpha: 0.6 # The transparency of the ribbon - zIndex: -1 # The display level of the ribbon - - -#! --------------------------------------------------------------- -#! DO NOT EDIT THE FOLLOWING SETTINGS -#! UNLESS YOU KNOW WHAT YOU ARE DOING -#! See: https://theme-next.org/docs/advanced-settings -#! --------------------------------------------------------------- - -# Script Vendors. Set a CDN address for the vendor you want to customize. -# Be aware that you would better use the same version as internal ones to avoid potential problems. -# Please use the https protocol of CDN files when you enable https on your site. -vendors: - # Internal path prefix. Please do not edit it. - _internal: lib - - # Internal version: 3.1.0 - # Example: - # anime: //cdn.jsdelivr.net/npm/animejs@3.1.0/lib/anime.min.js - anime: - - # Internal version: 4.7.0 - # Example: - # fontawesome: //cdn.jsdelivr.net/npm/font-awesome@4/css/font-awesome.min.css - # fontawesome: //cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css - fontawesome: - - # MathJax - # Example: - # mathjax: //cdn.jsdelivr.net/npm/mathjax@2/MathJax.js?config=TeX-AMS-MML_HTMLorMML - # mathjax: //cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-MML-AM_CHTML - # mhchem: //cdn.jsdelivr.net/npm/mathjax-mhchem@3 - # mhchem: //cdnjs.cloudflare.com/ajax/libs/mathjax-mhchem/3.3.0 - mathjax: - mhchem: - - # KaTeX - # Example: - # katex: //cdn.jsdelivr.net/npm/katex@0/dist/katex.min.css - # katex: //cdnjs.cloudflare.com/ajax/libs/KaTeX/0.7.1/katex.min.css - # copy_tex_js: //cdn.jsdelivr.net/npm/katex@0/dist/contrib/copy-tex.min.js - # copy_tex_css: //cdn.jsdelivr.net/npm/katex@0/dist/contrib/copy-tex.min.css - katex: - copy_tex_js: - copy_tex_css: - - # Internal version: 0.2.8 - # Example: - # pjax: //cdn.jsdelivr.net/gh/theme-next/theme-next-pjax@0/pjax.min.js - pjax: - - # FancyBox - # Example: - # jquery: //cdn.jsdelivr.net/npm/jquery@3/dist/jquery.min.js - # fancybox: //cdn.jsdelivr.net/gh/fancyapps/fancybox@3/dist/jquery.fancybox.min.js - # fancybox_css: //cdn.jsdelivr.net/gh/fancyapps/fancybox@3/dist/jquery.fancybox.min.css - jquery: - fancybox: - fancybox_css: - - # Medium-zoom - # Example: - # mediumzoom: //cdn.jsdelivr.net/npm/medium-zoom@1/dist/medium-zoom.min.js - mediumzoom: - - # Lazyload - # Example: - # lazyload: //cdn.jsdelivr.net/npm/lozad@1/dist/lozad.min.js - # lazyload: //cdnjs.cloudflare.com/ajax/libs/lozad.js/1.9.0/lozad.min.js - lazyload: - - # Pangu - # Example: - # pangu: //cdn.jsdelivr.net/npm/pangu@4/dist/browser/pangu.min.js - # pangu: //cdnjs.cloudflare.com/ajax/libs/pangu/4.0.7/pangu.min.js - pangu: - - # Quicklink - # Example: - # quicklink: //cdn.jsdelivr.net/npm/quicklink@1/dist/quicklink.umd.js - quicklink: - - # DisqusJS - # Example: - # disqusjs_js: //cdn.jsdelivr.net/npm/disqusjs@1/dist/disqus.js - # disqusjs_css: //cdn.jsdelivr.net/npm/disqusjs@1/dist/disqusjs.css - disqusjs_js: - disqusjs_css: - - # Valine - # Example: - # valine: //cdn.jsdelivr.net/npm/valine@1/dist/Valine.min.js - # valine: //cdnjs.cloudflare.com/ajax/libs/valine/1.3.4/Valine.min.js - valine: - - # Gitalk - # Example: - # gitalk_js: //cdn.jsdelivr.net/npm/gitalk@1/dist/gitalk.min.js - # gitalk_css: //cdn.jsdelivr.net/npm/gitalk@1/dist/gitalk.css - gitalk_js: - gitalk_css: - - # Algolia Search - # Example: - # algolia_instant_js: //cdn.jsdelivr.net/npm/instantsearch.js@2/dist/instantsearch.min.js - # algolia_instant_css: //cdn.jsdelivr.net/npm/instantsearch.js@2/dist/instantsearch.min.css - algolia_instant_js: - algolia_instant_css: - - # PDF - # Example: - # pdfobject: //cdn.jsdelivr.net/npm/pdfobject@2/pdfobject.min.js - # pdfobject: //cdnjs.cloudflare.com/ajax/libs/pdfobject/2.1.1/pdfobject.min.js - pdfobject: - - # Mermaid - # Example: - # mermaid: //cdn.jsdelivr.net/npm/mermaid@8/dist/mermaid.min.js - # mermaid: //cdnjs.cloudflare.com/ajax/libs/mermaid/8.0.0/mermaid.min.js - mermaid: - - # Internal version: 1.2.1 - # Example: - # velocity: //cdn.jsdelivr.net/npm/velocity-animate@1/velocity.min.js - # velocity: //cdnjs.cloudflare.com/ajax/libs/velocity/1.2.1/velocity.min.js - # velocity_ui: //cdn.jsdelivr.net/npm/velocity-animate@1/velocity.ui.min.js - # velocity_ui: //cdnjs.cloudflare.com/ajax/libs/velocity/1.2.1/velocity.ui.min.js - velocity: - velocity_ui: - - # Internal version: 1.0.2 - # Example: - # pace: //cdn.jsdelivr.net/npm/pace-js@1/pace.min.js - # pace: //cdnjs.cloudflare.com/ajax/libs/pace/1.0.2/pace.min.js - # pace_css: //cdn.jsdelivr.net/npm/pace-js@1/themes/blue/pace-theme-minimal.css - # pace_css: //cdnjs.cloudflare.com/ajax/libs/pace/1.0.2/themes/blue/pace-theme-minimal.min.css - pace: - pace_css: - - # Internal version: 1.0.0 - # Example: - # three: //cdn.jsdelivr.net/gh/theme-next/theme-next-three@1/three.min.js - # three_waves: //cdn.jsdelivr.net/gh/theme-next/theme-next-three@1/three-waves.min.js - # canvas_lines: //cdn.jsdelivr.net/gh/theme-next/theme-next-three@1/canvas_lines.min.js - # canvas_sphere: //cdn.jsdelivr.net/gh/theme-next/theme-next-three@1/canvas_sphere.min.js - three: - three_waves: - canvas_lines: - canvas_sphere: - - # Internal version: 1.0.0 - # Example: - # canvas_nest: //cdn.jsdelivr.net/gh/theme-next/theme-next-canvas-nest@1/canvas-nest.min.js - # canvas_nest_nomobile: //cdn.jsdelivr.net/gh/theme-next/theme-next-canvas-nest@1/canvas-nest-nomobile.min.js - canvas_nest: - canvas_nest_nomobile: - - # Internal version: 1.0.0 - # Example: - # canvas_ribbon: //cdn.jsdelivr.net/gh/theme-next/theme-next-canvas-ribbon@1/canvas-ribbon.js - canvas_ribbon: - -# Assets -css: css -js: js -images: images + symbols: true + time: true + total_symbols: true + total_time: true + +search: + path: search.xml + field: post + format: html + limit: 10000 + +# https://github.com/mythsman/hexo-douban +douban: + user: incoder + builtin: true + book: + title: '书中自有黄金屋' + quote: '只有学习才能让我快乐~' + movie: + title: '有人的地方,就有江湖!' + quote: '时光追忆!' + game: + title: '那时候太年轻' + quote: '游戏可以重来,人生呢?' + timeout: 10000 # optional + +leancloud_counter_security: + enable_sync: true + app_id: 3ShrIGfQL4TLamd48UtbdDEK-gzGzoHsz + app_key: cW8VJrB2yJiIBLtYA0KdE8vW + username: Blade # Will be asked while deploying if is left blank + password: bladecode # Recommmended to be left blank. Will be asked while deploying if is left blank + +# Markdown-it config +## Docs: https://github.com/celsomiranda/hexo-renderer-markdown-it/wiki +markdown: + # 渲染设置 + render: + # 置为true时,html内容保持不变;置为false时,html内容将被转义成普通字符串 + html: true + # 是否生成与XHTML完全兼容的标签(虽然我不懂是什么意思) + xhtmlOut: false + # 置为true时,每个换行符都被渲染成一个
(即Hexo的默认表现);置为false时,只有空行才会被渲染为
(GFM的默认表现) + breaks: true + # 是否自动识别链接并把它渲染成链接 + linkify: true + # 是否自动识别印刷格式(意思是把(c)渲染为©这样的) + typographer: true + # 如果typographer被设置为true,则该选项用于设置将dumb quotes("")自动替换为smart quotes + quotes: '“”‘’' + # 设置所需插件 + plugins: + - markdown-it-abbr + - markdown-it-footnote + - markdown-it-ins + - markdown-it-sub + - markdown-it-sup + # 锚点设置(因为我没有尝试相关内容,所以就不翻译相关说明了) + anchors: + level: 2 + collisionSuffix: 'v' + permalink: true + permalinkClass: header-anchor + permalinkSymbol: '' \ No newline at end of file diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 000000000..d43bed601 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,4641 @@ +{ + "name": "hexo-site", + "version": "0.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@babel/runtime": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.6.2.tgz", + "integrity": "sha512-EXxN64agfUqqIGeEjI5dL5z0Sw0ZwWo1mLTi4mQowCZ42O59b7DRpZAnTC6OqdF28wMBMFKNb/4uFGrVaigSpg==", + "requires": { + "regenerator-runtime": "^0.13.2" + } + }, + "JSONStream": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", + "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", + "requires": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + } + }, + "a-sync-waterfall": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/a-sync-waterfall/-/a-sync-waterfall-1.0.1.tgz", + "integrity": "sha512-RYTOHHdWipFUliRFMCS4X2Yn2X8M87V/OpSqWzKKOGhzqyUxzyVmhHDH9sAvG+ZuQf/TAOFsLCpMw09I1ufUnA==" + }, + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + }, + "accepts": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "requires": { + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + } + }, + "acorn": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.3.0.tgz", + "integrity": "sha512-/czfa8BwS88b9gWQVhc8eknunSA2DoJpJyTQkhheIf5E48u1N0R4q/YxxsAeqRrmK9TQ/uYfgLDfZo91UlANIA==" + }, + "address": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/address/-/address-1.1.2.tgz", + "integrity": "sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA==" + }, + "align-text": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", + "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", + "requires": { + "kind-of": "^3.0.2", + "longest": "^1.0.1", + "repeat-string": "^1.5.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "amdefine": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", + "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=" + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8=" + }, + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + }, + "dependencies": { + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "requires": { + "remove-trailing-separator": "^1.0.1" + } + } + } + }, + "archy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", + "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=" + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=" + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==" + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=" + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" + }, + "asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=" + }, + "ascli": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ascli/-/ascli-1.0.1.tgz", + "integrity": "sha1-vPpZdKYvGOgcq660lzKrSoj5Brw=", + "requires": { + "colour": "~0.7.1", + "optjs": "~3.2.2" + } + }, + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=" + }, + "async": { + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz", + "integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E=" + }, + "async-each": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", + "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==" + }, + "async-limiter": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", + "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==" + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, + "atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==" + }, + "babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", + "requires": { + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" + }, + "dependencies": { + "core-js": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.9.tgz", + "integrity": "sha512-HOpZf6eXmnl7la+cUdMnLvUxKNqLUzJvgIziQ0DiF3JwSImNphIqdGqzj6hIKyX04MmV0poclQ7+wjWvxQyR2A==" + }, + "regenerator-runtime": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" + } + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "requires": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "base64-arraybuffer": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz", + "integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg=" + }, + "basic-auth": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", + "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", + "requires": { + "safe-buffer": "5.1.2" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + } + } + }, + "binary-extensions": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", + "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==" + }, + "bluebird": { + "version": "3.5.5", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.5.tgz", + "integrity": "sha512-5am6HnnfN+urzt4yfg7IgTbotDjIT/u8AJpEt0sIU9FtXfVeezXAPKswrG+xKUCOYAINpSdgZVDU6QFh+cuH3w==" + }, + "boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=" + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "browser-fingerprint": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/browser-fingerprint/-/browser-fingerprint-0.0.1.tgz", + "integrity": "sha1-jfPNyiW/fVs1QtYVRdcwBT/OYEo=" + }, + "bytebuffer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/bytebuffer/-/bytebuffer-5.0.1.tgz", + "integrity": "sha1-WC7qSxqHO20CCkjVjfhfC7ps/d0=", + "requires": { + "long": "~3" + } + }, + "bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=" + }, + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "requires": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + } + }, + "camel-case": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz", + "integrity": "sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M=", + "requires": { + "no-case": "^2.2.0", + "upper-case": "^1.1.1" + } + }, + "camelcase": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", + "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=" + }, + "center-align": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", + "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", + "requires": { + "align-text": "^0.1.3", + "lazy-cache": "^1.0.3" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "charenc": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", + "integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=" + }, + "cheerio": { + "version": "0.22.0", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-0.22.0.tgz", + "integrity": "sha1-qbqoYKP5tZWmuBsahocxIe06Jp4=", + "requires": { + "css-select": "~1.2.0", + "dom-serializer": "~0.1.0", + "entities": "~1.1.1", + "htmlparser2": "^3.9.1", + "lodash.assignin": "^4.0.9", + "lodash.bind": "^4.1.4", + "lodash.defaults": "^4.0.1", + "lodash.filter": "^4.4.0", + "lodash.flatten": "^4.2.0", + "lodash.foreach": "^4.3.0", + "lodash.map": "^4.4.0", + "lodash.merge": "^4.4.0", + "lodash.pick": "^4.2.1", + "lodash.reduce": "^4.4.0", + "lodash.reject": "^4.4.0", + "lodash.some": "^4.4.0" + } + }, + "chokidar": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", + "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", + "requires": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "fsevents": "^1.2.7", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + } + }, + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "requires": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wrap-ansi": "^2.0.0" + }, + "dependencies": { + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + } + } + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" + }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "requires": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "colour": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/colour/-/colour-0.7.1.tgz", + "integrity": "sha1-nLFpkX7F0SwHNtPoaFdG3xyt93g=" + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "command-exists": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.8.tgz", + "integrity": "sha512-PM54PkseWbiiD/mMsbvW351/u+dafwTJ0ye2qB60G1aGQP9j3xK2gmMDc+R34L3nDtx4qMCitXT75mkbkGJDLw==" + }, + "component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" + }, + "compressible": { + "version": "2.0.17", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.17.tgz", + "integrity": "sha512-BGHeLCK1GV7j1bSmQQAi26X+GgWcTjLr/0tzSvMCl3LH1w1IJ4PFSPoV5316b30cneTziC+B1a+3OjoSUcQYmw==", + "requires": { + "mime-db": ">= 1.40.0 < 2" + } + }, + "compression": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", + "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", + "requires": { + "accepts": "~1.3.5", + "bytes": "3.0.0", + "compressible": "~2.0.16", + "debug": "2.6.9", + "on-headers": "~1.0.2", + "safe-buffer": "5.1.2", + "vary": "~1.1.2" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + } + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "connect": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz", + "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==", + "requires": { + "debug": "2.6.9", + "finalhandler": "1.1.2", + "parseurl": "~1.3.3", + "utils-merge": "1.0.1" + } + }, + "cookiejar": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.2.tgz", + "integrity": "sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA==" + }, + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=" + }, + "copy-to": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/copy-to/-/copy-to-2.0.1.tgz", + "integrity": "sha1-JoD7uAaKSNCGVrYJgJK9r8kG9KU=" + }, + "core-js": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz", + "integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=" + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "cross-spawn": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-4.0.2.tgz", + "integrity": "sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE=", + "requires": { + "lru-cache": "^4.0.1", + "which": "^1.2.9" + } + }, + "crypt": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", + "integrity": "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=" + }, + "css": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz", + "integrity": "sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==", + "requires": { + "inherits": "^2.0.3", + "source-map": "^0.6.1", + "source-map-resolve": "^0.5.2", + "urix": "^0.1.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + } + } + }, + "css-parse": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/css-parse/-/css-parse-1.7.0.tgz", + "integrity": "sha1-Mh9s9zeCpv91ERE5D8BeLGV9jJs=" + }, + "css-select": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", + "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=", + "requires": { + "boolbase": "~1.0.0", + "css-what": "2.1", + "domutils": "1.5.1", + "nth-check": "~1.0.1" + } + }, + "css-what": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz", + "integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==" + }, + "cuid": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/cuid/-/cuid-1.3.8.tgz", + "integrity": "sha1-S4deCWm612T37AcGz0T1+wgx9rc=", + "requires": { + "browser-fingerprint": "0.0.1", + "core-js": "^1.1.1", + "node-fingerprint": "0.0.2" + } + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" + }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=" + }, + "default-user-agent": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/default-user-agent/-/default-user-agent-1.0.0.tgz", + "integrity": "sha1-FsRu/cq6PtxF8k8r1IaLAbfCrcY=", + "requires": { + "os-name": "~1.0.3" + } + }, + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "dependencies": { + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" + }, + "digest-header": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/digest-header/-/digest-header-0.0.1.tgz", + "integrity": "sha1-Ecz23uxXZqw3l0TZAcEsuklRS+Y=", + "requires": { + "utility": "0.1.11" + }, + "dependencies": { + "utility": { + "version": "0.1.11", + "resolved": "https://registry.npmjs.org/utility/-/utility-0.1.11.tgz", + "integrity": "sha1-/eYM+bTkdRlHoM9dEEzik2ciZxU=", + "requires": { + "address": ">=0.0.1" + } + } + } + }, + "dom-serializer": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.1.tgz", + "integrity": "sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA==", + "requires": { + "domelementtype": "^1.3.0", + "entities": "^1.1.1" + } + }, + "domelementtype": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", + "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==" + }, + "domhandler": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", + "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", + "requires": { + "domelementtype": "1" + } + }, + "domutils": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", + "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", + "requires": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + }, + "ejs": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.5.6.tgz", + "integrity": "sha1-R5Y2v6P+Ox3r1SCH8KyyBLTxnIg=" + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" + }, + "entities": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", + "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==" + }, + "es6-promise": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.3.tgz", + "integrity": "sha512-vLf5iali3jKqlJoo6SryDwe3nxCmiueNjbjLWDIpNbAcKnQXAsAdZk+pM17nSYp3AQMbTmAQVCQSeDLfA87SNA==" + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" + }, + "eventemitter3": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-2.0.3.tgz", + "integrity": "sha1-teEHm1n7XhuidxwKmTvgYKWMmbo=" + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "expand-range": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", + "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", + "requires": { + "fill-range": "^2.1.0" + }, + "dependencies": { + "fill-range": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", + "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", + "requires": { + "is-number": "^2.1.0", + "isobject": "^2.0.0", + "randomatic": "^3.0.0", + "repeat-element": "^1.1.2", + "repeat-string": "^1.5.2" + } + }, + "is-number": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", + "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", + "requires": { + "kind-of": "^3.0.2" + } + }, + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "requires": { + "isarray": "1.0.0" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "filename-regex": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", + "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=" + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + } + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=" + }, + "for-own": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", + "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", + "requires": { + "for-in": "^1.0.1" + } + }, + "form-data": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", + "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "formidable": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.1.tgz", + "integrity": "sha512-Fs9VRguL0gqGHkXS5GQiMCr1VhZBxz0JnJs4JmMp/2jL18Fmbzvv7vOFRU+U8TBkHEE/CX1qDXzJplVULgsLeg==" + }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "requires": { + "map-cache": "^0.2.2" + } + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "fsevents": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.9.tgz", + "integrity": "sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw==", + "optional": true, + "requires": { + "nan": "^2.12.1", + "node-pre-gyp": "^0.12.0" + }, + "dependencies": { + "abbrev": { + "version": "1.1.1", + "bundled": true, + "optional": true + }, + "ansi-regex": { + "version": "2.1.1", + "bundled": true + }, + "aproba": { + "version": "1.2.0", + "bundled": true, + "optional": true + }, + "are-we-there-yet": { + "version": "1.1.5", + "bundled": true, + "optional": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "balanced-match": { + "version": "1.0.0", + "bundled": true + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "chownr": { + "version": "1.1.1", + "bundled": true, + "optional": true + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true + }, + "core-util-is": { + "version": "1.0.2", + "bundled": true, + "optional": true + }, + "debug": { + "version": "4.1.1", + "bundled": true, + "optional": true, + "requires": { + "ms": "^2.1.1" + } + }, + "deep-extend": { + "version": "0.6.0", + "bundled": true, + "optional": true + }, + "delegates": { + "version": "1.0.0", + "bundled": true, + "optional": true + }, + "detect-libc": { + "version": "1.0.3", + "bundled": true, + "optional": true + }, + "fs-minipass": { + "version": "1.2.5", + "bundled": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "optional": true + }, + "gauge": { + "version": "2.7.4", + "bundled": true, + "optional": true, + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "glob": { + "version": "7.1.3", + "bundled": true, + "optional": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "has-unicode": { + "version": "2.0.1", + "bundled": true, + "optional": true + }, + "iconv-lite": { + "version": "0.4.24", + "bundled": true, + "optional": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore-walk": { + "version": "3.0.1", + "bundled": true, + "optional": true, + "requires": { + "minimatch": "^3.0.4" + } + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "optional": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "bundled": true + }, + "ini": { + "version": "1.3.5", + "bundled": true, + "optional": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "bundled": true, + "optional": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "bundled": true + }, + "minipass": { + "version": "2.3.5", + "bundled": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.2.1", + "bundled": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.1.1", + "bundled": true, + "optional": true + }, + "needle": { + "version": "2.3.0", + "bundled": true, + "optional": true, + "requires": { + "debug": "^4.1.0", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + } + }, + "node-pre-gyp": { + "version": "0.12.0", + "bundled": true, + "optional": true, + "requires": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.1", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4" + } + }, + "nopt": { + "version": "4.0.1", + "bundled": true, + "optional": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "npm-bundled": { + "version": "1.0.6", + "bundled": true, + "optional": true + }, + "npm-packlist": { + "version": "1.4.1", + "bundled": true, + "optional": true, + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1" + } + }, + "npmlog": { + "version": "4.1.2", + "bundled": true, + "optional": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true, + "optional": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "requires": { + "wrappy": "1" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "optional": true + }, + "os-tmpdir": { + "version": "1.0.2", + "bundled": true, + "optional": true + }, + "osenv": { + "version": "0.1.5", + "bundled": true, + "optional": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "optional": true + }, + "process-nextick-args": { + "version": "2.0.0", + "bundled": true, + "optional": true + }, + "rc": { + "version": "1.2.8", + "bundled": true, + "optional": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "bundled": true, + "optional": true + } + } + }, + "readable-stream": { + "version": "2.3.6", + "bundled": true, + "optional": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "rimraf": { + "version": "2.6.3", + "bundled": true, + "optional": true, + "requires": { + "glob": "^7.1.3" + } + }, + "safe-buffer": { + "version": "5.1.2", + "bundled": true + }, + "safer-buffer": { + "version": "2.1.2", + "bundled": true, + "optional": true + }, + "sax": { + "version": "1.2.4", + "bundled": true, + "optional": true + }, + "semver": { + "version": "5.7.0", + "bundled": true, + "optional": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "optional": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "optional": true + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "optional": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "bundled": true, + "optional": true + }, + "tar": { + "version": "4.4.8", + "bundled": true, + "optional": true, + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.3.4", + "minizlib": "^1.1.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.2" + } + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true, + "optional": true + }, + "wide-align": { + "version": "1.1.3", + "bundled": true, + "optional": true, + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true + }, + "yallist": { + "version": "3.0.3", + "bundled": true + } + } + }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=" + }, + "glob": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", + "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", + "optional": true, + "requires": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-base": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", + "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", + "requires": { + "glob-parent": "^2.0.0", + "is-glob": "^2.0.0" + }, + "dependencies": { + "glob-parent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", + "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "requires": { + "is-glob": "^2.0.0" + } + }, + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=" + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "requires": { + "is-extglob": "^1.0.0" + } + } + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "requires": { + "is-extglob": "^2.1.0" + } + } + } + }, + "graceful-fs": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", + "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==" + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "requires": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "dependencies": { + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "hexo": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/hexo/-/hexo-3.9.0.tgz", + "integrity": "sha512-uga6MsxGlD0AeafiObbFkQVWlUO+wWTb/IJVPI3fFpmAJu0PBD//Ek0qVOxHjlzdvFGeW0bYWYqXgDbR7suJng==", + "requires": { + "abbrev": "^1.1.1", + "archy": "^1.0.0", + "bluebird": "^3.5.2", + "chalk": "^2.4.1", + "cheerio": "0.22.0", + "hexo-cli": "^2.0.0", + "hexo-front-matter": "^0.2.3", + "hexo-fs": "^1.0.0", + "hexo-i18n": "^0.2.1", + "hexo-log": "^0.2.0", + "hexo-util": "^0.6.3", + "js-yaml": "^3.12.0", + "lodash": "^4.17.11", + "minimatch": "^3.0.4", + "moment": "^2.22.2", + "moment-timezone": "^0.5.21", + "nunjucks": "^3.1.3", + "pretty-hrtime": "^1.0.3", + "resolve": "^1.8.1", + "strip-ansi": "^5.0.0", + "strip-indent": "^2.0.0", + "swig-extras": "0.0.1", + "swig-templates": "^2.0.3", + "text-table": "^0.2.0", + "tildify": "^1.2.0", + "titlecase": "^1.1.2", + "warehouse": "^2.2.0" + }, + "dependencies": { + "hexo-cli": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hexo-cli/-/hexo-cli-2.0.0.tgz", + "integrity": "sha512-ZHWh2W35IHaAv9vmcrq+yWjubF26TV+qXoihMnJ3LojWlUCFoMWfEoxJcm0AL709SSuVMpwvUI8la4CpQCOGXQ==", + "requires": { + "abbrev": "^1.1.1", + "acorn": "^6.1.1", + "bluebird": "^3.5.3", + "chalk": "^2.4.2", + "command-exists": "^1.2.8", + "hexo-fs": "^1.0.2", + "hexo-log": "^0.2.0", + "hexo-util": "^0.6.3", + "minimist": "^1.2.0", + "resolve": "^1.10.0", + "tildify": "^1.2.0" + } + } + } + }, + "hexo-bunyan": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hexo-bunyan/-/hexo-bunyan-1.0.0.tgz", + "integrity": "sha512-RymT8Ck+K77mLt9BEYNb4uyfC7RIQnU5N3laXowMrS28jj2h89VHJCOnhV00mmta4fHRqNa07kP1Hrn17nvMkQ==", + "requires": { + "moment": "^2.10.6", + "mv": "~2", + "safe-json-stringify": "~1" + } + }, + "hexo-deployer-git": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hexo-deployer-git/-/hexo-deployer-git-2.0.0.tgz", + "integrity": "sha512-YwEwZNmqYxq7VXM92uyay8HcPF/BqROhfnySnv5Gf5BpH1FXY8Suu9kxjv+8x5np7YRUH8WVyxWprwd4W16kdA==", + "requires": { + "bluebird": "^3.5.0", + "chalk": "^2.4.1", + "hexo-fs": "^2.0.0", + "hexo-util": "^1.0.0", + "moment": "^2.18.0", + "swig-templates": "^2.0.2" + }, + "dependencies": { + "anymatch": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.0.tgz", + "integrity": "sha512-Ozz7l4ixzI7Oxj2+cw+p0tVUt27BpaJ+1+q1TCeANWxHpvyn2+Un+YamBdfKu0uh8xLodGhoa1v7595NhKDAuA==", + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "binary-extensions": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz", + "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==" + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "requires": { + "fill-range": "^7.0.1" + } + }, + "chokidar": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.1.1.tgz", + "integrity": "sha512-df4o16uZmMHzVQwECZRHwfguOt5ixpuQVaZHjYMvYisgKhE+JXwcj/Tcr3+3bu/XeOJQ9ycYmzu7Mv8XrGxJDQ==", + "requires": { + "anymatch": "^3.1.0", + "braces": "^3.0.2", + "fsevents": "^2.0.6", + "glob-parent": "^5.0.0", + "is-binary-path": "^2.1.0", + "is-glob": "^4.0.1", + "normalize-path": "^3.0.0", + "readdirp": "^3.1.1" + } + }, + "cross-spawn": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.0.tgz", + "integrity": "sha512-6U/8SMK2FBNnB21oQ4+6Nsodxanw1gTkntYA2zBdkFYFu3ZDx65P2ONEXGSvob/QS6REjVHQ9zxzdOafwFdstw==", + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==" + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "fsevents": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.0.7.tgz", + "integrity": "sha512-a7YT0SV3RB+DjYcppwVDLtn13UQnmg0SWZS7ezZD0UjnLwXmy8Zm21GMVGLaFGimIqcvyMQaOJBrop8MyOp1kQ==", + "optional": true + }, + "glob-parent": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz", + "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==", + "requires": { + "is-glob": "^4.0.1" + } + }, + "hexo-fs": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hexo-fs/-/hexo-fs-2.0.0.tgz", + "integrity": "sha512-mtwjfh5IZMXVCoITtoV+LfWbrD7xCWyv8OTIrOmwUW4JR+7EEvuwqu+QDztt4RS0azxUuc1sKVK68Mxfp2AoYQ==", + "requires": { + "bluebird": "^3.5.1", + "chokidar": "^3.0.0", + "escape-string-regexp": "^2.0.0", + "graceful-fs": "^4.1.11" + } + }, + "hexo-util": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/hexo-util/-/hexo-util-1.3.1.tgz", + "integrity": "sha512-s/o0BMaU6F/1KqWZO4fvChAk/NbXeTjAKtxgZXqdJrPChpXHWtybKer3qzh7ZYn0Srdb3v1lkrReTXDtivzDoA==", + "requires": { + "bluebird": "^3.5.2", + "camel-case": "^3.0.0", + "cross-spawn": "^7.0.0", + "highlight.js": "^9.13.1", + "html-entities": "^1.2.1", + "striptags": "^3.1.1" + } + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + }, + "readdirp": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.1.2.tgz", + "integrity": "sha512-8rhl0xs2cxfVsqzreYCvs8EwBfn/DhVdqtoLmw19uI3SC5avYX9teCurlErfpPXGmYtMHReGaP2RsLnFvz/lnw==", + "requires": { + "picomatch": "^2.0.4" + } + }, + "striptags": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/striptags/-/striptags-3.1.1.tgz", + "integrity": "sha1-yMPn/db7S7OjKjt1LltePjgJPr0=" + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "requires": { + "is-number": "^7.0.0" + } + } + } + }, + "hexo-douban": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/hexo-douban/-/hexo-douban-1.1.3.tgz", + "integrity": "sha512-XP2jeVOLg2eU55XFO5zoYiJtgcJgObGDGrkcTReVRg6mAYQaJmZW+N7EU17IHeXGAKdalRwrmp1pcP8AIla3Dg==", + "requires": { + "ejs": "2.5.6", + "hexo-fs": "^0.2.2", + "hexo-i18n": "^0.2.1", + "hexo-log": "^0.2.0", + "path": "^0.12.7", + "urllib-sync": "^1.0.1", + "xmldom": "^0.1.27", + "xpath": "^0.0.24" + }, + "dependencies": { + "anymatch": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", + "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", + "requires": { + "micromatch": "^2.1.5", + "normalize-path": "^2.0.0" + } + }, + "arr-diff": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", + "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", + "requires": { + "arr-flatten": "^1.0.1" + } + }, + "array-unique": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", + "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=" + }, + "braces": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", + "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "requires": { + "expand-range": "^1.8.1", + "preserve": "^0.2.0", + "repeat-element": "^1.1.2" + } + }, + "chokidar": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", + "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", + "requires": { + "anymatch": "^1.3.0", + "async-each": "^1.0.0", + "fsevents": "^1.0.0", + "glob-parent": "^2.0.0", + "inherits": "^2.0.1", + "is-binary-path": "^1.0.0", + "is-glob": "^2.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.0.0" + } + }, + "expand-brackets": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", + "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "requires": { + "is-posix-bracket": "^0.1.0" + } + }, + "extglob": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", + "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "requires": { + "is-extglob": "^1.0.0" + } + }, + "glob-parent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", + "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "requires": { + "is-glob": "^2.0.0" + } + }, + "hexo-fs": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/hexo-fs/-/hexo-fs-0.2.3.tgz", + "integrity": "sha512-rLB1rMVUW3csAljvJgHfyjemL0BrmcUZfBf9hJe6S0pA53igFa3ON0PFwomvoLs1Wdmjs9Awnw9Tru4PjWFSlQ==", + "requires": { + "bluebird": "^3.4.0", + "chokidar": "^1.5.2", + "escape-string-regexp": "^1.0.5", + "graceful-fs": "^4.1.4" + } + }, + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=" + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "requires": { + "is-extglob": "^1.0.0" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + }, + "micromatch": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", + "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", + "requires": { + "arr-diff": "^2.0.0", + "array-unique": "^0.2.1", + "braces": "^1.8.2", + "expand-brackets": "^0.1.4", + "extglob": "^0.3.1", + "filename-regex": "^2.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.1", + "kind-of": "^3.0.2", + "normalize-path": "^2.0.1", + "object.omit": "^2.0.0", + "parse-glob": "^3.0.4", + "regex-cache": "^0.4.2" + } + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "requires": { + "remove-trailing-separator": "^1.0.1" + } + } + } + }, + "hexo-front-matter": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/hexo-front-matter/-/hexo-front-matter-0.2.3.tgz", + "integrity": "sha1-x8qO9CDqNr2F6ECKLoyb9J76YF4=", + "requires": { + "js-yaml": "^3.6.1" + } + }, + "hexo-fs": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/hexo-fs/-/hexo-fs-1.0.2.tgz", + "integrity": "sha512-cbDnYuk6IndW/Fr2RcfZsZXE5wlG6tFoeBgZsHY230sSYalvX4JBPOUrE8As7Agysl+NGMthtr/Drtuliy5foQ==", + "requires": { + "bluebird": "^3.5.1", + "chokidar": "^2.0.4", + "escape-string-regexp": "^1.0.5", + "graceful-fs": "^4.1.11" + } + }, + "hexo-generator-archive": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/hexo-generator-archive/-/hexo-generator-archive-0.1.5.tgz", + "integrity": "sha512-jPbMtibqkJnAX3hCwhYhK3r6cqy9OKQsVEScjk7LDok+iPmFmkKCNdU/OccxGe1CWAZpT+ta4+LknwNeHG2G4w==", + "requires": { + "hexo-pagination": "0.0.2", + "object-assign": "^2.0.0" + } + }, + "hexo-generator-category": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/hexo-generator-category/-/hexo-generator-category-0.1.3.tgz", + "integrity": "sha1-uealhiUwqDvdfaTIGcG58+TMtLI=", + "requires": { + "hexo-pagination": "0.0.2", + "object-assign": "^2.0.0" + } + }, + "hexo-generator-feed": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/hexo-generator-feed/-/hexo-generator-feed-1.2.2.tgz", + "integrity": "sha512-4jcvVhFgpEFRJ7A+KhBSfWoQaewRBjcVWEO4OmBgnvaZOm6XwK+b5ZXx/8BpujCLHbjXWzglXhiT7qFFS/nvzw==", + "requires": { + "nunjucks": "^3.0.0", + "object-assign": "^4.1.1" + }, + "dependencies": { + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + } + } + }, + "hexo-generator-index": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/hexo-generator-index/-/hexo-generator-index-0.2.1.tgz", + "integrity": "sha1-kEIin8rHmq9wBXXaGTMr8/fuXF0=", + "requires": { + "hexo-pagination": "0.0.2", + "object-assign": "^4.0.1" + }, + "dependencies": { + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + } + } + }, + "hexo-generator-searchdb": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/hexo-generator-searchdb/-/hexo-generator-searchdb-1.0.8.tgz", + "integrity": "sha1-BCRSVuFBOmYxOTLb8cCn5WhVkwE=", + "requires": { + "ejs": "^1.0.0", + "striptags": "^3.1.1", + "utils-merge": "^1.0.0" + }, + "dependencies": { + "ejs": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-1.0.0.tgz", + "integrity": "sha1-ycYKSKRu5FL7MqccMXuV5aofyz0=" + }, + "striptags": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/striptags/-/striptags-3.1.1.tgz", + "integrity": "sha1-yMPn/db7S7OjKjt1LltePjgJPr0=" + } + } + }, + "hexo-generator-sitemap": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/hexo-generator-sitemap/-/hexo-generator-sitemap-1.2.0.tgz", + "integrity": "sha1-MBj419Hi5Cs/caZacxb/z1g7w/M=", + "requires": { + "minimatch": "^3.0.0", + "nunjucks": "^2.3.0", + "object-assign": "^4.0.1" + }, + "dependencies": { + "anymatch": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", + "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", + "requires": { + "micromatch": "^2.1.5", + "normalize-path": "^2.0.0" + } + }, + "arr-diff": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", + "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", + "requires": { + "arr-flatten": "^1.0.1" + } + }, + "array-unique": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", + "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=" + }, + "braces": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", + "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "requires": { + "expand-range": "^1.8.1", + "preserve": "^0.2.0", + "repeat-element": "^1.1.2" + } + }, + "chokidar": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", + "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", + "requires": { + "anymatch": "^1.3.0", + "async-each": "^1.0.0", + "fsevents": "^1.0.0", + "glob-parent": "^2.0.0", + "inherits": "^2.0.1", + "is-binary-path": "^1.0.0", + "is-glob": "^2.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.0.0" + } + }, + "expand-brackets": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", + "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "requires": { + "is-posix-bracket": "^0.1.0" + } + }, + "extglob": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", + "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "requires": { + "is-extglob": "^1.0.0" + } + }, + "glob-parent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", + "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "requires": { + "is-glob": "^2.0.0" + } + }, + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=" + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "requires": { + "is-extglob": "^1.0.0" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + }, + "micromatch": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", + "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", + "requires": { + "arr-diff": "^2.0.0", + "array-unique": "^0.2.1", + "braces": "^1.8.2", + "expand-brackets": "^0.1.4", + "extglob": "^0.3.1", + "filename-regex": "^2.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.1", + "kind-of": "^3.0.2", + "normalize-path": "^2.0.1", + "object.omit": "^2.0.0", + "parse-glob": "^3.0.4", + "regex-cache": "^0.4.2" + } + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "requires": { + "remove-trailing-separator": "^1.0.1" + } + }, + "nunjucks": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/nunjucks/-/nunjucks-2.5.2.tgz", + "integrity": "sha1-6n00bnhbikh0Zmw8yp4YxXf7oiw=", + "requires": { + "asap": "^2.0.3", + "chokidar": "^1.6.0", + "yargs": "^3.32.0" + } + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + } + } + }, + "hexo-generator-tag": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/hexo-generator-tag/-/hexo-generator-tag-0.2.0.tgz", + "integrity": "sha1-xXFYRrtB5X2cIMHWbX2yGhq/emI=", + "requires": { + "hexo-pagination": "0.0.2", + "object-assign": "^4.0.1" + }, + "dependencies": { + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + } + } + }, + "hexo-i18n": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/hexo-i18n/-/hexo-i18n-0.2.1.tgz", + "integrity": "sha1-hPFBQyvwnYtVjth4xygWS20c1t4=", + "requires": { + "sprintf-js": "^1.0.2" + } + }, + "hexo-leancloud-counter-security": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/hexo-leancloud-counter-security/-/hexo-leancloud-counter-security-1.4.1.tgz", + "integrity": "sha512-O6r1aRhpLlwdLDGT/vj0yTh+LBPp5cqFImKVRl0dz895DwvgYFej0zReU9l2TtP58akXJt0z1C/sIJF8uN3NYQ==", + "requires": { + "leancloud-storage": "^3.15.0", + "readline-sync": "^1.4.10" + } + }, + "hexo-log": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/hexo-log/-/hexo-log-0.2.0.tgz", + "integrity": "sha512-fzoc+GQexxPPILTjoOQILnA3ZG2MFgqMBVel4xvJ11pXptw9+f97ynTgDAExXafyp9Nz2ChXRuqlCYgPtZSlxQ==", + "requires": { + "chalk": "^1.1.1", + "hexo-bunyan": "^1.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + } + } + }, + "hexo-pagination": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/hexo-pagination/-/hexo-pagination-0.0.2.tgz", + "integrity": "sha1-jPRwx9sN5bGKOSanbesZQBXffys=", + "requires": { + "utils-merge": "^1.0.0" + } + }, + "hexo-renderer-ejs": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/hexo-renderer-ejs/-/hexo-renderer-ejs-0.3.1.tgz", + "integrity": "sha512-XN8pYJU+Wr3dT8ipqEPRlOBySJpd1C5NUBBzgZpVSVBC/6L36O0YZI/Qd5NxQqwfGfSuKQ8N5iMyjmRXSR1MdA==", + "requires": { + "ejs": "^2.3.4", + "object-assign": "^4.0.1" + }, + "dependencies": { + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + } + } + }, + "hexo-renderer-markdown-it": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/hexo-renderer-markdown-it/-/hexo-renderer-markdown-it-3.4.1.tgz", + "integrity": "sha1-1AmkTJssGzMe0ubzdJAfmFznIxw=", + "requires": { + "lodash.assign": "^3.2.0", + "markdown-it": "^5.0.1", + "markdown-it-abbr": "^1.0.0", + "markdown-it-footnote": "^2.0.0", + "markdown-it-ins": "^2.0.0", + "markdown-it-sub": "^1.0.0", + "markdown-it-sup": "^1.0.0", + "sluggo": "^0.2.0" + } + }, + "hexo-renderer-stylus": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/hexo-renderer-stylus/-/hexo-renderer-stylus-0.3.3.tgz", + "integrity": "sha1-xU6ifh/Y48ipp6hM+6itNUEiyn8=", + "requires": { + "nib": "^1.1.2", + "stylus": "^0.54.5" + } + }, + "hexo-server": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/hexo-server/-/hexo-server-0.3.3.tgz", + "integrity": "sha512-70zQaf4Z+bj37Kvq7tEyn9WHH+Xj7uqbvOlGp8pHaOzWLp/riX3rMq3nnQKA2P8dKkBaM0/72IqjJPWu2Zt2WA==", + "requires": { + "bluebird": "^3.5.1", + "chalk": "^1.1.3", + "compression": "^1.7.3", + "connect": "^3.6.6", + "mime": "^1.6.0", + "morgan": "^1.9.0", + "object-assign": "^4.1.1", + "opn": "^5.3.0", + "serve-static": "^1.13.2" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + } + } + }, + "hexo-symbols-count-time": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/hexo-symbols-count-time/-/hexo-symbols-count-time-0.6.1.tgz", + "integrity": "sha512-DEkVmprZMlqVCU9fCgBgwFFBqDZ+HaF/Skcg/K8pfqgaNC0oT2eqw3slM6nTSoUGvYYjckgKoWXs7cEAlbvM1w==" + }, + "hexo-util": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/hexo-util/-/hexo-util-0.6.3.tgz", + "integrity": "sha512-zPxaqCWZz3/25SAB4FlrRtWktJ+Pr+vBiv/nyHpXKgXPt1m70liViKlRwWLqDmRjJ72x6/k4qCEeXHajvcGHUw==", + "requires": { + "bluebird": "^3.4.0", + "camel-case": "^3.0.0", + "cross-spawn": "^4.0.0", + "highlight.js": "^9.4.0", + "html-entities": "^1.2.0", + "striptags": "^2.1.1" + } + }, + "highlight.js": { + "version": "9.15.10", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-9.15.10.tgz", + "integrity": "sha512-RoV7OkQm0T3os3Dd2VHLNMoaoDVx77Wygln3n9l5YV172XonWG6rgQD3XnF/BuFFZw9A0TJgmMSO8FEWQgvcXw==" + }, + "html-entities": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.2.1.tgz", + "integrity": "sha1-DfKTUfByEWNRXfueVUPl9u7VFi8=" + }, + "htmlparser2": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", + "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", + "requires": { + "domelementtype": "^1.3.1", + "domhandler": "^2.3.0", + "domutils": "^1.5.1", + "entities": "^1.1.1", + "inherits": "^2.0.1", + "readable-stream": "^3.1.1" + } + }, + "http-errors": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz", + "integrity": "sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + } + }, + "humanize-ms": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", + "integrity": "sha1-xG4xWaKT9riW2ikxbYtv6Lt5u+0=", + "requires": { + "ms": "^2.0.0" + } + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "invert-kv": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", + "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=" + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "requires": { + "binary-extensions": "^1.0.0" + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" + } + } + }, + "is-dotfile": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", + "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=" + }, + "is-equal-shallow": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", + "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", + "requires": { + "is-primitive": "^2.0.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=" + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "requires": { + "isobject": "^3.0.1" + } + }, + "is-posix-bracket": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", + "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=" + }, + "is-primitive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", + "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=" + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==" + }, + "is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=" + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + }, + "javascript-state-machine": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/javascript-state-machine/-/javascript-state-machine-2.4.0.tgz", + "integrity": "sha1-2L4x7DjySsGhgy8LZy/DzV95yW4=" + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=" + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" + }, + "lazy-cache": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", + "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=" + }, + "lcid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", + "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", + "requires": { + "invert-kv": "^1.0.0" + } + }, + "leancloud-realtime": { + "version": "5.0.0-alpha.3", + "resolved": "https://registry.npmjs.org/leancloud-realtime/-/leancloud-realtime-5.0.0-alpha.3.tgz", + "integrity": "sha512-sADjDJ6NSAV/cDgCkn5cmsvBCJt3p1jcbI8QNI16iQ83QqXCmRYjb/QzY9LH0VWoFisE+GmhMFoXOWkP7mCeAw==", + "requires": { + "@babel/runtime": "^7.0.0", + "base64-arraybuffer": "^0.1.5", + "debug": "^3.1.0", + "eventemitter3": "^3.0.0", + "javascript-state-machine": "^2.3.5", + "lodash": "^4.17.10", + "protobufjs": "^5.0.1", + "superagent": "^4.1.0", + "uuid": "^3.0.0", + "ws": "^5.2.1" + }, + "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "requires": { + "ms": "^2.1.1" + } + }, + "eventemitter3": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", + "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==" + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "superagent": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/superagent/-/superagent-4.1.0.tgz", + "integrity": "sha512-FT3QLMasz0YyCd4uIi5HNe+3t/onxMyEho7C3PSqmti3Twgy2rXT4fmkTz6wRL6bTF4uzPcfkUCa8u4JWHw8Ag==", + "requires": { + "component-emitter": "^1.2.0", + "cookiejar": "^2.1.2", + "debug": "^4.1.0", + "form-data": "^2.3.3", + "formidable": "^1.2.0", + "methods": "^1.1.1", + "mime": "^2.4.0", + "qs": "^6.6.0", + "readable-stream": "^3.0.6" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + } + } + } + } + }, + "leancloud-realtime-plugin-live-query": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/leancloud-realtime-plugin-live-query/-/leancloud-realtime-plugin-live-query-1.2.0.tgz", + "integrity": "sha512-eJooIH8/FyUoozr3Eeby2DpDnmX39m1bfxfxlYPuojkio+i/DLwPD+aTHnRDH6QXJcT6tNTt85RcxVR/Txg98Q==" + }, + "leancloud-storage": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/leancloud-storage/-/leancloud-storage-3.15.0.tgz", + "integrity": "sha512-UbR6pLA0tVYPcY7AND0pey45iFsB2PkIo8Wz0DZ9BabKyqndA1ey2LKzYpFDGNh3ODrmT3fValVn9yY4bgf9Uw==", + "requires": { + "debug": "^3.1.0", + "es6-promise": "4.2.3", + "eventemitter3": "^2.0.3", + "leancloud-realtime": "^5.0.0-alpha.3", + "leancloud-realtime-plugin-live-query": "^1.2.0", + "localstorage-memory": "^1.0.1", + "md5": "^2.0.0", + "superagent": "^3.3.1", + "underscore": "^1.8.3", + "uuid": "^3.3.2" + }, + "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, + "linkify-it": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-1.2.4.tgz", + "integrity": "sha1-B3NSbDF8j9E71TTuHRgP+Iq/iBo=", + "requires": { + "uc.micro": "^1.0.1" + } + }, + "localstorage-memory": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/localstorage-memory/-/localstorage-memory-1.0.3.tgz", + "integrity": "sha512-t9P8WB6DcVttbw/W4PIE8HOqum8Qlvx5SjR6oInwR9Uia0EEmyUeBh7S+weKByW+l/f45Bj4L/dgZikGFDM6ng==" + }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" + }, + "lodash._baseassign": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz", + "integrity": "sha1-jDigmVAPIVrQnlnxci/QxSv+Ck4=", + "requires": { + "lodash._basecopy": "^3.0.0", + "lodash.keys": "^3.0.0" + } + }, + "lodash._basecopy": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz", + "integrity": "sha1-jaDmqHbPNEwK2KVIghEd08XHyjY=" + }, + "lodash._bindcallback": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._bindcallback/-/lodash._bindcallback-3.0.1.tgz", + "integrity": "sha1-5THCdkTPi1epnhftlbNcdIeJOS4=" + }, + "lodash._createassigner": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/lodash._createassigner/-/lodash._createassigner-3.1.1.tgz", + "integrity": "sha1-g4pbri/aymOsIt7o4Z+k5taXCxE=", + "requires": { + "lodash._bindcallback": "^3.0.0", + "lodash._isiterateecall": "^3.0.0", + "lodash.restparam": "^3.0.0" + } + }, + "lodash._getnative": { + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", + "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=" + }, + "lodash._isiterateecall": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz", + "integrity": "sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw=" + }, + "lodash.assign": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-3.2.0.tgz", + "integrity": "sha1-POnwI0tLIiPilrj6CsH+6OvKZPo=", + "requires": { + "lodash._baseassign": "^3.0.0", + "lodash._createassigner": "^3.0.0", + "lodash.keys": "^3.0.0" + } + }, + "lodash.assignin": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.assignin/-/lodash.assignin-4.2.0.tgz", + "integrity": "sha1-uo31+4QesKPoBEIysOJjqNxqKKI=" + }, + "lodash.bind": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/lodash.bind/-/lodash.bind-4.2.1.tgz", + "integrity": "sha1-euMBfpOWIqwxt9fX3LGzTbFpDTU=" + }, + "lodash.defaults": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", + "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=" + }, + "lodash.filter": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.filter/-/lodash.filter-4.6.0.tgz", + "integrity": "sha1-ZosdSYFgOuHMWm+nYBQ+SAtMSs4=" + }, + "lodash.flatten": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", + "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=" + }, + "lodash.foreach": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.foreach/-/lodash.foreach-4.5.0.tgz", + "integrity": "sha1-Gmo16s5AEoDH8G3d7DUWWrJ+PlM=" + }, + "lodash.isarguments": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", + "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=" + }, + "lodash.isarray": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz", + "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=" + }, + "lodash.keys": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", + "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=", + "requires": { + "lodash._getnative": "^3.0.0", + "lodash.isarguments": "^3.0.0", + "lodash.isarray": "^3.0.0" + } + }, + "lodash.map": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.map/-/lodash.map-4.6.0.tgz", + "integrity": "sha1-dx7Hg540c9nEzeKLGTlMNWL09tM=" + }, + "lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" + }, + "lodash.pick": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz", + "integrity": "sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM=" + }, + "lodash.reduce": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.reduce/-/lodash.reduce-4.6.0.tgz", + "integrity": "sha1-8atrg5KZrUj3hKu/R2WW8DuRTTs=" + }, + "lodash.reject": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.reject/-/lodash.reject-4.6.0.tgz", + "integrity": "sha1-gNZJLcFHCGS79YNTO2UfQqn1JBU=" + }, + "lodash.restparam": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/lodash.restparam/-/lodash.restparam-3.6.1.tgz", + "integrity": "sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU=" + }, + "lodash.some": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.some/-/lodash.some-4.6.0.tgz", + "integrity": "sha1-G7nzFO9ri63tE7VJFpsqlF62jk0=" + }, + "long": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/long/-/long-3.2.0.tgz", + "integrity": "sha1-2CG3E4yhy1gcFymQ7xTbIAtcR0s=" + }, + "longest": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", + "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=" + }, + "lower-case": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz", + "integrity": "sha1-miyr0bno4K6ZOkv31YdcOcQujqw=" + }, + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=" + }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "requires": { + "object-visit": "^1.0.0" + } + }, + "markdown": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/markdown/-/markdown-0.5.0.tgz", + "integrity": "sha1-KCBbVlqK51kt4gdGPWY33BgnIrI=", + "requires": { + "nopt": "~2.1.1" + } + }, + "markdown-it": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-5.1.0.tgz", + "integrity": "sha1-JShrhGW6xJbz8bd+7VRGQ+m9cY0=", + "requires": { + "argparse": "~1.0.3", + "entities": "~1.1.1", + "linkify-it": "~1.2.0", + "mdurl": "~1.0.1", + "uc.micro": "^1.0.0" + } + }, + "markdown-it-abbr": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/markdown-it-abbr/-/markdown-it-abbr-1.0.4.tgz", + "integrity": "sha1-1mtTZFIcuz3Yqlna37ovtoZcj9g=" + }, + "markdown-it-footnote": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/markdown-it-footnote/-/markdown-it-footnote-2.0.0.tgz", + "integrity": "sha1-FOnE9o/xLPNU+jZa43gnboEEypQ=" + }, + "markdown-it-ins": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/markdown-it-ins/-/markdown-it-ins-2.0.0.tgz", + "integrity": "sha1-papqMPHi9x6Ul1Z8/f9A8f3mdIM=" + }, + "markdown-it-sub": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/markdown-it-sub/-/markdown-it-sub-1.0.0.tgz", + "integrity": "sha1-N1/WAm6ufdywEkl/ZBEZXqHjr+g=" + }, + "markdown-it-sup": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/markdown-it-sup/-/markdown-it-sup-1.0.0.tgz", + "integrity": "sha1-y5yf+RpSVawI8/09YyhuFd8KH8M=" + }, + "math-random": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz", + "integrity": "sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==" + }, + "md5": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/md5/-/md5-2.2.1.tgz", + "integrity": "sha1-U6s41f48iJG6RlMp6iP6wFQBJvk=", + "requires": { + "charenc": "~0.0.1", + "crypt": "~0.0.1", + "is-buffer": "~1.1.1" + } + }, + "mdurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", + "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=" + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "mime": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz", + "integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==" + }, + "mime-db": { + "version": "1.40.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", + "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==" + }, + "mime-types": { + "version": "2.1.24", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", + "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", + "requires": { + "mime-db": "1.40.0" + } + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + }, + "mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "requires": { + "minimist": "0.0.8" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + } + } + }, + "moment": { + "version": "2.24.0", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", + "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==" + }, + "moment-timezone": { + "version": "0.5.26", + "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.26.tgz", + "integrity": "sha512-sFP4cgEKTCymBBKgoxZjYzlSovC20Y6J7y3nanDc5RoBIXKlZhoYwBoZGe3flwU6A372AcRwScH8KiwV6zjy1g==", + "requires": { + "moment": ">= 2.9.0" + } + }, + "morgan": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.9.1.tgz", + "integrity": "sha512-HQStPIV4y3afTiCYVxirakhlCfGkI161c76kKFca7Fk1JusM//Qeo1ej2XaMniiNeaZklMVrh3vTtIzpzwbpmA==", + "requires": { + "basic-auth": "~2.0.0", + "debug": "2.6.9", + "depd": "~1.1.2", + "on-finished": "~2.3.0", + "on-headers": "~1.0.1" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "mv": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", + "integrity": "sha1-rmzg1vbV4KT32JN5jQPB6pVZtqI=", + "optional": true, + "requires": { + "mkdirp": "~0.5.1", + "ncp": "~2.0.0", + "rimraf": "~2.4.0" + } + }, + "nan": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", + "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==", + "optional": true + }, + "nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + } + }, + "ncp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", + "integrity": "sha1-GVoh1sRuNh0vsSgbo4uR6d9727M=", + "optional": true + }, + "negotiator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" + }, + "nib": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/nib/-/nib-1.1.2.tgz", + "integrity": "sha1-amnt5AgblcDe+L4CSkyK4MLLtsc=", + "requires": { + "stylus": "0.54.5" + }, + "dependencies": { + "glob": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.0.6.tgz", + "integrity": "sha1-IRuvr0nlJbjNkyYNFKsTYVKz9Xo=", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.2", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "source-map": { + "version": "0.1.43", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz", + "integrity": "sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=", + "requires": { + "amdefine": ">=0.0.4" + } + }, + "stylus": { + "version": "0.54.5", + "resolved": "https://registry.npmjs.org/stylus/-/stylus-0.54.5.tgz", + "integrity": "sha1-QrlWCTHKcJDOhRWnmLqeaqPW3Hk=", + "requires": { + "css-parse": "1.7.x", + "debug": "*", + "glob": "7.0.x", + "mkdirp": "0.5.x", + "sax": "0.5.x", + "source-map": "0.1.x" + } + } + } + }, + "no-case": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz", + "integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==", + "requires": { + "lower-case": "^1.1.1" + } + }, + "node-fingerprint": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/node-fingerprint/-/node-fingerprint-0.0.2.tgz", + "integrity": "sha1-Mcur63GmeufdWn3AQuUcPHWGhQE=" + }, + "nopt": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-2.1.2.tgz", + "integrity": "sha1-bMzZd7gBMqB3MdbozljCyDA8+a8=", + "requires": { + "abbrev": "1" + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" + }, + "nth-check": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", + "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", + "requires": { + "boolbase": "~1.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" + }, + "nunjucks": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/nunjucks/-/nunjucks-3.2.0.tgz", + "integrity": "sha512-YS/qEQ6N7qCnUdm6EoYRBfJUdWNT0PpKbbRnogV2XyXbBm2STIP1O6yrdZHgwMVK7fIYUx7i8+yatEixnXSB1w==", + "requires": { + "a-sync-waterfall": "^1.0.0", + "asap": "^2.0.3", + "chokidar": "^2.0.0", + "yargs": "^3.32.0" + } + }, + "object-assign": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-2.1.1.tgz", + "integrity": "sha1-Q8NuXVaf+OSBbE76i+AtJpZ8GKo=" + }, + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "requires": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "requires": { + "isobject": "^3.0.0" + } + }, + "object.omit": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", + "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", + "requires": { + "for-own": "^0.1.4", + "is-extendable": "^0.1.1" + } + }, + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "requires": { + "isobject": "^3.0.1" + } + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "requires": { + "ee-first": "1.1.1" + } + }, + "on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==" + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "opn": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz", + "integrity": "sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA==", + "requires": { + "is-wsl": "^1.1.0" + } + }, + "optimist": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", + "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", + "requires": { + "minimist": "~0.0.1", + "wordwrap": "~0.0.2" + }, + "dependencies": { + "minimist": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", + "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=" + } + } + }, + "optjs": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/optjs/-/optjs-3.2.2.tgz", + "integrity": "sha1-aabOicRCpEQDFBrS+bNwvVu29O4=" + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" + }, + "os-locale": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", + "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", + "requires": { + "lcid": "^1.0.0" + } + }, + "os-name": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/os-name/-/os-name-1.0.3.tgz", + "integrity": "sha1-GzefZINa98Wn9JizV8uVIVwVnt8=", + "requires": { + "osx-release": "^1.0.0", + "win-release": "^1.0.0" + } + }, + "osx-release": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/osx-release/-/osx-release-1.1.0.tgz", + "integrity": "sha1-8heRGigTaUmvG/kwiyQeJzfTzWw=", + "requires": { + "minimist": "^1.1.0" + } + }, + "parse-glob": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", + "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", + "requires": { + "glob-base": "^0.3.0", + "is-dotfile": "^1.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.0" + }, + "dependencies": { + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=" + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "requires": { + "is-extglob": "^1.0.0" + } + } + } + }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" + }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=" + }, + "path": { + "version": "0.12.7", + "resolved": "https://registry.npmjs.org/path/-/path-0.12.7.tgz", + "integrity": "sha1-1NwqUGxM4hl+tIHr/NWzbAFAsQ8=", + "requires": { + "process": "^0.11.1", + "util": "^0.10.3" + } + }, + "path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=" + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "path-key": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.0.tgz", + "integrity": "sha512-8cChqz0RP6SHJkMt48FW0A7+qUOn+OsnOsVtzI59tZ8m+5bCSk7hzwET0pulwOM2YMn9J1efb07KB9l9f30SGg==" + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" + }, + "picomatch": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.0.7.tgz", + "integrity": "sha512-oLHIdio3tZ0qH76NybpeneBhYVj0QFTfXEFTc/B3zKQspYfYYkWYgFsmzo+4kvId/bQRcNkVeguI3y+CD22BtA==" + }, + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=" + }, + "preserve": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", + "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=" + }, + "pretty-hrtime": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", + "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=" + }, + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=" + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "protobufjs": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-5.0.3.tgz", + "integrity": "sha512-55Kcx1MhPZX0zTbVosMQEO5R6/rikNXd9b6RQK4KSPcrSIIwoXTtebIczUrXlwaSrbz4x8XUVThGPob1n8I4QA==", + "requires": { + "ascli": "~1", + "bytebuffer": "~5", + "glob": "^7.0.5", + "yargs": "^3.10.0" + }, + "dependencies": { + "glob": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", + "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + } + } + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" + }, + "qs": { + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.0.tgz", + "integrity": "sha512-27RP4UotQORTpmNQDX8BHPukOnBP3p1uUJY5UnDhaJB+rMt9iMsok724XL+UHU23bEFOHRMQ2ZhI99qOWUMGFA==" + }, + "randomatic": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz", + "integrity": "sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==", + "requires": { + "is-number": "^4.0.0", + "kind-of": "^6.0.0", + "math-random": "^1.0.1" + }, + "dependencies": { + "is-number": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", + "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==" + } + } + }, + "range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" + }, + "readable-stream": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", + "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "requires": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "readline-sync": { + "version": "1.4.10", + "resolved": "https://registry.npmjs.org/readline-sync/-/readline-sync-1.4.10.tgz", + "integrity": "sha512-gNva8/6UAe8QYepIQH/jQ2qn91Qj0B9sYjMBBs3QOB8F2CXcKgLxQaJRP76sWVRQt+QU+8fAkCbCvjjMFu7Ycw==" + }, + "regenerator-runtime": { + "version": "0.13.3", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz", + "integrity": "sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw==" + }, + "regex-cache": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", + "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", + "requires": { + "is-equal-shallow": "^0.1.3" + } + }, + "regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "requires": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + } + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=" + }, + "repeat-element": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==" + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" + }, + "resolve": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz", + "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==", + "requires": { + "path-parse": "^1.0.6" + } + }, + "resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=" + }, + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==" + }, + "right-align": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", + "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", + "requires": { + "align-text": "^0.1.1" + } + }, + "rimraf": { + "version": "2.4.5", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz", + "integrity": "sha1-7nEM5dk6j9uFb7Xqj/Di11k0sto=", + "optional": true, + "requires": { + "glob": "^6.0.1" + } + }, + "safe-buffer": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", + "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==" + }, + "safe-json-stringify": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/safe-json-stringify/-/safe-json-stringify-1.2.0.tgz", + "integrity": "sha512-gH8eh2nZudPQO6TytOvbxnuhYBOvDBBLW52tz5q6X58lJcd/tkmqFR+5Z9adS8aJtURSXWThWy/xJtJwixErvg==", + "optional": true + }, + "safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "requires": { + "ret": "~0.1.10" + } + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "sax": { + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/sax/-/sax-0.5.8.tgz", + "integrity": "sha1-1HLbIo6zMcJQaw6MFVJK25OdEsE=" + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + }, + "send": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", + "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", + "requires": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.7.2", + "mime": "1.6.0", + "ms": "2.1.1", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" + }, + "dependencies": { + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" + } + } + }, + "serve-static": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", + "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.1" + } + }, + "set-value": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" + }, + "sluggo": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/sluggo/-/sluggo-0.2.0.tgz", + "integrity": "sha1-XQvLKNcMjB7udz/uxibRUYlonL8=" + }, + "snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "requires": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "requires": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "requires": { + "kind-of": "^3.2.0" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "source-map-resolve": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", + "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", + "requires": { + "atob": "^2.1.1", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "source-map-url": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=" + }, + "split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "requires": { + "extend-shallow": "^3.0.0" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "requires": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + }, + "dependencies": { + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + } + } + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "requires": { + "safe-buffer": "~5.2.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "requires": { + "ansi-regex": "^4.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + } + } + }, + "strip-indent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz", + "integrity": "sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g=" + }, + "striptags": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/striptags/-/striptags-2.2.1.tgz", + "integrity": "sha1-TEULcI1BuL85zyTEn/I0/Gqr/TI=" + }, + "stylus": { + "version": "0.54.7", + "resolved": "https://registry.npmjs.org/stylus/-/stylus-0.54.7.tgz", + "integrity": "sha512-Yw3WMTzVwevT6ZTrLCYNHAFmanMxdylelL3hkWNgPMeTCpMwpV3nXjpOHuBXtFv7aiO2xRuQS6OoAdgkNcSNug==", + "requires": { + "css-parse": "~2.0.0", + "debug": "~3.1.0", + "glob": "^7.1.3", + "mkdirp": "~0.5.x", + "safer-buffer": "^2.1.2", + "sax": "~1.2.4", + "semver": "^6.0.0", + "source-map": "^0.7.3" + }, + "dependencies": { + "css-parse": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/css-parse/-/css-parse-2.0.0.tgz", + "integrity": "sha1-pGjuZnwW2BzPBcWMONKpfHgNv9Q=", + "requires": { + "css": "^2.0.0" + } + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, + "glob": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", + "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + }, + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==" + } + } + }, + "superagent": { + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/superagent/-/superagent-3.8.3.tgz", + "integrity": "sha512-GLQtLMCoEIK4eDv6OGtkOoSMt3D+oq0y3dsxMuYuDvaNUvuT8eFBuLmfR0iYYzHC1e8hpzC6ZsxbuP6DIalMFA==", + "requires": { + "component-emitter": "^1.2.0", + "cookiejar": "^2.1.0", + "debug": "^3.1.0", + "extend": "^3.0.0", + "form-data": "^2.3.1", + "formidable": "^1.2.0", + "methods": "^1.1.1", + "mime": "^1.4.1", + "qs": "^6.5.1", + "readable-stream": "^2.3.5" + }, + "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "requires": { + "ms": "^2.1.1" + } + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + }, + "swig-extras": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/swig-extras/-/swig-extras-0.0.1.tgz", + "integrity": "sha1-tQP+3jcqucJMasaMr2VrzvGHIyg=", + "requires": { + "markdown": "~0.5.0" + } + }, + "swig-templates": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/swig-templates/-/swig-templates-2.0.3.tgz", + "integrity": "sha512-QojPTuZWdpznSZWZDB63/grsZuDwT/7geMeGlftbJXDoYBIZEnTcKvz4iwYDv3SwfPX9/B4RtGRSXNnm3S2wwg==", + "requires": { + "optimist": "~0.6", + "uglify-js": "2.6.0" + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=" + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + }, + "tildify": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/tildify/-/tildify-1.2.0.tgz", + "integrity": "sha1-3OwD9V3Km3qj5bBPIYF+tW5jWIo=", + "requires": { + "os-homedir": "^1.0.0" + } + }, + "titlecase": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/titlecase/-/titlecase-1.1.3.tgz", + "integrity": "sha512-pQX4oiemzjBEELPqgK4WE+q0yhAqjp/yzusGtlSJsOuiDys0RQxggepYmo0BuegIDppYS3b3cpdegRwkpyN3hw==" + }, + "to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "requires": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + }, + "toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" + }, + "uc.micro": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", + "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==" + }, + "uglify-js": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.6.0.tgz", + "integrity": "sha1-JeqhzDVQ45QQzu+v0c+7a20V8AE=", + "requires": { + "async": "~0.2.6", + "source-map": "~0.5.1", + "uglify-to-browserify": "~1.0.0", + "yargs": "~3.10.0" + }, + "dependencies": { + "camelcase": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", + "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=" + }, + "cliui": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", + "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", + "requires": { + "center-align": "^0.1.1", + "right-align": "^0.1.1", + "wordwrap": "0.0.2" + } + }, + "window-size": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", + "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=" + }, + "wordwrap": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", + "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=" + }, + "yargs": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", + "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", + "requires": { + "camelcase": "^1.0.2", + "cliui": "^2.1.0", + "decamelize": "^1.0.0", + "window-size": "0.1.0" + } + } + } + }, + "uglify-to-browserify": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", + "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=" + }, + "underscore": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz", + "integrity": "sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==" + }, + "union-value": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + } + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + }, + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "requires": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "requires": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=" + } + } + }, + "upath": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", + "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==" + }, + "upper-case": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz", + "integrity": "sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg=" + }, + "urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=" + }, + "urllib": { + "version": "2.11.1", + "resolved": "https://registry.npmjs.org/urllib/-/urllib-2.11.1.tgz", + "integrity": "sha1-5F1Xnxu+Qsn64hzf9yVo88jIyUU=", + "requires": { + "any-promise": "^1.2.0", + "debug": "^2.2.0", + "default-user-agent": "^1.0.0", + "digest-header": "^0.0.1", + "humanize-ms": "^1.2.0", + "iconv-lite": "^0.4.13", + "media-typer": "^0.3.0", + "statuses": "^1.3.0" + } + }, + "urllib-sync": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/urllib-sync/-/urllib-sync-1.1.4.tgz", + "integrity": "sha1-yRMI9JkaZe5iDWc85g/dJLvRjMo=", + "requires": { + "urllib": "~2.11.0", + "utility": "~1.7.1" + } + }, + "use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==" + }, + "util": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz", + "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==", + "requires": { + "inherits": "2.0.3" + }, + "dependencies": { + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + } + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "utility": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/utility/-/utility-1.7.1.tgz", + "integrity": "sha1-+3TN3IFqQRJ2ym6MqZMkfyPusKc=", + "requires": { + "copy-to": "~2.0.1", + "escape-html": "~1.0.3" + } + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" + }, + "uuid": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.3.tgz", + "integrity": "sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ==" + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" + }, + "warehouse": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/warehouse/-/warehouse-2.2.0.tgz", + "integrity": "sha1-XQnWSUKZK+Zn2PfIagnCuK6gQGI=", + "requires": { + "JSONStream": "^1.0.7", + "bluebird": "^3.2.2", + "cuid": "~1.3.8", + "graceful-fs": "^4.1.3", + "is-plain-object": "^2.0.1", + "lodash": "^4.2.1" + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "requires": { + "isexe": "^2.0.0" + } + }, + "win-release": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/win-release/-/win-release-1.1.1.tgz", + "integrity": "sha1-X6VeAr58qTTt/BJmVjLoSbcuUgk=", + "requires": { + "semver": "^5.0.1" + } + }, + "window-size": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.4.tgz", + "integrity": "sha1-+OGqHuWlPsW/FR/6CXQqatdpeHY=" + }, + "wordwrap": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", + "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=" + }, + "wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + }, + "dependencies": { + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "ws": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz", + "integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==", + "requires": { + "async-limiter": "~1.0.0" + } + }, + "xmldom": { + "version": "0.1.27", + "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.27.tgz", + "integrity": "sha1-1QH5ezvbQDr4757MIFcxh6rawOk=" + }, + "xpath": { + "version": "0.0.24", + "resolved": "https://registry.npmjs.org/xpath/-/xpath-0.0.24.tgz", + "integrity": "sha1-Gt4WLhzFI8jTn8fQavwW6iFvKfs=" + }, + "y18n": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", + "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=" + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" + }, + "yargs": { + "version": "3.32.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.32.0.tgz", + "integrity": "sha1-AwiOnr+edWtpdRYR0qXvWRSCyZU=", + "requires": { + "camelcase": "^2.0.1", + "cliui": "^3.0.3", + "decamelize": "^1.1.1", + "os-locale": "^1.4.0", + "string-width": "^1.0.1", + "window-size": "^0.1.4", + "y18n": "^3.2.0" + } + } + } +} diff --git a/package.json b/package.json index 3716f964a..6982b61cb 100644 --- a/package.json +++ b/package.json @@ -1,39 +1,27 @@ { - "name": "hexo-theme-next", - "version": "7.4.1", - "description": "Elegant and powerful theme for Hexo", - "main": "gulpfile.js", - "scripts": { - "test": "gulp", - "contributors:add": "all-contributors add", - "contributors:generate": "all-contributors generate" + "name": "hexo-site", + "version": "0.0.0", + "private": true, + "hexo": { + "version": "3.9.0" }, - "repository": { - "type": "git", - "url": "git+https://github.com/theme-next/hexo-theme-next.git" - }, - "keywords": [ - "hexo", - "theme", - "next" - ], - "author": "NexT (https://theme-next.org)", - "license": "AGPL", - "bugs": { - "url": "https://github.com/theme-next/hexo-theme-next/issues" - }, - "homepage": "https://theme-next.org", - "devDependencies": { - "all-contributors-cli": "^6.9.1", - "eslint": "^6.5.1", - "eslint-config-theme-next": "^1.1.3", - "gulp": "^4.0.2", - "gulp-eslint": "^6.0.0", - "gulp-shell": "^0.7.1", - "js-yaml": "^3.13.1", - "stylint": "^2.0.0" - }, - "engines": { - "node": ">=8.6.0" + "dependencies": { + "hexo": "^3.9.0", + "hexo-deployer-git": "^2.0.0", + "hexo-douban": "^1.1.3", + "hexo-generator-archive": "^0.1.5", + "hexo-generator-category": "^0.1.3", + "hexo-generator-feed": "^1.2.2", + "hexo-generator-index": "^0.2.1", + "hexo-generator-searchdb": "^1.0.8", + "hexo-generator-sitemap": "^1.2.0", + "hexo-generator-tag": "^0.2.0", + "hexo-leancloud-counter-security": "^1.4.1", + "hexo-renderer-ejs": "^0.3.1", + "hexo-renderer-markdown-it": "^3.4.1", + "hexo-renderer-stylus": "^0.3.3", + "hexo-server": "^0.3.3", + "hexo-symbols-count-time": "^0.6.1", + "babel-runtime": "6.26.0" } } diff --git a/scaffolds/draft.md b/scaffolds/draft.md new file mode 100644 index 000000000..498e95baf --- /dev/null +++ b/scaffolds/draft.md @@ -0,0 +1,4 @@ +--- +title: {{ title }} +tags: +--- diff --git a/scaffolds/page.md b/scaffolds/page.md new file mode 100644 index 000000000..f01ba3cd8 --- /dev/null +++ b/scaffolds/page.md @@ -0,0 +1,4 @@ +--- +title: {{ title }} +date: {{ date }} +--- diff --git a/scaffolds/post.md b/scaffolds/post.md new file mode 100644 index 000000000..1f9b9a465 --- /dev/null +++ b/scaffolds/post.md @@ -0,0 +1,5 @@ +--- +title: {{ title }} +date: {{ date }} +tags: +--- diff --git a/source/CNAME b/source/CNAME new file mode 100644 index 000000000..c5eb9eade --- /dev/null +++ b/source/CNAME @@ -0,0 +1 @@ +incoder.org \ No newline at end of file diff --git a/source/README.md b/source/README.md new file mode 100644 index 000000000..a68c0dd46 --- /dev/null +++ b/source/README.md @@ -0,0 +1,51 @@ +

+ BladeCode +

+ +![BladeCode](https://travis-ci.com/BladeCode/BladeCode.github.io.svg?branch=dev) + +| emoji | emoji代码 | 语义 | +| --------------------------------------- | :--------------------------: | --------------------- | +| :tada:(庆祝) | `:tada:` | 初次提交 | +| :sparkles: (火花) | `:sparkles:` | 引入新功能 | +| :bookmark: (书签) | `:bookmark:` | 发行/版本标签 | +| :bug: (bug) | `:bug:` | 修复 bug | +| :ambulance: (急救车) | `:ambulance:` | 重要补丁 | +| :globe_with_meridians: (地球) | `:globe_with_meridians:` | 国际化与本地化 | +| :rotating_light: (警车灯) | `:rotating_light:` | 移除 linter 警告 | +| :wrench: (扳手) | `:wrench:` | 修改配置文件 | +| :heavy_plus_sign: (加号) | `:heavy_plus_sign:` | 增加一个依赖 | +| :heavy_minus_sign: (减号) | `:heavy_minus_sign:` | 减少一个依赖 | +| :arrow_up: (上升箭头) | `:arrow_up:` | 升级依赖 | +| :arrow_down: (下降箭头) | `:arrow_down:` | 降级依赖 | +| :zap: (闪电) | `:zap:` | 提升性能 | +| :racehorse: (赛马) | `:racehorse:` | 提升性能 | +| :chart_with_upwards_trend: (上升趋势图) | `:chart_with_upwards_trend:` | 添加分析或跟踪代码 | +| :rocket: (火箭) | `:rocket:` | 部署功能 | +| :white_check_mark: (白色复选框) | `:white_check_mark:` | 增加测试 | +| :memo: (备忘录) | `:memo:` | 撰写文档 | +| :hammer: (锤子) | `:hammer:` | 重大重构 | +| :art: (调色板) | `:art:` | 改进代码结构/代码格式 | +| :fire: (火焰) | `:fire:` | 移除代码或文件 | +| :pencil2: (铅笔) | `:pencil2:` | 修复 typo | +| :construction: (施工) | `:construction:` | 工作进行中 | +| :construction_worker: (工人) | `:construction_worker:` | 添加 CI 构建系统 | +| :green_heart: (绿心) | `:green_heart:` | 修复 CI 构建问题 | +| :lock: (锁) | `:lock:` | 修复安全问题 | +| :whale: (鲸鱼) | `:whale:` | Docker 相关工作 | +| :apple: (苹果) | `:apple:` | 修复 macOS 下的问题 | +| :penguin: (企鹅) | `:penguin:` | 修复 Linux 下的问题 | +| :checkered_flag: (旗帜) | `:checked_flag:` | 修复 Windows 下的问题 | + +## 附录 +* [Conventional Commits](https://www.conventionalcommits.org) +* [优雅的提交你的 Git Commit Message](https://juejin.im/post/5afc5242f265da0b7f44bee4) +* [Commit message 和 Change log 编写指南](http://www.ruanyifeng.com/blog/2016/01/commit_message_change_log.html) +* [gitemoji](https://gitmoji.carloscuesta.me) + +## Thanks +1. [Node](https://nodejs.org) +2. [Hexo](https://hexo.io) +3. [Next](https://github.com/theme-next/hexo-theme-next) +4. [LeanCloud](https://leancloud.cn) +5. [Valine](https://valine.js.org) \ No newline at end of file diff --git a/source/_data/next.yml b/source/_data/next.yml new file mode 100644 index 000000000..3f676c74f --- /dev/null +++ b/source/_data/next.yml @@ -0,0 +1,1132 @@ +# --------------------------------------------------------------- +# Theme Core Configuration Settings +# See: https://theme-next.org/docs/theme-settings/ +# --------------------------------------------------------------- + +# If false, merge configs from `_data/next.yml` into default configuration (rewrite). +# If true, will fully override default configuration by options from `_data/next.yml` (override). Only for NexT settings. +# And if true, all config from default NexT `_config.yml` must be copied into `next.yml`. Use if you know what you are doing. +# Useful if you want to comment some options from NexT `_config.yml` by `next.yml` without editing default config. +override: true + +# Console reminder if new version released. +reminder: true + +# Allow to cache content generation. Introduced in NexT v6.0.0. +cache: + enable: true + +# Remove unnecessary files after hexo generate. +minify: true + +# Define custom file paths. +# Create your custom files in site directory `source/_data` and uncomment needed files below. +custom_file_path: + #head: source/_data/head.swig + #header: source/_data/header.swig + #sidebar: source/_data/sidebar.swig + #postMeta: source/_data/post-meta.swig + #postBodyEnd: source/_data/post-body-end.swig + #footer: source/_data/footer.swig + #bodyEnd: source/_data/body-end.swig + #variable: source/_data/variables.styl + #mixin: source/_data/mixins.styl + #style: source/_data/styles.styl + + +# --------------------------------------------------------------- +# Site Information Settings +# See: https://theme-next.org/docs/getting-started/ +# --------------------------------------------------------------- + +favicon: + small: https://res.cloudinary.com/incoder/image/upload/v1525515979/favicon-16x16.png + medium: https://res.cloudinary.com/incoder/image/upload/v1525515979/favicon-32x32.png + apple_touch_icon: https://res.cloudinary.com/incoder/image/upload/v1525515979/apple-touch-icon.png + safari_pinned_tab: /images/logo.svg + #android_manifest: /images/manifest.json + #ms_browserconfig: /images/browserconfig.xml + +# hexo-generator-feed required for rss support. Leave rss as blank to use site's feed link. +# Set rss to false to disable feed link. Set rss to specific value if you have burned your feed already. +rss: + +footer: + # Specify the date when the site was setup. If not defined, current year will be used. + #since: 2015 + + # Icon between year and copyright info. + icon: + # Icon name in Font Awesome. See: https://fontawesome.com/v4.7.0/icons/ + # `heart` is recommended with animation in red (#ff0000). + name: user + # If you want to animate the icon, set it to true. + animated: false + # Change the color of icon, using Hex Code. + color: "#808080" + + # If not defined, `author` from Hexo `_config.yml` will be used. + copyright: + + powered: + # Hexo link (Powered by Hexo). + enable: true + # Version info of Hexo after Hexo link (vX.X.X). + version: true + + theme: + # Theme & scheme info link (Theme - NexT.scheme). + enable: true + # Version info of NexT after scheme info (vX.X.X). + version: true + + # Beian ICP information for Chinese users. See: http://www.beian.miit.gov.cn + beian: + enable: false + icp: + # The digit in the num of gongan beian. + gongan_id: + # The full num of gongan beian. + gongan_num: + # The icon for gongan beian. See: http://www.beian.gov.cn/portal/download + gongan_icon_url: + +# Creative Commons 4.0 International License. +# See: https://creativecommons.org/share-your-work/licensing-types-examples +# Available values of license: by | by-nc | by-nc-nd | by-nc-sa | by-nd | by-sa | zero +# You can set a language value if you prefer a translated version of CC license, e.g. deed.zh +# CC licenses are available in 39 languages, you can find the specific and correct abbreviation you need on https://creativecommons.org +creative_commons: + license: by-nc-sa + sidebar: false + post: true + language: + + +# --------------------------------------------------------------- +# SEO Settings +# --------------------------------------------------------------- + +# Disable Baidu transformation on mobile devices. +disable_baidu_transformation: false + +# Set a canonical link tag in your hexo, you could use it for your SEO of blog. +# See: https://support.google.com/webmasters/answer/139066 +# Remember to set up your URL in Hexo `_config.yml` (e.g. url: http://yourdomain.com) +canonical: true + +# Change headers hierarchy on site-subtitle (will be main site description) and on all post / page titles for better SEO-optimization. +seo: false + +# If true, will add site-subtitle to index page. +# Remember to set up your site-subtitle in Hexo `_config.yml` (e.g. subtitle: Subtitle) +index_with_subtitle: false + +# Automatically add external URL with Base64 encrypt & decrypt. +exturl: false + +# Google Webmaster tools verification. +# See: https://www.google.com/webmasters +google_site_verification: + +# Bing Webmaster tools verification. +# See: https://www.bing.com/webmaster +bing_site_verification: + +# Yandex Webmaster tools verification. +# See: https://webmaster.yandex.ru +yandex_site_verification: + +# Baidu Webmaster tools verification. +# See: https://ziyuan.baidu.com/site +baidu_site_verification: + +# Enable baidu push so that the blog will push the url to baidu automatically which is very helpful for SEO. +baidu_push: false + + +# --------------------------------------------------------------- +# Menu Settings +# --------------------------------------------------------------- + +# Usage: `Key: /link/ || icon` +# Key is the name of menu item. If the translation for this item is available, the translated text will be loaded, otherwise the Key name will be used. Key is case-senstive. +# Value before `||` delimiter is the target link. +# Value after `||` delimiter is the name of Font Awesome icon. If icon (with or without delimiter) is not specified, question icon will be loaded. +# When running the site in a subdirectory (e.g. domain.tld/blog), remove the leading slash from link value (/archives -> archives). +# External url should start with http:// or https:// +menu: + home: / || home + tags: /tags/ || tags + categories: /categories/ || th + archives: /archives/ || archive + books: /books/ || book + movies: /movies || film + java: https://java.incoder.org/ || globe + mobile: https://mobile.incoder.org/ || paper-plane-o + about: /about/ || user + #schedule: /schedule/ || calendar + #sitemap: /sitemap.xml || sitemap + #commonweal: /404/ || heartbeat + +# Enable / Disable menu icons / item badges. +menu_settings: + icons: true + badges: true + + +# --------------------------------------------------------------- +# Scheme Settings +# --------------------------------------------------------------- + +# Schemes +scheme: Muse +# scheme: Mist +# scheme: Pisces +# scheme: Gemini + + +# --------------------------------------------------------------- +# Sidebar Settings +# See: https://theme-next.org/docs/theme-settings/sidebar +# --------------------------------------------------------------- + +# Posts / Categories / Tags in sidebar. +site_state: false + +# Social Links +# Usage: `Key: permalink || icon` +# Key is the link label showing to end users. +# Value before `||` delimiter is the target permalink. +# Value after `||` delimiter is the name of Font Awesome icon. If icon (with or without delimiter) is not specified, globe icon will be loaded. +social: + GitHub: https://github.com/BladeCode || github + E-Mail: mailto:incoder.xu@gmail.com || envelope + Weibo: https://weibo.com/onblade || weibo + #Google: https://plus.google.com/yourname || google + Twitter: https://twitter.com/_incoder || twitter + Medium: https://medium.com/@incoder || medium + #FB Page: https://www.facebook.com/yourname || facebook + #VK Group: https://vk.com/yourname || vk + #StackOverflow: https://stackoverflow.com/yourname || stack-overflow + #YouTube: https://youtube.com/yourname || youtube + #Instagram: https://instagram.com/yourname || instagram + #Skype: skype:yourname?call|chat || skype + +social_icons: + enable: true + icons_only: false + transition: false + +# Blog rolls +links_settings: + icon: link + title: Links + # Available values: block | inline + layout: block + +links: + TwoDragonLake: https://twodragonlake.com + RootCluster: https://rootcluster.github.io + 南贺神社: https://ceaser.wang + Alyenc: https://kaifa.dev + 大师傅: https://blog.dazhidayong.cn + +# Sidebar Avatar +avatar: + # In theme directory (source/images): /images/avatar.gif + # In site directory (source/uploads): /uploads/avatar.gif + # You can also use other linking images. + url: https://res.cloudinary.com/incoder/image/upload/v1525515979/avatar.png + # If true, the avatar would be dispalyed in circle. + rounded: false + # If true, the avatar would be rotated with the cursor. + rotated: false + +# Table Of Contents in the Sidebar +toc: + enable: true + # Automatically add list number to toc. + number: true + # If true, all words will placed on next lines if header width longer then sidebar width. + wrap: false + # If true, all level of TOC in a post will be displayed, rather than the activated part of it. + expand_all: false + # Maximum heading depth of generated toc. You can set it in one post through `toc_max_depth` in Front-matter. + max_depth: 6 + +sidebar: + # Sidebar Position. + # position: left + position: right + + # Manual define the sidebar width. If commented, will be default for: + # Muse | Mist: 320 + # Pisces | Gemini: 240 + #width: 300 + + # Sidebar Display (only for Muse | Mist), available values: + # - post expand on posts automatically. Default. + # - always expand for all pages automatically. + # - hide expand only when click on the sidebar toggle icon. + # - remove totally remove sidebar including sidebar toggle. + display: post + + # Sidebar offset from top menubar in pixels (only for Pisces | Gemini). + offset: 12 + # Enable sidebar on narrow view (only for Muse | Mist). + onmobile: false + +# A button to open designated chat widget in sidebar. +# Firstly, you need enable the chat service you want to activate its sidebar button. +chat: + enable: false + #service: chatra + #service: tidio + icon: comment # Icon name in Font Awesome, set false to disable icon. + text: Chat # Button text, change it as you wish. + + +# --------------------------------------------------------------- +# Post Settings +# See: https://theme-next.org/docs/theme-settings/posts +# --------------------------------------------------------------- + +# Automatically scroll page to section which is under mark. +scroll_to_more: true + +# Automatically excerpt description in homepage as preamble text. +excerpt_description: true + +# Automatically excerpt (Not recommend). +# Use in the post to control excerpt accurately. +auto_excerpt: + enable: true + length: 150 + +# Read more button +# If true, the read more button would be displayed in excerpt section. +read_more_btn: true + +# Post meta display settings +post_meta: + item_text: true + created_at: true + updated_at: + enable: false + another_day: true + categories: true + +# Post wordcount display settings +# Dependencies: https://github.com/theme-next/hexo-symbols-count-time +symbols_count_time: + separated_meta: true + item_text_post: true + item_text_total: false + awl: 4 + wpm: 275 + +# Use icon instead of the symbol # to indicate the tag at the bottom of the post +tag_icon: true + +# Wechat Subscriber +wechat_subscriber: + enable: true + qcode: https://res.cloudinary.com/incoder/image/upload/v1554537454/qrcode_incoder.jpg # /path/to/your/wechatqcode e.g. /uploads/wechat-qcode.jpg + description: 一个程序猿的成长历程~ # e.g. subscribe to my blog by scanning my public wechat account + +# Reward (Donate) +reward_settings: + # If true, reward would be displayed in every article by default. + # You can show or hide reward in a specific article throuth `reward: true | false` in Front-matter. + enable: true + animation: true + #comment: Donate comment here. + +reward: + wechatpay: https://res.cloudinary.com/incoder/image/upload/v1525515979/wechatpay.png + alipay: https://res.cloudinary.com/incoder/image/upload/v1525515979/alipay.png + #bitcoin: /images/bitcoin.png + +# Related popular posts +# Dependencies: https://github.com/tea3/hexo-related-popular-posts +related_posts: + enable: true + title: # Custom header, leave empty to use the default one + display_in_home: true + params: + maxCount: 5 + #PPMixingRate: 0.0 + isDate: true + #isImage: false + #isExcerpt: false + +# Post edit +# Dependencies: https://github.com/hexojs/hexo-deployer-git +post_edit: + enable: false + url: https://github.com/user-name/repo-name/tree/branch-name/subdirectory-name # Link for view source + #url: https://github.com/user-name/repo-name/edit/branch-name/subdirectory-name # Link for fork & edit + + +# --------------------------------------------------------------- +# Custom Page Settings +# See: https://theme-next.org/docs/theme-settings/custom-pages +# --------------------------------------------------------------- + +# Enable "cheers" for archive page. +cheers: true + +# TagCloud settings for tags page. +tagcloud: + # If true, font size, font color and amount of tags can be customized + enable: true + # All values below are same as default, change them by yourself + min: 12 # Minimun font size in px + max: 30 # Maxium font size in px + start: "#ccc" # Start color (hex, rgba, hsla or color keywords) + end: "#111" # End color (hex, rgba, hsla or color keywords) + amount: 200 # Amount of tags, change it if you have more than 200 tags + +# Google Calendar +# Share your recent schedule to others via calendar page. +# API Documentation: https://developers.google.com/google-apps/calendar/v3/reference/events/list +# To get api_key: https://console.developers.google.com +# Create & manage a public Google calendar: https://support.google.com/calendar/answer/37083 +calendar: + calendar_id: # Your Google account E-Mail + api_key: + orderBy: startTime + offsetMax: 24 # Time Range + offsetMin: 4 # Time Range + showDeleted: false + singleEvents: true + maxResults: 250 + + +# --------------------------------------------------------------- +# Misc Theme Settings +# --------------------------------------------------------------- + +# Set the text alignment in posts / pages. +text_align: + # Available values: start | end | left | right | center | justify | justify-all | match-parent + desktop: justify + mobile: justify + +# Reduce padding / margin indents on devices with narrow width. +mobile_layout_economy: true + +# Android Chrome header panel color ($brand-bg / $headband-bg => $black-deep). +android_chrome_color: "#222" + +# Hide sticky headers and color the menu bar on Safari (iOS / macOS). +safari_rainbow: false + +# Optimize the display of scrollbars on webkit based browsers. +custom_scrollbar: true + +# Custom Logo (Do not support scheme Mist) +custom_logo: https://res.cloudinary.com/incoder/image/upload/v1525515979/favicon-32x32.png #/uploads/custom-logo.jpg + +codeblock: + # Code Highlight theme + # Available values: normal | night | night eighties | night blue | night bright + # See: https://github.com/chriskempson/tomorrow-theme + highlight_theme: night + # Add copy button on codeblock + copy_button: + enable: true + # Show text copy result. + show_result: true + # Available values: default | flat | mac + style: mac + +back2top: + enable: true + # Back to top in sidebar. + sidebar: false + # Scroll percent label in b2t button. + scrollpercent: true + +# Reading progress bar +reading_progress: + enable: true + # Available values: top | bottom + position: top + color: "#37c6c0" + height: 2px + +# Bookmark Support +bookmark: + enable: false + # Customize the color of the bookmark. + color: "#222" + # If auto, save the reading progress when closing the page or clicking the bookmark-icon. + # If manual, only save it by clicking the bookmark-icon. + save: auto + +# `Follow me on GitHub` banner in the top-right corner. +github_banner: + enable: true + permalink: https://github.com/BladeCode + title: Follow me on GitHub + + +# --------------------------------------------------------------- +# Font Settings +# See: https://theme-next.org/docs/theme-settings/#Fonts-Customization +# --------------------------------------------------------------- +# Find fonts on Google Fonts (https://www.google.com/fonts) +# All fonts set here will have the following styles: +# light | light italic | normal | normal italic | bold | bold italic +# Be aware that setting too much fonts will cause site running slowly +# --------------------------------------------------------------- +# To avoid space between header and sidebar in scheme Pisces / Gemini, Web Safe fonts are recommended for `global` (and `title`): +# Arial | Tahoma | Helvetica | Times New Roman | Courier New | Verdana | Georgia | Palatino | Garamond | Comic Sans MS | Trebuchet MS +# --------------------------------------------------------------- + +font: + # Use custom fonts families or not. + # Depended options: `external` and `family`. + enable: false + + # Uri of fonts host, e.g. //fonts.googleapis.com (Default). + host: + + # Font options: + # `external: true` will load this font family from `host` above. + # `family: Times New Roman`. Without any quotes. + # `size: x.x`. Use `em` as unit. Default: 1 (16px) + + # Global font settings used for all elements inside . + global: + external: true + family: Lato + size: + + # Font settings for site title (.site-title). + title: + external: true + family: + size: + + # Font settings for headlines (

to

). + headings: + external: true + family: + size: + + # Font settings for posts (.post-body). + posts: + external: true + family: + + # Font settings for and code blocks. + codes: + external: true + family: + + +# --------------------------------------------------------------- +# Third Party Plugins & Services Settings +# See: https://theme-next.org/docs/third-party-services/ +# You may need to install dependencies or set CDN URLs in `vendors` +# There are two different CDN providers by default: +# - jsDelivr (cdn.jsdelivr.net), works everywhere even in China +# - CDNJS (cdnjs.cloudflare.com), provided by cloudflare +# --------------------------------------------------------------- + +# Math Formulas Render Support +math: + enable: true + + # Default (true) will load mathjax / katex script on demand. + # That is it only render those page which has `mathjax: true` in Front-matter. + # If you set it to false, it will load mathjax / katex srcipt EVERY PAGE. + per_page: true + + # hexo-renderer-pandoc (or hexo-renderer-kramed) required for full MathJax support. + mathjax: + enable: false + # See: https://mhchem.github.io/MathJax-mhchem/ + mhchem: false + + # hexo-renderer-markdown-it-plus (or hexo-renderer-markdown-it with markdown-it-katex plugin) required for full Katex support. + katex: + enable: false + # See: https://github.com/KaTeX/KaTeX/tree/master/contrib/copy-tex + copy_tex: false + +# Easily enable fast Ajax navigation on your website. +# Dependencies: https://github.com/theme-next/theme-next-pjax +# For moreinformation: https://github.com/MoOx/pjax +pjax: false + +# FancyBox is a tool that offers a nice and elegant way to add zooming functionality for images. +# For more information: https://fancyapps.com/fancybox +fancybox: true + +# A JavaScript library for zooming images like Medium. +# Do not enable both `fancybox` and `mediumzoom`. +# For more information: https://github.com/francoischalifour/medium-zoom +mediumzoom: false + +# Vanilla JavaScript plugin for lazyloading images. +# For more information: https://github.com/ApoorvSaxena/lozad.js +lazyload: true + +# Pangu Support +# For more information: https://github.com/vinta/pangu.js +pangu: false + +# Quicklink Support +# For more information: https://github.com/GoogleChromeLabs/quicklink +quicklink: + enable: false + + # Quicklink (quicklink.umd.js script) is loaded on demand. + # Add `quicklink: true` in Front-matter of the page or post you need. + # Home page and archive page can be controlled through home and archive options below. + home: true + archive: true + + # Default (true) will initialize quicklink after the load event fires. + delay: true + # Custom a time in milliseconds by which the browser must execute prefetching. + timeout: 3000 + # Default (true) will enable fetch() or falls back to XHR. + priority: true + + # For more flexibility you can add some patterns (RegExp, Function, or Array) to ignores. + # See: https://github.com/GoogleChromeLabs/quicklink#custom-ignore-patterns + ignores: + + +# --------------------------------------------------------------- +# Comments Settings +# See: https://theme-next.org/docs/third-party-services/comments +# --------------------------------------------------------------- + +# Multiple Comment System Support +comments: + # Available values: tabs | buttons + style: tabs + # Choose a comment system to be displayed by default. + # Available values: changyan | disqus | disqusjs | facebook_comments_plugin | gitalk | livere | valine | vkontakte + active: + # Setting `true` means remembering the comment system selected by the visitor. + storage: true + # Modify icons and texts for any style, here are some examples. + nav: + #disqus: + # text: Load Disqus + # order: -1 + #facebook_comments_plugin: + # text: facebook + #gitalk: + # order: -2 + +# Disqus +disqus: + enable: false + shortname: + count: true + lazyload: false + #post_meta_order: 0 + +# DisqusJS +# Alternative Disqus - Render comment component using Disqus API. +# Demo: https://suka.js.org/DisqusJS/ +# For more information: https://github.com/SukkaW/DisqusJS +disqusjs: + enable: false + # API Endpoint of Disqus API (https://disqus.com/api/). + # Leave api empty if you are able to connect to Disqus API. + # Otherwise you need a reverse proxy for Disqus API. + # For example: + # api: https://disqus.skk.moe/disqus/ + api: + apikey: # Register new application from https://disqus.com/api/applications/ + shortname: # See: https://disqus.com/admin/settings/general/ + +# Changyan +changyan: + enable: false + appid: + appkey: + #post_meta_order: 0 + +# Valine +# You can get your appid and appkey from https://leancloud.cn +# For more information: https://valine.js.org, https://github.com/xCss/Valine +valine: + enable: true # When enable is set to be true, leancloud_visitors is recommended to be closed for the re-initialization problem within different leancloud adk version + appid: 3ShrIGfQL4TLamd48UtbdDEK-gzGzoHsz # Your leancloud application appid + appkey: cW8VJrB2yJiIBLtYA0KdE8vW # Your leancloud application appkey + notify: false # Mail notifier. See: https://github.com/xCss/Valine/wiki + verify: false # Verification code + placeholder: Just go go # Comment box placeholder + avatar: identicon # Gravatar style + guest_info: nick,mail # Custom comment header + pageSize: 10 # Pagination size + language: # Language, available values: en, zh-cn + visitor: false # leancloud-counter-security is not supported for now. When visitor is set to be true, appid and appkey are recommended to be the same as leancloud_visitors' for counter compatibility. Article reading statistic https://valine.js.org/visitor.html + comment_count: true # If false, comment count will only be displayed in post page, not in home page + #post_meta_order: 0 + +# LiveRe comments system +# You can get your uid from https://livere.com/insight/myCode (General web site) +livere_uid: # + +# Gitalk +# Demo: https://gitalk.github.io +# For more information: https://github.com/gitalk/gitalk +gitalk: + enable: false + github_id: # GitHub repo owner + repo: # Repository name to store issues + client_id: # GitHub Application Client ID + client_secret: # GitHub Application Client Secret + admin_user: # GitHub repo owner and collaborators, only these guys can initialize gitHub issues + distraction_free_mode: true # Facebook-like distraction free mode + # Gitalk's display language depends on user's browser or system environment + # If you want everyone visiting your site to see a uniform language, you can set a force language value + # Available values: en | es-ES | fr | ru | zh-CN | zh-TW + language: + + +# --------------------------------------------------------------- +# Post Widgets / Content Sharing Services +# See: https://theme-next.org/docs/third-party-services/post-widgets +# --------------------------------------------------------------- + +# Facebook SDK Support +facebook_sdk: + enable: false + app_id: # + fb_admin: # + like_button: # true + webmaster: # true + +# Facebook comments plugin +# This plugin depends on Facebook SDK. +# If facebook_sdk.enable is false, Facebook comments plugin is unavailable. +facebook_comments_plugin: + enable: false + num_of_posts: 10 # Minimum posts num is 1 + width: 100% # Default width is 550px + scheme: light # Default scheme is light (light or dark) + #post_meta_order: 0 + +# VKontakte API Support +# To get your AppID visit https://vk.com/editapp?act=create +vkontakte_api: + enable: false + app_id: # + like: true + comments: true + num_of_posts: 10 + +# Star rating support to each article. +# To get your ID visit https://widgetpack.com +rating: + enable: false + id: # + color: fc6423 + +# AddThis Share. See: https://www.addthis.com +# Go to https://www.addthis.com/dashboard to customize your tools. +add_this_id: ra-5ca8705bf505f047 + + +# --------------------------------------------------------------- +# Statistics and Analytics +# See: https://theme-next.org/docs/third-party-services/statistics-and-analytics +# --------------------------------------------------------------- + +# Baidu Analytics +baidu_analytics: # + +# Growingio Analytics +# Copyright 2015-2018 GrowingIO, Inc. More info available at https://www.growingio.com +growingio_analytics: # + +# Google Analytics +google_analytics: + tracking_id: UA-100235665-1 + localhost_ignored: true + +# CNZZ count +cnzz_siteid: + +# Application Insights +# See: https://azure.microsoft.com/en-us/services/application-insights +application_insights: + +# Show number of visitors to each article. +# You can visit https://leancloud.cn to get AppID and AppKey. +leancloud_visitors: + enable: true + app_id: 3ShrIGfQL4TLamd48UtbdDEK-gzGzoHsz # + app_key: cW8VJrB2yJiIBLtYA0KdE8vW # + # Dependencies: https://github.com/theme-next/hexo-leancloud-counter-security + # If you don't care about security in leancloud counter and just want to use it directly + # (without hexo-leancloud-counter-security plugin), set `security` to `false`. + security: false + betterPerformance: true + +# Another tool to show number of visitors to each article. +# Visit https://console.firebase.google.com/u/0/ to get apiKey and projectId. +# Visit https://firebase.google.com/docs/firestore/ to get more information about firestore. +firestore: + enable: false + collection: articles # Required, a string collection name to access firestore database + apiKey: # Required + projectId: # Required + +# Show Views / Visitors of the website / page with busuanzi. +# Get more information on http://ibruce.info/2015/04/04/busuanzi +busuanzi_count: + enable: false + total_visitors: true + total_visitors_icon: user + total_views: true + total_views_icon: eye + post_views: true + post_views_icon: eye + +# Tencent analytics +tencent_analytics: # + +# Tencent MTA +tencent_mta: # + + +# --------------------------------------------------------------- +# Search Services +# See: https://theme-next.org/docs/third-party-services/search-services +# --------------------------------------------------------------- + +# Algolia Search +# Dependencies: https://github.com/theme-next/theme-next-algolia-instant-search +# For more information: https://www.algolia.com +algolia_search: + enable: false + hits: + per_page: 10 + labels: + input_placeholder: Search for Posts + hits_empty: "We didn't find any results for the search: ${query}" + hits_stats: "${hits} results found in ${time} ms" + +# Local search +# Dependencies: https://github.com/wzpan/hexo-generator-search +local_search: + enable: true + # If auto, trigger search by changing input. + # If manual, trigger search by pressing enter key or search button. + trigger: auto + # Show top n results per article, show all results by setting to -1 + top_n_per_article: 1 + # Unescape html strings to the readable one. + unescape: true + # Preload the search data when the page loads. + preload: true + +# Swiftype Search API Key +swiftype_key: + + +# --------------------------------------------------------------- +# Chat Services +# See: https://theme-next.org/docs/third-party-services/chat-services +# --------------------------------------------------------------- + +# Chatra Support +# See: https://chatra.io +# Dashboard: https://app.chatra.io/settings/general +chatra: + enable: false + async: true + id: # Visit Dashboard to get your ChatraID + #embed: # Unfinished experimental feature for developers. See: https://chatra.io/help/api/#injectto + +# Tidio Support +# See: https://www.tidiochat.com +# Dashboard: https://www.tidiochat.com/panel/dashboard +tidio: + enable: false + key: # Public Key, get it from dashboard. See: https://www.tidiochat.com/panel/settings/developer + + +# --------------------------------------------------------------- +# Tags Settings +# See: https://theme-next.org/docs/tag-plugins/ +# --------------------------------------------------------------- + +# Note tag (bs-callout) +note: + # Note tag style values: + # - simple bs-callout old alert style. Default. + # - modern bs-callout new (v2-v3) alert style. + # - flat flat callout style with background, like on Mozilla or StackOverflow. + # - disabled disable all CSS styles import of note tag. + style: simple + icons: false + border_radius: 3 + # Offset lighter of background in % for modern and flat styles (modern: -12 | 12; flat: -18 | 6). + # Offset also applied to label tag variables. This option can work with disabled note tag. + light_bg_offset: 0 + +# Tabs tag +tabs: + transition: + tabs: true + labels: true + border_radius: 0 + +# PDF tag, requires two plugins: pdfObject and pdf.js +# pdfObject will try to load pdf files natively, if failed, pdf.js will be used. +# The following `cdn` setting is only for pdfObject, because cdn for pdf.js might be blocked by CORS policy. +# So, you must install the dependency of pdf.js if you want to use pdf tag and make it available to all browsers. +# See: https://github.com/theme-next/theme-next-pdf +pdf: + enable: false + # Default height + height: 500px + +# Mermaid tag +mermaid: + enable: true + # Available themes: default | dark | forest | neutral + theme: forest + + +# --------------------------------------------------------------- +# Animation Settings +# --------------------------------------------------------------- + +# Use velocity to animate everything. +# For more information: http://velocityjs.org +motion: + enable: true + async: false + transition: + # Transition variants: + # fadeIn | fadeOut | flipXIn | flipXOut | flipYIn | flipYOut | flipBounceXIn | flipBounceXOut | flipBounceYIn | flipBounceYOut + # swoopIn | swoopOut | whirlIn | whirlOut | shrinkIn | shrinkOut | expandIn | expandOut + # bounceIn | bounceOut | bounceUpIn | bounceUpOut | bounceDownIn | bounceDownOut | bounceLeftIn | bounceLeftOut | bounceRightIn | bounceRightOut + # slideUpIn | slideUpOut | slideDownIn | slideDownOut | slideLeftIn | slideLeftOut | slideRightIn | slideRightOut + # slideUpBigIn | slideUpBigOut | slideDownBigIn | slideDownBigOut | slideLeftBigIn | slideLeftBigOut | slideRightBigIn | slideRightBigOut + # perspectiveUpIn | perspectiveUpOut | perspectiveDownIn | perspectiveDownOut | perspectiveLeftIn | perspectiveLeftOut | perspectiveRightIn | perspectiveRightOut + post_block: fadeIn + post_header: slideDownIn + post_body: slideDownIn + coll_header: slideLeftIn + # Only for Pisces | Gemini. + sidebar: slideUpIn + +# Progress bar in the top during page loading. +# Dependencies: https://github.com/theme-next/theme-next-pace +# For more information: https://github.com/HubSpot/pace +pace: + enable: false + # Themes list: + # big-counter | bounce | barber-shop | center-atom | center-circle | center-radar | center-simple + # corner-indicator | fill-left | flat-top | flash | loading-bar | mac-osx | material | minimal + theme: minimal + +# JavaScript 3D library. +# Dependencies: https://github.com/theme-next/theme-next-three +three: + enable: false + delay: false # Set true to further delay loading + three_waves: false + canvas_lines: false + canvas_sphere: false + +# Canvas-nest +# Dependencies: https://github.com/theme-next/theme-next-canvas-nest +# For more information: https://github.com/hustcc/canvas-nest.js +canvas_nest: + enable: false + onmobile: true # Display on mobile or not + color: "0,0,255" # RGB values, use `,` to separate + opacity: 0.5 # The opacity of line: 0~1 + zIndex: -1 # z-index property of the background + count: 99 # The number of lines + +# Canvas-ribbon +# Dependencies: https://github.com/theme-next/theme-next-canvas-ribbon +# For more information: https://github.com/zproo/canvas-ribbon +canvas_ribbon: + enable: false + size: 300 # The width of the ribbon + alpha: 0.6 # The transparency of the ribbon + zIndex: -1 # The display level of the ribbon + + +#! --------------------------------------------------------------- +#! DO NOT EDIT THE FOLLOWING SETTINGS +#! UNLESS YOU KNOW WHAT YOU ARE DOING +#! See: https://theme-next.org/docs/advanced-settings +#! --------------------------------------------------------------- + +# Script Vendors. Set a CDN address for the vendor you want to customize. +# Be aware that you would better use the same version as internal ones to avoid potential problems. +# Please use the https protocol of CDN files when you enable https on your site. +vendors: + # Internal path prefix. Please do not edit it. + _internal: lib + + # Internal version: 3.1.0 + # Example: + # anime: //cdn.jsdelivr.net/npm/animejs@3.1.0/lib/anime.min.js + anime: + + # Internal version: 4.7.0 + # Example: + # fontawesome: //cdn.jsdelivr.net/npm/font-awesome@4/css/font-awesome.min.css + # fontawesome: //cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css + fontawesome: + + # MathJax + # Example: + # mathjax: //cdn.jsdelivr.net/npm/mathjax@2/MathJax.js?config=TeX-AMS-MML_HTMLorMML + # mathjax: //cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-MML-AM_CHTML + # mhchem: //cdn.jsdelivr.net/npm/mathjax-mhchem@3 + # mhchem: //cdnjs.cloudflare.com/ajax/libs/mathjax-mhchem/3.3.0 + mathjax: + mhchem: + + # KaTeX + # Example: + # katex: //cdn.jsdelivr.net/npm/katex@0/dist/katex.min.css + # katex: //cdnjs.cloudflare.com/ajax/libs/KaTeX/0.7.1/katex.min.css + # copy_tex_js: //cdn.jsdelivr.net/npm/katex@0/dist/contrib/copy-tex.min.js + # copy_tex_css: //cdn.jsdelivr.net/npm/katex@0/dist/contrib/copy-tex.min.css + katex: + copy_tex_js: + copy_tex_css: + + # Internal version: 0.2.8 + # Example: + # pjax: //cdn.jsdelivr.net/gh/theme-next/theme-next-pjax@0/pjax.min.js + pjax: + + # FancyBox + # Example: + # jquery: //cdn.jsdelivr.net/npm/jquery@3/dist/jquery.min.js + # fancybox: //cdn.jsdelivr.net/gh/fancyapps/fancybox@3/dist/jquery.fancybox.min.js + # fancybox_css: //cdn.jsdelivr.net/gh/fancyapps/fancybox@3/dist/jquery.fancybox.min.css + jquery: + fancybox: + fancybox_css: + + # Medium-zoom + # Example: + # mediumzoom: //cdn.jsdelivr.net/npm/medium-zoom@1/dist/medium-zoom.min.js + mediumzoom: + + # Lazyload + # Example: + # lazyload: //cdn.jsdelivr.net/npm/lozad@1/dist/lozad.min.js + # lazyload: //cdnjs.cloudflare.com/ajax/libs/lozad.js/1.9.0/lozad.min.js + lazyload: + + # Pangu + # Example: + # pangu: //cdn.jsdelivr.net/npm/pangu@4/dist/browser/pangu.min.js + # pangu: //cdnjs.cloudflare.com/ajax/libs/pangu/4.0.7/pangu.min.js + pangu: + + # Quicklink + # Example: + # quicklink: //cdn.jsdelivr.net/npm/quicklink@1/dist/quicklink.umd.js + quicklink: + + # DisqusJS + # Example: + # disqusjs_js: //cdn.jsdelivr.net/npm/disqusjs@1/dist/disqus.js + # disqusjs_css: //cdn.jsdelivr.net/npm/disqusjs@1/dist/disqusjs.css + disqusjs_js: + disqusjs_css: + + # Valine + # Example: + # valine: //cdn.jsdelivr.net/npm/valine@1/dist/Valine.min.js + # valine: //cdnjs.cloudflare.com/ajax/libs/valine/1.3.4/Valine.min.js + valine: + + # Gitalk + # Example: + # gitalk_js: //cdn.jsdelivr.net/npm/gitalk@1/dist/gitalk.min.js + # gitalk_css: //cdn.jsdelivr.net/npm/gitalk@1/dist/gitalk.css + gitalk_js: + gitalk_css: + + # Algolia Search + # Example: + # algolia_instant_js: //cdn.jsdelivr.net/npm/instantsearch.js@2/dist/instantsearch.min.js + # algolia_instant_css: //cdn.jsdelivr.net/npm/instantsearch.js@2/dist/instantsearch.min.css + algolia_instant_js: + algolia_instant_css: + + # PDF + # Example: + # pdfobject: //cdn.jsdelivr.net/npm/pdfobject@2/pdfobject.min.js + # pdfobject: //cdnjs.cloudflare.com/ajax/libs/pdfobject/2.1.1/pdfobject.min.js + pdfobject: + + # Mermaid + # Example: + # mermaid: //cdn.jsdelivr.net/npm/mermaid@8/dist/mermaid.min.js + # mermaid: //cdnjs.cloudflare.com/ajax/libs/mermaid/8.0.0/mermaid.min.js + mermaid: + + # Internal version: 1.2.1 + # Example: + # velocity: //cdn.jsdelivr.net/npm/velocity-animate@1/velocity.min.js + # velocity: //cdnjs.cloudflare.com/ajax/libs/velocity/1.2.1/velocity.min.js + # velocity_ui: //cdn.jsdelivr.net/npm/velocity-animate@1/velocity.ui.min.js + # velocity_ui: //cdnjs.cloudflare.com/ajax/libs/velocity/1.2.1/velocity.ui.min.js + velocity: + velocity_ui: + + # Internal version: 1.0.2 + # Example: + # pace: //cdn.jsdelivr.net/npm/pace-js@1/pace.min.js + # pace: //cdnjs.cloudflare.com/ajax/libs/pace/1.0.2/pace.min.js + # pace_css: //cdn.jsdelivr.net/npm/pace-js@1/themes/blue/pace-theme-minimal.css + # pace_css: //cdnjs.cloudflare.com/ajax/libs/pace/1.0.2/themes/blue/pace-theme-minimal.min.css + pace: + pace_css: + + # Internal version: 1.0.0 + # Example: + # three: //cdn.jsdelivr.net/gh/theme-next/theme-next-three@1/three.min.js + # three_waves: //cdn.jsdelivr.net/gh/theme-next/theme-next-three@1/three-waves.min.js + # canvas_lines: //cdn.jsdelivr.net/gh/theme-next/theme-next-three@1/canvas_lines.min.js + # canvas_sphere: //cdn.jsdelivr.net/gh/theme-next/theme-next-three@1/canvas_sphere.min.js + three: + three_waves: + canvas_lines: + canvas_sphere: + + # Internal version: 1.0.0 + # Example: + # canvas_nest: //cdn.jsdelivr.net/gh/theme-next/theme-next-canvas-nest@1/canvas-nest.min.js + # canvas_nest_nomobile: //cdn.jsdelivr.net/gh/theme-next/theme-next-canvas-nest@1/canvas-nest-nomobile.min.js + canvas_nest: + canvas_nest_nomobile: + + # Internal version: 1.0.0 + # Example: + # canvas_ribbon: //cdn.jsdelivr.net/gh/theme-next/theme-next-canvas-ribbon@1/canvas-ribbon.js + canvas_ribbon: + +# Assets +css: css +js: js +images: images \ No newline at end of file diff --git a/source/_posts/android-audio-base.md b/source/_posts/android-audio-base.md new file mode 100644 index 000000000..817aaad7d --- /dev/null +++ b/source/_posts/android-audio-base.md @@ -0,0 +1,154 @@ +--- +title: Android 音频基础知识 +date: 2018-10-26 10:14:20 +categories: Android +tag: [media] +--- + +关于音频技术是一门庞大且很专业的学术,这里不会阐述该知识的底层原理知识(比如:声音的原理,音波的正弦平面波合成等等),主要介绍音频相关的一些基本的知识概念,以及在实际开发过程中需要掌握关键API等。 + +## 声音 + +"声音是振动产生的`声波`,通过`介质`(`气体`,`固体`,`液体`)传播并能被人或动物`听觉器官`所感知的`波动`现象"。声音的频率一般以[赫兹](https://zh.wikipedia.org/wiki/%E8%B5%AB%E5%85%B9)表示,记为`Hz`,指每秒周期性震动的次数 + +![trasound_range_diagram](https://res.cloudinary.com/incoder/image/upload/v1541400788/blog/trasound_range_diagram.png) +>图片来自[Wikipedia](https://zh.wikipedia.org/wiki/%E5%A3%B0%E9%9F%B3) + +* 红:次声波(由火山爆发、龙卷风、雷暴、台风等许多灾害性事件发生前都会产生出次声波,人们就可以利用这种前兆来预报灾害事件的发生) +* 蓝:可听声波(20~20000Hz) +* 绿:超声波(广泛应用于工业、军事、医疗等行业。在工业上,常用超声波来清洗精密零件,原理是利用超声波在清洗液中产生震荡波,使清洗液产生瞬间的小气泡,从而冲洗零件的每个角落) + +## 音频开发应用场景 + +* 音频播放器,录音机 +* 语音电话 +* 音视频监控 +* 音视频直播 +* 音视频编辑/处理软件 +* 蓝牙耳机/音响等 + +## 音频开发具体内容 + +* [音频采集/播放](https://www.incoder.org/2018/10/27/android-audio/) +* 音频算法处理(去噪,静音检测,回声消除,音效处理,功放/增强,混音/分离,等等) +* [音频的编解码和格式转换](https://www.incoder.org/2018/11/07/android-audio-convert/) +* 音频传输协议的开发([SIP](https://zh.wikipedia.org/wiki/%E4%BC%9A%E8%AF%9D%E5%8F%91%E8%B5%B7%E5%8D%8F%E8%AE%AE),[A2DP](https://zh.wikipedia.org/wiki/%E8%97%8D%E7%89%99%E8%A6%8F%E7%AF%84#%E8%97%8D%E7%89%99%E7%AB%8B%E9%AB%94%E8%81%B2%E9%9F%B3%E8%A8%8A%E5%82%B3%E8%BC%B8%E8%A6%8F%E7%AF%84%EF%BC%88A2DP%EF%BC%89),[AVRCP](https://zh.wikipedia.org/wiki/%E8%97%8D%E7%89%99%E8%A6%8F%E7%AF%84#%E9%9F%B3%E9%A2%91%EF%BC%8F%E8%A7%86%E9%A2%91%E8%BF%9C%E7%A8%8B%E6%8E%A7%E5%88%B6%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6%EF%BC%88AVRCP%EF%BC%89),等等) + * SIP(Session Initiation Protocol:会话发起协议):一个由IETF MMUSIC工作组开发的协议,作为标准被提议用于建立,修改和终止包括视频,语音,即时通信,在线游戏和虚拟现实等多种多媒体元素在内的交互式用户会话 + * A2DP(Advance Audio Distribution Profile:蓝牙立体声音频传输规范):规定了使用蓝牙异步传输信道方式,传输高质量音乐文件数据的协议堆栈软件和使用方法,基于该协议就能通过以蓝牙方式传输高质量的立体声音乐 + * AVRCP(Audio Video Remote Control Profile:音频/视频远程控制配置文件):用于提供控制 TV、Hi-Fi 设备等的标准接口。此配置文件用于许可单个远程控制设备。 + +## 音频基础知识 + +声音经过麦克风采集后,得到是模拟信号,接着我们需要用程序将采集得到模拟型号,进行转换得到数字信号,这样我们才可以存储,交换等 + +>关于声音信息得到模拟信号的转换,我们一般是无需关心,设备的麦克风这些都已经帮我们转换好了,我们需要关心的是从麦克风得到的模拟信号,如何去转换为数字信号,最终保存为音频文件 + +### 模拟信号转数字信号 + +模拟信号一般通过[PCM(Pulse-code modulation:脉冲编码调制)](https://zh.wikipedia.org/wiki/%E8%84%88%E8%A1%9D%E7%B7%A8%E7%A2%BC%E8%AA%BF%E8%AE%8A)方法转换为数字信号 + +#### 转换步骤 + +1. [采样](https://zh.wikipedia.org/wiki/%E5%8F%96%E6%A8%A3):将一段时间内的连续信号转为离散信号 + * [模拟信号](https://zh.wikipedia.org/wiki/%E8%BF%9E%E7%BB%AD%E4%BF%A1%E5%8F%B7)本身是一种连续信号,它在一定的时间范围内可以有无限多个不同的取值 + * [数值信号](https://zh.wikipedia.org/wiki/%E7%A6%BB%E6%95%A3%E4%BF%A1%E5%8F%B7)指在取值上是离散的,不连续的信号 +2. 量化:值采样得到后的数据,我们用多少位的二进制数字来表示声音的振幅 +3. [编码](https://zh.wikipedia.org/wiki/%E8%AA%9E%E9%9F%B3%E7%B7%A8%E7%A2%BC):将采样量化后的数据按照一定的格式进行记录 + +#### PCM + +音频编码最多只能做到无限接近,至少目前的技术只能这样,相对自然界的信号,任何数字音频编码方式都是有损,因为无法完全还原。在计算机应用中,能够达到最高保真的就是PCM编码,因此PCM约定俗成了无损编码(PCM代表了数字音频中最佳的保真水平,并不意味着PCM就能够确保信号绝对保真,PCM也只能做到最大程度的无限接近) + +经过采集和量化后的声音信号已经是数字形式了,但是为了便于计算机的存储,处理,传输,还必须按照一定的要求进行数据`压缩`和`编码` + +##### 压缩 +一种音频文件格式可以支持多种编码,例如AVI文件格式,但多数的音频文件仅支持一种音频编码 + +主要的音频文件格式: + +* 无损格式,例如:[WAV](https://zh.wikipedia.org/wiki/WAV),[FLAC](https://zh.wikipedia.org/wiki/FLAC),[APE](https://zh.wikipedia.org/wiki/Monkey%27s_Audio),[ALAC](https://zh.wikipedia.org/wiki/Apple_Lossless),[WavPack(WV)](https://zh.wikipedia.org/wiki/WavPack) +* 有损格式,例如:[MP3](https://zh.wikipedia.org/wiki/MP3),[AAC](https://zh.wikipedia.org/wiki/%E9%80%B2%E9%9A%8E%E9%9F%B3%E8%A8%8A%E7%B7%A8%E7%A2%BC),[Ogg Vorbis](https://zh.wikipedia.org/wiki/Vorbis),[Opus](https://zh.wikipedia.org/wiki/Opus_%28%E9%9F%B3%E9%A2%91%E6%A0%BC%E5%BC%8F%29) + +##### 编码 + +根据编码方式的不同,音频编码技术分为三种 + +* 波形编码:音质质量高,编码速率也很高。脉冲编码调变(PCM)、自适应增量调制( ADM )、Adaptive( ADPCM )等都属于该类编码器。 +* 参数编码:音质质量低,编码速率也很低 +* 混合编码:音质和速率介于波形编码,参数编码之间 + +>为什么音频需要编码 +1. PCM所量化得到的数据是原始无损的数据,文件很大,不利于传播,存储等 +2. 如果都是未压缩的文件,那么基本无法做到差异化即部分需要知识产权保护的组织或机构等 + +## 音频开发中重要参数 + +### [采样率(samplerate)](https://zh.wikipedia.org/wiki/%E9%87%87%E6%A0%B7%E7%8E%87) + +指每秒从连续信号中提取并组成离散信号的采样个数,也就是1S内,对模拟信号进行多少次采样;采样频率越高,说明采样点之间越密集,记录这段音频所用的数据量就越大,因此音质也就越好 + +>[为什么通用的采样率是44.1kHz?](https://www.zhihu.com/question/22027722) + +### 量化精度(位宽) + +用二进位来表示每一个采样值,也称为量化位数,声音信号的量化位数一般是4,6,8,12或16 bits. + +这个数值的数据类型大小可以是:4bit,8bit,16bit,32bit等等,位数越多,表示的就越精细,声音的质量也就越好,当然文件大小也会成倍增大 + +### 声道数(channels) + +由于音频的采集和播放是可以叠加的,因此,可以同时从多个音频源采集声音,并分别输出到不同的扬声器,故声道数一般表示声音录制时的音源数量或回放时相应的扬声器数量 + +* 单声道(Mono):1 +* 双声道(Stereo):2 + +### 比特率 + +比特率是音频文件每秒占据的字节数(比特数) + +比特率规定适用“比特每秒”(`bit/s`或`bps`)为单位,其中`ps`指的是`/s`,即每秒。 + +通常我们在音乐播放软件中看到的音乐质量『标准(128kbit/s),较高(198kbit/s),极高(320kbit/s)』表述的即比特率 + +### 音频帧(frame) + +视频每一帧就是一张图像,而音频数据是流式,本身没有明确的一帧帧的概念,在实际的应用中,为了音频算法处理/传输的方便,一般约定俗称2.5ms~60ms为单位的数据量为一帧音频。 + +### 理论音频的大小 + +假设某通道的音频信号是采样率为8kHz,位宽为16bit,20ms一帧,双通道,则一帧音频数据的大小为: +```java +# 一帧音频的大小 +int size = 8000 x 16bit x 0.02s x 2 = 5120 bit = 640 byte; +``` + +## 音频处理开源项目 + +### VoIP相关 +基于IP的语音传输(英语:Voice over Internet Protocol,缩写为VoIP)是一种语音通话技术,经由网际协议(IP)来达成语音通话与多媒体会议,也就是经由互联网来进行通信。其他非正式的名称有IP电话(IP telephony)、互联网电话(Internet telephony)、宽带电话(broadband telephony)以及宽带电话服务(broadband phone service)。 +* imsdroid +* sipdroid +* csipsimple +* linphone +* WebRTC + +### 算法相关 +* ffmpeg +* speex + +### 其他 +MP3编码库 +* [Lame](https://sourceforge.net/projects/lame) + +## Android提供相关API + +* 音频采集:MediaRecoder,AudioRecord +* 音频播放:SoundPool,MediaPlayer,AudioTrack +* 音频编解码:MediaCodec +* NDK API:OpenSL ES + +## 附录 + +* [语音编码](https://zh.wikipedia.org/wiki/%E8%AA%9E%E9%9F%B3%E7%B7%A8%E7%A2%BC) +* [高级音频编码 ● AAC](https://zh.wikipedia.org/wiki/%E9%80%B2%E9%9A%8E%E9%9F%B3%E8%A8%8A%E7%B7%A8%E7%A2%BC) +* [音频技术可以延展众多应用场景](https://yq.aliyun.com/articles/628109) \ No newline at end of file diff --git a/source/_posts/android-audio.md b/source/_posts/android-audio.md new file mode 100644 index 000000000..55eaf9ca3 --- /dev/null +++ b/source/_posts/android-audio.md @@ -0,0 +1,395 @@ +--- +title: Android 音频录制与播放 +date: 2018-10-27 09:44:46 +categories: Android +tag: [media] +--- + +上一篇主要介绍了音频相关的一些基础知识,本篇主要介绍在Android系统中如何进行音频的录制,播放 + +## 音频录制 + +Android SDK中提供了`AudioRecord`,`MediaRecorder`两个API经行音频的录制,具体的优缺点等如下: + +* [AudioRecord](https://developer.android.google.cn/reference/android/media/AudioRecord) 『added in API level 3』(基于字节流录音): + 优点:可以实现语音的实时处理,进行边录边播,对音频的实时处理。 + 缺点:输出的是PCM的语音数据,如果保存成音频文件是不能被播放器播放的。要用到这个去进行处理。 + 适用场景:需要实时处理分析的录音场景等,如:会说话的汤姆猫『[AppStore](https://itunes.apple.com/cn/app/%E4%BC%9A%E8%AF%B4%E8%AF%9D%E7%9A%84%E6%B1%A4%E5%A7%86%E7%8C%AB/id377194688?mt=8) | [GooglePlay](https://play.google.com/store/apps/details?id=com.outfit7.talkingtom&hl=zh)』 + +* [MediaRecorder](https://developer.android.google.cn/reference/android/media/MediaRecorder) 『added in API level 1』(基于文件音视频录制): + 优点:封装度很高,操作简单,无需处理中间录制过程;录制的音频文件是经过压缩的,需要设置编码器;录制的音频文件可以使用系统自带的播放器播放 + 缺点:无法实现实时处理音频,输出的音频格式少。 + 适用场景:录制过程需要实时处理的场景等 + +## 音频播放 +* [AudioTrack](https://developer.android.google.cn/reference/android/media/AudioTrack)『added in API level 3』: +AudioTrack 则更接近底层,提供了非常强大的控制能力,支持低延迟播放,适合流媒体和VoIP语音电话等场景 + +* [SoundPool](https://developer.android.google.cn/reference/android/media/SoundPool) 『added in API level 1』: + 优点:主要用于播放一些较短的声音片段,支持从程序的资源或文件系统加载;CPU的资源占用量低、反应延迟小,并且可以加载多个音频到`SoundPool`中,通过资源ID来管理 + 缺点:SoundPool加载资源,最大只能申请 **1MB** 的内存控件,因此只能用来播放一些很短的声音片段 + 适用场景:播放短,反应要求高的音频 + +* [MediaPlayer](https://developer.android.google.cn/reference/android/media/MediaPlayer) 『added in API level 1』(基于字节流音视频播放): + 优点:支持本地,网络音频资源的播放 + 缺点:资源占用量较高、加载延迟时间较长;不支持多个音频同时播放等 + 适用场景:播放长音频 + +>Google官方给出了[兼容支持](https://developer.android.google.cn/guide/topics/media/media-formats#audio-formats) + +## AudioRecord + +### 录制流程 + +1. 构造一个`AudioRecord`对象,其中需要的最小音频缓存`buffer`大小可以通过`getMinBufferSize()`方法得到,如果`buffer`容量过小,将导致对象构造失败 +2. 初始化一个`buffer`,该`buffer` 大于等于`AudioRecord`对象用于写音频数据的`buffer`大小 +3. 开始录音 +4. 创建一个数据流,一边从`AudioRecord`中读取音频数据到初始化的`buffer`,一边将`buffer`中的数据导入数据流 +5. 关闭数据流 +6. 停止录音 + +### 参数配置 + +* audioSource :音频采集的输入源 + * DEFAULT(默认) + * VOICE_RECOGNITION(用于语音识别,等同于DEFAULT) + * MIC(由手机麦克风输入) + * VOICE_COMMUNICATION(用于VoIP应用) +* sampleRateInHz:采样率 + 目前44100Hz是唯一可以保证兼容所有Android手机的采样率 +* channelConfig:通道数的配置 + * CHANNEL_IN_MONO:单通道 + * CHANNEL_IN_STEREO:双通道 +* audioFormat:数据位宽 + * ENCODING_PCM_8BIT:8bit + * ENCODING_PCM_16BIT:16bit +* bufferSizeInBytes:AudioRecord 内部的音频缓冲区的大小,该缓冲区的值不能低于一帧“音频帧”(Frame)的大小 + + +### 示例代码 +```java +public class AudioCapturer { + + private static final String TAG = "AudioCapturer"; + + private static final int DEFAULT_SOURCE = MediaRecorder.AudioSource.MIC; + private static final int DEFAULT_SAMPLE_RATE = 44100; + private static final int DEFAULT_CHANNEL_CONFIG = AudioFormat.CHANNEL_IN_MONO; + private static final int DEFAULT_AUDIO_FORMAT = AudioFormat.ENCODING_PCM_16BIT; + + private AudioRecord mAudioRecord; + private int mMinBufferSize = 0; + + private Thread mCaptureThread; + private boolean mIsCaptureStarted = false; + private volatile boolean mIsLoopExit = false; + + private OnAudioFrameCapturedListener mAudioFrameCapturedListener; + + public interface OnAudioFrameCapturedListener { + public void onAudioFrameCaptured(byte[] audioData); + } + + public boolean isCaptureStarted() { + return mIsCaptureStarted; + } + + public void setOnAudioFrameCapturedListener(OnAudioFrameCapturedListener listener) { + mAudioFrameCapturedListener = listener; + } + + public boolean startCapture() { + return startCapture(DEFAULT_SOURCE, DEFAULT_SAMPLE_RATE, DEFAULT_CHANNEL_CONFIG, + DEFAULT_AUDIO_FORMAT); + } + + public boolean startCapture(int audioSource, int sampleRateInHz, int channelConfig, int audioFormat) { + + if (mIsCaptureStarted) { + Log.e(TAG, "Capture already started !"); + return false; + } + + mMinBufferSize = AudioRecord.getMinBufferSize(sampleRateInHz,channelConfig,audioFormat); + if (mMinBufferSize == AudioRecord.ERROR_BAD_VALUE) { + Log.e(TAG, "Invalid parameter !"); + return false; + } + Log.d(TAG , "getMinBufferSize = "+mMinBufferSize+" bytes !"); + + mAudioRecord = new AudioRecord(audioSource,sampleRateInHz,channelConfig,audioFormat,mMinBufferSize); + if (mAudioRecord.getState() == AudioRecord.STATE_UNINITIALIZED) { + Log.e(TAG, "AudioRecord initialize fail !"); + return false; + } + + mAudioRecord.startRecording(); + + mIsLoopExit = false; + mCaptureThread = new Thread(new AudioCaptureRunnable()); + mCaptureThread.start(); + + mIsCaptureStarted = true; + + Log.d(TAG, "Start audio capture success !"); + + return true; + } + + public void stopCapture() { + + if (!mIsCaptureStarted) { + return; + } + + mIsLoopExit = true; + try { + mCaptureThread.interrupt(); + mCaptureThread.join(1000); + } + catch (InterruptedException e) { + e.printStackTrace(); + } + + if (mAudioRecord.getRecordingState() == AudioRecord.RECORDSTATE_RECORDING) { + mAudioRecord.stop(); + } + + mAudioRecord.release(); + + mIsCaptureStarted = false; + mAudioFrameCapturedListener = null; + + Log.d(TAG, "Stop audio capture success !"); + } + + private class AudioCaptureRunnable implements Runnable { + + @Override + public void run() { + + while (!mIsLoopExit) { + + byte[] buffer = new byte[mMinBufferSize]; + + int ret = mAudioRecord.read(buffer, 0, mMinBufferSize); + if (ret == AudioRecord.ERROR_INVALID_OPERATION) { + Log.e(TAG , "Error ERROR_INVALID_OPERATION"); + } + else if (ret == AudioRecord.ERROR_BAD_VALUE) { + Log.e(TAG , "Error ERROR_BAD_VALUE"); + } + else { + if (mAudioFrameCapturedListener != null) { + mAudioFrameCapturedListener.onAudioFrameCaptured(buffer); + } + Log.d(TAG , "OK, Captured "+ret+" bytes !"); + } + } + } + } +} +``` +## AudioTrack + +### 播放流程 + +1. 配置参数,初始化内部的音频播放缓冲区到,如果`buffer`容量过小,将导致对象构造失败 +2. 开始播放 +3. 需要一个线程,不断地向 AudioTrack 的缓冲区`写入`音频数据,注意,这个过程一定要及时,否则就会出现`underrun`的错误,该错误在音频开发中比较常见,意味着应用层没有及时地“送入”音频数据,导致内部的音频播放缓冲区为空 +4. 停止播放,释放资源 + +### 参数配置 +* streamType:当前应用使用的哪一种音频管理策略 +当系统有多个进程需要播放音频时,这个管理策略会决定最终的展现效果 + * STREAM_VOCIE_CALL:电话声音 + * STREAM_SYSTEM:系统声音 + * STREAM_RING:铃声 + * STREAM_MUSCI:音乐声 + * STREAM_ALARM:警告声 + * STREAM_NOTIFICATION:通知声 +* sampleRateInHz:采样率 +采样率的取值范围必须在 4000Hz~192000Hz 之间 +* channelConfig:通道数的配置 + * CHANNEL_IN_MONO:单通道 + * CHANNEL_IN_STEREO:双通道 +* audioFormat:数据位宽 + * ENCODING_PCM_8BIT:8bit + * ENCODING_PCM_16BIT:16bit +* bufferSizeInBytes:配置的是 AudioTrack 内部的音频缓冲区的大小,该缓冲区的值不能低于一帧“音频帧”(Frame)的大小 +* mode:AudioTrack 播放模式 + * MODE_STATIC + static:一次性将所有的数据都写入播放缓冲区,简单高效,通常用于播放铃声、系统提醒的音频片段 + * MODE_STREAM + streaming:按照一定的时间间隔不间断地写入音频数据,理论上它可用于任何音频播放的场景 + +### 示例代码 + +```java +public class AudioPlayer { + + private static final String TAG = "AudioPlayer"; + + private static final int DEFAULT_STREAM_TYPE = AudioManager.STREAM_MUSIC; + private static final int DEFAULT_SAMPLE_RATE = 44100; + private static final int DEFAULT_CHANNEL_CONFIG = AudioFormat.CHANNEL_IN_STEREO; + private static final int DEFAULT_AUDIO_FORMAT = AudioFormat.ENCODING_PCM_16BIT; + private static final int DEFAULT_PLAY_MODE = AudioTrack.MODE_STREAM; + + private boolean mIsPlayStarted = false; + private int mMinBufferSize = 0; + private AudioTrack mAudioTrack; + + public boolean startPlayer() { + return startPlayer(DEFAULT_STREAM_TYPE,DEFAULT_SAMPLE_RATE,DEFAULT_CHANNEL_CONFIG,DEFAULT_AUDIO_FORMAT); + } + + public boolean startPlayer(int streamType, int sampleRateInHz, int channelConfig, int audioFormat) { + + if (mIsPlayStarted) { + Log.e(TAG, "Player already started !"); + return false; + } + + mMinBufferSize = AudioTrack.getMinBufferSize(sampleRateInHz,channelConfig,audioFormat); + if (mMinBufferSize == AudioTrack.ERROR_BAD_VALUE) { + Log.e(TAG, "Invalid parameter !"); + return false; + } + Log.d(TAG , "getMinBufferSize = "+mMinBufferSize+" bytes !"); + + mAudioTrack = new AudioTrack(streamType,sampleRateInHz, + channelConfig,audioFormat,mMinBufferSize,DEFAULT_PLAY_MODE); + + if (mAudioTrack.getState() == AudioTrack.STATE_UNINITIALIZED) { + Log.e(TAG, "AudioTrack initialize fail !"); + return false; + } + + mIsPlayStarted = true; + + Log.d(TAG, "Start audio player success !"); + + return true; + } + + public int getMinBufferSize() { + return mMinBufferSize; + } + + public void stopPlayer() { + + if (!mIsPlayStarted) { + return; + } + + if (mAudioTrack.getPlayState() == AudioTrack.PLAYSTATE_PLAYING) { + mAudioTrack.stop(); + } + + mAudioTrack.release(); + mIsPlayStarted = false; + + Log.d(TAG, "Stop audio player success !"); + } + + public boolean play(byte[] audioData, int offsetInBytes, int sizeInBytes) { + + if (!mIsPlayStarted) { + Log.e(TAG, "Player not started !"); + return false; + } + + if (sizeInBytes < mMinBufferSize) { + Log.e(TAG, "audio data is not enough !"); + return false; + } + + if (mAudioTrack.write(audioData,offsetInBytes,sizeInBytes) != sizeInBytes) { + Log.e(TAG, "Could not write all the samples to the audio device !"); + } + + mAudioTrack.play(); + + Log.d(TAG , "OK, Played "+sizeInBytes+" bytes !"); + + return true; + } +} +``` + +## MediaRecorder + +![mediarecorder](https://developer.android.google.cn/images/mediarecorder_state_diagram.gif) + +如上所示表述整个MediaRecorder的整个生命过程,可以看出初始化之后,在任意的状态下调用`reset()`方法均可以回到MediaRecorder刚刚初始化完成的状态 + +## MediaPlayer + +![mediaplayer](https://developer.android.google.cn/images/mediaplayer_state_diagram.gif) + +### MediaPlayer 工作流程 + +1. 创建一个MediaPlayer对象 +2. 调用setDataSource()方法,设置音频文件的路径 +3. 接着调用prepare()方法,使MediaPlayer进入的准备状态 +4. 调用start()方法,开始播放音频『pause()方法表示:暂停播放』 + +### MediaPlayer常用的控制方法 + +| 方法名 | 功能描述 | +| ---------- | --- | +| setDataSource() | 设置要播放的音频文件的位置 | +| prepare() | 在开始播放之前调用这个方法完成准备工作 | +| start() | 开始或继续播放音频 | +| pause() | 暂停播放音频 | +| reset() | 将MediaPlayer对象重置到刚刚创建的状态 | +| seekTo() | 从指定位置开始播放音频 | +| stop() | 停止播放音频。调用这个方法后的MediaPlayer对象无法再播放音频 | +| release() | 释放掉与MediaPlayer对象相关的资源 | +| isPlaying() | 判断当前MediaPlayer是否正在播放音频 | +| getDuration() | 获取站如的音频文件的时长 | + +### 注意事项 + +1. 在使用`star()`播放流媒体之前,需要装载流媒体资源。这里最好使用`prepareAsync()`异步的方式装载流媒体资源,在使用`prepareAsync()`异步加载时,为避免还没有装载完就调用了`start()`而保存,需要绑定`MediaPlayer.setOnPreparedListener()`事件,它将在异步装在完成后回调 +原因:流媒体资源的装载是会消耗系统资源,在一些硬件不理想的设备上,如果使用`prepare()`同步的方式装载资源,可能会造成UI界面卡顿,其次避免装载超时而引发`ANR`等问题 +2. 使用完MediaPlayer需要回收资源。MediaPlayer时很消耗系统资源的,所以在使用完MediaPlayer,及时主动回收资源 +3. 对于单曲循环之类的操作,除了使用`setLooping()`方法设置之外,还可以为MediaPlayer注册回调函数,`MediaPlayer.setOnCompletionListener()`,它会在MediaPlayer播放完被回调 +4. 由于无法确保播放的流媒体是完整(中间有错误),我们需要处理这个错误,否则会影响用户体验。可以在MediaPlayer中注册`setOnErrorListener()`错误回调,一般重新播放或者播放下一个流媒体 + +## 跨平台 + +关于音频编解码在各平台上的情况如下 +![wiki-ecode](https://res.cloudinary.com/incoder/image/upload/v1541055152/blog/android-audio.png) + +从上图可知,[AAC](https://zh.wikipedia.org/wiki/%E9%80%B2%E9%9A%8E%E9%9F%B3%E8%A8%8A%E7%B7%A8%E7%A2%BC),[FLAC](https://zh.wikipedia.org/wiki/FLAC),[MP3](https://zh.wikipedia.org/wiki/MP3)三种编码是全平台支持的音频编码方式(或音频压缩方式),注意编码方式并不是文件格式即文件的扩展名 + +* AAC 主要扩展名 + * `.aac` + * `.mp4` + * `.m4a` +* FLAC 扩展名 + * `.flac` +* MP3 扩展名 + * `.mp3` + +## 总结 + +* 音频的录制,Android SDK提供了两套音频采集的API,分别是:`MediaRecorder`和`AudioRecord`,前者是一个更加上层一点的API,它可以直接把手机麦克风录入的音频数据进行编码压缩(如:`AMR`,`OGG`等)并存储成文件,而后者则更接近底层,能够更加自由灵活的控制,可以得到原始的一帧帧`PCM`音频数据 +* 如果要简单的进行音频的采集,录制成音频文件,则推荐适用`MediaRecorder`,而如果需要对音频做进一步的算法处理,或者采用第三方的编码库进行压缩、以及网络传输等应用,则建议适用`AudioRecord` +* `MediaRecorder`底层的实现也是调用了`AudioRecord`与`Android Framework` 层的`AudioFlinger`进行交互 + +> 关于音视频相关的资料参差不齐,目前尚未有大量相关专门的书籍来介绍该领域的图书或者易懂视频,很多情况需要根据所处应用场景灵活应变。 +推荐刚刚发行的一本关于音频方面的图书[《Android音视频开发》](https://item.jd.com/35027062396.html) +推荐国内比较专业音视频方面相关的介绍[《雷霄骅的专栏》](http://blog.csdn.net/leixiaohua1020) +## 附录 + +* [音频编码格式的比较](https://zh.wikipedia.org/wiki/%E9%9F%B3%E9%A2%91%E7%BC%96%E7%A0%81%E6%A0%BC%E5%BC%8F%E7%9A%84%E6%AF%94%E8%BE%83) +* [第一行代码](https://book.douban.com/subject/26915433) +* [Android MediaRecorder架构详解](http://www.isclab.org.cn/archives/2014/12/2946.html) +* [参考代码](https://github.com/googlesamples/android-MediaRecorder) +* [浏览器引擎](https://zh.wikipedia.org/wiki/%E6%8E%92%E7%89%88%E5%BC%95%E6%93%8E) +* [主流浏览器内核介绍](https://www.cnblogs.com/zichi/p/5116764.html) +* [腾讯X5内核介绍](https://x5.tencent.com/tbs/product/tbs.html) +* [Android 音视频开发学习思路](http://www.cnblogs.com/renhui/p/7452572.html) \ No newline at end of file diff --git a/source/_posts/android-string.md b/source/_posts/android-string.md new file mode 100644 index 000000000..2da3fec70 --- /dev/null +++ b/source/_posts/android-string.md @@ -0,0 +1,138 @@ +--- +title: Android XML字符串 +date: 2019-10-27 09:44:46 +categories: Android +tag: [Util] +--- + +Android在开发过程中,一些特殊字符时无法直接在 `strings.xml` 文件中写,需要用对应的转义字符代替或者在特殊符号(比如:`´`,`"` 等待)前添加 `\` ,比如一个 `TextView` 控件中,需要动态替换其中的一些数据,再比如需要调整 `TextView` 字体的一些HTML样式(比如:粗体,斜体,下划线等),虽然这些都可以用 `TextView` 去修改,但更简单的方法是设置string提供的属性即可 + +## 特殊字符 + +```xml + + + + + I'm developer + + I\'m developer + +``` + +## 动态替换或拼接 + +* `%n$ms`:代表输出的是字符串,n代表是第几个参数,设置m的值可以在输出之前放置空格 +* `%n$md`:代表输出的是整数,n代表是第几个参数,设置m的值可以在输出之前放置空格 +* `%n$mf`:代表输出的是浮点数,n代表第几个参数,m在浮点类型之前放置几个空格 + +### XML配置 + +```xml + + + + Hello, %1$s, You have %2$d new messages. total cost %3$4.2f + +``` + +### Java设置 + +```java +mTextConent = (TextView) findViewById(R.id.tv_String); +mTextConent.setText(String.format(getString(R.string.welcome_messages), "Jerry", 36, 195.1255)); +``` + +## HTML标记 + +* `` 表示 **粗体** 文本。 +* `` 表示 *斜体* 文本。 +* `` 表示 下划线 文本。 + +```xml + + + Welcome to Android! + Welcome to Android! + Welcome to Android! + +``` + +## ASCII对照表 + +| ASCII码 | 符号 | ASCII码 | 符号 | ASCII码 | 符号 | ASCII码 | 符号 | +| --------- | -------------------------------- | --------- | ------ | -------- | ---- | -------- | ---- | +| `@` | @ | `:` | : | ` ` | 空格 | ` ` | 空格 | +| `!` | ! | `"` | " | `#` | # | `$` | $ | +| `%` | % | `&` | & | `'` | ´ | `(` | ( | +| `* ` | * | `+` | + | `,` | , | `)` | ) | +| `-` | - | `.` | . | `/` | / | `:` | : | +| `;` | ; | `<` | < | `=` | = | `>` | > | +| `?` | ? | `@` | @ | `[` | [ | `\` | > | +| `]` | ] | `^` | ^ | `_` | _ | ``` | ` | +| `{` | { | `| ` | | | `}` | } | `~` | ~ | +| ` ` | (空格,在xml首字符中不会被忽略) | `¡` | ¡ | `¢` | ¢ | `£` | £ | +| `¤` | ¤ | `¥` | ¥ | `¦` | ¦ | `§` | § | +| `¨` | ¨ | `©` | © | `ª` | ª | `«` | « | +| `¬` | ¬ | `­` | -­ | `®` | ® | `¯` | ¯ | +| `°` | ° | `±` | ± | `²` | ² | `³` | ³ | +| `´` | ´ | `µ` | µ | `¶` | ¶ | `·` | • | +| `¸` | ¸ | `¹` | ¹ | `º` | º | `»` | » | +| `¼` | ¼ | `½` | ½ | `¾` | ¾ | `¿` | ¿ | +| `À` | À | `Á` | Á | `Â` |  | `Ã` | à | +| `Ä` | Ä | `Å` | Å | `Æ` | Æ | `Ç` | Ç | +| `È` | È | `É` | É | `Ê` | Ê | `Ë` | Ë | +| `Ì` | Ì | `Í` | Í | `Î` | Î | `Ï` | Ï | +| `Ð` | Ð | `Ñ` | Ñ | `Ò` | Ò | `Ó` | Ó | +| `Ô` | Ô | `Õ` | Õ | `Ö` | Ö | `×` | × | +| `Ø` | Ø | `Ù` | Ù | `Ú` | Ú | `Û` | Û | +| `Ü` | Ü | `Ý` | Ý | `Þ` | Þ | `ß` | ß | +| `à` | à | `á` | á | `â` | â | `ã` | ã | +| `ä` | ä | `å` | å | `æ` | æ | `ç` | ç | +| `è` | è | `é` | é | `ê` | ê | `ë` | ë | +| `ì` | ì | `í` | í | `î` | î | `ï` | ï | +| `ð` | ð | `ñ` | ñ | `ò` | ò | `ó` | ó | +| `ô` | ô | `õ` | õ | `ö` | ö | `÷` | ÷ | +| `ø` | ø | `ù` | ù | `ú` | ú | `û` | û | +| `ü` | ü | `ý` | ý | `þ` | þ | `ÿ` | ÿ | +| `Ā` | Ā | `ā` | ā | `Ă` | Ă | `ă` | ă | +| `Ą` | Ą | `ą` | ą | `Ć` | Ć | `ć` | ć | +| `Ĉ` | Ĉ | `ĉ` | ĉ | `Ċ` | Ċ | `ċ` | ċ | +| `Č` | Č | `č` | č | `Ď` | Ď | `ď` | ď | +| `Đ` | Đ | `đ` | đ | `Ē` | Ē | `ē` | ē | +| `Ĕ` | Ĕ | `ĕ` | ĕ | `Ė` | Ė | `ė` | ė | +| `Ę` | Ę | `ę` | ę | `Ě` | Ě | `ě` | ě | +| `Ĝ` | Ĝ | `ĝ` | ĝ | `Ğ` | Ğ | `ğ` | ğ | +| `Ġ` | Ġ | `ġ` | ġ | `Ģ` | Ģ | `ģ` | ģ | +| `Ĥ` | Ĥ | `ĥ` | ĥ | `Ħ` | Ħ | `ħ` | ħ | +| `Ĩ` | Ĩ | `ĩ` | ĩ | `Ī` | Ī | `ī` | ī | +| `Ĭ` | Ĭ | `ĭ` | ĭ | `Į` | Į | `į` | į | +| `İ` | İ | `ı` | ı | `IJ` | IJ | `ij` | ij | +| `Ĵ` | Ĵ | `ĵ` | ĵ | `Ķ` | Ķ | `ķ` | ķ | +| `ĸ` | ĸ | `Ĺ` | Ĺ | `ĺ` | ĺ | `Ļ` | Ļ | +| `ļ` | ļ | `Ľ` | Ľ | `ľ` | ľ | `Ŀ` | Ŀ | +| `ŀ` | ŀ | `Ł` | Ł | `ł` | ł | `Ń` | Ń | +| `ń` | ń | `Ņ` | Ņ | `ņ` | ņ | `Ň` | Ň | +| `ň` | ň | `ʼn` | ʼn | `Ŋ` | Ŋ | `ŋ` | ŋ | +| `Ō` | Ō | `ō` | ō | `Ŏ` | Ŏ | `ŏ` | ŏ | +| `Ő` | Ő | `ő` | ő | `Œ` | Œ | `œ` | œ | +| `Ŕ` | Ŕ | `ŕ` | ŕ | `Ŗ` | Ŗ | `ŗ` | ŗ | +| `Ř` | Ř | `ř` | ř | `Ś` | Ś | `ś` | ś | +| `Ŝ` | Ŝ | `ŝ` | ŝ | `Ş` | Ş | `ş` | ş | +| `Š` | Š | `š` | š | `Ţ` | Ţ | `ţ` | ţ | +| `Ť` | Ť | `ť` | ť | `Ŧ` | Ŧ | `ŧ` | ŧ | +| `Ũ` | Ũ | `ũ` | ũ | `Ū` | Ū | `ū` | ū | +| `Ŭ` | Ŭ | `ŭ` | ŭ | `Ů` | Ů | `ů` | ů | +| `Ű` | Ű | `ű` | ű | `Ų` | Ų | `ų` | ų | +| `Ŵ` | Ŵ | `ŵ` | ŵ | `Ŷ` | Ŷ | `ŷ` | ŷ | +| `Ÿ` | Ÿ | `Ź` | Ź | `ź` | ź | `Ż` | Ż | +| `ż` | ż | `Ž` | Ž | `ž` | ž | | | + +## 附录 + +* [字符串资源](https://developer.android.google.cn/guide/topics/resources/string-resource?hl=zh-cn) \ No newline at end of file diff --git a/source/_posts/charles.md b/source/_posts/charles.md new file mode 100644 index 000000000..867580c22 --- /dev/null +++ b/source/_posts/charles.md @@ -0,0 +1,152 @@ +--- +title: Charles 使用教程 +date: 2018-11-29 11:25:46 +categories: DevTool +tag: [Charles] +--- + +![charles](https://res.cloudinary.com/incoder/image/upload/v1559463393/blog/charles.png) + +Charles is an HTTP proxy / HTTP monitor / Reverse Proxy that enables a developer to view all of the HTTP and SSL / HTTPS traffic between their machine and the Internet. This includes requests, responses and the HTTP headers (which contain the cookies and caching information) + + + +Charles是一个HTTP代理/ HTTP监视器/ 反向代理,使开发人员能够查看其机器和Internet之间的所有HTTP和SSL / HTTPS流量,这包括请求,响应和HTTP标头(包含cookie和缓存信息) + +## Charles +主要特点 +* [SSL代理](https://www.charlesproxy.com/documentation/proxying/ssl-proxying/) - 以纯文本格式查看SSL请求和响应 +* [Bandwidth Throttling](https://www.charlesproxy.com/documentation/proxying/throttling/)模拟较慢的Internet连接,包括延迟 +* AJAX调试 - 以树或文本形式查看XML和JSON请求和响应 +* [AMF](https://www.charlesproxy.com/documentation/additional/amf/) - 以树形式查看Flash Remoting / Flex Remoting消息的内容 +* 重复请求以测试后端更改 +* 编辑测试不同输入的请求 +* 用于拦截和编辑请求或响应的断点 +* 使用W3C验证器验证记录的HTML,CSS和RSS / atom响应 + +>本篇文章操作均基于Charlers 4.2.8版本,及 macOS 10.14.5 版本 + +### 安装 + +* Windows:略 +* macOS:略 +>下载地址:[官方Charles](https://www.charlesproxy.com/download/) + +#### 激活 + +有能力,请支持付费支持正版~ +有能力,请支持付费支持正版~ +有能力,请支持付费支持正版~ + +仅供个人学习研究和交流使用,请勿用于任何商业用途。 +Charles ——> Help ——> Register Charles... +``` +Registered Name: https://zhile.io +License Key: 48891cf209c6d32bf4 +``` +[激活密钥来自CSDN](https://blog.csdn.net/qq_25821067/article/details/79848589) + +### 配置 +配置流程 +1. 获取操作系统网络IP地址 +2. 修改客户端网络IP连接 +3. 在操作系统及客户端上安装证书 +4. 设置SSL代理 +> 以上配置要求,操作系统(Windows,macOS)及客户端(Android,iOS)连接在 **同一WiFi网络** + +#### 获取系统 IP +不管是是 Windows 系统还是 macOS 系统都可以通过 Charles 来获取,获取方式 `Help` ——> `Local IP Address` +![charles-ip](https://res.cloudinary.com/incoder/image/upload/v1559436487/blog/charles-ip.png) + +##### Windows +使用命令行查看网络 IP 地址 `ipconfig` +![charles-windows-ip](https://res.cloudinary.com/incoder/image/upload/v1559437724/blog/charles-windows-ip.png) + +##### macOS +* 使用命令行查看网络 IP 地址 `ifconfig en0` + ![charles-mac-ip](https://res.cloudinary.com/incoder/image/upload/v1559436484/blog/charles-mac-ip.png) +* macOS系统设置查看IP 地址 `System Preferences` ——> `Network` + ![charles-network-ip](https://res.cloudinary.com/incoder/image/upload/v1559437653/blog/charles-network-ip.png) + +#### 查看监听端口 +`Proxy`——> `Proxy settings...` +![charles-view-port](https://res.cloudinary.com/incoder/image/upload/v1559437270/blog/charles-view-port.png) + +#### 客户端设置 +要求手机网络与 PC 网络同链接在一个路由器网络下,这样手机的请求都将通过 PC,因此在 Charles 上可以看到手机上的网络请求。 + +手机上安装下面的步骤请看下面的详细介绍,安装完证书,Charles 将会收到提示,进行允许即可 +![charles-allow](https://res.cloudinary.com/incoder/image/upload/v1559465134/blog/charles-allow.png) + +##### Android +* 修改网络配置选项 + +* 导入Charles证书,使用浏览器打开 [www.charlesproxy.com/getssl](http://www.charlesproxy.com/getssl) 或 [http://chls.pro/ssl](chls.pro/ssl),下载证书,并进行安装 + +##### iOS +* 修改网络配置选项 + +* 导入Charles证书 + +* 证书授权 + +##### 模拟器 + +#### Charles设置 + +* Install Charles Root Certificate +完成客户端的设置,我们此时再对 Charles 进行设置,首先我们先进性安装 Charles 证书,`Help` ——> `SSL Proxying...` ——> `Install Charles Root Certificate` + ![charles-install-system](https://res.cloudinary.com/incoder/image/upload/v1559464456/blog/charles-install-system.png) +* 添加证书 + ![charles-add](https://res.cloudinary.com/incoder/image/upload/v1559464726/blog/charles-add.png) +* 证书授权设置 + ![charles-ca-settings](https://res.cloudinary.com/incoder/image/upload/v1559463067/blog/charles-ca-settings.png) +* SSL Proxy settings + ![charles-ssl-settings](https://res.cloudinary.com/incoder/image/upload/v1559463076/blog/charles-ssl-settings.png) + * Host:为需要过滤的域名地址,`*` 表示不过滤 + * Port:固定为443,`*` 表示任意端口 + +## 抓包 +不废话,请看图 +![charles-overview](https://res.cloudinary.com/incoder/image/upload/v1559467975/blog/charles-overview.png) + +* Structure:视图将网络请求按访问的域名分类 +* Sequence:视图将网络请求按访问的时间排序 + +> 客户端请不要开启其他代理 + +## 进阶 + +### 过滤网络请求 +* 方法一:在上面抓包的截图中,已经讲过,适用于 **临时型** 对请求进行过滤 +* 方法二:`Proxy` ——> `Recording settings` ——> `include` ,适用于 **经常性** 请求过滤 + ![charles-filter-often](https://res.cloudinary.com/incoder/image/upload/v1559470804/blog/charles-filter-often.png) + +### Map 功能 + +#### 设置本地映射 +指的是将网络请求重定向到本地的文件,适用于开发过程中,把线上的静态资源映射到本地,这样可以方便调试并及时查看效果,确定无误后再发布到线上环境 +![charles-map-local](https://res.cloudinary.com/incoder/image/upload/v1559473299/blog/charles-map-local.png) + +#### 设置远程映射 +指的是将网络请求重定向到另一个网络请求地址,适用于开发过程中,需要将请求重定向到其他的服务上 +![charles-map-remote](https://res.cloudinary.com/incoder/image/upload/v1559473845/blog/charles-map-remote.png) + +### 重复发送网络请求 +可以更加需要重复一次或多次的请求,对于多次的请求可用于服务器的压力测试 +![charles-repeat](https://res.cloudinary.com/incoder/image/upload/v1559475397/blog/charles-repeat.png) + +## 常见问题 +1. Charles无法抓取到客户端网络请求 + * 查看你的客户端网络设置,是否正确 + * 查看你的客户端和 Charles 是否是处于同一网络环境 +2. Charles 无法抓取 Https 网络请求 + * 查看你的客户端和 Charles 是否安装证书,并设置为终是允许 + +3. 网络请求及网络响应信息中文乱码 + +## 附录 +* [Charles Document](https://www.charlesproxy.com/documentation) +* [Charles抓包的安装,使用说明以及常见问题解决](https://blog.csdn.net/zhangxiang_1102/article/details/77855548) +* [抓包工具Charles的使用心得](https://www.jianshu.com/p/fdd7c681929c) +* [Charles抓包https](https://www.jianshu.com/p/ec0a38d9a8cf) \ No newline at end of file diff --git a/source/_posts/cloud-gcp.md b/source/_posts/cloud-gcp.md new file mode 100644 index 000000000..22f80d880 --- /dev/null +++ b/source/_posts/cloud-gcp.md @@ -0,0 +1,248 @@ +--- +title: Google Cloud Platform for VPN +date: 2018-11-07 14:43:46 +categories: Google +tag: [vpn] +--- + +![cloud-gcp](https://res.cloudinary.com/incoder/image/upload/v1541559310/blog/cloud-gcp.png) + +随着云产品的普及推广,各路国际大场也是纷纷推出了相关云产品的试用,其中具有代表性的[Google Cloud](https://cloud.google.com),[Amazon](https://aws.amazon.com),本篇主要讲解Googel Cloud产品的试用,并搭建SSR服务 + + + +Google Cloud 特点 + +* 可使用所有Cloud Platform产品 +* 免费获得$300赠金 +* 免费使用结束后不会自动收费 + +## 准备 +* Google Email +* visa 信用卡(需要$1进行认证,认传完成后返还$1) +> 因为Google本身在大陆是无法正常访问的,因此需要先**自备梯子**,可以先使用[Lantern](https://github.com/getlantern/lantern) + +## GCP + +### 申请Google Cloud Platform +[官网申请](https://cloud.google.com/free):https://cloud.google.com/free + +![gcp-register1](https://res.cloudinary.com/incoder/image/upload/v1542540776/blog/gcp-register1.png) +* 国家地区:`中国` +* 服务条款:`同意` +* 动态邮件:可选,根据自身需要勾选 + +![gcp-register2](https://res.cloudinary.com/incoder/image/upload/v1542540935/blog/gcp-register2.png) + +根据需要填写一些信息,由于我的Google账号已是开发者账号,一些信息都是完善的,所以Google直接关联了信息,因此也不会再扣除$1,如果你是新账号,详细步骤可参考附录 + +## VM创建 +在创建VM之前,我们先进行[网络防火墙修改](https://console.cloud.google.com/networking/firewalls/list),避免后续的麻烦 + +![gcp-firewall-settings](https://res.cloudinary.com/incoder/image/upload/v1542546675/blog/gcp-firewall-settings.png) +![gcp-create-firewall](https://res.cloudinary.com/incoder/image/upload/v1542545777/blog/gcp-create-firewall.png) +规则设置如下: +![gcp-firewall-rule](https://res.cloudinary.com/incoder/image/upload/v1542546500/blog/gcp-firewall-rule.png) + +* 名称:自己命名一个用于区分其它得规则 +* 来源IP地址范围:`0.0.0.0/0`,这个不要写错 +其它按照图上设置即可 + +### 创建VM实例 +![gcp-create-vm](https://res.cloudinary.com/incoder/image/upload/v1542546431/blog/gcp-create-vm.png) +![gcp-create-vm-init](https://res.cloudinary.com/incoder/image/upload/v1542546640/blog/gcp-create-vm-init.png) +![gcp-create-vm-course](https://res.cloudinary.com/incoder/image/upload/v1542546774/blog/gcp-create-vm-course.png) +* 名称:自己写一个即可 +* 地区:建议选亚洲,别人推荐`asia-east1-c`,**台湾彰化县**实测延迟低,我这里选择了香港 +* 机器类型:选微型(1个共享vCPU) +* 启动磁盘:推荐CentOS 7,当然也可以其它,选择自己熟悉的系统即可 +其中关于网络的设置如下: +![gcp-create-vm-network](https://res.cloudinary.com/incoder/image/upload/v1542547144/blog/gcp-create-vm-network.png) +* 名称:任意输入即可(小写字母开头,不能为大写字母) + +设置完成后,创建VM实例 + +## 连接VM + +当然,你可以使用浏览器打开连接VM +![gcp-link-vm-chrome](https://res.cloudinary.com/incoder/image/upload/v1542547502/blog/gcp-link-vm-chrome.png) + +经过实际操作,你会发现,在浏览器中操作延迟很高,因此我们就采用其它客户端去连接刚刚创建的这台服务器,下面分别以 [Xshell(Windows)](https://www.netsarang.com/products/xsh_overview.html) 和 [iTerm(macOS)](https://www.iterm2.com)来演示如何与 GCP 建立连接 + +### 使用Xshell + +#### 密钥生成 +1. 新建用户密钥生成向导 +![gcp-link-vm-xshell1](https://res.cloudinary.com/incoder/image/upload/v1542547944/blog/gcp-link-vm-xshell1.png) +2. 密钥类型长度设置 +![gcp-link-vm-xshell2](https://res.cloudinary.com/incoder/image/upload/v1542548236/blog/gcp-link-vm-xshell2.png) +3. 生成密钥 +![gcp-link-vm-xshell3](https://res.cloudinary.com/incoder/image/upload/v1542548733/blog/gcp-link-vm-xshell3.png) +4. 设置密钥名称及密码 +![gcp-link-vm-xshell4](https://res.cloudinary.com/incoder/image/upload/v1542548796/blog/gcp-link-vm-xshell4.png) +5. 保存密钥 +![gcp-link-vm-xshell5](https://res.cloudinary.com/incoder/image/upload/v1542548832/blog/gcp-link-vm-xshell5.png) + +#### GCP添加密钥 + +* 元数据 +![gcp-link-vm-settings](https://res.cloudinary.com/incoder/image/upload/v1542549326/blog/gcp-link-vm-settings.png) +* SSH +![gcp-link-vm-ssh](https://res.cloudinary.com/incoder/image/upload/v1542549369/blog/gcp-link-vm-ssh.png) +* SSH密钥添加 +![gcp-link-vm-create-ssh](https://res.cloudinary.com/incoder/image/upload/v1542549960/blog/gcp-link-vm-create-ssh.png) + +#### Xshell 连接服务 + +* 配置连接的服务器地址 +![gcp-link-vm-ssh-ip](https://res.cloudinary.com/incoder/image/upload/v1542554061/blog/gcp-link-vm-ssh-ip.png) +* 配置连接服务器的密钥 +![gcp-link-vm-ssh-login](https://res.cloudinary.com/incoder/image/upload/v1542554117/blog/gcp-link-vm-ssh-login.png) + +### 使用 iTerm + +稍后补充 + +## 准备工作 + +### 内核升级 +```bash +# 切换到root用户 +sudo -i +# 安装wget +yum install -y wget +# 安装bbr +wget --no-check-certificate https://github.com/teddysun/across/raw/master/bbr.sh +# 给bbr.sh文件设置权限 +chmod +x bbr.sh +# 启动bbr.sh脚本 +./bbr.sh +``` +执行完成后,会提示,输入`y`并`回车`后重启,这时需要等待几分钟 + +重启完成后,重新连接服务器 +```bash +# 切换到root用户 +sudo -i +# 查看内核(版本大于4.13或以上版本,就表示OK) +uname -r +``` + +### 选择安装服务 + +对于 SSR 和 v2ray **都**可以提供不可描述的服务,由于v2ray 功能更加强大,并且更加隐蔽,不易被发现,因此极力推荐使用 v2ray 方式 + +## SSR + +通过以上的配置,我们可以使用Xshell进行SSR工具的安装,安装SSR工具前,需要先升级系统内核,按照如下执行命令 + +### 安装SSR +```bash +# 切换到root用户 +sudo -i +# wget设置 +wget --no-check-certificate -O shadowsocks-all.sh +# 下载安装SSR +https://raw.githubusercontent.com/teddysun/shadowsocks_install/master/shadowsocks-all.sh +chmod +x shadowsocks-all.sh +# 执行SSR运行脚本 +./shadowsocks-all.sh 2>&1 | tee shadowsocks-all.log +``` +安装过程步骤如下: +* 选择版本:推荐ShadowsocksR,输入`2` +* 设置密码 +* 设置端口 +* 选择加密方式,这里选择chacha20,输入`12` +* 选择协议,这里选择auth_sha1_v4,输入`3` +* 选择混淆方式,这里选择http_simple,输入`2` +![gcp-link-vm-ssh-install](https://res.cloudinary.com/incoder/image/upload/v1542556264/blog/gcp-link-vm-ssh-install.png) + +等待安装完成,提示如下: +![gcp-link-vm-ssh-finish](https://res.cloudinary.com/incoder/image/upload/v1542556345/blog/gcp-link-vm-ssh-finish.png) + +根据安装完成后提示的信息配置你的SSR客户端即可 + +### 修改 SSR 配置 + +在实际过程中,我们安装完成后,可能根据实际环境,需要修改配置,那么我们该怎么去修改呢,直接看下面命令 +```bash +# shadowsocks-r 默认路径是 /etc/shadowsocks-r +vim /etc/shadowsocks-r/config.json +# 安装实际需要,更改后保存配置,然后重启shadowsocks-r 服务 +/etc/init.d/shadowsocks-r restart +# 记得更新你客户端相关的配置 +``` + +### 卸载 SSR + +```bash +# 切换到root用户 +sudo -i +# 进入脚本目录(可省略) +cd /home// +# 使用 help 查看指令(可省略) +./shadowsocks-all.sh -help +# 执行卸载 +./shadowsocks-all.sh uninstall +``` + +>当你不知道该应用拥有什么命令时,多用 help 来获取相关的指令 + +### SSR 常用命令 + +```bash +# 启动SSR +/etc/init.d/shadowsocks-r start +# 退出SSR +/etc/init.d/shadowsocks-r stop +# 重启SSR +/etc/init.d/shadowsocks-r restart +# SSR状态 +/etc/init.d/shadowsocks-r status +# 卸载SSR,默认目录 /home// +./shadowsocks-all.sh uninstall +``` + +## v2ray + +稍后补充 + +## 问题排查 + +每到敏感时期,一大批服务都会被封,这次我的服务也不理外,这里就讲一讲我是如何排除问题。 + +>所处环境说明: +>0. VPS 上安装的 SSR 服务 +>1. 可以使用 SSH 工具(比如:Xshell)可以连接 VPS 机器 +>2. 在 VPS 中 `ping google.com` 是可以的 +>3. 连接 VPS 的客户端,无法正常访问国外网站 + +出现以上情况,大概率是当前的 SSR 服务端口被封了,可以通过以下方式来验证 + +1. 使用国内站长工具端口扫描检查下 VPS 的端口是否可以正常访问,地址:[http://tool.chinaz.com/port](http://tool.chinaz.com/port/) + * 如果提示**关闭**,说明国内无法访问该 VPS 对应的端口服务 + * 如果提示**开启**,说明访问正常 + +2. 使用用国外端口扫描网站进行检查你的 VPS 服务是否可以正常访问,地址:[https://www.yougetsignal.com/tools/open-ports](https://www.yougetsignal.com/tools/open-ports/) + * 如果检查结果为**open**,说明国外可以正常访问你的 VPS 对应端口的服务 + * 如果检查结果为**close**,说明国外无法访问 + +经过上面的两部,可以快速定位到问题,如果你检查出来的结果一样,则可以更改 VPS 上的 SSR 服务端口,重新启动 SSR 服务即可,在上面已经讲到了如何[修改 SSR 配置](#修改SSR配置),切记一起连**加密方式**, +**协议**,**混淆方式**这些配置一并改掉,然后重启 SSR 服务,并修改连接 SSR 服务的**客户端配置**,其实这只是一个暂时的解决方法,我们可以使用更加隐蔽的 [v2ray](#v2ray) 服务 + +## 其它 +* 查询余额 +进入结算概览页面: https://console.cloud.google.com/billing/ +* 扣费计算 +主机:$5/月. +流量:谷歌云服务器出口大陆流量1T以内价格约为0.23$/1G. +每个月可用流量:$300-$5*12=$240/12/0.23 ≈ 86G +* [SSR客户端](https://www.mediafire.com/folder/btkdbx7j9lr98/Shadowsocks_%E7%9B%B8%E5%85%B3%E5%AE%A2%E6%88%B7%E7%AB%AF#myfiles) + +## 附录 +* [Google Cloud Platform免费申请&一键搭建SSR & BBR加速教程](https://www.wmsoho.com/google-cloud-platform-ssr-bbr-tutorial) +* [Google Cloud使用VM虚拟机详细操作指南](https://www.rultr.com/tutorials/vps/2303.html) +* [ShadowsocksR客户端 各种隐藏使用技巧说明](https://www.wmsoho.com/how-to-use-shadowsocksr) +* v2ray社区:~~[https://www.v2ray.com](https://www.v2ray.com)已被墙~~,[https://www.v2fly.org](https://www.v2fly.org) +* [自建v2ray服务器教程](https://github.com/Alvin9999/new-pac/wiki/%E8%87%AA%E5%BB%BAv2ray%E6%9C%8D%E5%8A%A1%E5%99%A8%E6%95%99%E7%A8%8B) +* [v2ray各平台图文使用教程](https://github.com/Alvin9999/new-pac/wiki/v2ray%E5%90%84%E5%B9%B3%E5%8F%B0%E5%9B%BE%E6%96%87%E4%BD%BF%E7%94%A8%E6%95%99%E7%A8%8B) \ No newline at end of file diff --git a/source/_posts/deploy-maven.md b/source/_posts/deploy-maven.md new file mode 100644 index 000000000..fa659f6e0 --- /dev/null +++ b/source/_posts/deploy-maven.md @@ -0,0 +1,330 @@ +--- +title: 发布 jar 到 Maven中央仓库 +date: 2019-07-21 10:00:46 +categories: Maven +tag: [Deploy] +--- + +## 背景 + +和朋友一起维护的开源组织(我就是打个辅助,逃~),其中有一个系列的项目,这些项目统一通过 base 项目的 pom 文件管理这个系列项目依赖的第三方 jar,其他一些辅助项目(如:tools)项目主要是一些常用工具方法的封装,为了能让我们在不同机器,不同地点能够无缝切换,更重要的让使用的伙伴能以最简便的方式运行(避免不必要的配置),我们需要把通用的东西托管起来,那么就需要将这些配置依赖或辅助 jar 托管到 Maven中央仓库,话不多说,就跟着我的步骤来看看如何将 jar 发布到 Maven中央仓库 + +## 准备 + +* Sonatype 账号 +* GPG +* 需要发布的项目 + +> 这里以 Mac 系统演示 + +## Sonatype + +### 账号注册 + +Sonatype 账号注册地址:[https://issues.sonatype.org/secure/Signup!default.jspa](https://issues.sonatype.org/secure/Signup!default.jspa) + +> 记录好你的账号和密码,后续会用到 + +### 创建 issue + +创建 issue 地址:[https://issues.sonatype.org/secure/CreateIssue.jspa?issuetype=21&pid=10134](https://issues.sonatype.org/secure/CreateIssue.jspa?issuetype=21&pid=10134) + +填写信息时,只填写必填项即可 + +1. `Summary`:简单的项目介绍,填写一下 +2. `Group Id`:项目ID,用来定位应用 jar 的坐标,可参考[官方说明](https://central.sonatype.org/pages/choosing-your-coordinates.html) +3. `Project URL`:项目主页地址 +4. `SCM url`:Git仓库地址 + +>注意: +* Group Id + * 无自己的域名:可以使用 Github,比如我的 GitHub 用户名是 BladeCode(也可以用你的组织名,如这里:twodragonlake),那么这里的Group Id应该填写 com.github.BladeCode,也可以使用 io.github.BladeCode + * 有自己的域名:按照要求添加一条 TXT 的 DNS 解析,用来验证你的 `Group Id` + ![ossrh-domain](https://res.cloudinary.com/incoder/image/upload/v1563762211/blog/ossrh-domain.png) +* 可参考:[OSSRH-45597](https://issues.sonatype.org/browse/OSSRH-45597) + +### 验证 Group Id + +根据你是否有自己的域名,有不同的方式来验证,上面的创建 issue 的注意中已经说明了,这里不啰嗦了,直接看下图 +![ossrh-ticket](https://res.cloudinary.com/incoder/image/upload/v1563705782/blog/ossrh-ticket.png) + +## GPG + +* Windows:[Gpg4win](https://www.gpg4win.org/download.html) +* macOS:gpg + +### 安装 + +macOS 为例 +```sh +# 安装 +brew install gpg +# 验证 +gpg --version +``` + +### 生成秘钥对 + +```sh +gpg --gen-key +``` +![ossrh-gpg-key](https://res.cloudinary.com/incoder/image/upload/v1563706827/blog/ossrh-gpg-key.png) + +这里用于生成秘钥的用户名和邮箱,可以和你的 `Sonatype` 账号不一样,记录`密码`,在部署时需要用到 +### 上传秘钥 + +```sh +# 上传秘钥,最好带上端口号 +gpg --keyserver hkp://pool.sks-keyservers.net:11371 --send-keys <密钥ID> +# 验证秘钥,最好带上端口号 +gpg --keyserver hkp://pool.sks-keyservers.net:11371 --recv-keys <密钥ID> +``` +![ossrh-gpg-send](https://res.cloudinary.com/incoder/image/upload/v1563707069/blog/ossrh-gpg-send.png) + +上传到其他服务器,命令同上,更换地址即可 +* hkp://keyserver.ubuntu.com:11371 +* hkp://keys.gnupg.net:11371 + +如果你忘记了你刚刚生成的秘钥,可以使用下面的命令来查看本地生成的所有秘钥 +```sh +gpg --list-keys +``` +## 配置 + +### maven 配置 + +* 查看路径 + macOS 可以使用 IDEA 查看 maven 的路径,`/usr/local/Cellar/maven/3.6.0/libexec/conf` + ![ossrh-maven-local](https://res.cloudinary.com/incoder/image/upload/v1563707961/blog/ossrh-maven-local.png) +* 修改 `settings.xml` 文件 + 在 `` 标签内,添加如下配置 + ```xml + + oss + 你注册的Sonatype账号 + 密码 + + ``` + +### pom 配置 + +配置你需要上传项目的 `pom` 文件 + +```xml + + org.sonatype.oss + oss-parent + 7 + + + tdl-base + TwoDragonLake base pom + https://github.com/TwoDragonLake/tdl-base + + + + Apache License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0 + + + + + + + Jerry xu + incoder.xu@gmail.com + + + + + master + https://github.com/TwoDragonLake/tdl-base.git + scm:git:https://github.com/TwoDragonLake/tdl-base.git + scm:git:https://github.com/TwoDragonLake/tdl-base.git + + + + + + release + + + + + maven-clean-plugin + 3.0.0 + + + org.apache.maven.plugins + maven-source-plugin + 3.0.1 + + + package + + jar-no-fork + + + + + + maven-compiler-plugin + 3.7.0 + + + maven-surefire-plugin + 2.20.1 + + + maven-jar-plugin + 3.0.2 + + + maven-install-plugin + 2.5.2 + + + maven-deploy-plugin + 2.8.2 + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 8 + 8 + + + + + org.apache.maven.plugins + maven-source-plugin + + + package + + jar-no-fork + + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.9.1 + + + + + package + + jar + + + + + + + org.apache.maven.plugins + maven-gpg-plugin + 1.6 + + + verify + + sign + + + + + + + + + + oss + https://oss.sonatype.org/content/repositories/snapshots/ + + + oss + https://oss.sonatype.org/service/local/staging/deploy/maven2/ + + + + +``` + +### 编译并部署 + +```sh +mvn clean deploy -P release -Dmaven.test.skip=true +``` + +然后在命令行的弹出中输入使用 gpg 命令生成秘钥时输入的密码,如果在命令行中没有弹框提示,那么可以在终端中输入`export GPG_TTY=$(tty)`命令,再次执行部署命令,部署完成参考下图提示 +![ossrh-deploy](https://res.cloudinary.com/incoder/image/upload/v1563725146/blog/ossrh-deploy.png) + +## 发布 + +### 编译构建验签 + +部署成功后,使用`Sonatype`登录 [https://oss.sonatype.org](https://oss.sonatype.org/#stagingRepositories)网站,进行发布,在`Build Promotion`中选择`Staging Repositories`,然后选择对应你的`groud id`的`Repository`,进行 close,这里的`Close`其实就是进行自动构建,进行验证 +![ossrh-close](https://res.cloudinary.com/incoder/image/upload/v1563725940/blog/ossrh-close.png) + +参看是自动化运行过程否有错误,正确如下截图没有错误提示,如果有错误提示,就按照提示内容进行处理 +![ossrh-build](https://res.cloudinary.com/incoder/image/upload/v1563726108/blog/ossrh-build.png) + +### 发布 + +构建成功无错误,后就可以发布了,其实发布和部署是一样的操作,只不过部署是进行`Close`,而发布是`Release`操作,此时会提示你发布成功后会删除`Staging Repositories` 的 `Repository` 记录 +![ossrh-release](https://res.cloudinary.com/incoder/image/upload/v1563726307/blog/ossrh-release.png) + +### 查看 + +打开你的[https://issues.sonatype.org](https://issues.sonatype.org/browse/OSSRH-45597),登录并查看,你的 issues 下,提示你,已经发布成功,稍后可以在[https://search.maven.org](https://search.maven.org)中搜索到 +![ossrh-deploy-success](https://res.cloudinary.com/incoder/image/upload/v1563726729/blog/ossrh-deploy-success.png) + +搜索结果,可以查看到我们发布的包 +![ossrh-search](https://res.cloudinary.com/incoder/image/upload/v1563726893/blog/ossrh-search.png) + +## 异常 + +### IDEA 中 not found + +项目中引入的 jar,IDEA 中提示无法找到包,可以打开 IDEA 的 Preferences 中进行同步 +![ossrh-idea-update](https://res.cloudinary.com/incoder/image/upload/v1563727259/blog/ossrh-idea-update.png) + +### 本地编译错误 + +* 无提示框提示输入密码 + ![ossrh-local-build-comfrim](https://res.cloudinary.com/incoder/image/upload/v1563727360/blog/ossrh-local-build-comfrim.png) + 解决方法:`export GPG_TTY=$(tty)` 命令,重新编译 +* 无法连接sonatype + ![ossrh-local-sonatype](https://res.cloudinary.com/incoder/image/upload/v1563727678/blog/ossrh-local-sonatype.png) + 解决方法:查看`settings.xml`文件中 ``标签中配置的 `id` 是否与项目`pom`文件的`` 标签下的 `id` 是否一致 + +### sonatype 构建错误 + +查看构建过程中错误提示,我这里是应为无法验证签名,因此我将提示中的服务器地址,全部都再发布`gpg`的秘钥,注意地址开头是 `hkp` +![ossrh-build-error](https://res.cloudinary.com/incoder/image/upload/v1563728038/blog/ossrh-build-error.png) + +## 附录 + +### 官方 + +* [OSSRH Guide](http://central.sonatype.org/pages/ossrh-guide.html) +* [发布要求、规范](https://central.sonatype.org/pages/apache-maven.html) +* [PGP签名使用](http://central.sonatype.org/pages/working-with-pgp-signatures.html) +* [发布项目文档](http://central.sonatype.org/pages/producers.html) + +### 其他 + +* [发布 Maven 构件到中央仓库](http://www.r9it.com/20190701/maven-artifact-deploy.html) +* [发布构件到Maven中央仓库](https://silloy.me/2018/06/19/%E5%8F%91%E5%B8%83%E6%9E%84%E4%BB%B6%E5%88%B0Maven%E4%B8%AD%E5%A4%AE%E4%BB%93%E5%BA%93/) +* [如何发布Jar包到Maven Central Repository](https://www.jianshu.com/p/1bd36edab4ee) diff --git a/source/_posts/docker-init.md b/source/_posts/docker-init.md new file mode 100644 index 000000000..abd8f6593 --- /dev/null +++ b/source/_posts/docker-init.md @@ -0,0 +1,6 @@ +--- +title: Docker 之 SpringBoot 项目部署 +date: 2019-01-10 01:04:16 +categories: Docker +tag: [SpringBoot, Deploy] +--- \ No newline at end of file diff --git a/source/_posts/fiddler.md b/source/_posts/fiddler.md new file mode 100644 index 000000000..6d810bdc8 --- /dev/null +++ b/source/_posts/fiddler.md @@ -0,0 +1,57 @@ +--- +title: Fiddler 初体验 +date: 2018-10-25 19:40:46 +categories: DevTool +tag: [Fiddler] +--- + +在开发的路上,有时候面对一些应用,我们可能回去分析研究它的实现以及数据交互等,在没有官方没有公开的Api提供时,我们会用到一项实用的技术,抓包,所谓的抓包,指的是截取网络传输发送与接收的数据包。其中在Windows平台上使用比较广泛的要数[Fiddler](https://www.telerik.com/fiddler) + +本节主要讲解Fiddler的相关配置及简单使用 + +## 资源 + +* Windows 10 +* Fiddler + +## 配置 + +需要使手机连接WiFi和电脑WiFi是使用同一个网络 + +### Fiddler 初始化 + +![fiddler-config](https://res.cloudinary.com/incoder/image/upload/v1540742306/blog/fiddler-config.png) +>默认端口:8888 + +### 网络地址 + +获取电脑所连接的网络IP地址 +![fiddler-ip](https://res.cloudinary.com/incoder/image/upload/v1540742723/blog/fiddler-ip.png) +这里获取的IP地址,将用于手机连接网络的代理 + +### 手机配置 + +关于手机相关的配置操作,步骤已经通过下面的视频展现。 +1. 连接与电脑相同的WiFi +2. 修改网络代理 +3. 手动模式,并设置电脑端获取的IP地址及Fiddler默认端口号8888 +4. 网络连接刷新 +5. 获取并下载安装Fiddler证书 + +## 其它 + +通过以上操作,现在可以在电脑端Fiddler工具中,拦截获取经过的所有网络信息。而我们一般是查看或者是分析某一款应用的数据信息,这样在查看起来就比较费力,那么我们就借助Fiddler提供的过滤功能 +![fiddler-filter](https://res.cloudinary.com/incoder/image/upload/v1540743106/blog/fiddler-filter.png) + +选择过滤方式中 +1. 第一项有三个选项,不做更改: + “No zone filter”; + “Show Only Intranet Hosts”; + “Show Only Internet Hosts” +2. 第二个选项是只监控以下网址,如只监控百度,在下面的输入框里填上 www.baidu.com + “No Host Filter”:不设置hosts过滤 + “Hide The Following Hosts”:隐藏过滤到的域名 + “Show Only The Following Hosts”:只显示过滤到的域名 + “Flag The Following Hosts”:标记过滤到的域名 +3. 文本框内输入需要过滤的域名,多个域名使用”;“分号分割。 +>fiddler默认会检查http头中设置的host,强制显示http地址中域名。 \ No newline at end of file diff --git a/source/_posts/flowable1.md b/source/_posts/flowable1.md new file mode 100644 index 000000000..3dfc80acc --- /dev/null +++ b/source/_posts/flowable1.md @@ -0,0 +1,73 @@ +--- +title: Flowable(一)初识 +date: 2019-09-25 12:40:46 +categories: Flowable +tag: [Flowable] +--- + +Flowable是一个使用Java编写的轻量级业务流程引擎。Flowable流程引擎可用于部署BPMN 2.0流程定义(用于定义流程的行业XML标准), 创建这些流程定义的流程实例,进行查询,访问运行中或历史的流程实例与相关数据等,众所周知,Flowable是Activit的一个分叉,[Flowable的第一个版本(5.22.0)是基于Activit(5.21.0)](https://blog.flowable.org/2016/10/13/flowable-5-22-0-release/),关于为什么Flowable会从Activit分叉,感兴趣可以查看Flowable官方的文章[Flowable and Activiti: What the Fork?!](https://blog.flowable.org/2016/10/12/flowable-and-activiti-what-the-fork/),这里不在赘述这些内容 + +从[Flowable官方文档](https://www.flowable.org/documentation.html)介绍,可知Flowable遵循[BPMN](https://www.flowable.org/docs/userguide/index.html),[CMMN](https://www.flowable.org/docs/userguide-cmmn/index.html),[DMN](https://www.flowable.org/docs/userguide-dmn/index.html),[From](https://www.flowable.org/docs/userguide-form/index.html)设计指导 +* BPMN:用于流程管理 +* CMMN:用于案例管理 +* DMN:用于决策规则 +* Form:用于表单和任务表单管理 + +## Flowable 直运行 + +>这里所说的"**直运行**",是指不需要写任何代码,仅需要改动相关的配置就可以运行起Flowable应用程序 + +准备工作 +* [Flowable v6.4.2](https://www.flowable.org/downloads.html) +* MySQL8+ +* JDK & Tomcat 环境 + +> MySQL8+ ,JDK,Tomcat环境代建可参考[Linux 之 MySQL](https://incoder.org/2018/07/23/linux-mysql/),[Linux 常用应用安装](https://incoder.org/2018/05/15/linux-build/),[Windows 之 常用应用安装](https://incoder.org/2019/09/25/windows-devtool/) + +已下操作均在Windows上,macOS上相差不大,操作流程基本一致 + +### war部署 + +1. 解压flowable.zip文件 + ![flowable-zip](https://res.cloudinary.com/incoder/image/upload/v1569565014/blog/flowable-zip.png) +2. 拷贝需要启动的war到安装的Tomcat的`webapps`路径下 + ![flowable-tomact](https://res.cloudinary.com/incoder/image/upload/v1569554378/blog/flowable-tomact.png) +3. 命令行中执行`startup.bat`命令,或执行Tomcat的`bin`路径下,启动`startup.bat`文件 + ![flowable-startup](https://res.cloudinary.com/incoder/image/upload/v1569554648/blog/flowable-startup.png) +4. 第一次启动,Tomcat控制台应该会出错,因为`flowable-admin.war`数据库配置默认使用H2数据库,我们需要修改数据库配置连接等信息 + ![flowable-mysql-config](https://res.cloudinary.com/incoder/image/upload/v1569555241/blog/flowable-mysql-config.png) + >* 文件地址:`/webapps/flowable-admin/WEB-INF/classes`路径,`flowable-default.properties`文件及`application-dev.properties`文件 + >* MySQL中需要一个名为 **flowable** 的数据库,没有请创建一个`CREATE DATABASE flowable` + >* 由于我使用的是 MySQL8 ,Tomcat 中不包含此驱动 jar 包,因此需要手动下载[mysql-connector-java-8.x.x(和你数据库匹配版本).zip](http://ftp.jaist.ac.jp/pub/mysql/Downloads/Connector-J/)文件进行解压,拷贝`mysql-connector-java-8.x.x.jar`文件到 `/lib`路径下 +5. 重新在命令行中执行`startup.bat`命令,或执行Tomcat的`bin`路径下,启动`startup.bat`文件 +6. 正常情况到此等待服务器启动完成,如果不能正常启动,请查看Tomcat控制台是否有错误,按照提示解决错误,直到Tomcat不再有错误提示即可 + + +### 使用 + +1. 访问[http://localhost:8080/flowable-idm](http://localhost:8080/flowable-idm),默认账号:admin,默认密码:test + ![flowable-admin](https://res.cloudinary.com/incoder/image/upload/v1569563245/blog/flowable-admin.png) +2. 访问[http://localhost:8080/flowable-admin](http://localhost:8080/flowable-admin),后台管理 +3. 访问[http://localhost:8080/flowable-modeler](http://localhost:8080/flowable-modeler),流程定义管理 +4. 访问[http://localhost:8080/flowable-task](http://localhost:8080/flowable-task),用户任务管理 +5. 访问[http://localhost:8080/flowable-rest/docs](http://localhost:8080/flowable-rest/docs),流程引擎对外提供的API接口 + +## Flowable 集成运行 + +>这里所说的"**集成运行**",是指通过Flowable官方提供的jar文件,集成到我们的项目中运行的方式 + +## Flowable 使用 + +## 其他 + +### 如何切换中文 + +Flowable中已包含中文语言,会根据操作系统语言,自动显示对应语言 + +### startup.bat异常 + +查看控制它异常,例如当前flowable启动默认端口8080,被占用 +![flowable-aleady-bind](https://res.cloudinary.com/incoder/image/upload/v1569556130/blog/flowable-aleady-bind.png) + +解决方法:查找占用端口进程`netstat -ano|findstr 端口号`,并kill它`taskkill -PID 进程号 -F` +![flowable-kill-task](https://res.cloudinary.com/incoder/image/upload/v1569556500/blog/flowable-kill-task.png) \ No newline at end of file diff --git a/source/_posts/flutter-init.md b/source/_posts/flutter-init.md new file mode 100644 index 000000000..ec5f3287c --- /dev/null +++ b/source/_posts/flutter-init.md @@ -0,0 +1,106 @@ +--- +title: Flutter(一)之环境搭建 +date: 2018-12-16 02:14:59 +categories: Android +tag: [flutter] +--- + +这两年随着前端的高速发展,大前端的趋势下,Native移动应用开发市场在一定程度上被前端瓜分,加之硬件的快速迭代,性能已不存在明显的短板,[React Native](https://facebook.github.io/react-native),[Vue](https://cn.vuejs.org/index.html),[Angular](https://angular.io/)等等这些Web框架,对移动端也有了较大的提升,毕竟这样的开发效率会直线上升,并且大大减少了成本。技术的革新真的好快,如果不去学习,很快就会被淘汰 + +那就直接进入正题,[flutter](https://flutter.io/)是一站式跨平台解决方案,一次开发,适配整个移动平台,并且是由Google进行主导开发,开源的一个项目,现如今已经迭代到1.0版本 + +本篇文章主要记录在macOS系统上搭建flutter开发环境的过程 + +## 准备 +* Android Studio开发环境(JDK,AndroidSDK,Gradle等等,这里不再赘述) +* [flutter SDK](https://flutter.io/docs/get-started/install) +* Android Studio Plugin --> Flutter + +## 步骤 +1. 解压下载的flutter SDK,并配置环境变量,例如这里配置在`.bash_profile`文件中 + ```bash + # 打开 .bash_profile文件 + vim .bash_profile + # .bash_profile文件中加入flutter sdk路径并保存 + export FLUTTER_HOME=/Users/blade/Documents/DevTools/flutter + export PATH=$FLUTTER_HOME/bin:$PATH + # 重新加载.bash_profile文件 + source .bash_profile + ``` +2. 检查环境变量是否配置正确,如果有相关命令说明,表示已配置好环境变量 + ```bash + flutter -h + ``` +3. 检查开发环境,第一次执行,应该提示如下图所示说明 + ```bash + flutter doctor + ``` + ![flutter-doctor](https://res.cloudinary.com/incoder/image/upload/v1544994568/blog/flutter-doctor.png) + 其实不难,看出我们需要安装一下其他辅助工具等 +4. 解决问题,按照如下命令,一步步执行,大概得1个小时左右(取决于你的网络情况) + ```bash + # 允许协议(android-licenses + flutter doctor --android-licenses + # 安装libimobiledevice + brew install --HEAD libimobiledevice + # 安装ideviceinstaller + brew install ideviceinstaller + # 安装ios-deploy + brew install ios-deploy + # 安装cocoapods + brew install cocoapods + # cocoapods 初始化,这一步比较耗时,需要下载文件大致547M,需要耐心等待 + pod setup + ``` +5. 以上步骤都正常运行后,再次检查环境,如下图所示结果,表示已完成flutter环境搭建 + ```bash + flutter doctor + ``` + + ![flutter-finish](https://res.cloudinary.com/incoder/image/upload/v1544994676/blog/flutter-finish.png) + +## 辅助 +如果你不习惯或者不想使用Android Studio来开发Flutter,那么使用[VS Code](https://code.visualstudio.com)是最佳推荐的文本编辑器,只需要在VS Code中安装[Flutter](https://marketplace.visualstudio.com/items?itemName=dart-code.flutter)插件即可,它已包含所需的[Dart](https://marketplace.visualstudio.com/items?itemName=dart-code.dart-code)语法插件 + +关于程序的运行,那么模拟器当然少不了,这里介绍下macOS上如何启动Android 模拟器 +* 首先AndroidSDK的环境变量配置少不了 +* 配置emulator + ```bash + export ANDROID_HOME=/Users/blade/Library/Android/sdk + export FLUTTER_HOME=/Users/blade/Documents/DevTools/flutter + export PATH=$ANDROID_HOME/emulator:$ANDROID_HOME/tools:$ANDROID_HOME/platform-tools:$FLUTTER_HOME/bin:$PATH + ``` +* 启动 + ```bash + # 查看已创建模拟器清单 + emulator -list-avds + # 选择需要启动的模拟器,avd_name:表示从上面列表获取到的模拟器名称 + emulator -avd [avd_name] + ``` +>注意: +>* 不推荐使用[Genymotion](https://www.genymotion.com/),flutter的运行在此模拟器上有各种灵异bug +>* PANIC: Missing emulator engine program for 'x86' CPU.解决方式:创建一个x64的模拟器 + +## 问题 + +### libusbmuxd version error during flutter install +```bahs +brew update +brew uninstall --ignore-dependencies libimobiledevice +brew uninstall --ignore-dependencies usbmuxd +brew install --HEAD usbmuxd +brew unlink usbmuxd +brew link usbmuxd +brew install --HEAD libimobiledevice +``` + +### Unbrewed header files were found in /usr/local/include + +![flutter-node](https://res.cloudinary.com/incoder/image/upload/v1544994898/blog/flutter-node.png) + +## 附录 +* [flutter docs](https://flutter.io/docs) +* [Flutter免费视频第一季-环境搭建](http://jspang.com/post/flutter1.html#toc-586) +* [flutter安装记录过程](https://www.jianshu.com/p/637796e9c0ea) +* [macOS上搭建Flutter开发环境](https://flutterchina.club/setup-macos/#%E8%AE%BE%E7%BD%AE%E6%82%A8%E7%9A%84android%E8%AE%BE%E5%A4%87) +* [官方命令行构建您的应用](https://developer.android.google.cn/studio/build/building-cmdline?hl=zh-cn) \ No newline at end of file diff --git a/source/_posts/gdd-2019.md b/source/_posts/gdd-2019.md new file mode 100644 index 000000000..2c1339477 --- /dev/null +++ b/source/_posts/gdd-2019.md @@ -0,0 +1,95 @@ +--- +title: Google Developer Days 2019 +date: 2019-09-12 10:43:46 +categories: Google +tag: [GDD] +--- + +![google-developer-days](https://res.cloudinary.com/incoder/image/upload/v1568675354/blog/google-developer-days.jpg) + +连续三年申请参加 Google Developer Days,今年终于中签了,而且和好友[大蛇丸](https://ceaser.wang)及公司同事同时中签(可能是我们都使用了忍术)。嗯,终于离404公司又进了一步,哈哈哈~ +废话不啰嗦了,这篇文章就唠唠参加 GDD 的前前后后。 + + + +众所周知每年 Google 会在 5 月份上旬在美国举行 Google 1/O (全球开发者大会)大会,在大会上无例外的推出新版本的 Android 系统(虽然只是 bate版本,今年 Android 取消了过去使用甜品命名的方式,而直接采用阿拉伯数字命名)等等软硬件上的技术探索和研究成果,给 Android 领域确立风向标。 + +而在中国,大概每年 9 月份会在中国上海举办 Google Developer Days,今年是第 4 年,可见 Google 对中国市场的重视。 + +* [2019](https://events.google.cn/intl/zh-CN/developerdays2019/) +* [2018](https://www.google.cn/intl/zh-CN/events/developerdays2018/) +* [2017](https://www.google.cn/intl/zh-CN/events/developerdays2017china/) +* [2016](https://www.google.cn/intl/zh-CN/events/developerday2016/) + +## 申请 + +由于 GDD 是不收取门票的,因此会对申请用户进行筛选,这个就要看运气了,可以通过以下的渠道获取信息,进行申请 +* 微信公众号 + ![](https://res.cloudinary.com/incoder/image/upload/v1568547420/blog/google-developers.gif) +* [微博 Google开发者](https://weibo.com/GoogleDevelopers) +* [知乎 谷歌开发者](https://www.zhihu.com/org/google-gu-ge) +* [社区 GDG](https://chinagdg.org) +* 其他渠道 + +申请时需要填写一些资料,如实填写即可,剩下就是静待消息,如果审核通过,会发送邮件/短信通知你,不同的同学接收到的时间可能不同,具体的截止时间,以官方通知为准,没有通过的可查看官方合作的直播平台进行直播观看 + +>众所周知,参加大会的基本是清一色的男同学,因此今年 Google 还专门有为女同学们提供了 1000 名的直通车,具体请移步[官方公众号](https://mp.weixin.qq.com/s/SWMy2pui7j2RMZCcA4bS5A) + +## 参加 + +筛选通过后,那就是自己安排好自己的工作或者是学习,因为大会时间不一定是周末,以及安排好你的行程和住宿(两天的午餐都是由 GDD 提供)。我在杭州,因此就搭乘动车当天早上抵达上海虹桥,换乘地铁抵达目的地(上海世博中心)。由于支付宝并不支持上海地铁,因此需要提前下载一款 "Metro 大都会"应用 + +## 感受 + +满满当当两天下来,收货不少,这一届可以通过官方日程看出,重点是 Flutter 以及 TensorFlow 相关,大部分内容都是偏大前端这个领域,不管是相关应用场景的尝试还是一些技术细节和技术的巧妙实现,都能看得出 Google 在技术领域的话语权,其中有两个技术探索以及一场《挖掘事业发展潜力 - 开拓自己的道路》课堂,各位老师对职业发展讲解让我印象深刻 + +* 与 AR 相结合的 AR 导航(与滴滴合作),解决室内定位问题 +* 与艺术(音乐)结合,让技术有了温度,通过深度学习 +* 开拓自己的道路 + * 对自己的专业技能需要达到融会贯通 + * 要主动的心态去工作,有企业家的精神 + * enjoy 的方式去对待自己所做的决定 + * 只有自己了解自己,才能将自己的推向更高的舞台 + +另外通过现场感受,可以看到活动的现场屏幕边框元素是[Material Desing](https://material.io)中的,三角,圆,矩形,线条,和现场灯光融为一体,每一个视频动画都看得出他们在背后的付出,每一段音乐都那么的契合场景,这是我参加众多线下交流会,在现场感受最深的一次 + +## 其他 + +我们来看一看来自官方的活动精彩瞬间 + + + +### 如何提高中签率 + +在知识星球中,看到有人分享 + +“简单说下对筛选的看法吧,报名的问卷非常的简单,都是一些有没有使用谷歌服务的选项。作为主办方,怎么样才能快速高效的在这之中找到自己想要的人呢? + +这其实就是如何帮助谷歌建立你的**用户画像**,如果谷歌能找到更多的有利的信息,那么成功报名的机率自然会高。 + +那如何做到这点呢?其实很简单,提供使用谷歌服务频率最高最深的邮箱,因为谷歌可以很方便的获取到想要的信息!” + +### 如何回顾 + +错过了现场参与,和视频直播,还能不能观看,答案是当然可以,官方会对直播视频进行剪辑,发布到[bilibili](https://space.bilibili.com/64169458/)视频网站,你可以关注[Google中国](https://space.bilibili.com/64169458) 官方账号方便你第一时间活动更新动态,截止目前为止已发布,随后发布的我会及时更新 + +* [谷歌开发者大会开幕主旨演讲](https://www.bilibili.com/video/av67946527) + +* 移动端 + * [Android 开发最新技术概览](https://www.bilibili.com/video/av68058096) + * [Android 10 和隐私保护:使您的应用顺应变更](https://www.bilibili.com/video/av68061328) + * [Android 无障碍:服务所有人](https://www.bilibili.com/video/av68066152) + * [利用 Kotlin 进行 Android 开发](https://www.bilibili.com/video/av68058669) + * [如何组装你的 Jetpack](https://www.bilibili.com/video/av68059087) + * [CameraX:面向开发者的摄像头支持库](https://bilibili.com/video/av68046760) + * [移动Web技术拓展无限商机](https://www.bilibili.com/video/av67907735) + * [AdMob 广告政策和工具](https://www.bilibili.com/video/av67905866) + * [用谷歌的新数据技术挖掘 App 变现潜力](https://www.bilibili.com/video/av67854284) + * [ConstraintLayout + MotionLayout:打造丰富界面并为其制作动画效果](https://www.bilibili.com/video/av68048631) + * [Material Theming:利用 Material 组件以极具表现力的方式构建主题背景](https://www.bilibili.com/video/av68049492) + * [利用 Material Design 设计深色主题背景](https://www.bilibili.com/video/av68050301) + +* 机器学习 + * [机器学习简介](https://www.bilibili.com/video/av68057077) + * [机器学习赋能智慧营销,成就商业新增长](https://www.bilibili.com/video/av67903202) + * [利用基准化分析和剖析功能提升应用性能](https://www.bilibili.com/video/av68051201) diff --git a/source/_posts/git-account.md b/source/_posts/git-account.md new file mode 100644 index 000000000..5da330130 --- /dev/null +++ b/source/_posts/git-account.md @@ -0,0 +1,70 @@ +--- +title: Git 多账号 +date: 2018-10-06 10:54:50 +categories: Git +tag: [git account] +--- + +以前,git的账号只用来在Github上操作,随着积累Git管理的项目不仅仅只来自Github,还有一些其它Git项目托管的平台,例如:[Bitbucket](https://bitbucket.org),[Coding](https://coding.net),[Gitee](https://gitee.com),[Gitlib](https://gitlab.com),以及公司内Git仓库 + +不同的托管平台有着不同的Git账号,无法用一个账号来管理其它的仓库,而且由于不同的托管平台账号不同,因此需要添加不同账号的公钥,这样我们再能在对应平台用对应的账号进行操作 + +## 环境 +* Windows 10 x64 +* Git version 2.16.0 + +>这里Git的安装不在赘述 + +## 生成对应账号的密钥 +```sh +# 进入到`your_pc_name/.ssh`, +cd .ssh +# Jerry.x@outlook.com 是我的Github的邮箱,这里需要替换成自己的邮箱 +ssh-keygen -t rsa -C "Jerry.x@outlook.com" +# 命名文件名称或指定文件存放路径等 +# 其它可以回车键进行确认,进行下一步 +``` +![git-account](https://res.cloudinary.com/incoder/image/upload/v1538887180/blog/git-account.png) + +>完成后,将会生成`id_rsa_company.pub`(存放公钥)与`id_rsa_company`(存放私钥)两个文件 + +## 添加公钥到托管平台 +* 在`.ssh`路径下,用文本编辑器打开`id_rsa_company.pub`文件,复制内容 +* 在托管平台上添加ssh public key +以下以GitHub添加为例,其它平台类似 +![git-add-key](https://res.cloudinary.com/incoder/image/upload/v1538887180/blog/git-add-key.png) + +## 添加配置文件 +在`.ssh`路径下,创建`config`文件,无文件后缀名,如下示例 + +```sh +# 配置github.com +Host github.com + HostName github.com + IdentityFile C:\\Users\\Jerry\\.ssh\\id_rsa + PreferredAuthentications publickey + User BladeCode + +# 配置 company.domain.com +Host company.domain.com + HostName company.domain.com + IdentityFile C:\\Users\\Jerry\\.ssh\\id_rsa_company + PreferredAuthentications publickey + User Jerry xu +``` + +* `Host`:的名字可以取为自己喜欢的名字 +* `HostName`:这个是真实的域名地址 +例如:https://github.com/BladeCode/BladeCode.github.io.git,红色标注字段 +* `IdentityFile`:这里是id_rsa的地址 +* `PreferredAuthentications`:配置登录时用什么权限认证 +可设为publickey,password publickey,keyboard-interactive等 +* `User`:配置使用用户名 + +## 测试 +```sh +ssh -T git@github.com +``` +![git-test](https://res.cloudinary.com/incoder/image/upload/v1538887180/blog/git-test.png) + +>git@github.com,github.com就是上一步中`config`文件中配置的`HostName`字段内容 \ No newline at end of file diff --git a/source/_posts/git-bash.md b/source/_posts/git-bash.md new file mode 100644 index 000000000..4eb322e72 --- /dev/null +++ b/source/_posts/git-bash.md @@ -0,0 +1,159 @@ +--- +title: Git 常用命令 +date: 2018-10-07 12:43:50 +categories: Git +tag: [git bash] +--- + +记录 Git 日常操作常用命令 + +## git config +Git级别:system(系统所有用户) < global(当前用户) < local(当前仓库) +* 查看配置信息 + ``` + # 查看对应 Git 级别(--local;--global;--system)的配置信息 + git config --list --local + ``` +* 新增或修改 + ```sh + git config --global user.name xxxxx + git config --global user.email xxx@xxxx.com + ``` +* 删除用户配置信息 + ```sh + # 如果当前只有一个用户,就不用加入xxxx + git config --global --unset user.name xxxx + ``` + +## git init +1. 把已有项目代码纳入 Git 管理 + ```sh + # 进入项目根路径 + cd project_dir + # 进行项目 Git 初始化 + git init + ``` +2. 新建项目直接使用 Git 管理 + ```sh + # 在当前路径下创建项目并使用 Git 初始化项目 + git init project_name + # 进入项目根路径 + cd project_name + ``` + +## git clone +* clone + ```sh + git clone url + ``` +* clone 指定分支 + ```sh + git clone -b branch_name url + ``` +* clone 指定tag + ```sh + # clone + git clone url + # checkout tag + git checkout tag_name + ``` +* clone 指定commit + ```sh + # 查看git commit 历史的 + git log + # 指定 commit SHA + git clone commit_sha_value + ``` + +## git commit + +```sh +git commit -m "注释" +``` + +## git branch +* 创建分支 + ```sh + # 创建分支 + git branch branch_name + # 创建并切换到新分支 + git checkout -b branch_name + ``` +* 切换分支 + ```sh + git checkout branch_name + ``` +* 删除分支 + ```sh + # 删除本地分支 + git branch -d branch_name + # 删除远程指定分支 + git push origin --delete branch_name + ``` +* 重命名分支 + ```sh + git branch -m old_branch_name new_branch_name + ``` +* 查看分支 + ```sh + # 查看本地所有分支 + git branch + # 查看远程所有分支 + git branch -r + # 查看本地和远程所有分支 + git branch -a + ``` + +## git tag +* 新增tag + ```sh + git tag -a tag_name -m "注释" + ``` +* 查看tag + ```sh + git tag -l + ``` +* 删除tag + ```sh + # 删除本地tag + git tag -d tag_name + # 删除远程指定tag + git push origin --delete tag tag_name + ``` + +## git mv +* 重命名文件 + ```sh + git mv old_file_name new_file_name + ``` + +## git log +* 查看仓库 commit 历史日志 + ```sh + # 下面参数可任意组合 + git log --oneline(简洁查看) --all(所有分支) -n4(最近 4 次记录) --graph(图形化展示) + ``` + +## git help +更多命令 + ```sh + git --help + ``` + +## git other +* 查看当前项目远程仓库地址 + ```sh + git remote -v + ``` +* 修改仓库地址 + ```sh + # 方式一:直接修改 + git remote set-url origin [url] + # 方式二:先删后加 + git remote rm origin + git remote add origin [url] + # 方式三:直接修改config文件 + ``` + +## 附录 +* [Git Docs](https://git-scm.com/docs) diff --git a/source/_posts/git-sub.md b/source/_posts/git-sub.md new file mode 100644 index 000000000..870eb904b --- /dev/null +++ b/source/_posts/git-sub.md @@ -0,0 +1,210 @@ +--- +title: Git 子仓库管理 +date: 2018-05-17 10:30:50 +categories: Git +tag: [git subtree, git submodule] +--- + +在使用NexT作为Hexo博客的主题时,不能 **友好** 的支持其主题的更新,以及 **多设备** 之间的主题同步。 +按照官方提供的导入主题操作指引 +```bash +$ cd hexo +$ git clone https://github.com/theme-next/hexo-theme-next themes/next +``` +发现commit并push到GitHub的远程服务器上,发现`themes/next`路径下并不能打开和查看该路径下的文件,原因是NexT是当前项目的一个子仓库(项目),在Github上对于之仓库项目的引用,推荐使用`git subtree`命令来进行对子仓库的管理,不推荐直接拷贝需要子仓库的代码到自己的项目中 + +原因是我是使用Travis CI来部署自己的项目,具体的[构建脚本和介绍](https://incoder.org/2018/05/02/hexo-iterative)请看,下面分别使用 `git submodule`、`git subtree`的方式进行NexT主题的管理 + +## git submodule 与 git subtree +* `git submodule`、`git subtree`都可以实现一个仓库作为其他仓库的子仓库的管理 +* `git submodule`:是Git官方以前的推荐方案 +* `git subtree`:Git [1.5.2](https://lwn.net/Articles/235109) 开始,Git 新增并推荐使用这个功能来管理子项目 +* `git subtree`与`git submodule`不同,它不增加任何像`.gitmodule`这样的新的元数据文件 +* `git subtree`对于项目中的其他成员透明,意味着可以不知道`git subtree`的存在 + +## git submodule 常用操作 +[Git Submodule](https://git-scm.com/book/zh/v2/Git-%E5%B7%A5%E5%85%B7-%E5%AD%90%E6%A8%A1%E5%9D%97)功能官方操作指引 + +### add 一个submodule + +1. Fork Repository + [hexo-theme-next](https://github.com/theme-next/hexo-theme-next)项目右上角`Fork`按钮即可 +2. Clone Repository + ```bash + git clone git@github.com:RootCluster/hexo-theme-test.git + ``` +3. Add Submodule + ```bash + # 进入项目 + cd hexo-theme-test + # 注册next项目是一个submodule,并把数据拷贝到`themes/next`路径 + git submodule add git@github.com:RootCluster/hexo-theme-next.git themes/next + ``` +4. status + ```bash + # 当前submodule已被注册并指向了某个commit + git submodule status + 1f5643061ec5257269673bd6159403c24015c53d themes/next (v6.3.0) + # 查看在父仓库中有哪些变化被注册 + git status + On branch submodule + Changes to be committed: + (use "git reset HEAD ..." to unstage) + new file: .gitmodules + new file: themes/next + ``` + + >有2个文件被修改过:`.gitmodules`,`themes/next`,当在父仓库时,Git不会跟踪submodule中的文件,Git只把它当成一个单一的文件 + + * `.gitmodules`:存有submodule的信息 + * `themes/next`:submodule它自己 + +5. commint + ```bash + # 推送到远程submodule分支 + git commit -am "add next submodule" + [submodule a5a612b] add next submodule + 2 files changed, 4 insertions(+) + create mode 100644 .gitmodules + create mode 160000 themes/next + ``` +6. push + ```bash + git push origin submodule + Counting objects: 4, done. + Delta compression using up to 4 threads. + Compressing objects: 100% (4/4), done. + Writing objects: 100% (4/4), 451 bytes | 451.00 KiB/s, done. + Total 4 (delta 1), reused 0 (delta 0) + remote: Resolving deltas: 100% (1/1), completed with 1 local object. + To github.com:RootCluster/hexo-themes-test.git + 71879a8..a5a612b submodule -> submodule + ``` +查看Github上的仓库,发现父仓库里有一个指向submodule的链接,表示你已经成功添加了一个submodule + +### clone 带 submodule的项目 +新路径下,clone项目,submodule分支 +```bash +# clone项目 +git clone -b submodule git@github.com:RootCluster/hexo-themes-test.git +# 进入项目路径 +cd hexo-themes-test/ +# 项目注册submodule +git submodule init +# clone submodule代码 +git submodule update + +``` + +### update 带 submodule的项目 +只要在submodule路径下,所有的常规Git操作,如`push`,`pull`,`reset`,`status`等,都可以正常工作,如果要保证submodule和远程仓库保存同步,在submodule路径下运行`git pull` + +* 如果你得到一个错误信息, 说你不在任何分支之上, 只要运行`git checkout master`就可修复 +* 如果你在`pull`后 `submodule` 有一些更新, 父仓库会告诉你有一些变动需要 `commit` 了. `submodule`自身指向一个指定的 `commit`, 并且如果这个 `commit` 改变了, 父仓库会得知这个改变. 如果你的 `submodule` 需要在一个指定 `commit` 上工作, 可用`git reset`来设置 + +例如:我需要把NexT的版本改变到上一个Tag 6.2.0 (目前是6.3.0) +> git reset --hard (commit hash) + +```bash +# 进入项目路径 +cd hexo-themes-test/ +# 重新指向submodule关联的commit记录 +git reset --hard 206d463 +# 回到父目录 +cd .. +# commit本次的修改 +git commit -am "set next version to 6.2.0" +``` + +{% note info %} 推送到远程仓库后,`submodule` 会和指定的`commit` 关联起来。如果你和别人一起工作在同一个项目,别人也可以在`submodule`下`pull`并且`commit`,因此改变了`submodule`的`commit`指向,这个问题,可以通过`git reset` 来解决{% endnote %} + +### remove 项目中的 submodule +* 项目的根目录下(不是 submodule 的目录),编辑 .gitmodules 文件,删除submodule配置 + ```bash + [submodule "themes/next"] + path = themes/next + url = https://github.com/RootCluster/hexo-theme-next.git + ``` +* 项目根目录下,编辑`.git`文件夹下`config`文件,删除submodule配置 + ```bash + [submodule "themes/next"] + url = https://github.com/RootCluster/hexo-theme-next.git + ``` +* 清除submodule缓存 + ```bash + git rm --cached themes/next + ``` + +## git subtree 常用操作(重点) + +### add一个subtree +* 在父仓库中新增子仓库 + ```bash + # 添加子仓库 + git subtree add --prefix=themes/next https://github.com/RootCluster/hexo-theme-next.git master --squash + git fetch https://github.com/RootCluster/hexo-theme-next.git master + warning: no common commits + remote: Counting objects: 3407, done. + remote: Total 3407 (delta 0), reused 0 (delta 0), pack-reused 3406 + Receiving objects: 100% (3407/3407), 1.21 MiB | 36.00 KiB/s, done. + Resolving deltas: 100% (2192/2192), done. + From https://github.com/RootCluster/hexo-theme-next + * branch master -> FETCH_HEAD + Added dir 'themes/next' + ``` + >`--squash`参数表示不拉取历史信息,而只生成一条commit信息 + +* 查看项目状态 + ```bash + # 查看项目状态 + git status + On branch subtree + Your branch is ahead of 'origin/subtree' by 2 commits. + (use "git push" to publish your local commits) + + nothing to commit, working tree clean + ``` + +* 推送更改到远程仓库 + ```bash + git push origin subtree + Counting objects: 381, done. + Delta compression using up to 4 threads. + Compressing objects: 100% (334/334), done. + Writing objects: 100% (381/381), 650.26 KiB | 34.22 MiB/s, done. + Total 381 (delta 23), reused 225 (delta 19) + remote: Resolving deltas: 100% (23/23), completed with 1 local object. + To https://github.com/RootCluster/hexo-themes-test.git + 8ed2e2e..405af42 subtree -> subtree + ``` + +### pull 子仓库更新 +```bash +# 更新子仓库 +git subtree pull --prefix=themes/next https://github.com/RootCluster/hexo-theme-next.git master --squash +From https://github.com/RootCluster/hexo-theme-next + * branch master -> FETCH_HEAD +Subtree is already at commit 1f5643061ec5257269673bd6159403c24015c53d. +``` + +### push 子仓库修改 +在引用子仓库的项目中修改了子仓库的相关代码,推送修改到源仓库 +* commit 修改记录 +* push 到源仓库 + ```bash + # 推送子仓库修改到源仓库master分支 + git subtree push --prefix=themes/next https://github.com/RootCluster/hexo-theme-next.git master + ``` + +### subtree 常用命令 +```bash +git subtree add --prefix= +git subtree add --prefix= +git subtree pull --prefix= +git subtree push --prefix= +git subtree merge --prefix= +git subtree split --prefix= [OPTIONS] [] +``` +## 附录 +* [如何使用 Git Submodule](http://linlexus.com/git-submodule-usage) +* [git subtree教程](https://www.jianshu.com/p/d42d330bfead) \ No newline at end of file diff --git a/source/_posts/gitignore.md b/source/_posts/gitignore.md new file mode 100644 index 000000000..f393df0f9 --- /dev/null +++ b/source/_posts/gitignore.md @@ -0,0 +1,44 @@ +--- +title: .gitignore 基础知识 +date: 2018-04-13 00:30:50 +categories: Git +tag: ignore +--- + +.gitignore顾名思义是Git中用来管理所需要忽略或者说不用纳入版本控制文件 + +## 基本配置语法 +1. “#“:表示注释 +2. “/“:表示目录 +3. “*“:表示通配符,用来通配多个字符 +4. “?“:表示通配单个字符 +5. “[]“:表示包含单个字符的匹配列表 +6. “!“:表示不忽略匹配到的文件或者目录 + +>注意:Git对.gitignore配置文件是从上往下进行规则匹配,这也意味如果:前(limit)>后(limit),则后面的规则不会被执行 + +## 全局与局部 +.gitignore分为: **全局** ignore,**局部** ignore + +### 全局ignore设置 +* 在用户账户文件夹(C:\Users\<'YourName'>)路径下新建一个命名为`.gitignore_global`的文件 +* 使用Git Bash(需要切换路径到C:\Users\<'YourName'>)或者Git CMD命令行工具输入: + ``` bash + git config --global core.excludesfile ~/.gitignore_global + ``` +* 此时全局ignore已经设置完成,你只需要修改`.gitignore_global`文件内需要忽略的文件类型就可以全局控制忽略不需要纳入版本控制的文件或文件夹 +* 不难发现,其实是往 `.gitconfig`中加入如下内容来指名Git忽略不纳入版本控制的文件,当然如果你不想用命令行完成全局设置,你也可以直接在`.gitconfig`文件中加入`[core] excludesfile= ~/.gitignore_global`内容即可 + +### 局部ignore设置 +* 只需要在Git控制版本控制项目的根目录中加入.gitignore文件,在.gitignore文件中写明忽略不纳入版本控制的文件即可 + +## 参考示例 + +>你可以查看参考[Github](https://github.com/github/gitignore)官方所写好的示例 + +## 插件.ignore +支持Android Studio,JetBrains系列 +安装方法 + +* `Settings` > `Plugs` > `Browse repositories` > `.ignore` > `Install plugin` +* 里面有已经写好的模板,只需适当修改 \ No newline at end of file diff --git a/source/_posts/gitlab1.md b/source/_posts/gitlab1.md new file mode 100644 index 000000000..760ff919f --- /dev/null +++ b/source/_posts/gitlab1.md @@ -0,0 +1,141 @@ +--- +title: Gitlab 应用搭建 +date: 2018-04-24 21:11:10 +categories: Git +tag: Gitlab +--- + +我司团队之前一直使用SVN来进行代码托管,主要问题 +1. 每次来个新人都需要找对应的[SVN](https://tortoisesvn.net/index.zh.html)管理员进行授权分配指定的仓库操作权限,有时候需要多个项目切换,还得再次提出进行仓库的指定 +2. SVN都是以中文命名,这其实没啥,但是在[eclipse](https://eclipse.org) 以及[IDEA](https://www.jetbrains.com/idea/?fromMenu) ,[Xcode](https://developer.apple.com/xcode)等开发工具,链接地址都会把中文字进行编码,造成路径非常的长,强迫症的我这怎么忍得了 +3. 产品相关的,设计相关的啥也都放在SVN里面,搞得SVN里面鱼龙混杂 + +因此在我提出及建议下,部门经理同意了对代码的管理进行隔离方便有效的对代码的授权监管,并同时制定代码的相关规范和服务的自动化部署等,提高团队的开发效率和代码质量。 + +本节主要介绍Gitlab的环境搭建和基础的功能配置 + +目的: +1. 搭建Gitlab服务 +2. 和公司AD域账号关联,用域账号直接登录Gitlab +3. 挂载Gitlab 仓库到指定存储位置 + +## Gitlab安装 + +### 环境 +* OS:CentOS 7 +* Gitlab:[Gitlab CE 10.6.4](https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el7/gitlab-ce-10.6.4-ce.0.el7.x86_64.rpm) + +>Gitlab 版本 +* Gitlab Community Edition (CE):社区版,免费,用户自行托管,通过社区提供技术支持 +* Gitlab Enterprise Edition (EE):企业版,付费,用户自行托管,提供附加的功能以及技术支持 +* Gitlab.com:免费的SaaS服务,可以创建共有以及私有的版本库,可以购买额外的技术支持 +* GitHost.io:由Gitlab提供的用户私有的独享服务 + +### Gitlab部署 +1. 系统防火墙中打开HTTP和SSH访问 + ```bash + sudo yum install -y curl policycoreutils-python openssh-server + sudo systemctl enable sshd + sudo systemctl start sshd + + sudo firewall-cmd --permanent --add-service=http + sudo systemctl reload firewalld + ``` +2. 安装Postfix发送通知邮件。如果您想使用其他解决方案发送电子邮件,请跳过此步骤并在安装GitLab后配置外部SMTP服务器 + ```bash + sudo yum install postfix + sudo systemctl enable postfix + sudo systemctl start postfix + ``` +3. 添加GitLab软件包存储库 + ```bash + curl -LJO https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el7/gitlab-ce-10.0.0-ce.0.el7.x86_64.rpm + ``` +4. 安装软件包 + ```bash + rpm -i gitlab-ce-10.0.0-ce.0.el7.x86_64.rpm + ``` + + 完成安装如下日志显示: + + ``` + *. *. + *** *** + ***** ***** + .****** ******* + ******** ******** + ,,,,,,,,,***********,,,,,,,,, + ,,,,,,,,,,,*********,,,,,,,,,,, + .,,,,,,,,,,,*******,,,,,,,,,,,, + ,,,,,,,,,*****,,,,,,,,,. + ,,,,,,,****,,,,,, + .,,,***,,,, + ,*,. + + + + _______ __ __ __ + / ____(_) /_/ / ____ _/ /_ + / / __/ / __/ / / __ \`/ __ \ + / /_/ / / /_/ /___/ /_/ / /_/ / + \____/_/\__/_____/\__,_/_.___/ + + ``` +5. 编译配置文件 + ```bash + cd /opt/gitlab/bin + ./gitlab-ctr reconfigure + ``` +6. 启动服务 + ```bash + ./gitlab-ctl start + ``` + > + * 成功启动服务,默认路径访问:http://localhost:80 + * 默认安装位置 `/opt/gitlab/` + * 配置文件默认路径 `/etc/gitlab/gitlab.rb` + * 默认账号:root,密码:5iveL!fe + +## 常用配置项修改 +以下配置项的修改,完成后**均需要重新编译**文件(配置文件默认路径 `/etc/gitlab/gitlab.rb`),默认,**并重启Gitlab**服务 + +### 访问地址 +修改`external_url`为Gitlab对应机器IP所配置的域名 +![gitlab-url](https://res.cloudinary.com/incoder/image/upload/v1525517587/blog/gitpages-gitlab-url.png) + +### LDAP启用 +修改`host`,`port`,`bind_dn`,`password`,`base`参数即可 +![gitlab-ladp](https://res.cloudinary.com/incoder/image/upload/v1525517612/blog/gitpages-gitlab-ldap.png) + +各参数解释: +* `host` 和 `port` 是 LDAP 服务的主机地址及端口 +* `bind_d`n 和 `password` 是一个管理 LDAP 的 dn 及密码 +* `base` 表示 LDAP 将以该 dn 为 节点,向下查找用户 +* `user_filter` 表示以某种过滤条件筛选用户 +* `attributes` 表示 GitLab 中的字段与 LDAP 中哪些字段可以相互对应,比如可以用 LDAP 中的 uid 来作为 GitLab 用户名 + +编译重启后,查看登录是否已经显示LDAP登录入口 + +![gitlab-ldap-login](https://res.cloudinary.com/incoder/image/upload/v1525517639/blog/gitpages-gitlab-ldap-login.png) + +为了安全我们需要关闭 GitLab 自己的注册功能,这样新用户只能通过 LDAP 认证的方式进行登陆。 + +![gitlab-sign-up](https://res.cloudinary.com/incoder/image/upload/v1525517671/blog/gitpages-gitlab-sign-up.png) + +### 存储仓库修改 +默认仓库存储位置:`/var/opt/gitlab/git-data/repositories/` +![gitlab-dirs](https://res.cloudinary.com/incoder/image/upload/v1525517697/blog/gitpages-gitlab-dirs.png) + +### Gitlab日志 +默认日志位置: `/var/log/gitlab` + +```bash +cd /opt/gitlab/bin +gitlab-ctl tail -f nginx/gitlab_access.log +``` +或者在Gitlab服务的系统设置中查看 +![gitlab-logs](https://res.cloudinary.com/incoder/image/upload/v1525517725/blog/gitpages-gitlab-logs.png) + +## 附录 +* [官方安装教程](https://about.gitlab.com/installation) +* [官方配置文件](https://docs.gitlab.com.cn/omnibus/settings/README.html) \ No newline at end of file diff --git a/source/_posts/hexo-blog.md b/source/_posts/hexo-blog.md new file mode 100644 index 000000000..93e10d44c --- /dev/null +++ b/source/_posts/hexo-blog.md @@ -0,0 +1,135 @@ +--- +title: Hexo Blog 搭建 +date: 2018-03-25 01:18:26 +categories: Hexo +tag: Build +--- + +之前一直纠结用[Jekyll](https://jekyllrb.com)还是[Hexo](https://hexo.io)来搭建[GitHub Page](https://pages.github.com)博客,原本一直想搭建一个[Material Design](https://material.io/guidelines)主题风格,从[Hexo Themes](https://hexo.io/themes)中寻找到一款不错的主题,[indigo](https://github.com/yscoder/hexo-theme-indigo)是一款支持IE10+,评论,目录导航,分享等功能的轻量Blog主题。 + +简单的修改了该主题之后,本地预览都没有什么问题,但是部署到[Github]()上,样式什么的都无法加载,应该是我的操作姿势不对吧,调整了半天没有解决,烦躁中找到之前star的另一款很受欢迎的[Next](https://github.com/iissnan/hexo-theme-next)主题。 + +既然自己修改的无法正常部署预览,那就用别人写好的吧,刚好赶上[Next](https://github.com/theme-next/hexo-theme-next)新版本V6.0系列的推出,那就不废话,直接开干 + +## 材料准备 +* [Node LTS](https://nodejs.org/en/download) +* [Git](https://git-scm.com/downloads) +* [Hexo](https://hexo.io) +* [Next](https://github.com/theme-next/hexo-theme-next) + +## 安装 +`Node`,`Git`的安装过程略 + +### Hexo +1. Hexo 安装 + ``` bash + $ npm install hexo-cli -g + ``` +2. 初始化 + ``` bash + $ hexo init + ``` +3. 安装依赖包 + ``` bash + $ cd + $ npm install + ``` +4. 启动服务预览 + ``` bash + $ hexo serve + ``` + +### Next +1. 安装Next 主题 + ``` bash + $ git clone https://github.com/theme-next/hexo-theme-next themes/next + ``` + > 当前操作在 `blog`的根目录下执行 + +2. 修改Blog 配置 +`you blog name` 根目录 `_config.yml` + * theme: 由原来默认`landscape`更改位`next`(大约:76行) + * 其他配置项,根据自己的需求进行更改,我这里更改了`title`,`subtitle`,`author`,`language`,`url`配置,其中`language`如果没有修改,默认为英文语言,在V6.0系列由原来`zh-Hans`更新为`zh-CN` + * 添加部署到Github配置 + ``` bash + deploy: + type: git + repo: https://github.com/BladeCode/BladeCode.github.io.git # 用户名仓库 + branch: master # 用户名仓库的分支应该指定master,master分支也可以不用写 + ``` + +3. 修改Theme 配置 +路径:`you blog name`/Themes/next/_config.yml +这里不罗嗦了,其配置可参考[hexo-theme-next](https://github.com/iissnan/hexo-theme-next)项目`README`文件 + +### 部署 +上面已经配置好了部署的目标仓库,那么这里直接使用Hexo提供的部署命令即可 +``` bash +$ hexo d +``` +相关命令介绍等,请查看[官方文档说明](https://hexo.io/docs) + +部署完成后,可以直接访问 http://`you blog name`/github.io + +## 自定义域名 +虽然现在blog可以使用Githug提供的项目二级域名来访问,为了个性化以及方便等,配置自己的域名 +1. 登录域名所属的管理网站(这里以阿里云域名服务为例) + ![gitpages-domain-manger](https://res.cloudinary.com/incoder/image/upload/v1525516603/blog/gitpages-domain-manger.png) +2. 添加解析 + ``` bash + $ # 解析一 + 记录类型:CNAME + 主机记录:www + 记录值:bladecode.github.io + 解析路线:default + + $ # 解析二 + 记录类型:A + 主机记录:@ + 记录值:192.30.252.153 + 解析路线:default + + $ # 解析三 + 记录类型:A + 主机记录:@ + 记录值:192.30.252.154 + 解析路线:default + ``` + > 192.30.252.153是GitHub的地址,你也可以ping你的 http://xxxx.github.io 的ip地址,填入进去 + +3. 修改Github上项目的domain设置 + ![gitpages-domain-custom](https://res.cloudinary.com/incoder/image/upload/v1525516630/blog/gitpages-domain-custom.png) +4. 添加CNAME文件 +保存路径:`you blog name`/source +新增文件:CNAME 文件 (格式要求:`保存成所有文件而不是txt文件`) +CNAME 文件内容:`incoder.org` +> 如果带有www,那么以后访问的时候必须带有www完整的域名才可以访问,但如果不带有www,以后访问的时候带不带www都可以访问。所以建议,不要带有www + +## Https开启 +开启Https 需要借助[Cloudflare](https://www.cloudflare.com),关于Cloudflare的介绍等不在这里展开 +1. 注册账号 +2. Add website + ![site](https://res.cloudinary.com/incoder/image/upload/v1525516650/blog/gitpages-https-add-site.png) +3. Querying your DNS + ![query](https://res.cloudinary.com/incoder/image/upload/v1525516664/blog/gitpages-https-dns-query.png) +4. Select Plan + ![plan](https://res.cloudinary.com/incoder/image/upload/v1525516681/blog/gitpages-https-select-plan.png) +5. 域名解析记录获取 + ![continue](https://res.cloudinary.com/incoder/image/upload/v1525516694/blog/gitpages-https-continue.png) +6. DNS 对比,并修改[Cloudflare]()提供的DNS来解析 + ![change](https://res.cloudinary.com/incoder/image/upload/v1525516714/blog/gitpages-https-change-dns.png) +7. 域名管理后台,修改DNS + ![dns](https://res.cloudinary.com/incoder/image/upload/v1525516733/blog/gitpages-https-wanwang-dns.png) + > 阿里云服务相关域名DNS修改帮助[文档](https://help.aliyun.com/knowledge_detail/39844.html) +8. 成功激活 + ![active](https://res.cloudinary.com/incoder/image/upload/v1525516756/blog/gitpages-https-active.png) +9. SSL证书申请提醒 + ![cer](https://res.cloudinary.com/incoder/image/upload/v1525516994/blog/gitpages-https-ssl-cer.png) +10. 添加强制HTTPS规则 + ![rule](https://res.cloudinary.com/incoder/image/upload/v1525517025/blog/gitpages-https-page-rule.png) +11. 规则制定 + ![deploy](https://res.cloudinary.com/incoder/image/upload/v1525517045/blog/gitpages-https-deploy-https.png) + +好了剩下的就是等证书颁发,可能要等上一些时间,具体每个人不尽相同,这里就不多做解释了。 + +Let's all,本次的Hexo的相关初级教程就到这里 diff --git a/source/_posts/hexo-iterative.md b/source/_posts/hexo-iterative.md new file mode 100644 index 000000000..7e9a42b93 --- /dev/null +++ b/source/_posts/hexo-iterative.md @@ -0,0 +1,104 @@ +--- +title: Hexo Blog 迭代 +date: 2018-05-02 18:18:18 +categories: Hexo +tag: Build +--- + +最初博客通过[Cloudflare](https://www.cloudflare.com)反向代理进行HTTPS解析,放完五一假期,Github官方开始支持[自定义域名的HTTPS解析](https://blog.github.com/2018-05-01-github-pages-custom-domains-https),在使用Cloudflare期间,经常性的521等问题烦恼,这次也可以名正言顺的弃用CloudFlare + +**本次迭代内容** +* 弃用Cloudflare +* 自动化部署 +* 常用设置 +* 常用插件安装 + +## 弃用Cloudflare +1. 关闭Cloudflare中设置Page Rules +2. 删除Cloudflare的DNS记录 +3. 还原域名配置中的DNS解析 +4. 添加Github提供的IP解析 + +[官方自定义域名设置](https://help.github.com/articles/setting-up-an-apex-domain/#configuring-an-alias-or-aname-record-with-your-dns-provider) + +## 自动化部署 +>[Github Pages](https://pages.github.com)是Github 提供一个渲染静态的Web页面服务 +* `{username}.github.io`仓库默认`master`分支 +* 其他项目仓库,默认`gh-pages`分支 +* [官方说明文档](https://help.github.com/articles/user-organization-and-project-pages) + +因此`{username}.github.io`仓库,dev分支用来存储网站的源码,`master`分支存放生成的静态文件,这样一个仓库就可以管理整个项目。每次`push`新的功能,然而每次都需要先`push`到`dev`分支,然后生成静态文件,再`push`到`master`分支,这种重复性的操作,实在太不优雅,所以采用[Travis CI](https://travis-ci.org)进行自动化部署 + +接着Github支持自定义域名开启HTTPS的好消息,Travis CI (https://travis-ci.com) 也支持开源项目啦 + +> Travis CI 区别 +* Travis-CI(https://travis-ci.org) :GitHub公开项目 +* Travis-CI(https://travis-ci.com) :~~私有付费项目~~,[2018.05.02也开始支持开源项目](https://blog.travis-ci.com/2018-05-02-open-source-projects-on-travis-ci-com-with-github-apps?utm_source=Broadcast&utm_campaign=2may_release) + +[GitHub Services are being deprecated](https://developer.github.com/changes/2018-04-25-github-services-deprecation),因此本节的自动化部署就开启Travis CI (https://travis-ci.com) 集成方案 + +### 准备 +1. 使用GitHub账号登录Travis-CI,并确认接受访问 +2. 同步了GitHub存储库,转到您的配置文件页面并启用您想要构建的存储库 +3. 添加 `.travis.yml` 文件到构建部署项目的根目录下 + +### Hexo 自动部署 +部署流程 +![部署流程](https://res.cloudinary.com/incoder/image/upload/v1525517765/blog/gitpages-travis-ci-branch-deploy.png) + +Hexo 部署脚本示例 +```bash +language: node_js # 设置语言 +node_js: stable # 设置相应的版本 +cache: + directories: + - node_modules +before_install: + - npm install -g hexo + - npm install -g hexo-cli +install: + - npm install # 安装hexo及插件 +before_script: + - npm install -g mocha + - git clone --branch master https://github.com/BladeCode/BladeCode.github.io.git public +script: + - hexo cl # 清除 + - hexo g # 生成 +after_script: + - cd ./public + - git init + - git config user.name "BladeCode" # 修改成自己的github用户名 + - git config user.email "Jerry.x@outlook.com" # 修改成自己的GitHub邮箱 + - git add . + - git commit -m "update by Travis-CI" # 更新日志 + - git push --force --quiet "https://${GH_TOKEN}@${GH_REF}" master:master # GH_token就是在travis中设置的token +branches: + only: + - dev # 只监测dev分支,一有动静就开始构建 +env: + global: + - GH_REF: github.com/BladeCode/BladeCode.github.io.git +``` + +## 常用设置 +[NexT 配置使用手册](http://theme-next.iissnan.com) +[NexT 配置使用手册 {% label primary@新 %}](https://theme-next.org/docs/) + +### NexT主题更新 + +[官方说明](https://github.com/theme-next/hexo-theme-next/blob/master/docs/zh-CN/DATA-FILES.md) + +## 常用插件安装 + +* 文章字符统计 [hexo-symbols-count-time](https://github.com/theme-next/hexo-symbols-count-time) +* 修复LeanCloud访客计数器中的严重安全漏洞 [hexo-leancloud-counter-security](https://github.com/theme-next/hexo-leancloud-counter-security) +* 图片灯箱 [theme-next-fancybox3](https://github.com/theme-next/theme-next-fancybox3) +* 本地检索 [hexo-generator-searchdb](https://github.com/theme-next/hexo-generator-searchdb) +* 注脚 [hexo-renderer-markdown-it-plus](https://github.com/CHENXCHEN/hexo-renderer-markdown-it-plus) + +## 其他 + +### 图床选择 +* [个人网站中的静态文件云存储选择](https://jimmysong.io/posts/static-website-storage) +* [嗯,图片就交给它了](https://sspai.com/post/40499) +* [NexT主题无法备份解决方式](https://github.com/iissnan/hexo-theme-next/issues/932) diff --git a/source/_posts/hugo.md b/source/_posts/hugo.md new file mode 100644 index 000000000..77770561a --- /dev/null +++ b/source/_posts/hugo.md @@ -0,0 +1,53 @@ +--- +title: Hugo 初体验 +date: 2018-07-11 16:34:10 +categories: Hugo +tag: Build +--- + +个人博客使用[Hexo](https://hexo.io/zh-cn/index.html)搭建,使用效果很不错,[RootCluster](https://github.com/RootCluster)组织主要存放自己新技术的学习和一些Demo实验。该组织同样也可以使用Github pages服务,因此也需要给RootCluster构建一个静态页面,可用直观清晰的看自己的项目,虽然之前已使用Hexo构建,为了了解其他的静态页面构建,所以这次选择了[Hugo](https://gohugo.io)。 + +[Hugo](https://gohugo.io)是世界上最快的静态网站引擎。它是用[Go](https://golang.org)(aka Golang)编写的,由[bep](https://github.com/bep),[spf13](https://github.com/spf13)和[朋友](https://github.com/gohugoio/hugo/graphs/contributors)开发 + +## 材料准备 +* SystemOS:Windows 10 +* [Chocolatey](https://chocolatey.org):Windows的包管理器 +* [Hugo](https://gohugo.io/getting-started/installing) + +## 安装 +### Chocolatey安装 +如果已安装,跳过该步骤 +* 使用 PowerShell.exe + ```bash + Set-ExecutionPolicy Bypass -Scope Process -Force; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1')) + ``` +* 使用 cmd.exe + ```bash + @"%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe" -NoProfile -InputFormat None -ExecutionPolicy Bypass -Command "iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))" && SET "PATH=%PATH%;%ALLUSERSPROFILE%\chocolatey\bin" + ``` +以上两种方式,选择其一即可 +![PowerShell.exe 演示](https://res.cloudinary.com/incoder/image/upload/v1531314279/blog/hugo_install.png) + +### hugo安装 + +```bash +choco install hugo -confirm +``` + +### 初始化Hugo +* 初始化hugo模板 + ```bash + hugo new site project_name + ``` +* 进入项目并启动项目 + ```bash + cd project_name + hugo serve + ``` + ![hugo_init](https://res.cloudinary.com/incoder/image/upload/v1531314737/blog/hugo_init.png) + +* [主题安装](https://themes.gohugo.io) + + 这里选择[Elate](https://themes.gohugo.io/hugo-elate-theme)主题作为组织的网站 + + ![主题安装](https://res.cloudinary.com/incoder/image/upload/v1531316293/blog/hugo_theme.png) \ No newline at end of file diff --git a/source/_posts/idea-multi-module.md b/source/_posts/idea-multi-module.md new file mode 100644 index 000000000..c20fe872b --- /dev/null +++ b/source/_posts/idea-multi-module.md @@ -0,0 +1,96 @@ +--- +title: IDEA 多模块项目 +date: 2019-01-10 00:32:10 +categories: IDEA +tag: [SpringBoot, Init] +--- + +[Jetbrains](https://www.jetbrains.com)系列中[IDEA](https://www.jetbrains.com/idea)是现如今公认最好用,最强大的Java开发工具,不接受任何反驳,本篇介绍macOS上使用 IDEA 创建 SpringBoot 多模块项目 + +## 准备工作 +* 系统环境:macOS 10.14.2 +* 应用工具:[IDEA](https://www.jetbrains.com/idea),[Maven](https://maven.apache.org) + +>这里不再介绍基本软件的安装及配置 + +## 多模块项目 + +一般简单的项目,按照如下项目结构进行构建,可根据也无需要自行调整 +``` +rc-springboot-docker + ├── boot-api # 项目对应用服务间提供api的接口,同时也管理项目常量、REST返回组装实体类等 + ├── boot-common # 项目公共基础包(可丢弃) + ├── boot-core # 项目业务操作,server dao层 + ├── boot-web # 项目后端Web管理 + ├── boot-rest # 项目业务控制层,给客户端提供rest接口 + └── README.md +``` + +* boot-api:是一个maven module +* boot-common:是一个maven module +* boot-core:是一个maven module +* boot-web:是一个springboot module +* boot-rest:是一个springboot module + +## 构建 + +### Parent Project +顾名思义,这是项目的外壳,一个标准的empty maven project,当然你要可以使用gradle来作为项目的构建工具,可根据自身需要自行选择,这里采用maven方式演示 +* `Create Project` + ![idea-new-project](https://res.cloudinary.com/incoder/image/upload/v1547062782/blog/idea-new-project.png) +* 设置项目groupId和artifactId等信息 + ![idea-new-setting](https://res.cloudinary.com/incoder/image/upload/v1547062780/blog/idea-new-setting.png) +* 设置项目名称及项目存储位置 + ![idea-new-path](https://res.cloudinary.com/incoder/image/upload/v1547062780/blog/idea-new-path.png) +* 删除项目src目录,使项目成为名副其实的空项目 + ![idea-delete-src](https://res.cloudinary.com/incoder/image/upload/v1547062780/blog/idea-delete-src.png) +* 新增忽略文件 + ![idea-new-ignore](https://res.cloudinary.com/incoder/image/upload/v1547062782/blog/idea-new-ignore.png) + 新增忽略文件的目的: + 1. 忽略项目中不需要进行版本追踪的文件 + 2. 隐藏忽略文件 + +* 选择maven项目模板忽略文件 + ![idea-select-maven](https://res.cloudinary.com/incoder/image/upload/v1547062782/blog/idea-select-maven.png) +* 修改忽略文件及隐藏忽略文件 + ![idea-ignore-settings](https://res.cloudinary.com/incoder/image/upload/v1547062781/blog/idea-ignore-settings.png) + ``` + # IntelliJ project files + .DS_Store + .idea/ + *.iml + out + gen + + # eclipse + *.classpath + *.project + *.springBeans + ``` + >关于ignore文件的写法,可以参考[.gitignore 基础知识](https://incoder.org/2018/04/13/gitignore/) + +### Module Project +在module中有两类,一类是maven项目,还有一类是需要启动的springboot项目 + +#### maven module project + +* 创建maven module + ![idea-module-maven](https://res.cloudinary.com/incoder/image/upload/v1547066735/blog/idea-module-maven.png) +* 设置maven module artifactId等信息 + ![idea-module-maven-artifact](https://res.cloudinary.com/incoder/image/upload/v1547066737/blog/idea-module-maven-artifact.png) +* 设置maven module 名称及存储位置 + ![idea-module-maven-name](https://res.cloudinary.com/incoder/image/upload/v1547066735/blog/idea-module-maven-name.png) +#### springboot module project + +* 创建springboot module + ![idea-new-module-springboot](https://res.cloudinary.com/incoder/image/upload/v1547066076/blog/idea-new-module-springboot.png) +* 设置springboot module 信息 + ![idea-module-metadata](https://res.cloudinary.com/incoder/image/upload/v1547066075/blog/idea-module-metadata.png) +* 选择核心组件 + ![idea-module-springboot-core](https://res.cloudinary.com/incoder/image/upload/v1547066076/blog/idea-module-springboot-core.png) +* 设置springboot module 名称及存储位置 +![idea-module-springboot-name](https://res.cloudinary.com/incoder/image/upload/v1547066076/blog/idea-module-springboot-name.png) + +### Modify Config + +#### Modify parent pom diff --git a/source/_posts/idea-skill.md b/source/_posts/idea-skill.md new file mode 100644 index 000000000..b9660eff2 --- /dev/null +++ b/source/_posts/idea-skill.md @@ -0,0 +1,80 @@ +--- +title: 开发小技巧 +date: 2019-01-02 15:00:10 +categories: DevTool +tag: [Android Studio, JetBrains] +--- + +[Android Studio](https://zh.wikipedia.org/wiki/Android_Studio)是Google基于JetBrains的[IntelliJ IDEA](https://www.jetbrains.com/idea)所定制开发的Android开发IDE。因此这里的设置适用于JetBrains公司系列的开发工具,同样也适用于Android Studio,这是一篇持续更新的文章,在平时的使用过程中一些习惯性的模板化的一些设置,可以减少我们一些重复性的操作,进而提高开发效率。 + +## 设置 + +快捷键: +* Windows:`Ctrl`+`Alt`+`S` +* macOS:`⌘`+`,` + +### 样式 + +#### 约束提示/空格及缩进 + +* 描述: + - 为了约束编写的代码过长而不换行,在代码编辑面板右侧右侧有个条竖线进行约束和警示,当然你可以关闭 + - 为了工整的显示代码的空格和换行是否正确,可以开启显示空格和缩进等样式 + +![idea-skill-line](https://res.cloudinary.com/incoder/image/upload/v1546416652/blog/idea-skill-line.png) + +#### 窗口打开全部展示 + +* 描述:为了在编辑器中展示全部打开的文件(不限制在同一行) + ![idea-open-windows-limit](https://res.cloudinary.com/incoder/image/upload/v1562844691/blog/idea-open-windows-limit.png) + + +### 颜色 + +#### 局部变量 + +* 描述:为了直观的区分出全局变量和局部变量,而不需要仔细阅读代码 +![idea-skill-local](https://res.cloudinary.com/incoder/image/upload/v1546417187/blog/idea-skill-local.png) + +#### 控制台日志 + +* 描述:为了直观在控制台上显示不同级别日志 +![idea-logcat-color](https://res.cloudinary.com/incoder/image/upload/v1562845142/blog/idea-logcat-color.png) + +颜色推荐: +* Assert:AA66CC +* Debug:33B5E5 +* Error:FF6B68 +* Info:99CC00 +* Verbose:BBBBBB +* Warning:FFBB33 + +### 其他 + +#### Toolbar添加设置按钮 + +* 描述:在不方便使用快捷键打开设置时,原本的操作是:File-->Settings Repository...,因此调整到状态栏上 +![idea-skill-settings](https://res.cloudinary.com/incoder/image/upload/v1546417198/blog/idea-skill-settings.png) + +#### 不区分大小写 + +* 描述:在编码过程中,通常一些智能提示需要根据输入的支付来提示,而大小写不同对应的提示也不完全一致,因此取消智能提示对大小写字符的要求 +![idea-skill-case](https://res.cloudinary.com/incoder/image/upload/v1546416873/blog/idea-skill-case.png) + +#### 自动导包 + +* 描述:在编码过程中,一些无用或者需要引入的包,可设置成自动的方式,当无法自动导入或移除无用包时,再手动的去选择处理 +![idea-skill-auto](https://res.cloudinary.com/incoder/image/upload/v1546416872/blog/idea-skill-auto.png) + +#### 字段默认前缀 +* 描述:为了让代码规范,我们会对变量前面设置默认前缀,那么 idea 也是支持 +![idea-field-prefix](https://res.cloudinary.com/incoder/image/upload/v1562845918/blog/idea-field-prefix.png) + +## 常用技巧 + +## 编码技巧 + +## 调试技巧 + +## 参考 +* [IntelliJ-IDEA-Tutorial](https://github.com/judasn/IntelliJ-IDEA-Tutorial) \ No newline at end of file diff --git a/source/_posts/linux-build.md b/source/_posts/linux-build.md new file mode 100644 index 000000000..43460a0a1 --- /dev/null +++ b/source/_posts/linux-build.md @@ -0,0 +1,393 @@ +--- +title: Linux 常用应用安装 +date: 2018-05-15 00:32:10 +categories: Linux +tag: Build +--- + +作为Android开发者,目标主要是在客户端,平时也就是和服务端对接数据接口,很少直接干到服务端的Linux机器,随着这波推动团队技术平台基础开发工具模块的完善,拿到了一台Linux机器,重新构建移动端的测试服务器。 + +该机器主要功能: +1. 提供移动端服务Api接口 +2. 提供移动端通讯录管理授权服务 +3. 提供企业微信通讯录同步服务 +4. 管理移动端服务器Api接口文档 + +也是第一次正式的从头开始安装所需软件及应用部署,虽然这些工作可以完全找运维去处理,难得这样的机会从头开始去熟悉Linux。 + +**安卓,是一个基于Linux内核的开放源代码移动操作系统**,因此多了解Linux是一件双赢的事情,基于当前机器需要提供的服务,安装部署需要的软件应用 + +
废话不多说,上来就是干
+ +查看当前系统版本信息 +```bash +lsb_release -a +``` +以下软件版本,请下载对应支持系统的软件 + +## Java + +[官方下载地址](http://www.oracle.com/technetwork/java/javase/downloads/index.html),选择需要的版本下载安装包 +>官方提供了`.rpm`,`.gz`两种格式安装包 + +```bash +# 1.下载安装包 +# 拷贝安装包到需要安装的服务器 +# 2.解压并安装 +# `.rpm`格式安装(jdk-xxx.rpm更换成对应的文件名) +sudo rpm -ivh jdk-xxx.rpm +# `.gz`格式安装(解压到指定目录,常存放`/usr/java/`路径) +tar zxvf jdk-xxx.tar.gz -C /usr/java/ +# 3.设置环境变量 +vim /etc/profile +# 指定JDK的配置信息(修改这里路径,指向jdk安装路径) +JAVA_HOME=/usr/java/jdk1.8.0_172 +PATH=$JAVA_HOME/bin:$PATH +CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar +export JAVA_HOME PATH CLASSPATH +# 4.编译配置文件,使修改生效 +source /etc/profile +# 5.验证jdk是否安装成功 +java –version +``` + +## Tomcat + +[官方下载地址](http://tomcat.apache.org),选择需要的版本下载安装包 +>官方提供了`.zip`,`.gz`两种格式安装包,Linux服务器下载`Core`类即可 + +```bash +# 1.下载安装文件 +wget http://mirrors.hust.edu.cn/apache/tomcat/tomcat-9/v9.0.8/bin/apache-tomcat-9.0.8.tar.gz +# 2.解压安装文件(解压到指定目录,常存放`/usr/tomcat/`路径) +tar -zxvf apache-tomcat-9.0.8.tar.gz -C /usr/tomcat/ +# 3.启动tomcat +cd /usr/local/tomcat/bin +./startup.sh +# 4.关闭tomcat +./shutdown.sh +``` + +### 配置Web管理账号 +* 修改文件conf/tomcat-users.xml,在元素中添加帐号密码,需要指定角色 + ```bash + vim /usr/local/tomcat/conf/tomcat-users.xml + # + # + # + ``` + +### 配置端口 +* 可以修改conf目录下的文件server.xml,修改Connector元素(Tomcat的默认端口是8080),需要重新启动Tomcat服务生效 + ```bash + vim /usr/local/tomcat/conf/server.xml + # + ``` + +### 应用部署 +* 放置需部署包到容器中`webapps`路径 + ```bash + cd /usr/local/tomcat/webapps + ``` +* 启动服务 + ```bash + cd /usr/local/tomcat/bin + ./startup.sh + ``` + +## Apache +一般系统中已经包含apache应用 +[官方下载地址](http://httpd.apache.org/download.cgi),选择需要的版本下载安装包 +>官方提供了`.bz2`,`.gz`两种格式安装包 + +### 安装 +查看系统中是否已包含httpd应用 +``` +rpm -qa | grep httpd 或 yum list | grep httpd +``` + +* 方式一 + ```bash + # 1.下载需要的版本文件 + wget http://apache.claz.org//httpd/httpd-2.4.33.tar.gz + # 2.解压安装文件(解压到指定目录,常存放`/usr/local/httpd/`路径) + tar -zxvf httpd-2.4.33.tar.gz -C /usr/local/httpd/ + ``` + +* 方式二(推荐) + ```bash + # 1.下载安装httpd + yum install httpd + ``` + +### 卸载 +```bash +yum erase httpd.x86_64 或 rpm -e httpd.x86_64 +``` + +### 常用命令 +```bash +# 查看服务运行状态 +systemctl status httpd.service +# 启动apache服务 +systemctl start httpd.service +# 停止apache服务 +systemctl stop httpd.service +``` + +RPM默认安装路径: + +| 路径 | 说明 | +| ---------- | --- | +| /etc | 一些设置文件放置的目录如/etc/crontab | +| /usr/bin | 一些可执行文件 | +| /usr/lib | 一些程序使用的动态函数库 | +| /usr/share/doc | 一些基本的软件使用手册与帮助文档 | +| /usr/share/man | 一些man page文件 | + +## Nginx +[官方下载地址](http://nginx.org/download),选择需要的版本下载安装包(最新安装版本1.14.0) +>官方提供了`.zip`,`.gz`两种格式安装包 + +### 安装 + +* 方式一 + ```bash + # 1.下载安装文件 + wget http://nginx.org/download/nginx-1.14.0.tar.gz + # 2.解压安装文件(解压到指定目录,常存放`/usr/local/`路径) + tar -zxvf nginx-1.14.0.tar.gz -C /usr/local/ + # 3. 编译安装依赖库 + cd /usr/local/nginx/ + ./configure + ``` + +* 方式二 + ```bash + # 默认安装路径/etc/nginx/ + yum install nginx + ``` + +### 常用命令 +* 加压文件安装常用命令 + ```bash + # 停止ngix + /usr/local/nginx/sbin/nginx -s quit + # 重新载入nginx(当配置信息发生修改时) + /usr/local/nginx/sbin/nginx -s reload + # 查看版本 + /usr/local/nginx/sbin/nginx -v + # 查看nginx的配置文件的目录 + /usr/local/nginx/sbin/nginx -t + # 查看帮助信息 + /usr/local/nginx/sbin/nginx -h + ``` +* yum安装常用命令 + ```bash + # 启动 + systemctl start nginx + # 停止 + systemctl stop nginx + # 重启 + systemctl restart nginx + # 查看运行状态 + systemctl status nginx + # 开机启动 + systemctl enable nginx + ``` + +## Node + +[官方下载地址](https://nodejs.org),选择需要的版本下载安装包 +>官方提供了`.gz`,`.7z`,`zip`等多种格式安装包 + +### 安装 +```bash +# 1.下载安装文件 +wget https://nodejs.org/download/chakracore-release/v8.6.0/node-v8.6.0-linux-x64.tar.gz +# 2.解压安装文件(解压到当前目录) +tar -zxf node-v8.6.0-linux-x64.tar.gz +# 3.建立软链接,实现全局访问 +ln -s /root/node-v8.6.0-linux-x64/bin/node /usr/local/bin/node +ln -s /root/node-v8.6.0-linux-x64/bin/npm /usr/local/bin/npm +``` + +## Redis +[官方下载地址](https://redis.io/download),选择需要的版本下载安装包 +>官方提供了`.gz`格式安装包 + +### 安装 +```bash +# 1.下载安装文件 +wget wget http://download.redis.io/releases/redis-4.0.10.tar.gz +# 2.解压安装文件(解压到当前目录) +tar xzf redis-4.0.10.tar.gz +# 3.编译安装 +cd redis-4.0.10 +make +# 4.启动服务 +src/redis-server +``` + +## 配置 +```bash +# 1.修改redis.conf文件中daemonize属性 为 yes +vim /you_install_path/redis.conf +``` +> 其他配置根据自身需要调整修改 + +## 其他命令 +1. 关闭服务 + ```bash + redis-cli -h 127.0.0.1 -p 6379 shutdown + ``` +2. 非安全模式启动 + ```bash + # 后台以非安全模式启动 + nohup /usr/local/bin/redis-server --protected-mode no & + ``` + +## 常用命令 + +### 文件查找 +#### find +find命令是根据文件的属性进行查找,如文件名,文件大小,所有者,所属组,是否为空,访问时间,修改时间等。 +* 基本格式: +find path expression +* 示例: + * 在根目录下查找文件httpd.conf,表示在整个硬盘查找 + find / -name httpd.conf + * 表示当前目录下查找文件名开头是字符串‘srm’的文件 + find . -name 'srm*' + * 查找在系统中最后10分钟访问的文件(access time) + find / -amin -10 + * 查找在系统中属于fred这个用户的文件 + find / -user fred + * 查找出小于1000KB的文件 + find / -size -1000k + +#### grep +grep是根据文件的内容进行查找,会对文件的每一行按照给定的模式(patter)进行匹配查找。 +* 基本格式: +find expression +* 主要参数: + -c:只输出匹配行的计数。 + -i:不区分大小写 + -h:查询多文件时不显示文件名。 + -l:查询多文件时只输出包含匹配字符的文件名。 + -n:显示匹配行及行号。 + -s:不显示不存在或无匹配文本的错误信息。 + -v:显示不包含匹配文本的所有行。 +* 示例: + * 显示所有包含每行字符串至少有5个连续小写字符的字符串的行 + grep ‘[a-z]\{5\}’ aa + * 显示所有以d开头的文件中包含 test的行 + grep 'test' d* + +### 进程相关 + +* 查看指定服务进程 + ```bash + # 查看httpd服务进程 + ps -ef | grep httpd + # UID PID PPID C STIME TTY TIME CMD + # root 7192 7103 0 19:59 pts/3 00:00:00 grep --color=auto httpd + ``` + + {% note info %} + * UID:用户ID + * PID:进程ID + * PPID:父进程ID + * C:CPU用于计算执行优先级的因子。数值越大,表明进程是CPU密集型运算,执行优先级会降低;数值越小,表明进程是I/O密集型运算,执行优先级会提高 + * STIME:进程启动的时间 + * TTY:完整的终端名称 + * TIME:CPU时间 + * CMD:完整的启动进程所用的命令和参数 + {% endnote %} + +* 杀死指定进程 + ```bash + kill -9 pid(逐个都删除) + ``` +* 查看指定端口 + ```bash + # 检测6379端口是否在监听 + netstat -lntp | grep 6379 + ``` + +### 文件复制 + +#### 语法 +``` +scp(选项)(参数) +``` +#### 选项 +``` +-1:使用ssh协议版本1; +-2:使用ssh协议版本2; +-4:使用ipv4; +-6:使用ipv6; +-B:以批处理模式运行; +-C:使用压缩; +-F:指定ssh配置文件; +-i:identity_file 从指定文件中读取传输时使用的密钥文件(例如亚马逊云pem),此参数直接传递给ssh; +-l:指定宽带限制; +-o:指定使用的ssh选项; +-P:指定远程主机的端口号; +-p:保留文件的最后修改时间,最后访问时间和权限模式; +-q:不显示复制进度; +-r:以递归方式复制。 +``` + +#### 参数 +* 源文件:指定要复制的源文件 +* 目标文件:目标文件。格式为user@host:filename(文件名为目标文件的名称) + +#### 示例 +* 上传本地文件到远程机器指定目录 + ``` + scp /opt/soft/nginx-0.5.38.tar.gz root@10.10.10.10:/opt/soft/scptest + # 指定端口 2222 + scp -rp -P 2222 /opt/soft/nginx-0.5.38.tar.gz root@10.10.10.10:/opt/soft/scptest + ``` + +* 上传本地目录到远程机器指定目录 + ``` + scp -r /opt/soft/mongodb root@10.10.10.10:/opt/soft/scptest + ``` + +* 从远程机器复制文件到本地 + ``` + scp root@10.10.10.10:/opt/soft/nginx-0.5.38.tar.gz /opt/soft/ + ``` + +* 从远程机器复制文件(含目录)到本地 + ``` + scp -r root@10.10.10.10:/opt/soft/mongodb /opt/soft/ + ``` + +### 文件删除 + +#### 语法 +```bash +rm [选项] 文件或目录 +``` + +#### 选项 +``` +-f:强行删除,忽略不存在的文件,不提示确认。(f为force的意思) +-i:进行交互式删除,即删除时会提示确认。(i为interactive的意思) +-r:将参数中列出的全部目录和子目录进行递归删除。(r为recursive的意思) +-v:详细显示删除操作进行的步骤。(v为verbose的意思) +``` + +#### 示例 +* 删除一个文件 + ```bash + rm file + ``` + +* 删除一个目录 + ```bash + rm file/ + ``` \ No newline at end of file diff --git a/source/_posts/linux-mysql.md b/source/_posts/linux-mysql.md new file mode 100644 index 000000000..09a108bdb --- /dev/null +++ b/source/_posts/linux-mysql.md @@ -0,0 +1,100 @@ +--- +title: Linux 之 MySQL +date: 2018-07-23 22:30:10 +categories: Linux +tag: MySQL +--- + +之前粗略的接触了Linux的基础使用和安装,这次准备在自购的服务器上跑些应用,纯属娱乐,废话不说,上来就先仍数据库。 +数据库常用的`Oracle`,`MySQL`,`SQL Server`,`MongoDB`等,排名不分先后,自己平时接触最多的也就是`MySQL`,`MongoDB`,好`MySQL`先来一份。 + +## 介绍 +MySQL是一个开源数据库管理系统,通常作为流行的LEMP(Linux,Nginx,MySQL / MariaDB,PHP / Python / Perl)堆栈的一部分安装。它使用关系数据库和SQL(结构化查询语言)来管理其数据。 + +[CentOS 7](https://www.centos.org)更喜欢[MariaDB](https://mariadb.org),它是由原始`MySQL`开发人员管理的`MySQL`分支,旨在替代MySQL。如果你在CentOS 7上运行`yum install mysql`,那么安装的是MariaDB,而不是MySQL。 + +## 清单 +* OS: CentOS 7 +* DataBase:MySQL 8.0.11 + +## 安装 + +```bash +# 1. 获取官方yum源安装包 mysql80-community-release-el7-1.noarch.rpm 是根据官网提供的版本信息 +wget wget https://dev.mysql.com/get/`mysql80-community-release-el7-1.noarch.rpm` +# 2. 安装rpm包 +rpm -ivh mysql80-community-release-el7-1.noarch.rpm +# 3. 安装mysql-server +yum install -y mysql-server +# 4. 启动mysqld服务 +systemctl start mysqld +# 5. 查看是否成功启动 +ps aux|grep mysqld +# 6. 设置mysqld服务开机自启动 +systemctl enable mysqld +``` + +## 配置 + +由于MySQL从5.7开始不允许在首次安装后,使用空密码进行登录,系统会随机生成一个密码以供管理员首次登录使用,这个密码记录在`/var/log/mysqld.log`文件中 + +```bash +# 1. 查看系统提供密码 +cat /var/log/mysqld.log|grep 'A temporary password' +# 2. 使用获取到的密码登录MySQL +mysql -u root -p +# 3. 切换数据库 +use mysql; +# 4. 修改root密码 your_password 替换成你自己的密码就可以了,这个密码是强密码,要求密码包含大小写字母、数字及标点符号,长度大于6 +alter user 'root'@'localhost' identified by 'your_password'; +``` + +## 链接 +自己平时习惯使用 [Navicat](https://www.navicat.com.cn) 进行数据库操作,因此这里进行配置链接已在云端刚刚安装的MySQL服务 +![linux-mysql](https://res.cloudinary.com/incoder/image/upload/v1532362215/blog/linux-mysql.png) +### ERROR 1130 +按照上图图的配置信息链接MySQL,发现错误提示:`ERROR 1130: Host 'xxx.xxx.xxx.xxx' is not allowed to connect to this MySQL server` + +#### 原因 +不允许从远程登陆MySQL服务,只能在localhost + +#### 解决方法 +```bash +# 切换数据库 +use mysql; +# 修改user 指定的host 为 % +update user set host = '%' where user = 'root'; +# 成功修改 ++-----------+------------------+ +| host | user | ++-----------+------------------+ +| % | root | +| localhost | mysql.infoschema | +| localhost | mysql.session | +| localhost | mysql.sys | ++-----------+------------------+ +4 rows in set (0.00 sec) +``` + +### ERROR 2059 +继续重试链接,错误提示:`ERROR 2059: Authentication plugin 'caching_sha2_password' cannot be loaded:The specified module could not be found.` + +#### 原因 +MySQL 8不支持动态修改密码验证方式 + +#### 解决方法 +```bash +# 停止mysql +systemctl stop mysqld.service +# my.cnf文件中默认有下面的语句,删除前面的#号即可,没有的话就把它添加到my.cnf中 ,默认路径`/etc/my.cnf` +default-authentication-plugin=mysql_native_password +# 切换数据库 +use mysql +# 给指定用户设置密码,这里`%`是因为之前已经将远程没有特殊指定,用%代替了localhost +ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'your_password'; +``` + +## 附录 +* [How To Install MySQL on CentOS 7](https://www.digitalocean.com/community/tutorials/how-to-install-mysql-on-centos-7) +* [ERROR 1130](https://blog.csdn.net/nyist327/article/details/45074559) +* [ERROR 2059](https://blog.csdn.net/airt_xiang/article/details/80261674) \ No newline at end of file diff --git a/source/_posts/lombok.md b/source/_posts/lombok.md new file mode 100644 index 000000000..19843421d --- /dev/null +++ b/source/_posts/lombok.md @@ -0,0 +1,333 @@ +--- +title: Lombok +date: 2019-08-21 22:00:46 +categories: Util +tag: [Util] +--- + +在实际开发过程中,不管是服务端(Java),还是客户端(Android)都需要创建对应的实例bean对象,用来实例化对象,在对需要实例化的对象中,通常需要写 `set`,`get` 方法,字段少的时候,还能忍受,尤其当客户端字段多的时候,而且字段类型或者字段名称来回改动时,稍不注意,就很大机率修改不全面,就会造成一些隐藏bug,有没有不需要手动取写(快捷键生成)这些方法,当然有,本片文章,我们就来学习 [Lombok](https://projectlombok.org) + +Project Lombok is a java library that automatically plugs into your editor and build tools, spicing up your java. +Never write another getter or equals method again, with one annotation your class has a fully featured builder, Automate your logging variables, and much more(Project Lombok是一个java库,可以自动插入编辑器并构建工具,为您的java增添色彩。 永远不要再写另一个getter或equals方法,使用一个注释,你的类有一个功能齐全的构建器,自动化你的日志记录变量等等),这是官方对Lombok的介绍,简单来讲就是通过注解的方式,代替一些重复性的代码,让代码更加简洁 + +## 安装集成 + +* 编辑器(IDEA or Android Studio)安装 Lombok 插件,`File` -> `Settings...` -> `Plugins` -> `搜索 Lombok 并安装` +* 开启编辑器 Annotation Processors + ![](https://res.cloudinary.com/incoder/image/upload/v1566701581/blog/idea-annotation-processors.png) +* 项目集成Lombok依赖,项目按照不同的包管理, 按照对应方式添加包依赖 + ```xml + + + repositories { + mavenCentral() + } + + dependencies { + implementationOnly 'org.projectlombok:lombok:1.18.8' + annotationProcessor 'org.projectlombok:lombok:1.18.8' + } + + + + + + org.projectlombok + lombok + 1.18.8 + provided + + + ``` + +## 稳定注解 + +Lombok提供稳定的注解,可以直接在生成环境使用,`org.projectlombok.lombok`包`lombok`路径下 + +### val + +**val** 作为任何局部变量声明类型(包含 for语句声明),并且该类型会推断初始化表达式的类型,同时也是`final`的。 + +* 0.10版本加入该功能 +* 使用场景:局部变量声明 + +```java +// x 将被推断为 double 类型,并且是final +val x = 10.0; +// y 将被推断为 ArrayList 类型,并且是final +val y = new ArrayList(); +// z 将被转换为 final int z = 10; +val z = 10; +``` + +> 官方示例[val](https://projectlombok.org/features/val) + +### var + +**var** 作为任何局部变量声明类型(包含 for语句声明),并且该类型会推断初始化表达式的类型。 + +* 1.16.20版本加入该功能 +* 使用场景:局部变量声明 + +```java +// x 将被推断为double,转换为 double x = 10.0d; +var x = 10.0; +``` + +> 官方示例[var](https://projectlombok.org/features/var) + +### @NonNull + +注解在 **属性** 上,会自动产生一个关于此参数的非空检查,如果参数为空,则抛出一个空指针异常,也会有一个默认的无参构造方法 + +* 0.11.10版本加入该功能 +* 支持字段,方法,参数,局部变量,枚举 + +> 官方示例[@NonNull](https://projectlombok.org/features/NonNull) + +### @Cleanup + +自动资源管理,安全地调用close()方法,确保通过调用 close() 方法清除你注释的变量声明,无论发生声明情况 + +* 支持局部变量 + +```java +public void copyFile(String in, String out) throws IOException { + @Cleanup FileInputStream inStream = new FileInputStream(in); + @Cleanup FileOutputStream outStream = new FileOutputStream(out); + byte[] b = new byte[65536]; + while (true) { + int r = inStream.read(b); + if (r == -1) break; + outStream.write(b, 0, r); + } +} +``` + +> 官方示例[@Cleanup](https://projectlombok.org/features/Cleanup) + +### @Getter/@Setter + +* 注解在 **属性** 上;为单个属性提供 set/get 方法; +* 注解在 **类** 上,为该类所有的属性提供 set/get 方法, 都提供默认构造方法 +* 等级可自己更改 PUBLIC, MODULE, PROTECTED, PACKAGE, PRIVATE,默认Public + +```java +// 可手动设置字段的set方法为你需要的修饰类型 +@Setter(AccessLevel.PROTECTED) +private String name; +``` + +> 官方示例[@Getter/@Setter](https://projectlombok.org/features/GetterSetter) + +### @ToString + +任何 **类** 定义都可以用 @ToString 注释,让lombok生成 toString() 方法的实现。默认情况下,它会按顺序打印您的类名以及每个字段,并以逗号分隔 + +* includeFieldNames,默认true:打印时包括每个字段的名称 +* callSuper,默认false:在输出中包含超类的实现的结果 +* doNotUseGetters,默认false:通常情况下,如果有可用的getter,那么就会调用它们。要禁止此操作并让生成的代码直接使用这些字段,请将其设置为true +* onlyExplicitlyIncluded,默认false:仅包含用明确标记的字段和方法。通常,默认情况下包含所有(非静态)字段 + +```java +// 排除该字段一同生成在 toString()方法中 +@ToString.Exclude +private int id; +// 配置在toString中呈现此成员的行为;如果在方法上,请在输出中包含方法的返回值 +// rank(默认为0):首先打印更高的等级。相同级别的成员按照它们在源文件中出现的顺序打印 +// name(默认为""):默认为带注释的成员的 字段/方法 名称。如果名称等于默认包含字段的名称,则此成员将取代它 +@ToString.Include(rank = 0, name = "") +private int id; +``` + +> 官方示例[@ToString](https://projectlombok.org/features/ToString) + +### @EqualsAndHashCode + +注解在 **类** 上, 可以生成 equals、canEqual、hashCode 方法,与 @Data 相比,少了 toString() 方法,部分属性和 @ToString 注解相同 + +> 官方示例[@EqualsAndHashCode](https://projectlombok.org/features/EqualsAndHashCode) + +### Constructor + +按照定制生成构造函数 + +* @NoArgsConstructor:生成不带参数的构造函数 +* @RequiredArgsConstructor:生成带有必需参数的构造函数。参数是final字段和字段是具有约束的,例如@NonNull +* @AllArgsConstructor:生成一个全参构造函数 + +> 官方示例[Constructor](https://projectlombok.org/features/constructor) + +### @Data + +生成所有字段的 getter,一个有用的 toString 方法,以及检查所有 `non-transient` 字段的 hashCode 和 equals 实现。还将为所有 `non-final` 字段以及构造函数生成setter + +> 官方示例[@Data](https://projectlombok.org/features/Data) + +### @Value + +@Value 是 @Data 的变体版,默认情况下,所有字段都是 `private` 和 `final` 的,并且不会生成setter,默认情况下,`class` 本身也是 `final` 的,因为不可变性不是可以强制进入子类的东西 + +* 0.12.0版本加入稳定的该功能 + +> 官方示例[@Value](https://projectlombok.org/features/Value) + +### @Builder + +* 对成员注解,则它必须是构造函数或方法 +* 对类(class)注解,那么将生成一个私有构造函数,所有字段都作为参数(就好像类上有@AllArgsConstructor(access = AccessLevel.PRIVATE)),并且这个构造函数已经被@Builder注释了 + +>注意,只有当您没有编写任何构造函数,也没有添加任何显式的@XArgsConstructor注释时,才会生成这个构造函数。在这些情况下,lombok将假定存在一个all-args构造函数,并生成使用它的代码;这意味着如果没有这个构造函数,就会出现编译器错误。 + +> 官方示例[@Builder](https://projectlombok.org/features/Builder) + +### @SneakyThrows + +* 捕获或抛出方法主体中语句声明它们生成的任何已检查异常 +* SneakyThrows不会下沉,封装到RuntimeException中,或者以其他方式修改列出的已检查异常类型的任何异常 + +```java +// lombok 写法 +@SneakyThrows(UnsupportedEncodingException.class) +public void utf8ToString(byte[] bytes) { + return new String(bytes, "UTF-8"); +} + +// 等价于下面写法 +public void utf8ToString(byte[] bytes) { + try { + return new String(bytes, "UTF-8"); + } catch (UnsupportedEncodingException $uniqueName) { + throw useMagicTrickeryToHideThisFromTheCompiler($uniqueName); + // This trickery involves a bytecode transformer run automatically during the final stages of compilation; + // there is no runtime dependency on lombok. + } +} +``` + +> 官方示例[@SneakyThrows](https://projectlombok.org/features/SneakyThrows) + +### @Synchronized + +@Synchronized几乎与将“synchronized”关键字放在方法上完全一样,只不过它将同步到一个私有内部对象上,这样其他不在您控制之下的代码就不会通过锁定自己的实例来干扰线程管理 +* 对于 **非静态** 方法,使用一个名为 `$lock` 的字段 +* 对于 **静态** 方法,则注释会锁定名为 `$LOCK` 的静态字段 + +> 官方示例[@Synchronized](https://projectlombok.org/features/Synchronized) + +### @Getter(lazy=true) + +适用于那些计算占用大量 CPU,或者占用较大内存时,该注解很有用 + +> 官方示例[@GetterLazy](https://projectlombok.org/features/GetterLazy) + +### @Log + +注解路径`lombok.extern.java`路径下,相关的 Log 有已下几种 + +* @CommonsLog + ```java + private static final org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog(LogExample.class); + ``` +* @Flogger + ```java + private static final com.google.common.flogger.FluentLogger log = com.google.common.flogger.FluentLogger.forEnclosingClass(); + ``` +* @JBossLog + ```java + private static final org.jboss.logging.Logger log = org.jboss.logging.Logger.getLogger(LogExample.class); + ``` +* @Log + ```java + private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger(LogExample.class.getName()); + ``` +* @Log4j + ```java + private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(LogExample.class); + ``` +* @Log4j2 + ```java + private static final org.apache.logging.log4j.Logger log = org.apache.logging.log4j.LogManager.getLogger(LogExample.class); + ``` +* @Slf4j + ```java + private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LogExample.class); + ``` +* @XSlf4j + ```java + private static final org.slf4j.ext.XLogger log = org.slf4j.ext.XLoggerFactory.getXLogger(LogExample.class); + ``` + +> 官方示例[@log](https://projectlombok.org/features/log) + +## 实验注解 + +Lombok提供实验性注解,请根据实际情况取舍,`org.projectlombok.lombok`包 `lombok.experimental`路径下 + +### @Accessors + + + +### @ExtensionMethod + + + +### @FieldDefaults + + + +### @Delegate + + + +### @Wither + + + +### onX + +* onMethod +* onConstructor +* onParam + +### UtilityClass + + + +### Helper + + + +### FieldNameConstants + + + +### SuperBuilder + + + +## 进阶配置 + +[Configuration system](https://projectlombok.org/features/configuration) + +## 其他 + +如果在对Android项目进行升级使用 Lombok 代替原来的写法,在很大程度上还是会遇到如下截图问题 +![lombok-error](https://res.cloudinary.com/incoder/image/upload/v1567324868/blog/lombok-error.png) +根据提示项目已经开启了 Annotation Processors,但是在每次打开项目都会提示错误信息 + +### 解决方法 + +Setting for all projects + +1. File -> Other Settings -> Settings for new projects -> Build, Execution, Deployment -> Compiler ->Annotation Processors +2. Enable Annotation Processing +3. Click Apply +4. Restart Your Android studio + +一些旧项目还需要额外的一些操作 + +1. 删除项目根路径下的 `yourProject.iml` 文件以及 `.idea` 目录 或者你可以 File -> Invalidate Caches / Restart... 操作 +2. 重新打开项目 + +>参考[issues264](https://github.com/mplushnikov/lombok-intellij-plugin/issues/264) diff --git a/source/_posts/mac-bash.md b/source/_posts/mac-bash.md new file mode 100644 index 000000000..4735bf1ac --- /dev/null +++ b/source/_posts/mac-bash.md @@ -0,0 +1,148 @@ +--- +title: 应该知道的系统环境配置文件 +date: 2018-11-24 15:27:20 +categories: Operating Systems +tag: [OS, Shell] +--- + +在计算机操作系统中`Shell`是用户与操作系统交互的媒介,而`bash`作为目前`Linux\macOS`系统中最常用的`Shell`,它支持的`startup`文件也并不单一,甚至让人感到费解,以下就是对Shell的学习 + +Shell:在计算机中,值“为用户提供用户界面”的软件,通常指的是 **命令行界面** 的解析器。一般来说,`Shell`指操作系统中提供访问内核所提供的服务程序。 + +通常将`Shell`分为两类 +* 命令行:提供一个命令行界面(CLI) +* 图形界面:提供一个图形用户界面(GUI) + +![linux_system](https://upload.wikimedia.org/wikipedia/commons/thumb/b/be/The_general_structure_of_a_Linux_system.jpeg/250px-The_general_structure_of_a_Linux_system.jpeg) + +在PC桌面领域,不同的操作系统都有自己的`Shell`,截止2018.10主流的操作系统市场占有率,Windows(78.04%),OS X(13.73%),Unknown(5.44%),Linux(1.64%),Chrome(1.15%),数据来源于[statcounter](http://gs.statcounter.com/os-market-share/desktop/worldwide/#monthly-201710-201810); + +这些操作系统中都有自己独特的`Shell`命令,在不同的系统版本中,命令工具也是不完全相同,例如: +* Windows:Windows CE、Windows NT常用[`cmd.exe`](https://en.wikipedia.org/wiki/Cmd.exe);Windows 10中常用[`PowerShell`](https://zh.wikipedia.org/wiki/Windows_PowerShell) +* OS X:默认[`bash`](https://zh.wikipedia.org/wiki/Bash),除此之外还提供了[`tcsh`](https://zh.wikipedia.org/wiki/Tcsh)、[`zsh`](https://zh.wikipedia.org/wiki/Z_shell)和[`ksh`](https://zh.wikipedia.org/wiki/Korn_shell) +* Linux:`/etc/shells`路径下,`/bin/sh`,`/bin/bash`,`/bin/csh`等应用 +> 更详细的请查阅[维基百科](https://zh.wikipedia.org/wiki/%E6%AE%BC%E5%B1%A4#%E5%91%BD%E4%BB%A4%E8%A1%8C%E7%95%8C%E9%9D%A2%EF%BC%88CLI%EF%BC%89%E6%AE%BC%E5%B1%A4) + +## Configuration Files +| 文件 | sh | ksh | csh | tcsh | bash | zsh | +| --------- | --- | --- | --- | --- | --- | --- | +| /etc/.login | --- | --- | login | login | --- | --- | +| /etc/csh.cshrc | --- | --- | yes | yes | --- | --- | +| /etc/csh.login | --- | --- | login | login | --- | --- | +| ~/.tcshrc | --- | --- | --- | yes | --- | --- | +| ~/.cshrc | --- | --- | yes | yes | --- | --- | +| ~/etc/ksh.kshrc | --- | int. | --- | --- | --- | --- | +| /etc/sh.shrc | int. | --- | --- | --- | --- | --- | +| $ENV (typically ~/.kshrc) | int. | int. | --- | --- | int. | --- | +| ~/.login | --- | --- | login | login | --- | --- | +| ~/.logout | --- | --- | login | login | --- | --- | +| /etc/profile | login | login | --- | --- | login | login | +| ~/.profile | login | login | --- | --- | login | login | +| ~/.bash_profile | --- | --- | --- | --- | login | --- | +| ~/.bash_login | --- | --- | --- | --- | login | --- | +| ~/.bash_logout | --- | --- | --- | --- | login | --- | +| ~/.bashrc | --- | --- | --- | --- | int.+n/login | --- | +| /etc/zshenv | --- | --- | --- | --- | --- | yes | +| /etc/zprofile | --- | --- | --- | --- | --- | login | +| /etc/zshrc | --- | --- | --- | --- | --- | int. | +| /etc/zlogin | --- | --- | --- | --- | --- | login | +| /etc/zlogout | --- | --- | --- | --- | --- | login | +| ~/.zshenv | --- | --- | --- | --- | --- | yes | +| ~/.zprofile | --- | --- | --- | --- | --- | login | +| ~/.zshrc | --- | --- | --- | --- | --- | int. | +| ~/.zlogin | --- | --- | --- | --- | --- | login | + +* yes:表示shell在启动时始终读取文件 +* login:表示如果shell是登录shell,则读取文件 +* n/login:表示如果shell不是登录shell,则读取文件 +* int.:表示如果shell是交互式的,则读取文件 + +>更详细的介绍请查阅[维基百科](https://en.wikipedia.org/wiki/Unix_shell#Configuration_files) + +关于常用`Shell`,执行流程如下图: +![flow](https://res.cloudinary.com/incoder/image/upload/v1543141362/blog/flow.png) + +## startup文件 +`bash`作为目前`Linux`,`macOS(默认bash命令)`系统中最常用的`shell`,通过上面的表格,我们可以知道macOS系统中,`bash`主要由以下文件 +* /etc/profile:The systemwide initialization file, executed for login shells +* ~/.profile: +* ~/.bash_profile:The personal initialization file, executed for login shells +* ~/.bash_login: +* ~/.bash_logout:The individual login shell cleanup file, executed when a login shell exits +* ~/.bashrc:The individual per-interactive-shell startup file + +我们看看在macOS系统中,bash的startup文件是如何进行加载 + +>注意: +>* `/etc/profile`和`/etc/paths`是系统级别,系统启动后就会加载,后面的配置文件是当前用户级的环境变量 +>* 如果`~/.bash_profile`存在,后面几个文件就会忽略不读,不在时,才会以此类推读取后面的文件 +>* `~/.bashrc`没有上述规则,他始终加载,它是在`bash shell`打开的时候载入的 + +## 特点 +`bash`的两种属性,即 **“交互”** 与 **“登录”**,按照`bash`是否与用户进行交互,可将其分为 **“交互式”** 与 **“非交互式”**;按照`bash`是否被用户登录,又可将其分为 **“登录shell”** 与 **“非登录shell”** + +### 交互式与非交互式 +* 交互式:shell的一种运行模式,交互式shell等待用户输入命令,并且立即执行,然后将结果反馈给用户。整个流程:登录——>执行命令——>退出。当你退出后,这个shell就终止 +* 非交互式:shell的另一种运行模式,它专门用来执行预先设定的命令。这种模式下,shell不予用户进行交互,而是读取存储在脚本文件中的命令并执行它们。当它读取到文件结尾,这个shell就终止 + +### 登录shell与非登录shell +* 登录shell: + * 用户通过输入用户名/密码(或者证书认证)后启动的shell; + * 通过带有`-l|--login`参数的`bash`命令启动的shell +例如:系统启动,远程启动,使用`su -`切换用户,通过`bash --login`命令启动的bash等 +* 非登录shell:以上情况除外基本就是 **“非登录shell”** +例如:从图形化界面启动终端,使用`su -`切换用户,通过`bash`命令启动bash等 + +### 主要区别 +* 使用`logout`退出`登录shell`,使用`exit`退出`非登录shell`。 +* 其实`exit`命令会判断当前shell的登录属性,并且分别调用`logout`或`exit`指令 +* **登录shell**和**非登录shell**的主要区别在于启动shell时所执行的startup文件不同;登录shell执行的startup文件为`~/.bash_profile`,而**非登录shell**执行的startup文件为`~/.bashrc` + +## 总结 + +### Path语法 +```bash +# 中间使用冒号分隔 +export PATH=$PATH::::------: +``` + +### 环境变量设置 + +#### 全局设置 +* `/etc/paths`:全局环境变量设置,建议修改此文件 +* `/etc/profile`:不建议修改此文件,全局配置,不管是哪个用户,登录时都会读取此文件 +* `/etc/bashrc`:一般在这个文件中添加系统级别环境变量,全局配置,bash shell执行时,不管是何种方式,都会读取此文件 + +#### 单用户设置 +* `~/.bash_profile`:添加用户级环境变量 +例如:设置`ANDROID_HOME`到PATH + ```bash + export ANDROID_HOME=/Users/shaoc/Library/Android/sdk + export PATH=$ANDROID_HOME/tools:$ANDROID_HOME/platform-tools:$PATH + ``` +* `~/.bashrc` 同上 +一般重启shell设置就会生效,如果想立刻生效,则可执行下面的语句: + ```bash + source 相应的文件 + ``` + +#### zsh中配置环境变量 +在安装 `oh my zsh`后,`.bash_profile`文件中的环境变量就无法起到作用,因为终端默认启动的是`zsh`,而不是`shell`,所以无法加载 + +* 解决方法 +在`~/.zshrc`配置文件中,增加对`.bash_profile`的引用: + ```bash + source ~/.bash_profile + ``` + + `.bash_profile`文件示例: + ```bash + export ANDROID_HOME=/Users/blade/Library/Android/sdk + export GRADLE_HOME=/Users/blade/Documents/DevTools/Gradle/gradle-4.6 + export FLUTTER_HOME=/Users/blade/Documents/DevTools/flutter + export PATH=$ANDROID_HOME/tools:$ANDROID_HOME/platform-tools:$GRADLE_HOME/bin:$FLUTTER_HOME/bin:$PATH + ``` + +## 附录 +* [原关于“.bash_profile”和“.bashrc”区别的总结](https://blog.csdn.net/sch0120/article/details/70256318) +* [Mac环境变量配置](https://hao5743.github.io/2017/06/28/2017-06-28/) \ No newline at end of file diff --git a/source/_posts/mac-download.md b/source/_posts/mac-download.md new file mode 100644 index 000000000..998fa14a7 --- /dev/null +++ b/source/_posts/mac-download.md @@ -0,0 +1,151 @@ +--- +title: Aria2 之 macOS +date: 2018-12-12 02:14:59 +categories: macOS +tag: [Download] +--- + +## Aria2 是什么 +Aria2 是一款支持多种协议的 **轻量级命令行** 下载工具。有以下特性: +* 多线程连线:Aria2 会自动从多个线程下载文件,并充分利用你的带宽; +* 轻量:运行时不会占用过多资源,根据官方介绍,内存占用通常在 4MB~9MB,使用 BitTorrent 协议,下行速度 2.8MB/s 时 CPU 占用率约 6%; +* 全功能 BitTorrent 客户端; +* 支持 RPC 界面远程控制 + +## Aria2 安装 +```bash +# 安装Homebrew +/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" +# 更新及体检 +brew update && brew doctor +# 安装Aria2 +brew install aria2 +``` + +> [Homebrew](https://brew.sh)是一款自由及开放源代码的软件包管理系统,用以简化Mac OS X系统上的软件安装过程,以Ruby语言写成,默认安装在`/usr/local` + +## Aria2 配置 + +```bash +# 进入~路径 +cd ~ +# 创建.aria2文件夹 +mkdir .aria2 +# 创建aria2.conf配置文件 +touch aria2.conf +``` + +复制以下内容保存在`aria2.conf`文件中,**修改** `dir=/Users/blade/Downloads`路径即可 + +``` +#用户名 +#rpc-user=user +#密码 +#rpc-passwd=passwd +#上面的认证方式不建议使用,建议使用下面的token方式 +#设置加密的密钥 +#rpc-secret=token +#允许rpc +enable-rpc=true +#允许所有来源, web界面跨域权限需要 +rpc-allow-origin-all=true +#允许外部访问,false的话只监听本地端口 +rpc-listen-all=true +#RPC端口, 仅当默认端口被占用时修改 +rpc-listen-port=6800 +#最大同时下载数(任务数), 路由建议值: 3 +max-concurrent-downloads=5 +#断点续传 +continue=true +#同服务器连接数 +max-connection-per-server=5 +#最小文件分片大小, 下载线程数上限取决于能分出多少片, 对于小文件重要 +min-split-size=10M +#单文件最大线程数, 路由建议值: 5 +split=10 +#下载速度限制 +max-overall-download-limit=0 +#单文件速度限制 +max-download-limit=0 +#上传速度限制 +max-overall-upload-limit=0 +#单文件速度限制 +max-upload-limit=0 +#断开速度过慢的连接 +#lowest-speed-limit=0 +#验证用,需要1.16.1之后的release版本 +#referer=* +#文件保存路径, 默认为当前启动位置 +dir=/Users/blade/Downloads +#文件缓存, 使用内置的文件缓存, 如果你不相信Linux内核文件缓存和磁盘内置缓存时使用, 需要1.16及以上版本 +#disk-cache=0 +#另一种Linux文件缓存方式, 使用前确保您使用的内核支持此选项, 需要1.15及以上版本(?) +#enable-mmap=true +#文件预分配, 能有效降低文件碎片, 提高磁盘性能. 缺点是预分配时间较长 +#所需时间 none < falloc ? trunc << prealloc, falloc和trunc需要文件系统和内核支持 +file-allocation=prealloc +``` + +### 开启 Aria2 +终端中输入,其中xxx是你的电脑用户名 +```bash +aria2c --conf-path="/Users/xxx/.aria2/aria2.conf" -D +``` + +### Aria2 开机自启 +1. 创建`aria2.plist`文件 + ```bash + cd ~/Library/LaunchAgents + touch aria2.plist + ``` +2. 修改`aria2.plist`文件内容,其中``中的值改为自己电脑上 aria2c 命令的路径,可以在终端输入which aria2c查看,将WorkingDirectory后面的``中的值改为自己的下载路径 + ```bash + + + + + KeepAlive + + RunAtLoad + + Label + aria2 + ProgramArguments + + /usr/local/bin/aria2c + + WorkingDirectory + /Users/blade/Downloads + + + ``` + +### 启用Web +其实,如果你喜欢使用命令来操作,那么此步可跳过 +```bash +# 获取项目代码 +git clone https://github.com/ziahamza/webui-aria2 +# 打开 index.html 文件 +cd webui-aria2/docs +open index.html +``` + +## 其他 + +### 进行brew更新警告 +警告内容:`Unbrewed header files were found in /usr/local/include ...` +原因:系统中已存在下面列表中包含的包内容不是通过`brew`进行安装 +解决方法:删除那些文件就可以了 +```bash +# 或者获取sudo权限删除 +sudo rm -rf ‘/usr/local/bin/node’ +# 重新安装node +brew install node +``` + +## 附录 +* [Mac安装使用aria2,AriaNg下载百度网盘资源](https://blog.tearth.me/mac_aria2_ariang/) +* [如何配置 Aria2 来进行文件下载](https://mofiter.com/2018/08/19/%E5%A6%82%E4%BD%95%E9%85%8D%E7%BD%AE-Aria2-%E6%9D%A5%E8%BF%9B%E8%A1%8C%E6%96%87%E4%BB%B6%E4%B8%8B%E8%BD%BD/) +* [Aria2 - 下载神器](https://mac-setup.wildflame.org/aria_2/readme.html) +* [Aria2 命令使用参考文档](https://github.com/erasin/notes/blob/master/linux/soft/aria2.md) \ No newline at end of file diff --git a/source/_posts/mac-init.md b/source/_posts/mac-init.md new file mode 100644 index 000000000..4e0dca9a8 --- /dev/null +++ b/source/_posts/mac-init.md @@ -0,0 +1,196 @@ +--- +title: MacBook Pro 初始化 +date: 2018-11-10 09:44:46 +categories: macOS +tag: [Build] +--- + +今天拿到了一辆跑车 MBP,虽然不是顶配,也能算上中等吧,废话不啰嗦,上来就是一顿操作猛如虎,最终效果就是唬 + +跑车的一些零配件来源地[Awesome Mac](https://github.com/jaywcjlove/awesome-mac/blob/master/README-zh.md) + +软件的安装,这里不再赘述,这里主要对常用开发软件的配置进行记录 + +## JDK +作为Android开发者,JDK的安装那是少不了 + +### 下载 +在Oracle 官网下载所需JDK 版本,这里举例:[JDK1.8.0_191](https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html) + +### 安装 +此处省略,简单的安装步骤 + +### 配置 +以下**命令**相关操作,均在自带系统**终端**应用或者自己安装的其他终端命令工具 +```bash +# 查看安装的Java版本 +java -version +# 编辑profile文件 +sudo vim /etc/profile +# 在打开的 profile 文件中,最下面加入以下文本,添加完成后,保存退出 +JAVA_HOME="/Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/" + +CLASS_PATH="$JAVA_HOME/lib" + +PATH=".:$PATH:$JAVA_HOME/bin" + +# 使配置生效 +source /etc/profile +# 查看JAVA_HOME是否正确 +echo $JAVA_HOME +``` +![jdk-command](https://res.cloudinary.com/incoder/image/upload/v1541968115/blog/mac-jdk-comand.png) + +![jdk-config](https://res.cloudinary.com/incoder/image/upload/v1541968115/blog/mac-jdk-config.png) + +>注意: +>1. `JAVA_HOME`中`jdk1.8.0_191.jdk`是自己安装对应版本的文件夹,可以在Finder中,快捷键:Command + Shift + G,输入:`/Library/Java/JavaVirtualMachines/`,最终得到对应的文件夹名,如:`jdk1.8.0_191.jdk` +>2. vim模式下,输入“i”:表示,插入,“esc”:表示退出编辑模式,“:wq!”:表示保存并退出 + +## Git +直接在自带系统**终端**应用中,输入`git --version`,由于之前并没有安装,系统会提示,直接同意并安装即可 + +### GitHub配置 +```bash +# 查看本地是否生成过秘钥,如果该文件夹不存在,则表示未生成过秘钥 +cd ~/.ssh +# 生成一个github的秘钥,这里github可以根据喜好自己命名(默认.ssh路径,不添加密码等操作,直接三次回车,即可生成秘钥) +ssh-keygen -t rsa -C "github" +# 查看公钥 +cat ~/.ssh/id_rsa.pub +# 复制公钥添加到GitHub的SSH设置中,这里省略操作截图步骤 +``` +![mac-github-config](https://res.cloudinary.com/incoder/image/upload/v1542034940/blog/mac-github-config.png) + +## iTerm2 +iTerm2是一款优秀强大的第三方终端,这里主要介绍如何进行对终端主题个性化的配置 + +### 下载 +[iTerm2官网](https://www.iterm2.com) + +> 注意: +>系统自带的终端默认使用`bash`;iTerm2默认使用`zsh`,因此两者切换如下命令 +```bash +# 安装完iTerm 可使用如下命令来切换 +chsh -s /bin/[zsh | bash] +``` +### 配置 + +### 基础设置 +1. 默认应用 +MenuBar -> iTerm2 -> Make iTerm2 Default Term +![iterm2-default](https://res.cloudinary.com/incoder/image/upload/v1541968115/blog/mac-iterm2-default.png) + +2. 全局热键 +MenuBar -> iTerm2 -> preference -> Keys -> Show/hide iTerm2 with a system-wide hotkey +输入设置的快捷键,这里使用`⌘,` +![iterm2-hotkey](https://res.cloudinary.com/incoder/image/upload/v1541968115/blog/mac-iterm2-hotkey.png) + +### 安装Oh my zsh +* 方式一:crul + ```bash + sh -c "$(curl -fsSL https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh)" + ``` +* 方式二:wget + ```bash + sh -c "$(wget https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh -O -)" + ``` + ![zsh-install](https://res.cloudinary.com/incoder/image/upload/v1541968115/blog/mac-zsh-install.png) + +#### PowerLine +```bash +pip install powerline-status --user +``` +> 如果提示: +command not found: pip +先执行,再执行上面的字体安装命令 +```bash +sudo easy_install pip +``` + +#### 安装PowerFonts +为避免后续的使用中,可能会遇到字符乱码的问题,因此安装字体 + +字体库需要首先将项目`clone`到本地,然后执行源码中的`install.sh`,根据自己的喜好存放在指定的位置 +```bash +# 进入Documents目录 +cd Documents +# 创建文件夹PowerFonts +mkdir PowerFonts +# 进入PowerFonts目录 +cd PowerFonts +# clone源码 +git clone https://github.com/powerline/fonts.git --depth=1 +# 进入fonts目录 +cd fonts +# 执行安装脚本 +./install.sh +``` + +#### 设置字体及背景 +* 设置字体 +MenuBar -> iTerm2 -> Preferences -> Profiles -> Text -> Change Font,选择`Meslo LG`字体,L,M,S风格,看个人喜好,这里选择`Meslo LG S Powerline` +![iterm2-font](https://res.cloudinary.com/incoder/image/upload/v1541968115/blog/mac-iterm2-font.png) + +* 背景设置 +![iterm2-presets](https://res.cloudinary.com/incoder/image/upload/v1541968117/blog/mac-iterm2-presets.png) + +#### 修改主题 +```bash +# 打开.zshrc隐藏文件 +vim ~/.zshrc +# 修改ZSH_THEME为agnoster +ZSH_THEME="agnoster" +``` +>默认:ZSH_THEME="robbyrussell" + +#### 辅助 +* 高亮插件 + ```bash + cd ~/.oh-my-zsh/custom/plugins/ + git clone https://github.com/zsh-users/zsh-syntax-highlighting.git + vim ~/.zshrc + # 添加zsh-syntax-highlighting到plugins中,放在git后面 + plugins=( + git + zsh-syntax-highlighting + ) + # 文件最后添加,然后保存并退出 + source ~/.oh-my-zsh/custom/plugins/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh + ``` + 最后,对配置文件进行生效处理 + ```bash + source ~/.zshrc + ``` +* 命令补全 +安装步骤和上面的高亮插件一致 + ```bash + cd ~/.oh-my-zsh/custom/plugins/ + + git clone https://github.com/zsh-users/zsh-autosuggestions + + vi ~/.zshrc + ``` +* 设置背景图 +iTerm2 -> Preferences -> Profiles -> Window -> BackGround Image + +## Gradle配置 +* 下载地址:[官网](http://services.gradle.org/distributions),下载-all版本 +* 设置GRADLE_HOME路径 + ```bash + # 打开.bash_profile文件 + open -e .bash_profile + # Gradle_HOME环境设置,并保存 + GRADLE_HOME=/Users/blade/Documents/DevTools/Gradle/gradle-4.6 + export GRADLE_HOME + export PATH=$PATH:$GRADLE_HOME/bin + # 配置文件生效 + source ~/.bash_profile + # 验证配置 + gradle -version + ``` + + >如果提示The file /Users/blade/.bash_profile does not exist.则在根路径下创建`.bash_profile`文件 + >执行命令`touch .bash_profilesss` + + ![gradle-config](https://res.cloudinary.com/incoder/image/upload/v1541968116/blog/mac-gradle-config.png) diff --git a/source/_posts/mac-question.md b/source/_posts/mac-question.md new file mode 100644 index 000000000..e3f1d12f7 --- /dev/null +++ b/source/_posts/mac-question.md @@ -0,0 +1,122 @@ +--- +title: MacBook Pro 疑难杂症 +date: 2019-01-10 02:04:46 +categories: macOS +tag: [Exp] +--- + +这是一篇记录使用macOS系统时遇到的一些疑难杂症 + +## iTerm2相关 + +### 文本乱码 +在一开始使用macOS就已经安装iTerm2来代替了系统自带的Terminal应用,毕竟颜值是决定要不用长期使用的重要因素 + +iTerm2对应的配置文件:`.zshrc`,Terminal对于的配置文件:`.bash_profile` 或 `.bashrc` + +* 问题:iTerm2查看本地文件,能正常显示,无乱码,但查看服务器上文件,出现乱码 +* 原因:本地iTerm2终端和服务器字符集不一致,造成乱码,macOS默认Terminal应用是`utf-8`,而iTerm2默认没有设置`utf-8`编码 +* 解决办法:给本地的`.zshrc`设置字符集编码 + ```bash + # 使用vim打开.zshrc文件 + vim ~/.zshrc + # 在文本内容末尾添加以下两行内容进行字符编码设置 + export LC_ALL=en_US.UTF-8 + export LANG=en_US.UTF-8 + # 保存文件内容,退出vim模式,并使刚刚设置的内容生效 + source ~/.zshrc + ``` + >帮助:可以在本地和服务器上分别使用`locale`命令来查看,本地和服务器的字符编码是否一致 + +### 结束指定进程 + +```bash +# 查看指定端口号 lsof -i:端口号 +lsof -i:8088 +COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME +java 72612 blade 18u IPv6 0x21ccddb0352361e5 0t0 TCP *:radan-http (LISTEN) +# kill指定进程 +kill -9 72612 +``` + +### 免密登录服务器 +一图胜千言,请看图 + +![ssh-login](https://res.cloudinary.com/incoder/image/upload/v1559382897/blog/ssh-login.png) + +### 代理处理 + +在 Mac 系统上,使用 iTerm2 是一件很享受的过程,很多事情都可以通过命令行直接完成,但是一个致命的问题是,很多连接在国内环境下,异常忙,比如通过命令 clone 或处理 GitHub 上的项目,速度慢的让人抓狂,虽然电脑开启了代理(非全局),但视乎没有什么作用,针对此问题,需要让我们的终端也通过代理 + +1. install privoxy + ```bash + brew install privoxy + ``` +2. setting privoxy + ```bash + vim /usr/local/etc/privoxy/config + ``` +3. config privoxy + ```bash + listen-address 0.0.0.0:xxxx + forward-socks5 / localhost:1080 . + ``` + >0.0.0.0 可以让其他设备访问到,若不需要,请修改成用 127.0.0.1;xxxx是HTTP代理的默认端口; + >localhost:1080 是 SOCKS5(shadowsocks) 默认的地址,可根据需要自行修改,且注意不要忘了最后有一个空格和点号。 +4. start privoxy + ```bash + # 因没有安装在系统目录内,所以启动的时候需要打全路径 + sudo /usr/local/sbin/privoxy /usr/local/etc/privoxy/config + # 查看是否启动成功(1087 端口号换成自己的) + netstat -na | grep 1087 + # 看到有类似如下信息就表示启动成功了 + tcp4 0 0 *.1087 *.* LISTEN + ``` + 代理端口查看 + ![shadowsocks-proxy](https://res.cloudinary.com/incoder/image/upload/v1562848027/blog/shadowsocks-proxy.png) +5. use proxy + * temp proxy + 如果关闭终端标签页或窗口,功能就会失效 + - star proxy + ```bash + # 这里的端口号1087,换成你自己的 + export http_proxy='http://localhost:1087' + export https_proxy='http://localhost:1087' + ``` + - cancel proxy + ```bash + unset http_proxy + unset https_proxy + + ``` + * auto proxy + - setting ~/.bash_profile + ```bash + # 打开.bash_profile 文件 + vim ~/.bash_profile + # .bash_profile文件最后添加(1087 端口替换成你自己的) + export http_proxy='http://localhost:1087' + export https_proxy='http://localhost:1087' + # 保存文件 :wq 后,使配置生效 + source ~/.bash_profile + ``` + - 上面的方式也可以在文件(`.bash_profile`)中加入如下方法,使用时只需要在终端中输入`proxy_on`命令,关闭输入`proxy_off` + ```bash + function proxy_off(){ + unset http_proxy + unset https_proxy + echo -e "已关闭代理" + } + + function proxy_on() { + export no_proxy="localhost,127.0.0.1,localaddress,.localdomain.com" + export http_proxy="http://127.0.0.1:1087" + export https_proxy=$http_proxy + echo -e "已开启代理" + } + ``` +6. test + ```bash + curl ip.gs + ``` + ![proxy-config](https://res.cloudinary.com/incoder/image/upload/v1562849019/blog/proxy-config.png) \ No newline at end of file diff --git a/source/_posts/memory-hs.md b/source/_posts/memory-hs.md new file mode 100644 index 000000000..9aed71cfb --- /dev/null +++ b/source/_posts/memory-hs.md @@ -0,0 +1,40 @@ +--- +title: 忆·黄山 +date: 2018-05-01 00:02:00 +categories: Memory +tag: 黄山 +--- + +{% cq %}黄山归来不看岳{% endcq %} + +五岳未归,先品黄山。以前看黄山还是小学课本《黄山》一文介绍黄山的美,黄山的秀丽,黄山的与众不同,这次是亲身去体验黄山的姿态;趁着五一,趁着年轻,趁着...。废话不多讲,先看黄山日出美景 + + + + + +>别问我为啥抖,没有支撑点,全程手持...逃 + +这次黄山之行并没有做任何功课,计划到实施前后不超过15天,抱着走一步,看一点的心态去玩,没想到五一节假日,来黄山的人不是很多。 + +## 出行方式 + +杭州 **城西客运站** 做大巴直达黄山景区,票价:¥110,时间:大约4小时左右到达 + +## 攻略 + +逃,没有...... +由于到达黄山游客集散中心已是14:00,由于距离黄山还有10多公里,你可以走路去黄山山脚下,而且16:00之后没有大巴去黄山景区。因此随便找了个地吃完中午饭,就往乘大巴车黄山景区去了(¥12/人),由于上山的入口有好几个,我们也没有去研究,大巴到 **云谷寺** 景区,我们也就下车从这里出发往山上去了,你可以坐缆车去往山顶,我们一行三人,选择了徒步上山,对了门票:¥230/人 + +一路说说笑笑,也没有预订上山的旅店,我们心真大,刚走了没多久,就看到了两个人被交椅抬着下山了,其中一个应该是摔了,头破血流的样子,还没开始,就...;没多管,一路还是很轻松,毕竟都是年轻人,体力不错,走到 **白鹅岭** 已经开始下雨,雨越下越大,因为在边走边看的路上,我们决定来黄山当然是去 **迎客松** 的景点,然后我们顺着 **白鹅岭** 前往 **白鹅山庄旅游商场** 去避雨,然后是人多的无法挪开脚,此时天色已晚,我们稍作休息,找了半天也没有能睡得地,那床都是人挤人。我们找了个茶馆,吃了些带着的食品,喝了一小时茶,大约20:00左右,我们决定,今晚夜行到 **迎客松** + +雨后起了大雾,山顶那时雾色正浓,能见度大约在3米。我们三人也紧随其形,在 **光明顶** 片区玩了一会,这里看日出不错,当我们并没有这里等日出,毕竟这里离 **迎客松** 有一小时多的行程,我们要明天早早的在 **迎客松** 那里拍照装逼,拍完照然后回走去最高峰 **莲花峰** ,然而到了 **迎客松** 才发现,并不像电视上看到的,是在山的悬崖边。好了,这会才23:00多,怎么办,还有好几小时,又没有帐篷什么地可住,三人就在这 **迎客松** 前的广场上,发现了超大遮阳伞两把,哈哈哈,我们就用遮阳伞前后堵住,加上自己的雨伞,构建了一个堡垒,这下,我们三可用在里面睡觉了,雨后的山上很潮湿,就这样半将半究的,坚持到4点多。 + +天快要亮了,要找地儿去拍日出,我答应别人了,要发日出照片给她,往回走去 **莲花峰** 那里并不合适,更重要的是山路也被封,不上上去,只好找到 **玉屏索道** 的另一条路上,这里刚刚好可用看到日出 + +![日出](https://res.cloudinary.com/incoder/image/upload/v1528023909/blog/travel/travel-huangshan-sunrise.jpg) + +拍完日出,我们快速折回到 **迎客松** ,那里已经开始有三三两两的人了,我们动作要快,否则等会从索道上来大批人马,嗯,快速装逼完成,迅速撤离战场 + +![迎客松](https://res.cloudinary.com/incoder/image/upload/v1528023881/blog/travel/travel-huangshan-yks.jpg) + diff --git a/source/_posts/memory-hz1.md b/source/_posts/memory-hz1.md new file mode 100644 index 000000000..77c67870a --- /dev/null +++ b/source/_posts/memory-hz1.md @@ -0,0 +1,20 @@ +--- +title: 品·杭州 +date: 2018-04-29 00:11:01 +categories: Memory +tag: 杭州 +--- + +上有天堂,下游苏杭,杭州,一个温文尔雅,一个记忆中天堂,一个南方姑娘的城市。 +杭州:毕业后的第二个城市,很开心在这样的城市生活,工作,结识这里的人,杭州和家乡的气候非常相似,因此在杭州有种在家的感觉,在这里遇到的的人,我都会记着你们美丽帅气的脸庞 + +18年是一个动荡的一年,曾经的伙伴渐渐的离开了的团队,这两年中,有的人毕业,有的人结婚,有的人生子,有的人成长,感谢我能成为你们生命中的一个过客,和你们一起经历生活百态 + +不管你们在何方,从事着什么样的工作,过着什么样的生活,我会想你们,愿你们的一切顺利 + +粗略的剪影,请异步[优酷](http://v.youku.com/v_show/id_XMzU4NTgyMDE0NA==.html?spm=a2hzp.8244740.0.0) + +{% note default %} +不遵守规则的人,我们叫他废物,但是,不珍惜同伴的人,连废物都不如 +——宁智波·带土 +{% endnote %} \ No newline at end of file diff --git a/source/_posts/microservices-vs-soa.md b/source/_posts/microservices-vs-soa.md new file mode 100644 index 000000000..de23f0aef --- /dev/null +++ b/source/_posts/microservices-vs-soa.md @@ -0,0 +1,6 @@ +--- +title: 微服务 VS 面向服务的架构 +date: 2019-06-21 10:00:00 +categories: Translation +tag: [SpringBoot] +--- \ No newline at end of file diff --git a/source/_posts/microservices.md b/source/_posts/microservices.md new file mode 100644 index 000000000..c2b4d5cf0 --- /dev/null +++ b/source/_posts/microservices.md @@ -0,0 +1,359 @@ +--- +title: 【译】• 微服务 +date: 2019-06-01 10:00:00 +categories: + - [Translation] + - [SpringBoot] +tag: [SpringBoot] +--- + +这是第一篇翻译文章,用于学习近些年火热的微服务,这篇是`微服务`概念是由 `James Lewis` 所著,虽然官网已有[中文翻译](https://mp.weixin.qq.com/s/clbRQZ6-5YoX68MzwBfQ_Q),但是在学习过程中,应该应该动手输出,这样有助于对知识的理解和记忆,废话不多说,开始翻译 + +## 微服务 +> 近些年术语“微服务架构”就像雨后春笋般蓬勃的发展,微服务描述软件应用设计是独立可部署服务一个特殊方式。虽然这些都不够准确的去定义一个架构风格,但存在一些通用的特质(大家达成共识的特征),如何去组织围绕业务能力,如何自动化部署,端点的智能发现,以及语言和数据去中心化的控制 + +### James Lewis +James Lewis 是 ThoughtWorks 的首席顾问,也是技术顾问委员会的成员。James 利用小型协作服务构建应用程序的兴趣起源于大规模集成企业系统的背景。他构建数量级的系统都使用微服务,并且几年来,他一直积极参与不断地社区发展 + +### Martin Fowler +Martin Fowler 是一个作者,演讲家,和普通的软件开发,他一直对如何组件化软件系统的问题感到困惑,他希望微服务能够实现其倡导者所发现的早期承诺 + +---------- + +“微服务”在当时任然是一个新的名词。虽然我们的自然倾向是通过这些构建,这个技术分隔软件系统,这个术语描述了一种我们发现越来越有吸引力的软件系统风格。我们已经看到很多项目在过去的几年中使用这种风格,到目前为止的结果是积极的,以至于对于我们的许多同事而言,这已成为构建企业级应用的默认样式。然而,遗憾的是,没有太多信息可以描述微服务的风格以及微服务是如何实现 + +简而言之,**微服务架构风格**[^1]是一个开发单应用作为小型服务套件开发模式,每个应用运行在自己的进程中并且他们之间通过轻量级的机制进行通信,通常的如 HTTP 资源 API。这些服务围绕业务能力并且这些都是可以独立的自动化部署。这些服务我们进行**去中心化**的集中管理。这些服务可以使用不同的编程语言来编写,同样也可以使用不同的数据存储技术 + +开始解释微服务风格,将它与单体风格进行比较是有用的:作为单元构建的单片应用程序。企业应用程序通常由 3 个之上主要构成部分: +* 客户端(由用户机器上的浏览器中运行的 HTML 页面和 JavaScript 组成) +* 数据库(由插入到公共中的许多表组成,通常是关系型,数据库管理系统) +* 服务端应用程序。 +这个服务端应用程序处理 HTTP 请求,执行域逻辑,从数据库中检索和更新数据,并选择装配发送到浏览器的 HTML 视图。这个服务端应用程序是一个单体的,一个逻辑可执行文件[^2] ,任何一次更改都生成一个新的版本去构建和部署 + +这种单体服务是构建这种系统的自然方式。所有的请求逻辑处理都运行在一个进程中,允许你使用语言的基本特性将应用划分为类,功能和命名空间。对于一些其他样例,你可以运行和测试应用在开发者的笔记本上,并使用部署管道确保已正确测试并部署到生成环境中。你可以通过负载均衡运行许多实例来进行水平扩展(常见单体应用模式 前面通过Nginx负载均衡,在 Nginx 后面运行多个应用实例) + +单体应用程序可以成功,但是越来越多的人感到沮丧-特别是随着更多应用程序部署到云端。更改周期紧密相连-对应用程序的一小部分更改,需要重新构建和部署整个应用。随着时间的推移,通常很难保持良好的模块化结构,是的更难以保持改变只影响模块中的一个模块的更改。扩展需要扩展整个应用程序,而不是需要更多资源的部分扩展 + +![图 1:单体应用和微服务](https://martinfowler.com/articles/microservices/images/sketch.png) +从上图可知单体应用和微服务在部署的角度(可升缩角度)来讲: +* 单体应用:进行可升缩,是将单体应用整个进行升缩,每台机器上的应用都是相同的 +* 微服务:每个服务都是独立的单元,可根据需要对服务单元进行任意组合进行升缩,每台机器上的应用是不相同的 + +这些挫折导致了微服务架构的风格:构建应用程序作为服务套件。事实上服务是独立部署和可扩展的,每个服务之间也提供坚实模块的边界,甚至允许不同的编程语言编写不同的服务。它们也可以由不同的团队来管理 + +我们并不认为微服务风格是新颖的或创新的,其根源可以归结为 Unix 的设计原则。但是我们认为这些没有足够的人考虑微服务架构风格,如果使用它们,许多软件的开发会更好,从中获益匪浅 + +## 微服务架构的特征 + +我们不能说微服务架构风格有正式的定义,但我们可以尝试描述我们认为合适标签的架构的共同特性。与概述共同特征的任何定义一样,并非所有的微服务架构都具备所有的特征,但我们确实希望大多数微服务架构都具有大多数的特性。虽然我们的作者一直是这个相当宽松社区的积极成员,我们的目的是尝试描述我们在自己的工作中所看到的以及我们所知道的团队的努力,特别是我们没有规定一些符合的定义 + +### 服务组件化 + +只要我们参与软件行业,人们一直希望通过将组件集成在一起来构建系统,我们在物质世界中看待事物的方式有很多类似,在过去的几十年中,我们已经看到了大多数语言平台的大型公共 libraries 的大量进展 + +在谈论组件时,我们遇到了组件构成的困难定义,我们的定义**组件**是一个可独立更换和升级的软件单元 + +微服务架构会使用到这些 libraries,但他们讲自己的软件组件化的主要方式是分解为服务。我们定义 **libraries** 作为组件链接到程序中,也可以使用内存函数中调用的组件,而**服务**是进程外的组件,它们与诸如 Web 服务请求或远程调用之类的机制进行通信。(这与许多 OOP[^3] 中的服务对象感念不同) +>所谓的库都是调用在同一个进程当中,而服务的调用是跨进程的,要通过 Web 请求的方式或者是 RPC 的方式进行通信 + +将服务用作组件(而不是 libraries)的一个主要原因是服务可以独立部署。如果你在单个进程中有多个 libraries组成的应用程序[^4],则对任何单个组件的更改都会导致必须重新部署整个应用程序。但如果一个应用由多个服务组成,你可以期望任何单服务的改变仅需要更新自己。这不是绝对的,一些更改改变了部分服务接口,从而导致一定的协调,但良好的微服务架构的目标是通过服务合同中的内聚服务边界和演化机制来最小化这些架构 + +将服务用作组件的另一个结果是更明确的组件接口,多数语言没有很好的机制来定义已[发布的接口](https://martinfowler.com/bliki/PublishedInterface.html)。通常这并不仅仅只有文档和原则性问题,来防止客户破坏组件的封装原则,而且会导致组件间过度紧密耦合。通过使用显示远程调用机制,服务可以更容易地避免这种情况 + +使用这种服务也有一些缺点。远程调用通常要比进程内调用成本要高,因此远程调用需要更粗粒度的,这通常更难以使用。如果你需要去更改组件间的职责分配,那么当你跨越流程边界时,这种行为的变化就更难 + +在第一次中,我们可以观察到服务可以映射到运行时的进程,但这只是一个大致的描述。一个服务可能包含多个进程,这些进程始终一起开发和部署,这样的应用进程和数据库是这个服务所独有的 + +### 围绕业务能力进行组织 + +在寻找将大型应用程序拆分为多个部分时,通常管理侧重于技术层,导致 UI 团队,服务器逻辑团队和数据库团队。当团队按照这些方式分开时,即使是简单的更改也可能导致跨团队项目需要时间和预算批准。一个聪明的团队围绕这个进行优化,并未减少这两个情况的发生——会强制将逻辑放置到可以访问的应用中。换句话说,逻辑无处不在。这就是康威定律[^5] 的一个例子 +>Any organization that designs a system (defined broadly) will produce a design whose structure is a copy of the organization's communication structure +> ——Melvyn Conway, 1967 + +![Conway's Law in action](https://martinfowler.com/articles/microservices/images/conways-law.png) +微服务划分方法是不同的,分为围绕**业务能力**组织的服务。此类服务为该业务领域采用广泛的软件实现,包括用户页面,持久存储,以及任何额外协作。因此,团队是跨职能的,包括开发所需的全部技能:用户体验,数据库和项目管理 + +![Service boundaries reinforced by team boundaries](https://martinfowler.com/articles/microservices/images/PreferFunctionalStaffOrganization.png) + +>微服务有多大? +虽然“微服务”已经成为这种架构风格的流行名称,但它的名字确实导致了对微服务的不关注以及关于什么构成“micro”的争论。在我们与微服务从业者的对话中,我们看到了一系列服务规模。报道的最大数量遵循亚马逊的 Two Pizza Team 的概念(比如:整个团队都可以讨厌两个披萨),意味着不超过十二人。对于规模较小的服务,我们已经看到一个6人的团队在支持6个服务。 +> +> 这导致了这样的问题:在这个尺寸范围内是否存在足够大的差异,每个人的服务和每个服务的尺寸不应该集中在一个微服务的标签下。目前我们认为将它们组合在一起会更好,但当我们进一步探索这种风格时,我们肯定会改变主意 + +以这种方式组建的一家公司是 [www.comparethemarket.com](http://www.comparethemarket.com)。跨职能团队负责构建和运营每个产品,每个产品分为多个通过消息总线进行通信的单独服务。 + +大型单机应用程序也可以围绕业务功能进行模块化,尽管这不是常见的情况。当然,我们会敦促一个庞大的团队构建一个单体的应用,以便在业务线上划分自己。我们在这里看到的主要问题是,它们往往围绕太多的背景进行组织。如果整体跨许多这些模块化边界,那么团队中的个体成员很难将它们适应其短期组织中。此外,我们看到模块化生产线需要大量的规范来执行。服务组件所需要的更明确的分离是的更容易保持团队边界清晰 + +### 产品不是项目 + +我们看到的大多数应用程序开发工作都使用项目模型:其目的是提供一些软件然后被认为是完成的。完成后,软件将移交给维护组织,构建他的项目团队将被解散。 + +微服务支持者倾向于避免这种模式,而是倾向于认为团队应该在其整个生命周期内拥有产品。对此的一个共同启示是亚马逊的概念[“你构建,运行它”](https://queue.acm.org/detail.cfm?id=1142065),开发团队对生产中的软件负全部责任。这使的开发人员能够日常接触他们的软件在生成中的行为,并增加与用户的联系,因此他们必须承担至少一些支持工作。 + +产品心态,与业务能力的联系紧密相连。不是将软件视为一组要完成的功能,而是存在一种持续的关系,其中的问题是软件如何帮助其用户增强业务能力 + +没有理由不采用单一应用程序采用相同的方法,但较小的服务粒度可以更容易地在服务开发人员和用户之间创建个人关系 + +### 智能端点和哑的 pips + +在构建不同进程间通信结构时,我们已经看到许多产品和方法都强调将重要的`smarts`放入沟通机制本身。一个很好的例子是企业服务总线(ESB),其中 ESB 产品通常包括用于消息路由,编排,转换和应用业务规则的复杂工具。 + +>微服务和 SOA +>当我们谈到微服务时,一个常见的问题,这是否是我们十年前看到的面向服务的体系结构(SOA),这一点是有道理的,因为微服务风格非常类似于 SOA 的一些拥护者所支持的。然而,问题在于 SOA 意味着[太多不同的东西](https://martinfowler.com/bliki/ServiceOrientedAmbiguity.html),并且大多数时候我们遇到称为“SOA”的东西,它与我们在这里描述的样式有很大不同,通常是由于专注于用于集成单片应用程序的 ESB +> +>特别是我们已经看到了许多拙劣的服务导向实现——从隐藏 ESB[^6] 中的复杂性的趋势,失败的多年计划,耗资数百万美元,没有任何价值,积极治理模式,积极抑制变化,有时很难看到过去的这些问题 +> +>当然,微服务社区中使用的许多技术都是从开发人员在大型组织中集成服务的经验中发展而来的。[容忍读者](https://martinfowler.com/bliki/TolerantReader.html)模式就是一个例子。使用网络努力做出了贡献,使用简单的协议是从这些经验中得到的另一种方法——远离中心标准的反应,这种标准已达到复杂性,坦率地说,[令人叹为观止](http://wiki.apache.org/ws/WebServiceSpecifications)(只要你需要一个本体来管理你的本体,你就知道你遇到了很大的麻烦) +> +>SOA 的这种场景表现导致一些服务提倡者完全拒绝 SOA 标签,尽管其他人认为服务是 SOA 的一种形式,也许正确的服务向导,无论哪种方式,SOA[^7] 意味着这些不同的事物意味着有一个更清晰地定义这种建筑风格的术语是有价值的 + +微服务社区倾向于采用另一种方法:智能端点和愚蠢的 pips。从微服务构建的应用程序旨在尽可能地分离和聚集——他们拥有自己的域逻辑,在经典的 Unix 意义上更像是过滤器——接收请求,适当地应用逻辑并产生响应。这些是使用简单的 RESTish 协议而不是复杂的协议(如 WS-Choregoraphy 或 BPEL 中央工具的编排)编排的。 + +最常用的两个协议是 HTTP 请求——响应资源 API 和轻量级消息[^8] 传递。第一个最好的表达方式是 +>Be of the web, not behind the wed +> -- lan Robinson + +微服务团队使用万维网(在很大程度上,Unix)构建的原则和协议。经常使用的资源可以通过开发人员或操作人员的非常小的努力来缓存。 + +常用的第二种方法是通过轻量级消息总线进行消息传递。选择的基础设施通常是哑的(哑仅作为消息路由器的行为)—— 向 RabbitMQ 或者 ZeroMQ 这样的简单实现不仅仅提供可靠的异步结构——智能功能存在于那些生产和消费诸多消息的各个端点中,即存在于各个服务中。 + +在一个单体应用中,组件在进程中执行,它们之间通信是通过方法调用或函数调用。将整体变为微服务的最大问题在于改变通信模式。从内存中方法调用到 RPC 的简单转换导致繁琐的通信,这种通信效果不佳。相反,您需要粗粒度的方法替换细粒度的通信。 + +### 去中心化的治理 + +集中治理的后果之一是在单个技术平台上实现标准化的趋势。经验表明,这种方法是有限的——不是每个平台是一样的,不是每个平台的解决方案是一致的。我们推荐使用正确的工具来完成工作,而单体应用程序在一定程度上利用不同的语言,但这并不常见 + +将单个应用组件拆分为多个服务,我们可以在构建每个组件时做出选择。你希望使用 Node.js 建立一个简单的报告页面?没问题。想通过 C++ 来实现出彩的实时组件?没毛病。想换不同风格的数据库,以更好地适应一个组件的读取行为?可以重建 + +当然,只是因为你可以做某件事,并不意味着你可以应该——但以这种方式划分你的系统意味着你可以选择 + +构建微服务的团队也更喜欢采用不同的标准方法。他们更倾向于其他开发人员可以使用的有用工具来解决与他们面临的类似问题,而不是使用在纸上某处写下的一组定义标准。这些工具通常从实现中收集并广泛的共享,有时,但不仅仅是使用内部开源模型。现在 Git 和 GitHub 已经成为事实上的版本控制系统,开源实践在内部变得越来越普遍。 + +Netflix 是遵循这一理念的组织的一个很好的例子。共享有用的,尤其是经过实战考验的代码,因为鼓励其他开发人员以类似的方式解决类似问题,但如果需要,可以选择不同的方法。共享库往往侧重于数据存储,进程间通信的常见问题,我们将在下面进一步讨论基础架构自动化 + +对于微服务社区来说,管理费用特别缺乏吸引力。这并不是说社区不重视服务契约。恰恰相反,因为往往会有更多。只是他们正在寻找管理这些契约的不同方式。像[容错读取](https://martinfowler.com/bliki/TolerantReader.html)和[消费者驱动的契约](https://martinfowler.com/articles/consumerDrivenContracts.html)这样的模式通常应用于微服务。这些援助服务契约独立发展。在构建过程中执行消费者驱动的契约可以增强信心,并提供有关您的服务是否正常运行的快速反馈。事实上,我们知道澳大利亚的一个团队通过消费者驱动的契约推动服务的建设。他们使用简单的工具来定义合同服务。在编写新服务的代码之前,这将成为自动构建的一部分。然后,该服务仅构建在满足合同的程度——在构建新软件时避免“YAGNI”[^9] 困境的优雅方法。这些技术和围绕他们成长的工具通过减少服务间的时间耦合来限制重要合同管理的需要 + +>多语言,多选择 +JVM 作为平台的发展只是在一个通用平台中混合语言的最新例子。近十年依赖,通常的做法是采用更高级别的语言来更高级别的抽象。同样,在平台底层以更低层次的编程语言编写性能敏感的代码也很普遍。然而,许多单块系统并不需要这种级别的性能优化,另外 DSL 和更高层次的抽象也不常用(这令我们感到失望)。相反,许多单体应用通常就使用单一编程语言,并且对所用的技术数量进行限制的趋势[^10] + +也许去中心化治理的最高点就是建立它/运行它,由亚马逊推广的精神。团队负责他们构建的软件的所有方面,包括全天候运行软件。这种责任水平的下放绝对不是常态,但我们确实看到越来越多的公司将责任推向开发团队。Netflix 是另一个采用这种精神[^11] 的组织。每天晚上凌晨 3 点您被你的寻呼机唤醒,无疑是在编写代码时专注于质量的强大动力。这些想法与传统的集中治理模式相差甚远 + +### 去中心化数据管理 + +去中心化数据管理以多种不同的方式呈现。在最抽象的层面上,它意味着世界的概念模型在不同系统之间会有所不同。在整个大型企业时,这是一个常见问题,客户的销售视角将与支持视角不同。从销售视角中称为“客户”的某些内容,可能根本不会出现在支持视角中。那些在两个视角中具有相同属性的事物,或许在语义上有微妙的不同 + +>经过实战检验的标准和强制执行的标准 +微服务团队倾向于避开企业架构小组制定的严格执行标准,但很乐意使用甚至宣传 HTTP,ATOM 和其他微格式等开放标准的使用,这有点很二分法 +> +>关键的区别在于如何制定标准以及如何实施标准。有 IETF 等团体管理的标准只有在更广泛的世界中有多高实施时才能成为标准,并且通常来至于成功的开源项目 +> +> 这些标准与企业的许多标准不同,后者通常由最近没有编程或受供应商过度影响的团体开发 + +此问题在应用程序间很常见,但也可能在应用程序中发生,特别是将应用程序划分为单独的组件时。一种有用的思考方式是“领域驱动设计”中的[“限定上下文”](https://martinfowler.com/bliki/BoundedContext.html)的概念。DDD 将复杂领域划分为多个限界上下文,并映射出他们之间的关系。此过程对单体和微服务架构两者都很有用,而且就像前面有关“业务功能”一节中所讨论的那样,在服务和各个限界上下文之间所存在的自然的联动关系,能有助于澄清和强化这种划分。 + +除了关于概念模型的分散决策之外,微服务还分散了数据存储决策。虽然单一应用程序更喜欢使用单个逻辑数据库来存储持久性数据,但企业通常更喜欢在一系列应用程序中使用单个数据库——其中许多决策是通过供应商的商业模式来实现。微服务更喜欢让每个服务管理自己的数据库,可以是同一数据库技术的不同实例,也可以是完全不同的数据库系统——这种方法称为["Polyglot Persistence"](https://martinfowler.com/bliki/PolyglotPersistence.html)。你可以在整体中使用多语言持久性,但它在微服务中更常出现。 +![](https://martinfowler.com/articles/microservices/images/decentralised-data.png) + +跨服务分散数据责任对管理更新有影响。处理更新的常用方法是在更新多个资源时使用事务来保证一致性。这种方法通常用于整体结构中。 + +使用这样的事务有助于保持一致性,但会产生显著的时间耦合,在多个服务中是有问题。众所周知,分布式事务很难实现,因此微服务架构[强调服务之间的无事务协调](http://www.eaipatterns.com/ramblings/18_starbucks.html),明确承认一致性可能只有最终的一致性,而问题则通过补偿操作来处理。 + +选择以这种方式管理不一致是许多开发团队面临的新挑战,但它通常与业务实践相匹配。企业通常会处理一定程度的不一致,以便快速响应需求,同时采取某种逆转流程来应对错误。只要修复错误的成本低于在更大的一致性下丢失业务的成本,那么权衡是值得的。 + +### 基建设施自动化 + +基础设施自动糊技术在过去几年中发生了巨大变化——特别是云和 AWS 的发展降低了构建,部署和运行微服务的操作复杂性。 + +许多使用微服务构建的产品或系统都是由具有丰富的[持续交付(Continuous Delivery)](https://martinfowler.com/bliki/ContinuousDelivery.html)经验的团队构建的,并且是前身的[持续集成(Continuous Integration)](https://martinfowler.com/articles/continuousIntegration.html)。以这种方式构建软件的团队广泛使用基础设施自动化技术。这在下面显示的构建管道中说明 + +![basic build pipeline](https://martinfowler.com/articles/microservices/images/basic-pipeline.png) + +由于这不是关于持续交付的文章,我们将在这里引起注意几个关键功能。我们希望尽可能地信心使我们的软件正常工作,因此我们进行了大量的**自动化测试**。推广工作软件“向上”管道意味着我们**自动化部署**到每个新环境。 + +>做正取的事情很容易 +我们发现由于持续交付和部署而增加自动化的一个副作用是创建有用的工具来帮助开发人员和操作人员。用于创建人工制品,管理代码库,提供简单服务或添加标准监视器和日志记录的工具现在非常普遍。网上最好的例子可能是 [Netflix 的开源工具集](https://netflix.github.io/),但还有其他一些,包括我们官方使用的 [Dropwizard](http://dropwizard.codahale.com/) + +一个单一的应用程序将非常愉快地构建,测试和推动通过这些环境。事实证明,一旦你投资自动化整个生产的生产之路,那么部署更多地应用程序视乎不再那么可怕。请记住,CD的目标之一就是使用部署无聊,所以无论是一个还是多个应用,只要它任然无聊就无聊无所谓[^12] + +我们看到团队使用广泛的基础设施自动化的另一个领域是管理生产中的微服务。与我们上面的断言相反,只要部署很无聊,单块和微服务之间没有太大的区别,每个部署的运营环境可能会截然不同 +![Module deployment often differs](https://martinfowler.com/articles/microservices/images/micro-deployment.png) + +### 容错设计 +使用服务作为组件的结果是,应用需要设计以便他们能够容忍服务的失败。由于提供者不可用(不可达)等,任何服务调用都可能失败,客户端必须尽可能优雅地对此作出响应。与单体设计相比,这是一个缺点,因为它引入了额外的复杂性来处理它。结果是微服务团队持续不断反思服务失败如何影响用户体验。Netflix 的 Simian Army 在工作日引发服务甚至数据中心的故障,以测试应用程序的弹性和监控。 + +>断路器和“可随时上线的代码” +断路器一词与其他一些模式一起出现发布,如 Bulkhead 和 Timeout。在构建彼此通信的应用系统时,将这些模式加以综合运用变得至关重要。[Netflix 博客](http://techblog.netflix.com/2012/02/fault-tolerance-in-high-volume.html)这篇文章很好的解释了这些模式如何应用。 + +这种在生产环境中所进行自动化测试,足以让大多数运维组织兴奋地浑身颤栗,就像在一周的长假即将到来前那样。这并不是说单体式架构风格不具备复杂的监控设置——在我们的经验中,这在单体系统中并不常见罢了。 + +由于服务可能随时发生故障,因此能够快速检测故障并在可能情况下自动恢复服务非常重要。微服务应用程序非常重视应用程序的实时监控,检查“架构元素指标”(数据库每秒获得多少请求)和“业务相关指标”(例如每分钟收到多少订单)。当系统某个地方出现问题,语义监控可以提供一个预警,从而触发开发团队跟进和调查工作。 + +这对于微服务架构尤为重要,因为微服务对编排和事件协作的偏好会导致紧急行为。虽然许多权威人士赞扬偶然出现的价值,但事实是,新兴行为有时可能是一件坏事。监控对于快速发现下不良紧急行为至关重要,因此可以修复。 + +>“同步调用”有害 +每当您在服务之间进行多次同步调用时,您将遇到停机的乘法效应。简而言之,就是系统停机时间成为各个组件停机时间的产物。您面临一个选择,使您的呼叫异步或管理停机时间。在 `www.guardian.co.uk`网站上,他们在新平台上实施了一条简单的规则——每个用户请求一次同步调用,而在 Netflix,他们的平台 API 重新设计已经在 API 结构中建立了异步性。 + +monoliths 可以像微服务一样透明——事实上,他们应该是。不同之处在于您绝对需要知道在不同进程中运行的服务何时断开连接。对于同一过程中的库,这种透明性不太可能有用。 + +微服务团队希望看到针对每个服务的复杂监控和日志记录设置,例如显示上/下状态的仪表板以及各种运营和业务相关指标。有关断路器状态,当前吞吐量和延迟的详细信息是我们经常遇到的其他示例。 + +### “演进式”设计 + +微服务从业者通常拥有“演进式”设计背景,而且通常将服务分解视为额外的工具,使应用程序开发人员能够控制应用程序中的更改而不会减慢变更。变更控制并不一定意味着改变——通过正确的态度和工具,你可以对软件进行频繁,快速和良好控制的变更。 + +每当你尝试将软件系统分解为组件时,就面临着如何进行划分各个部分的决定——我们决定将应用程序切分的遵循的原则是什么?组件的关键属性是独立替换和可升级性[^13] 的特点——这意味着需要寻找这些点,即想象在不影响其合作者的情况下重写组件。事实上,许多微服务团队通过明确预期服务将来会废弃,而不是守着这些服务做长期的演进。 + +Guardian 网站是一个设计和构建为单体的应用程序的一个很好例子,然而它已经开始向在微服务方向进行演进了。原先的单体系统依然是网站的核心,但在添加新特性时他们愿意以构建一些微服务的方式来进行添加,而这些微服务会去调用原先那个单体系统的 API。这种方法对于本质上是临时的功能尤其方便,例如报道体育赛事的专用页面。当使用快速开发语言时,像这样的网站就能被快速整合在一起,并在时间结束后删除。我们在金融机构看到了类似的做法,针对一个市场机会,添加新服务进来,并在几个月甚至几周后丢弃。 + +这种对可替换性的强调是模块化设计一般性原则的一个特例,即通过“演进式”模式推动模块化实现。大家都愿意将那些在同时发生变化[^14] 的东西,放到同一个模块中。很少变化的部分,应该放在不同的服务中,以区别那些当前正在经历大量变动的部分。如果您发现需要同时反复变更的两个服务时,那就表明他们应该合并。 + +将组件放入服务中可以为更细粒度的发布计划添加机会。对于单体应用,任何更改都需要完整构建和部署整个应用程序。但是对使用微服务,您只需要重新部署您修改的服务。这可以简化并加快发布过程。缺点是:必须考虑当一个服务发生变化时,依赖它并对其进行消费的其他服务将无法工作。传统的集成方法是尝试使用版本控制来解决这个问题,但微服务领域中,大家更喜欢使用版本控制作为[最后不得已的手段](https://martinfowler.com/articles/enterpriseREST.html#versioning)。我们可以通过将服务设计为对提供者变更,尽量能够容错来避免大量版本控制 + +## 未来的方向是“微服务”吗? + +我们写这篇文章的主要目的是解释微服务的主要思想和原则。通过花时间来做到这一点,我们清楚地认为微服务架构风格是一个重要的想法——值得认真考虑企业应用程序。我们最近使用这种方式构建了几个系统,并了解其他团队已经使用并支持这种方法。 + +我们了解到那些在某种程度上做为这种架构风格的实践先驱包括:亚马逊,Netflix,[Guardian](https://www.theguardian.com/) 和 [UK Government Digital Service](https://gds.blog.gov.uk/),[realeastate.com.au](https://martinfowler.com/articles/realestate.com.au),[comparethemarket.com](http://www.comparethemarket.com/)。2013 年的技术大会圈子充满了各种各样的,正在转向可以归类为微服务的公司——包括 Travis CI。此外,有很多组织长期以来一直在做我们称为微服务的东西,但没有使用过这个名字(通常被标记为 SOA——尽管如我们所说,SOA 有许多互相矛盾的形式[^15] ) + +然而,尽管有这些积极的经验,但我们并不认为我们确信微服务是软件架构的未来发展方向。虽然到目前为止我们的经验与单体应用相比是积极的,但我们意识到没有足够的时间让我们做出充分的判断。 + +![](https://martinfowler.com/articles/microservices/images/sam-book.jpg) +>我们的同事 Sam Newman 在 2014 年的大部分时间都在撰写一本书,该书描述了我们构建微服务的经验。如果想进一步了解该主题,这应该是您的下一步 + +通常,您的架构决策的真正后果只有在开发它几年后才会明显。我们已经由带着强烈模块化愿望的优秀团队所做的一些项目,最终却构建出一个单体架构,并在几年内不断腐化。许多人认为微服务不太可能出现这种衰退,因为服务边界是明确的,很难随意捣乱。然而,对于那些开发时间足够长的各种系统,除非我们已经见识的足够多,否则我们无法真正评估微服务架构是如何成熟的。 + +人们可能会期望微服务成熟得很好。在组件化的任何努力中,成功取决于在组件中的适用程度。很难弄清楚组件边界的确切位置。“演进式”设计承认难以对边界进行正确定位,因此它将工作的重点放到了易于对边界进行重构之上。但是当您的组件是具有远程通信的服务时。那么重构比适用进程内库要困难的多。跨服务边界移动代码很困难,任何接口更改都需要在参与者之间协调,需要添加向后兼容性,测试变得更加复杂。 + +另一个问题是,如果组件没有干净利落地组成一个系统,那么您所做的就是将复杂性从组件内部转移到组件之间的连接。这样做的后果,不仅仅是移动复杂性,而是将其移动到一个不那么明确且难以控制的地方。当你在一个小而简单的组件内部查看时,人们很容易认为事情已经变得更好了,然而却忽略了服务之间的杂乱连接 + +最后,还有团队技能的因素。新技术往往被技术更加过硬的团队所采用。对于技术更加过硬的团队更更有效的一项技术,并不一定适用于技术略逊一筹的团队。我们已经看到很多不太熟练的团队构建混乱的单体架构,当微服务发生这种混乱时,会出现什么情况?这需要花时间来观察。一个糟糕的团队,总是会创建一个糟糕的系统——很难说微服务是减少了杂乱,还是让事情变得更糟。 + +我们听到一个合理的说法,不应该一上来就以微服务架构作为起点。相反,从[单体应用开始](https://martinfowler.com/bliki/MonolithFirst.html),保持模块化。当单体系统出现问题时将其拆分为微服务。(虽然[这个建议并不理想](https://martinfowler.com/articles/dont-start-monolith.html),但是好的进程内接口通常不是一个好的服务接口) + +因此,我们谨慎乐观地写下这一点。到目前为止,我们已经看到了足够多的微服务风格,觉得它是[一条值得走的路](https://martinfowler.com/microservices/)。我们无法确定最终会在哪里结束,但软件开发的挑战之一是您只能根据您当前必须提供的不完善信息作出决策。 + +## 参考 + +虽然这不是一个详尽的列表,但是它们是微服务从业者可以从中吸取灵感来源,或者是那些倡导的理念与本所述内容详实的一些资料 + +博客和在线文章 +* [Clemens Vasters’ blog on cloud at microsoft](http://blogs.msdn.com/b/clemensv/) +* [David Morgantini’s introduction to the topic on his blog](http://davidmorgantini.blogspot.com/2013/08/micro-services-introduction.htm) +* [12 factor apps from Heroku](http://12factor.net/) +* [UK Government Digital Service design principles](https://www.gov.uk/design-principles) +* [Jimmy Nilsson’s blog](http://jimmynilsson.com/blog/) and [article on infoq about Cloud Chunk Computing](http://www.infoq.com/articles/CCC-Jimmy-Nilsson) +* [Alistair Cockburn on Hexagonal architectures](http://alistair.cockburn.us/Hexagonal+architecture) + +书籍 +* [Release it](https://www.amazon.com/gp/product/0978739213?ie=UTF8&tag=martinfowlerc-20&linkCode=as2&camp=1789&creative=9325&creativeASIN=0978739213) +* [Rest in practice](https://www.amazon.com/gp/product/0596805829?ie=UTF8&tag=martinfowlerc-20&linkCode=as2&camp=1789&creative=9325&creativeASIN=0596805829) +* [Web API Design (free ebook)](https://pages.apigee.com/web-api-design-ebook.html). Brian Mulloy, Apigee. +* [Enterprise Integration Patterns](https://www.amazon.com/gp/product/0321200683?ie=UTF8&tag=martinfowlerc-20&linkCode=as2&camp=1789&creative=9325&creativeASIN=0321200683) +* [Art of unix programming](https://www.amazon.com/gp/product/0131429019?ie=UTF8&tag=martinfowlerc-20&linkCode=as2&camp=1789&creative=9325&creativeASIN=0131429019) +* [Growing Object Oriented Software, Guided by Tests](https://www.amazon.com/gp/product/0321503627?ie=UTF8&tag=martinfowlerc-20&linkCode=as2&camp=1789&creative=9325&creativeASIN=0321503627) +* [The Modern Firm: Organizational Design for Performance and Growth](https://www.amazon.com/gp/product/0198293755?ie=UTF8&tag=martinfowlerc-20&linkCode=as2&camp=1789&creative=9325&creativeASIN=0198293755) +* [Continuous Delivery: Reliable Software Releases through Build, Test, and Deployment Automation](https://www.amazon.com/gp/product/0321601912?ie=UTF8&tag=martinfowlerc-20&linkCode=as2&camp=1789&creative=9325&creativeASIN=0321601912) +* [Domain-Driven Design: Tackling Complexity in the Heart of Software](https://www.amazon.com/gp/product/0321125215?ie=UTF8&tag=martinfowlerc-20&linkCode=as2&camp=1789&creative=9325&creativeASIN=0321125215) + +简报 +* [Architecture without Architects](https://www.youtube.com/watch?v=qVyt3qQ_7TA). Erik Doernenburg +* [Does my bus look big in this?](http://www.infoq.com/presentations/soa-without-esb). Jim Webber and Martin Fowler, QCon 2008 +* [Guerilla SOA](http://www.infoq.com/presentations/webber-guerilla-soa). Jim Webber, 2006 +* [Patterns of Effective Delivery](http://vimeo.com/43659070).Daniel Terhorst-North, 2011. +* [Adrian Cockcroft's slideshare channel.](http://www.slideshare.net/adrianco) +* [Hydras and Hypermedia](http://vimeo.com/28608667). Ian Robinson, JavaZone 2010 +* Justice will take a million intricate moves Leonard Richardson, Qcon 2008. +* [Java, the UNIX way](http://vimeo.com/74452550). James Lewis, JavaZone 2012 +* [Micro services architecture](http://yow.eventer.com/yow-2012-1012/micro-services-architecture-by-fred-george-1286). Fred George, YOW! 2012 +* [Democratising attention data at guardian.co.uk](http://gotocon.com/video#18). Graham Tackley, GOTO Aarhus 2013 +* [Functional Reactive Programming with RxJava](http://gotocon.com/video#6). Ben Christensen, GOTO Aarhus 2013 (registration required). +* [Breaking the Monolith](http://www.infoq.com/presentations/Breaking-the-Monolith). Stefan Tilkov, May 2012. + +论文 +* L. Lamport,[“The Implementation of Reliable Distributed Multiprocess Systems”](http://research.microsoft.com/en-us/um/people/lamport/pubs/implementation.pdf), 1978 +* L. Lamport, R. Shostak, M. Pease,["The Byzantine Generals Problem"](http://www.cs.cornell.edu/courses/cs614/2004sp/papers/lsp82.pdf), 1982 +* R.T. Fielding, ["Architectural Styles and the Design of Network-based Software Architectures"](http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm), 2000 +* E. A. Brewer, ["Towards Robust Distributed Systems"](http://www.cs.berkeley.edu/~brewer/cs262b-2004/PODC-keynote.pdf), 2000 +* E. Brewer, ["CAP Twelve Years Later: How the 'Rules' Have Changed"](http://www.infoq.com/articles/cap-twelve-years-later-how-the-rules-have-changed), 2012 + +## 总结 + +单体应用与微服务比较 + +### 单体应用 + +#### 特性 +* 调用方便,都是在一个进程内进行调用(针对于 Java 来说,就是运行在一个 JVM 上的应用) +* 部署方式简单, +* 事务处理方式可以容易处理 +* 由于都在一个进程内API 调用,不涉及网络的访问,因此出错的可能性要低很多 + +#### 优缺点 + +* 优点 + * 为人所熟知 + * 便于共享 + * 易于测试 + * 容易部署 +* 缺点 + * 复杂性逐渐变高 + * 技术债务逐渐上升 + * 部署速度逐渐变慢 + * 阻碍技术创新 + * **无法按需伸缩** + +### 微服务 + +#### 特性 + +* 每个微服务可独立运行在自己的进程里 +* 一系列独立运行的微服务共同构建起了这个系统 +* 每个服务为独立的业务开发,一个微服务一般玩某个特定的功能,比如:订单管理,用户管理等 +* 微服务之间通过一些轻量的通讯机制进行通信,比如通过 REST API 或者 RPC 的方式调用 + +#### 优缺点 + +* 优点 + * 易于开发和维护 + * 启动较快 + * 局部修改容易部署 + * 技术栈不受限 + * 按需伸缩 + * DevOps +* 缺点 + * 运维复杂 + * 数据一致性问题 + * 集成测试复杂 + * **重复代码** + * 监控困难 +* 挑战 + * **运维要求较高** + * 分布式的复杂性 + * 接口调整成本高 + * 重复你劳动 + +#### 设计原则 +* 单一职责原则 +* 服务自治原则 +* 轻量级通信原则 +* 接口明确原则 + +## 附录 +* [Microservices](https://martinfowler.com/articles/microservices.html) +* 校验 • [CeaserWang](https://github.com/1156721874) + +[^1]: The term "microservice" was discussed at a workshop of software architects near Venice in May, 2011 to describe what the participants saw as a common architectural style that many of them had been recently exploring. In May 2012, the same group decided on "microservices" as the most appropriate name. James presented some of these ideas as a case study in March 2012 at 33rd Degree in Krakow in [Microservices - Java, the Unix Way](http://2012.33degree.org/talk/show/67) as did Fred George [about the same time](https://www.slideshare.net/fredgeorge/micro-service-architecure). Adrian Cockcroft at Netflix, describing this approach as "fine grained SOA" was pioneering the style at web scale as were many of the others mentioned in this article - Joe Walnes, Daniel Terhorst-North, Evan Botcher and Graham Tackley. +[^2]: The term monolith has been in use by the Unix community for some time. It appears in [The Art of Unix Programming](https://www.amazon.com/gp/product/B003U2T5BA?ie=UTF8&tag=martinfowlerc-20&linkCode=as2&camp=1789&creative=9325&creativeASIN=B003U2T5BA) to describe systems that get too big. +[^3]: Many object-oriented designers, including ourselves, use the term service object in the [Domain-Driven Design](https://www.amazon.com/gp/product/0321125215?ie=UTF8&tag=martinfowlerc-20&linkCode=as2&camp=1789&creative=9325&creativeASIN=0321125215) sense for an object that carries out a significant process that isn't tied to an entity. This is a different concept to how we're using "service" in this article. Sadly the term service has both meanings and we have to live with the polyseme. +[^4]: We consider [an application to be a social construction](https://martinfowler.com/bliki/ApplicationBoundary.html) that binds together a code base, group of functionality, and body of funding. +[^5]: The original paper can be found on Melvyn Conway's website [here](http://www.melconway.com/Home/Committees_Paper.html). +[^6]: We can't resist mentioning Jim Webber's statement that ESB stands for ["Egregious Spaghetti Box"](http://www.infoq.com/presentations/soa-without-esb). +[^7]: Netflix makes the link explicit - until recently referring to their architectural style as fine-grained SOA. +[^8]: At extremes of scale, organisations often move to binary protocols - [protobufs](https://code.google.com/p/protobuf/) for example. Systems using these still exhibit the characteristic of smart endpoints, dumb pipes - and trade off transparency for scale. Most web properties and certainly the vast majority of enterprises don't need to make this tradeoff - transparency can be a big win. +[^9]: "YAGNI" or "You Aren't Going To Need It" is an [XP principle](http://c2.com/cgi/wiki?YouArentGonnaNeedIt) and exhortation to not add features until you know you need them. +[^10]: It's a little disengenuous of us to claim that monoliths are single language - in order to build systems on todays web, you probably need to know JavaScript and XHTML, CSS, your server side language of choice, SQL and an ORM dialect. Hardly single language, but you know what we mean. +[^11]: Adrian Cockcroft specifically mentions "developer self-service" and "Developers run what they wrote"(sic) in [this excellent presentation](http://www.slideshare.net/adrianco/flowcon-added-to-for-cmg-keynote-talk-on-how-speed-wins-and-how-netflix-is-doing-continuous-delivery) delivered at Flowcon in November, 2013. +[^12]: We are being a little disengenuous here. Obviously deploying more services, in more complex topologies is more difficult than deploying a single monolith. Fortunately, patterns reduce this complexity - investment in tooling is still a must though. +[^13]: In fact, Daniel Terhorst-North refers to this style as Replaceable Component Architecture rather than microservices. Since this seems to talk to a subset of the characteristics we prefer the latter. +[^14]: Kent Beck highlights this as one his design principles in [Implementation Patterns](https://www.amazon.com/gp/product/0321413091?ie=UTF8&tag=martinfowlerc-20&linkCode=as2&camp=1789&creative=9325&creativeASIN=0321413091). +[^15]: And SOA is hardly the root of this history. I remember people saying "we've been doing this for years" when the SOA term appeared at the beginning of the century. One argument was that this style sees its roots as the way COBOL programs communicated via data files in the earliest days of enterprise computing. In another direction, one could argue that microservices are the same thing as the Erlang programming model, but applied to an enterprise application context. \ No newline at end of file diff --git a/source/_posts/movie-fierce.md b/source/_posts/movie-fierce.md new file mode 100644 index 000000000..ea1e488ce --- /dev/null +++ b/source/_posts/movie-fierce.md @@ -0,0 +1,22 @@ +--- +title: 《激战》 +date: 2018-10-03 00:02:00 +categories: Movie +tag: 激战 +--- + +{% cq %}怕,你就会输一辈子{% endcq %} + +喜欢其中的一些台词,大伙共勉 +* 其实,我每次上台都很怕的,不过每次我都会跟自己说,我能做到 +* 这场比赛我可能会跌倒,但我一定会站起来 +* 怕,你就会输一辈子 + +自己的一些感触: +其实很多时候,道理都懂,但却不能坚持下去,但这些道理都在自己生活中一点点的用生活感悟出来,那这些道理会更浓烈,更让人刻骨铭心 +* 尊重和珍惜,那些愿意为你去花时间的人 +* 要和自己志同道合,有共同目标的伙伴去互相较劲 +* 从哪里跌倒就要从哪里爬起来 +* 一路跌跌撞撞走下去,中间的酸甜苦辣是最美的味道 + + \ No newline at end of file diff --git a/source/_posts/network-http.md b/source/_posts/network-http.md new file mode 100644 index 000000000..9e3c46a50 --- /dev/null +++ b/source/_posts/network-http.md @@ -0,0 +1,179 @@ +--- +title: Http VS Https +date: 2018-06-22 01:14:25 +categories: Network +tag: [Http,Https] +--- +## 基础名称 +### 请求报文 +客户端发送一个HTTP请求到服务器的请求消息包括以下格式: +请求行(request line)、请求头(header)、请求内容组成,如下请求报文的一般格式。 +![请求报文](https://res.cloudinary.com/incoder/image/upload/v1562212437/blog/newwork-request.webp) + +#### 请求行 +1. 方法: + * GET: 获取资源 + * POST: 向服务器端发送数据,传输实体主体 + * PUT: 传输文件 + * HEAD: 获取报文首部 + * DELETE: 删除文件 + * OPTIONS: 询问支持的方法 + * TRACE: 追踪路径 +2. URL: + `scheme://host:port/path?query` + * scheme: 表示协议,如Http, Https, Ftp等 + * host: 表示所访问资源所在的主机名:如:www.baidu.com + * port: 表示端口号,Http默认为80,Https默认为443 + * path: 表示所访问的资源在目标主机上的储存路径 + * query: 表示查询条件 + +3. 协议/版本号: + +#### 请求头 +1. 通用首部(General Header) +2. 请求首部(Request Header) +3. 实体首部(Entity Header Fields) + +#### 请求内容 +如: 客户端POST的数据就放在这里(对比:GET的数据放在请求行的URL里) + +例如: +![请求示例](https://res.cloudinary.com/incoder/image/upload/v1529805798/blog/http-request.png) + +### 响应报文 +服务端响应一个HTTP请求消息包括以下格式: +响应行(response line)、响应头(header)、响应内容组成 + +#### 响应行 +1. 状态码: + * 1XX:Informational(信息性状态码) + * 2XX:Success(成功状态码) + * 3XX:Redirection(重定向) + * 4XX:Client Error(客户端错误状态码) + * 5XX:Server Error(服务器错误状态吗) +2. 状态码描述: +3. 协议/版本号: + +#### 响应头 +1. 通用首部(General Header) +2. 响应首部(Response Header) +3. 实体首部(Entity Header Fields) + +#### 响应内容 +如:服务器返回的HTML、JSON等数据 + +![响应示例](https://res.cloudinary.com/incoder/image/upload/v1529805798/blog/http-response.png) + +## Http +### 概念 +* [HTTP](https://zh.wikipedia.org/wiki/%E8%B6%85%E6%96%87%E6%9C%AC%E4%BC%A0%E8%BE%93%E5%8D%8F%E8%AE%AE):超文本传输协议(HyperText Transfer Protocol)是一种用于分布式、协作式和超媒体信息系统的应用层协议. +* HTTP是万维网的数据通信的基础. + +### 通信 +1. 建立TCP连接 +在HTTP工作开始之前,Client首先要通过网络与Service建立连接,该连接是通过TCP来完成的,HTTP是比TCP更高层次的应用层协议,根据规则,只有低层协议建立之后才能进行更高层协议的连接,因此,首先要建立TCP连接 +2. Client发起HTTP请求(Request) +Requset通常包含请求行,请求头,请求内容这三部风组成的请求报文 +3. Service发送HTTP响应(Response) +Response通常包含响应行,响应头,响应内容这三部风组成的响应报文 +4. Client关闭TCP连接 + +### 特点 +1. 无状态 + * 每个请求结束后都会被关闭,每次的请求都是独立的,它的执行情况和结果与前面的请求和之后的请求是无直接关系的,它不会受前面的请求应答情况直接影响,也不会直接影响后面的请求应答情况 + * 服务器中没有保存客户端的状态,客户端必须每次带上自己的状态去请求服务器 +2. 明文传输,可能被窃听 +3. 不验证通信方的身份,可能遭遇伪装 + * HTTP 协议中的请求和响应不会对通信方进行确认。也就是说存在“服务器是否就是发送请求中 URI 真正指定的主机,返回的响应是否真的返回到实际提出请求的客户端”等类似问题 + * HTTP 协议通信时,由于不存在确认通信方的处理步骤,任何人都可以发起请求 +4. 无法证明报文的完整性,可能遭遇篡改 + * 在请求或响应送出之后直到对方接收之前的这段时间内,即使请求或响应的内容遭到篡改,也没有办法获悉 + +## Https +### 概念 +* [HTTPS](https://zh.wikipedia.org/wiki/%E8%B6%85%E6%96%87%E6%9C%AC%E4%BC%A0%E8%BE%93%E5%AE%89%E5%85%A8%E5%8D%8F%E8%AE%AE):超文本传输安全协议(Hypertext Transfer Protocol Secure,常称为HTTP over TLS,HTTP over SSL或HTTP Secure)是一种通过计算机网络进行安全通信的传输协议. +* HTTPS经由HTTP进行通信,但利用`SSL/TLS`来加密数据包. + +> HTTP+加密+认证+完整性保护 = HTTPS + +![HTTP VS HTTPS](https://res.cloudinary.com/incoder/image/upload/v1529822573/blog/HTTPS.png) + +### 通信 +#### SSL/TLS +SSL/TLS:安全传输层协议(Transport Layer Security), 是介于TCP和HTTP之间的一层安全协议,TLS的前身是SSL(Secure Sockets Layer) + +>TLS/SSL关系 +* SSL2.0 +* SSL3.0 +* TLS1.0(SSL3.1) +* TLS1.1(SSL3.2) +* TLS1.2(SSL3.3) + +#### SSL/TLS工作原理 +HTTPS协议的主要功能都依赖于SSL/TLS协议,SSL/TLS的功能实现主要依赖于三类算法:`对称加密`,`非对称加密`,`散列函数Hash` +* 非对称加密实现身份认证和密钥协商, +* 对称加密算法采用协商的密钥对数据加密, +* 基于散列函数验证信息的完整性 + +#### SSL/TLS协议实现 +TLS以记录协议(record protocol)实现。记录协议负责在传输连接上交换所有的底层消息,并可以配置加密。每一条TLS记录以一个短标头起始。标头包含记录内容的类型(或子协议)、协议版本和长度 + +TLS的主规格说明书定义了四个核心子协议: + +* 握手协议(handshake protocol); +* 密钥规格变更协议(change cipher spec protocol); +* 应用数据协议(application data protocol); +* 警报协议(alert protocol); + +#### 握手协议 +握手是TLS协议中最精密复杂的部分。在这个过程中,通信双方协商连接参数,并且完成身份验证。根据使用的功能的不同,整个过程通常需要交换6~10条消息。根据配置和支持的协议扩展的不同,交换过程可能有许多变种,在使用中经常可以观察到以下三种流程: +* 单向验证(完整的握手,对服务器进行身份验证) +* 双向验证(对客户端和服务器都进行身份验证的握手) +* 简短握手(恢复之前的会话) + +##### 单向验证 +![单向验证](https://blog-10039692.file.myqcloud.com/1494841223417_6503_1494841223715.png) +1. Handshake:ClentHello +客户端通过发送 Client Hello 报文开始 SSL通信。报文中包含客户端支持的 SSL的指定版本、加密组件(Cipher Suite)列表(所使用的加密算法及密钥长度等)。 +2. Handshake:ServerHello +服务器可进行 SSL通信时,会以 ServerHello 报文作为应答。和客户端一样,在报文中包含 SSL版本以及加密组件。服务器的加密组件内容是从接收到的客户端加密组件内筛选出来的。 +3. Handshake:Certificate +之后服务器发送 Certificate 报文。报文中包含公开密钥证书。 +4. Handshake:ServerHelloDone +最后服务器发送 ServerHelloDone 报文通知客户端,最初阶段的 SSL握手协商部分结束。 +5. Handshake:ClientKeyExchange +SSL第一次握手结束之后,客户端以 ClientKeyExchange 报文作为回应。报文中包含通信加密中使用的一种被称为 Pre-mastersecret 的随机密码串。该报文已用3 中的公开密钥进行加密。 +6. ChangeCipherSpec +接着客户端继续发送 ChangeCipherSpec 报文。该报文会提示服务器,在此报文之后的通信会采用 Pre-master secret 密钥加密。 +7. Handshake:Finished +客户端发送 Finished 报文。该报文包含连接至今全部报文的整体校验值。这次握手协商是否能够成功,要以服务器是否能够正确解密该报文作为判定标准。 +8. ChangeCipherSpec +服务器同样发送 ChangeCipherSpec 报文。 +9. Handshake:Finished +服务器同样发送 Finished 报文。 +10. Application Data(HTTP) +服务器和客户端的 Finished 报文交换完毕之后,SSL连接就算建立完成。当然,通信会受到 SSL的保护。从此处开始进行应用层协议的通信,即发送 HTTP 请求。 +11. Application Data(HTTP) +应用层协议通信,即发送 HTTP 响应。 +12. Alert:warning,close notify +最后由客户端断开连接。断开连接时,发送 close_notify 报文(上图做了一些省略,实际到这一步还需要发送TCP FIN报文关闭TCP链接) + +##### 双向验证 +![双向验证](https://blog-10039692.file.myqcloud.com/1494841503771_6933_1494841504095.png) +同单向验证流程相比,双向验证多了如下两条消息:`CertificateRequest`与`CertificateVerify`,其余流程大致相同 +* CertificateRequest +CertificateRequest是TLS规定的一个可选功能,用于服务器认证客户端的身份。通过服务器要求客户端发送一个证书实现,服务器应该在ServerKeyExchange之后立即发送CertificateRequest消息 +* CertificateVerify +当需要做客户端认证时,客户端发送CertificateVerify消息,来证明自己确实拥有客户端证书的私钥。这条消息仅仅在客户端证书有签名能力的情况下发送 + +#### 应用数据协议(application data protocol) +应用数据协议携带着应用消息,只以TLS的角度考虑的话,这些就是数据缓冲区。记录层使用当前连接安全参数对这些消息进行打包、碎片整理和加密 + +#### 警报协议(alert protocol) +警报的目的是以简单的通知机制告知对端通信出现异常状况。它通常会携带close_notify异常,在连接关闭时使用,报告错误 + +## 附录 +* 《图解HTTP》 +* [HTTP | MDN](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Overview) +* [数字证书及CA的扫盲介绍](https://kb.cnblogs.com/page/194742) +* [HTTPS 原理浅析及其在 Android 中的使用](https://cloud.tencent.com/developer/article/1005073) \ No newline at end of file diff --git a/source/_posts/network-okhttp1.md b/source/_posts/network-okhttp1.md new file mode 100644 index 000000000..ea2e8f94e --- /dev/null +++ b/source/_posts/network-okhttp1.md @@ -0,0 +1,542 @@ +--- +title: Network(一) 之OkHttp 入门 +date: 2018-06-23 12:44:25 +categories: Network +tag: OkHttp +--- + +自从Android4.4的源码中可以看到`HttpURLConnection`已经替换成`OkHttp`开始( [JakeWharton曾在Twitter表示](https://twitter.com/JakeWharton/status/482563299511250944) ) ,`OkHttp`+`Retrofit`+`RxJava`的组合网络请求一直经久不衰,主流app的网络架构基本都是这样的组合模式,存在即合理,说明`OkHttp`+`Retrofit`+`RxJava`的方式确实给开发,用户体验等带来可观的优势,那么这个系列文章围绕Android的网络展开. + +OkHttp:An HTTP & HTTP/2 client for Android and Java applications + +>Android 历史网络库 +* `HttpClient` 是 Apache 提供的HTTP网络访问接口,从一开始的时候就被引入到了Android的API中; +* `HttpURLConnection` 是一种多用途, 轻量极的HTTP客户端, 提供的API比较简单, 可以容易地去使用和扩展. + +## OkHttp优势 +* 支持HTTP/2, HTTP/2通过使用多路复用技术在一个单独的TCP连接上支持并发, 通过在一个连接上一次性发送多个请求来发送或接收数据 +* 如果HTTP/2不可用, 连接池复用技术也可以极大减少延时 +* 支持GZIP, 可以压缩下载体积 +* 响应缓存可以直接避免重复请求 +* 会从很多常用的连接问题中自动恢复 +* 如果您的服务器配置了多个IP地址, 当第一个IP连接失败的时候, OkHttp会自动尝试下一个IP +* OkHttp还处理了代理服务器问题和SSL握手失败问题,等等... + +## 基本使用 +该系列版本说明 +* OkHttp版本统一:**3.10.0** +* JDK:**1.8+** + +Gradle包导入 +```groovy +// okhttp核心库 +implementation 'com.squareup.okhttp3:okhttp:3.10.0' +// okhttp网络请求拦截日志库 +implementation 'com.squareup.okhttp3:logging-interceptor:3.10.0' +``` +> 关于网络请求 +基本网络请求由请求(`请求行`,`请求头`,`请求内容`),响应(`响应行`,`响应头`,`响应内容`)两大部分组成,具体的内容请查看[Http VS Https](https://incoder.org/2018/06/22/network-http)这篇文章 + +### OkHttp请求 +已在[Http VS Https](https://incoder.org/2018/06/22/network-http/#%E8%AF%B7%E6%B1%82%E6%8A%A5%E6%96%87)文章中介绍了,HTTP请求相关内容 + +### OkHttp响应 +已在[Http VS Https](https://incoder.org/2018/06/22/network-http/#%E5%93%8D%E5%BA%94%E6%8A%A5%E6%96%87)文章中介绍了,HTTP响应相关内容 + +## 同步与异步 +网络请求执行方式为:同步与异步;`同步`和`异步`关注的是消息通信机制 (synchronous communication/ asynchronous communication) + +### 同步 +就是在发出一个 **调用** 时,在没有得到结果之前,该 **调用** 就不返回,但是一旦调用返回,就得到返回值了。 +换句话说,就是由 **调用者** 主动等待这个 **调用** 的结果。 +Okhttp同步(`execute()`):Invokes the request immediately, and blocks until the response can be processed or is in error. + +```java +String url = "https://api.github.com/users/BladeCode"; +OkHttpClient client = new OkHttpClient(); + +String run(String url) throws IOException { + Request request = new Request.Builder().url(url).build(); + // 执行同步操作 + Response response = client.newCall(request).execute(); + if (response.isSuccessful()) { + return response.body().string(); + } else { + throw new IOException("Unexpected code " + response); + } +} +``` + +### 异步 +**异步** 则与同步相反,**调用** 在发出之后,这个调用就直接返回了,所以没有返回结果。 +换句话说,当一个异步过程调用发出后,**调用者** 不会立刻得到结果。而是在 **调用** 发出后,**被调用者** 通过状态、通知来通知 **调用者**,或通过回调函数处理这个调用。 +Okhttp同步(`enqueue(Callback responseCallback)`):Schedules the request to be executed at some point in the future. + +```java +String url = "https://api.github.com/users/BladeCode"; +OkHttpClient client = new OkHttpClient(); + +Request request = new Request.Builder().url(url).build(); +// 返回response 对象 +Response response = client.newCall(request).enqueue(new Callback() { + + @Override + public void onFailure(Call call, IOException e) { + System.out.println(e.toString()); + } + + @Override + public void onResponse(Call call, Response response) throws IOException { + // 字符串形式表达响应 + System.out.println(response.body().string()); + // 或流的形式表达响应 + System.out.println(response.body().charStream()); + System.out.println(response.body().byteStream()); + } +}); +``` +>注意: +* 响应体太大(超过1MB), 应避免使用 string()方法, 因为它会将把整个文档加载到内存中. +* 对于超过1MB的响应body, 应使用流的方式来处理响应body. 这和我们处理xml文档的逻辑是一致的, 小文件可以载入内存树状解析, 大文件就必须流式解析 + +## OkHttp Get +```java +String url = "https://api.github.com/users/BladeCode"; +OkHttpClient client = new OkHttpClient(); + +String run(String url) throws IOException { + Request request = new Request.Builder().url(url).build(); + Response response = client.newCall(request).execute(); + + if (response.isSuccessful()) { + return response.body().string(); + } else { + throw new IOException("Unexpected code " + response); + } +} +``` + +## OkHttp Post +```java +public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8"); + +OkHttpClient client = new OkHttpClient(); + +String post(String url, String json) throws IOException { + RequestBody body = RequestBody.create(JSON, json); + Request request = new Request.Builder() + .url(url) + .post(body) + .build(); + + Response response = client.newCall(request).execute(); + + if (response.isSuccessful()) { + return response.body().string(); + } else { + throw new IOException("Unexpected code " + response); + } + +} +``` + +### Posting a String +```java +public static final MediaType MEDIA_TYPE_MARKDOWN = MediaType.parse("text/x-markdown; charset=utf-8"); + +private final OkHttpClient client = new OkHttpClient(); + +public void run() throws Exception { + String postBody = "" + + "Releases\n" + + "--------\n" + + "\n" + + " * _1.0_ May 6, 2013\n" + + " * _1.1_ June 15, 2013\n" + + " * _1.2_ August 11, 2013\n"; + + Request request = new Request.Builder() + .url("https://api.github.com/markdown/raw") + .post(RequestBody.create(MEDIA_TYPE_MARKDOWN, postBody)) + .build(); + + try(Response response = client.newCall(request).execute()){ + if (!response.isSuccessful()) throw new IOException("Unexpected code " + response); + + System.out.println(response.body().string()); + } +} +``` +> 注意:当提交数据大于1MB,请使用流的方式 + +### Post Streaming +```java +public static final MediaType MEDIA_TYPE_MARKDOWN = MediaType.parse("text/x-markdown; charset=utf-8"); + +private final OkHttpClient client = new OkHttpClient(); + +public void run() throws Exception { + RequestBody requestBody = new RequestBody() { + @Override + public MediaType contentType() { + return MEDIA_TYPE_MARKDOWN; + } + + @Override + public void writeTo(BufferedSink sink) throws IOException { + sink.writeUtf8("Numbers\n"); + sink.writeUtf8("-------\n"); + for (int i = 2; i <= 997; i++) { + sink.writeUtf8(String.format(" * %s = %s\n", i, factor(i))); + } + } + + private String factor(int n) { + for (int i = 2; i < n; i++) { + int x = n / i; + if (x * i == n) return factor(x) + " × " + i; + } + return Integer.toString(n); + } + }; + + Request request = new Request.Builder() + .url("https://api.github.com/markdown/raw") + .post(requestBody) + .build(); + + try(Response response = client.newCall(request).execute()){ + if (!response.isSuccessful()) throw new IOException("Unexpected code " + response); + + System.out.println(response.body().string()); + } +} +``` + +### Posting a File +```java +public static final MediaType MEDIA_TYPE_MARKDOWN = MediaType.parse("text/x-markdown; charset=utf-8"); + +private final OkHttpClient client = new OkHttpClient(); + +public void run() throws Exception { + File file = new File("README.md"); + + Request request = new Request.Builder() + .url("https://api.github.com/BladeCode/raw") + .post(RequestBody.create(MEDIA_TYPE_MARKDOWN, file)) + .build(); + + try(Response response = client.newCall(request).execute()){ + if (!response.isSuccessful()) throw new IOException("Unexpected code " + response); + + System.out.println(response.body().string()); + } +} +``` + +### Posting form parameters +使用`FormEncodingBuilder`来构建和HTML
标签相同效果的请求体。键值对将使用一种HTML兼容形式的URL编码来进行编码 + +```java +private final OkHttpClient client = new OkHttpClient(); + +public void run() throws Exception { + RequestBody formBody = new FormEncodingBuilder() + .add("search", "Jurassic Park") + .build(); + Request request = new Request.Builder() + .url("https://en.wikipedia.org/w/index.php") + .post(formBody) + .build(); + + try(Response response = client.newCall(request).execute()){ + if (!response.isSuccessful()) throw new IOException("Unexpected code " + response); + + System.out.println(response.body().string()); + } +} +``` + +### Posting a multipart request +`MultipartBuilder`可以构建复杂的请求体,与HTML文件上传形式兼容。多块请求体中每块请求都是一个请求体,可以定义自己的请求头。这些请求头可以用来描述这块请求,例如他的`Content-Disposition`。如果`Content-Length`和`Content-Type`可用的话,他们会被自动添加到请求头中。 + +```java +private static final String IMGUR_CLIENT_ID = "..."; +private static final MediaType MEDIA_TYPE_PNG = MediaType.parse("image/png"); + +private final OkHttpClient client = new OkHttpClient(); + +public void run() throws Exception { + // Use the imgur image upload API as documented at https://api.imgur.com/endpoints/image + RequestBody requestBody = new MultipartBuilder() + .type(MultipartBuilder.FORM) + .addPart( + Headers.of("Content-Disposition", "form-data; name=\"title\""), + RequestBody.create(null, "Square Logo")) + .addPart( + Headers.of("Content-Disposition", "form-data; name=\"image\""), + RequestBody.create(MEDIA_TYPE_PNG, new File("website/static/logo-square.png"))) + .build(); + + Request request = new Request.Builder() + .header("Authorization", "Client-ID " + IMGUR_CLIENT_ID) + .url("https://api.imgur.com/3/image") + .post(requestBody) + .build(); + + try(Response response = client.newCall(request).execute()){ + if (!response.isSuccessful()) throw new IOException("Unexpected code " + response); + + System.out.println(response.body().string()); + } +} +``` +## Header +通常,HTTP headers 的工作方式类似于 `Map`:每个字段都有一个值或没有,但是一些headers允许多个值 +* 例如:Guava's Multimap. +* 例如:提供多个vary headers的HTTP响应是合法且常见的。OkHttp的API试图使用两种情况都很舒适 + +在编写请求headers时 +* 使用 `header(name, value)`将 `name` 的唯一内容设置为 `value`。如果 `name` 存在现有值,则在添加新值之前将删除它。 +* 使用 `addHeader(name, value)` 添加 `headers` 不会删除已存在的 `header` + +在读取headers响应时,使用 `header(name)` 返回最后异常出现的命名值。通常这也是唯一发生,如果没有值,则 `header(name)` 返回null。将所有字段的值作为列表读取,请使用 `headers(name)` + +```java +private final OkHttpClient client = new OkHttpClient(); + +public void run() throws Exception { + Request request = new Request.Builder() + .url("https://api.github.com/repos/square/okhttp/issues") + .header("User-Agent", "OkHttp Headers.java") + .addHeader("Accept", "application/json; q=0.5") + .addHeader("Accept", "application/vnd.github.v3+json") + .build(); + + try (Response response = client.newCall(request).execute()) { + if (!response.isSuccessful()) throw new IOException("Unexpected code " + response); + + System.out.println("Server: " + response.header("Server")); + System.out.println("Date: " + response.header("Date")); + System.out.println("Vary: " + response.headers("Vary")); + } +} +``` + +### Response Caching +实现缓存响应,你需要一个可以读写的缓存目录,以及缓存大小的限制。缓存目录应该是私有的,不受信任的应用程序不应该读取其内容 + +让多个缓存同时访问同一缓存目录是错误的。大多数应用程序应该只调用一次 `new OkHttpClient()`,使用它们的缓存配置它,并在任何地方使用相同的实例。否则,两个缓存实例将互相踩踏,破坏响应缓存,并可能导致程序奔溃 + +响应缓存使用HTTP headers进行所有的配置。你可以添加headers,如:`Cache-Control: max-stale=3600`,OkHttp的缓存将遵循它。你的Web服务器使用自己的响应headers配置缓存响应的时间,例如:`Cache-Control: max-age=9600`。有缓存headers可强制缓存响应,强制网络响应,或者强制使用条件GET验证网络响应 + +```java +private final OkHttpClient client; + +public CacheResponse(File cacheDirectory) throws Exception { + // 设置缓存大小 10 MiB + int cacheSize = 10 * 1024 * 1024; + // 实例化Cache对象 + Cache cache = new Cache(cacheDirectory, cacheSize); + + client = new OkHttpClient.Builder() + .cache(cache) + .build(); +} + +public void run() throws Exception { + Request request = new Request.Builder() + .url("http://publicobject.com/helloworld.txt") + .build(); + + String response1Body; + try (Response response1 = client.newCall(request).execute()) { + if (!response1.isSuccessful()) throw new IOException("Unexpected code " + response1); + + response1Body = response1.body().string(); + System.out.println("Response 1 response: " + response1); + System.out.println("Response 1 cache response: " + response1.cacheResponse()); + System.out.println("Response 1 network response: " + response1.networkResponse()); + } + + String response2Body; + try (Response response2 = client.newCall(request).execute()) { + if (!response2.isSuccessful()) throw new IOException("Unexpected code " + response2); + + response2Body = response2.body().string(); + System.out.println("Response 2 response: " + response2); + System.out.println("Response 2 cache response: " + response2.cacheResponse()); + System.out.println("Response 2 network response: " + response2.networkResponse()); + } + + System.out.println("Response 2 equals Response 1? " + response1Body.equals(response2Body)); +} +``` +* 要阻止响应使用缓存,请使用 `CacheControl.FORCE_NETWORK` +* 要阻止它使用网络,请使用 `CacheControl.FORCE_CACHE` + +>警告:如果你使用 `FORCE_CACHE` 且响应需要网络,OkHttp将返回504不满意请求响应 + +### Canceling a Call +使用 `Call.cancel()` 立即停止正在进行的请求,如果线程当前正在请求或读取响应,则它将收到 `IOException`。当不在需要call时,使用它来保护网络,例如,当你的用户导航离开应用程序时,同步和异步调用都可以取消 + +```java +private final ScheduledExecutorService executor = Executors.newScheduledThreadPool(1); +private final OkHttpClient client = new OkHttpClient(); + +public void run() throws Exception { + Request request = new Request.Builder() + .url("http://httpbin.org/delay/2") // This URL is served with a 2 second delay. + .build(); + + final long startNanos = System.nanoTime(); + final Call call = client.newCall(request); + + // Schedule a job to cancel the call in 1 second. + executor.schedule(new Runnable() { + @Override public void run() { + System.out.printf("%.2f Canceling call.%n", (System.nanoTime() - startNanos) / 1e9f); + call.cancel(); + System.out.printf("%.2f Canceled call.%n", (System.nanoTime() - startNanos) / 1e9f); + } + }, 1, TimeUnit.SECONDS); + + System.out.printf("%.2f Executing call.%n", (System.nanoTime() - startNanos) / 1e9f); + try (Response response = call.execute()) { + System.out.printf("%.2f Call was expected to fail, but completed: %s%n", + (System.nanoTime() - startNanos) / 1e9f, response); + } catch (IOException e) { + System.out.printf("%.2f Call failed as expected: %s%n", + (System.nanoTime() - startNanos) / 1e9f, e); + } +} +``` + +### Timeouts +当无法访问时,使用超时来使call失败。网络分区可能是由于客户端连接问题,服务器可读性问题或其他任何问题时。OkHttp支持连接,读取和写入超时配置 + +```java +private final OkHttpClient client; + +public ConfigureTimeouts() throws Exception { + client = new OkHttpClient.Builder() + .connectTimeout(10, TimeUnit.SECONDS) + .writeTimeout(10, TimeUnit.SECONDS) + .readTimeout(30, TimeUnit.SECONDS) + .build(); +} + +public void run() throws Exception { + Request request = new Request.Builder() + .url("http://httpbin.org/delay/2") // This URL is served with a 2 second delay. + .build(); + + try (Response response = client.newCall(request).execute()) { + System.out.println("Response completed: " + response); + } +} +``` + +### Per-call Configuration +所有的HTTP 客户端配置都在 `OkHttpClient` 中,包括代理设置,超时和缓存。当你需要修改单个调用时的配置时,请调用 `OkHttpClient.newBuilder()`。这将返回与原始客户端共享相同连接池,调度程序和配置的构建器(`Builder`) + +```java +// 示例:我们发出一个请求,其中500毫秒超时,另一个请求超时3000毫秒 +private final OkHttpClient client = new OkHttpClient(); + +public void run() throws Exception { + Request request = new Request.Builder() + // This URL is served with a 1 second delay. + .url("http://httpbin.org/delay/1") + .build(); + + // Copy to customize OkHttp for this request. + OkHttpClient client1 = client.newBuilder() + .readTimeout(500, TimeUnit.MILLISECONDS) + .build(); + try (Response response = client1.newCall(request).execute()) { + System.out.println("Response 1 succeeded: " + response); + } catch (IOException e) { + System.out.println("Response 1 failed: " + e); + } + + // Copy to customize OkHttp for this request. + OkHttpClient client2 = client.newBuilder() + .readTimeout(3000, TimeUnit.MILLISECONDS) + .build(); + try (Response response = client2.newCall(request).execute()) { + System.out.println("Response 2 succeeded: " + response); + } catch (IOException e) { + System.out.println("Response 2 failed: " + e); + } +} +``` + +### Handling authentication +OkHttp可以自动重试未经身份验证的请求。如果响应为401 Not Authorized,则要求Authenticator提供凭证。实现应该构建一个包含缺少凭证的新请求。如果没有可用的凭证,则返回null以跳过重试。 + +使用 `Response.challenges()`来获取任何身份验证挑战的方案和领域。在完成基本挑战时,使用 `Credentials.basic(username, password)` 对请求header进行编码 + +```java +private final OkHttpClient client; + +public Authenticate() { + client = new OkHttpClient.Builder() + .authenticator(new Authenticator() { + @Override public Request authenticate(Route route, Response response) throws IOException { + if (response.request().header("Authorization") != null) { + return null; // Give up, we've already attempted to authenticate. + } + + System.out.println("Authenticating for response: " + response); + System.out.println("Challenges: " + response.challenges()); + String credential = Credentials.basic("jesse", "password1"); + return response.request().newBuilder() + .header("Authorization", credential) + .build(); + } + }) + .build(); +} + +public void run() throws Exception { + Request request = new Request.Builder() + .url("http://publicobject.com/secrets/hellosecret.txt") + .build(); + + try (Response response = client.newCall(request).execute()) { + if (!response.isSuccessful()) throw new IOException("Unexpected code " + response); + + System.out.println(response.body().string()); + } +} +``` + +为避免在身份验证不起作用时进行多次重试,你可以在返回null以放弃,例如,你可能希望在尝试这些确切凭证时跳过重试 +```java +if (credential.equals(response.request().header("Authorization"))) { + return null; // If we already failed with these credentials, don't retry. +} +``` + +当你达到应用程序定义的尝试限制时,你也可以跳过重试 +```java +private int responseCount(Response response) { + int result = 1; + while ((response = response.priorResponse()) != null) { + result++; + } + return result; +} + +if (responseCount(response) >= 3) { + // If we've failed 3 times, give up. + return null; +} +``` + +## 附录 +* [OkHttp Wiki](https://github.com/square/okhttp/wiki) +* [怎样理解阻塞非阻塞与同步异步的区别](https://www.zhihu.com/question/19732473) +* [OkHttp使用教程](http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0106/2275.html) \ No newline at end of file diff --git a/source/_posts/ooad-uml.md b/source/_posts/ooad-uml.md new file mode 100644 index 000000000..fbe286804 --- /dev/null +++ b/source/_posts/ooad-uml.md @@ -0,0 +1,204 @@ +--- +title: OOAD 与 UML +date: 2019-05-27 22:00:10 +categories: DevTool +tag: [OOAD, UML] +--- + +OOAD(Object Oriented Analysis and Desigin) 是根据 OO 的方法学,对软件系统进行分析和设计的过程 +* OOA(Object Oriented Analysis):分析阶段 +* OOD(Object Oriented Desigin):设计阶段 + +## What to do +分析阶段主要解决以下问题 +* 建立针对业务问题域的清晰视图 +* 列出系统必须要完成的核心任务 +* 针对问题域建立公共词汇表 +* 列出针对此问题域的最佳解决方案 + +## How to do +设计阶段主要解决以下问题(How to do?) +* 如何解决具体的业务问题 +* 引入系统工作所需的支持元素 +* 定义系统的实现策略 + +## OOP的主要特征 + +### 抽象(abstract) +* 忽略到一个对象或实体的细节而只关注其本质特征的过程 +* 简化功能与格式 +* 帮助用户与对象交互 + +### 封装(encapsulation) +* 隐藏数据和实现 +* 提供公共方法供用户调用功能 +* 对象的两种视图 + * 外部视图:对象能做的工作 + * 内部视图:对象如何完成工作 + +### 继承(inheritance) +* 通过存在的类型定义新类型的机制 +* 通常在两个类型之间存在“is a” 或 “kind of” 这样的关系 +* 通过继承可实现代码重用,另外继承也是多态的基础 +* 如苹果 “is a” 水果 + +### 多态(polymorphism) +* 一个名称,多种形式 +* 基于继承的多态 +* 调用方法时根据所给对象的不同选择不同的处理方式 +* 如 Football——play() +* 给出一个具体的足球或篮球,用户自动知道该使用谁的方式去执行 + +### 关联(association) +* 对象之间交互时的一种引用方式 +* 当一个对象通过对另一个对象的引用去使用另一个对象的服务或操作时,两个对象之间便产生了关联 +* 如 person 使用 computer,person 与 computer 之间就存在了关联关系 + +### 聚合(aggregation) +* 关联关系的一种,一个对象成为另一个对象的组成部分 +* 使用关系强的关联 +* 在两个对象之间存在 “has a”这样的关系,一个对象作为另一个对象的属性存在,在外部对象被产生时,可由客户端指定与其关联的内部对象 + +> 如汽车与轮胎,轮胎作为汽车的一个组成部分,它和汽车可由分别产生以后转配起来使用,但汽车可由换新轮胎,轮胎也可以卸下来给其他汽车使用 + +### 组合(composition) +* 当一个对象包含另一个对象时,外部对象负责管理内部对象的生命周期的情况 +* 关联关系中最为强烈的一种 +* 内部对象的创建由外部对象自己控制 +* 外部对象不存在时,内部对象也不能存在 + +> 如电视机与显示器 + +### 内聚与耦合(cohesion & coupling) +* 域模型是面向对象的。在面向对象术语中域模型也可称为设计模型。 +* 域模型由以下内容组成 + * 关联(Association):一对多,多对一,一对一 + * 依赖(Dependency) + * 聚集(Aggregation):整体和部分之间的关系 + * 一般化(泛化)(Generalization):类与类之间的**继承** +* 内聚:度量一个类独立完成某项工作的能力 +* 耦合:度量系统内或系统之间依赖关系的复杂度 +* 设计原则:增加内聚,减少耦合 + +## 开发过程概述 + +### 传统开发过程 +* 瀑布模型(真实环境,不可能满足这些) + +### 统一软件开发过程(USDP) +特点: 项目是迭代,递增 +* 迭代指生命周期中的一个步骤 +* 迭代导致“递增”或者是整个项目的增长 +* 大项目分解为子项目 +* 在每一个迭代的阶段,应该做以下工作 + * 选择并分析相关用例 + * 更加所选架构进行设计 + * 在组件层次实现设计 + * 验证组件满足用例的需要 +* 当一次迭代满足目标后,开发进入下一个迭代周期 +* 每一个周期包含一次或多次迭代 +* 一个阶段的结束称之为“里程碑” + +### 阶段 + +#### 初始化阶段 +该阶段的增量集中于: +* 项目启动 +* 建立业务模型 +* 定义业务问题域 +* 找出主要的风险因素 +* 定义项目需求的外延 +* 创建业务问题域的相关说明文档 + +#### 细化阶段 +本阶段的增量集中于 +* 高层的分析与设计 +* 建立项目的基础框架 +* 监督主要的风险因素 +* 制订达成项目目标的创建计划 + +#### 构建阶段 + 本阶段的增量集中于 + * 代码及功能的实现 + +#### 移交阶段 +本阶段的增量集中于: +* 向用户发布产品 +* beta 测试 +* 执行性能调优,用户培训和接收测试 + +#### 阶段特点 +每一个阶段所包含的工作流,每一次递增都由 5 个部分工作流组成 +* 需求与初始化分析 +* 分析 +* 设计 +* 实现 +* 测试 +* 每一次迭代执行工作流的深度不同 +* 早期的迭代在深度上覆盖初始工作流,后期迭代在深度上覆盖后期工作流 +* 80/20原则 + +## UML +UML(Unified Modeling Language)统一建模语言,图形化语言表示,它可以帮助我们在 OOAD 过程中标识元素,构建模块,分析过程并可通过文档说明系统中的重要细节 + +### 静态模型(static model) +* 创建并记录一个系统的静态特征 +* 反映一个软件系统基础,固定的框架结构 +* 创建相关问题域主要元素的视图 +* 静态建模包括: + * **用例图(use case diagrams)** + * **类图(class diagrams)** + * 对象图(object diagrams) + * 组件图(component diagrams) + * 部署图(deployment diagrams) + +### 动态模型(dynamic model) +* 用以展示系统的行为 +* 动态建模包括: + * **时序图(sequence diagrams)** + * 协作图(collaboration diagrams) + * 状态图(state chart diagrams) + * 活动图(activity diagrams) + +### UML 其他重要元素 +* 包(package) +* UML 的扩展机制 + * 注释(comments) + * 构造型(stereotypes) + * 标记值(tagged values) + * 限制(constraints) + +### 示例 + +#### 用例图 +* 展示系统的核心功能及逾期交互的用户 +* 用户被称为“活动者”(Actor) +* 用例使用椭圆表示 +* 为简化建模过程,用例图可以标注优先级 +![uml-usecase-diagram](https://res.cloudinary.com/incoder/image/upload/v1559486362/blog/uml-usecase-diagram.png) + +#### 类图 +* 表现类的特征 +* 类图描述了多个类,接口的特征,以及对象之间的协作与交互 +* 由一个或者多个矩形区域构成,内容包括 + * 类型(类名) + * 属性(可选) + * 操作(可选) +![uml-class-diagram](https://res.cloudinary.com/incoder/image/upload/v1559486361/blog/uml-class-diagram.png) + +#### 对象图 +* 表现对象的特征 +* 对象图展现了多个对象的特征及对象之间的交互 +![uml-object-diagram](https://res.cloudinary.com/incoder/image/upload/v1559486360/blog/uml-object-diagram.png) + +#### 组件图 +* 表示软件组件之间的关系 +![uml-component-diagram](https://res.cloudinary.com/incoder/image/upload/v1559486358/blog/uml-component-diagram.png) + +#### 部署图 +* 表现用于部署软件应用的物理设备信息 +![uml-deployment-diagram](https://res.cloudinary.com/incoder/image/upload/v1559486362/blog/uml-deployment-diagram.png) + +#### 时序图 +* 捕捉一段时间范围内多个对象之间的交互信息 +* 强调消息交互的时间顺序 diff --git a/source/_posts/rap1.md b/source/_posts/rap1.md new file mode 100644 index 000000000..bb27ab1bd --- /dev/null +++ b/source/_posts/rap1.md @@ -0,0 +1,76 @@ +--- +title: Api 文档管理系统 RAP1环境搭建 +date: 2018-03-27 10:19:25 +categories: Api +tag: RAP +--- + +前后端分离的路上,一款强大的API管理工具,可以降低沟通成本,大大提高开发效率,节省的时间,让我们去做更有意义的事情。 + +API管理工具有很多,选择适合自身需求的就是最好 + +这里以[阿里妈妈](https://thx.github.io)出品的[RAP](https://thx.github.io/RAP)产品;目前RAP分为: ~~[RAP1](https://github.com/thx/RAP)~~,[RAP2](https://github.com/thx/rap2-delos) + +>虽然RAP1不再添加新功能,只做维护工作,介于RAP2目前还不是很成熟,本篇文章先讲RAP1的搭建过程(虽然官方[Wiki](https://github.com/thx/RAP/wiki)已经有很详细的部署教程,但在部署过程中还是遇到一些问题,因此就记录下来) + +如果你不需要搭建,可以直接访问RAP1提供的服务[http://rapapi.org](http://rapapi.org) + +## 项目构建 + +* 系统环境:Windows 10 x64 +* 应用工具:[Git](https://git-scm.com/downloads),[IDEA](https://www.jetbrains.com/idea/download),[JDK1.8+](https://www.java.com/zh_CN/download/manual.jsp),[Tomcat8+](https://tomcat.apache.org/download-80.cgi),[MySQL](https://www.mysql.com/cn/downloads),[Redis3+](https://redis.io/download) + +这里Git,IDEA,JDK1.8,Tomcat8,MySQL不再赘述安装步骤以及环境配置 + +### 安装基本工具 +#### Redis +由于Redis 官方并未支持Windows系统,因此借助MicrosoftArchive团队所提供的[Windows Redis安装包](https://github.com/MicrosoftArchive/redis/releases),这里下载最新的`Redis-x64-3.2.100.msi` + +* 以管理员身份运行安装包`Redis-x64-3.2.100.msi` + 1. 添加环境变量 + ![env](https://res.cloudinary.com/incoder/image/upload/v1525517089/blog/gitpages-redis-env-var.png) + 2. 默认`6379`端口 + ![port](https://res.cloudinary.com/incoder/image/upload/v1525517270/blog/gitpages-redis-port.png) + 3. 检查Redis服务,是否已经启动 + ![serve](https://res.cloudinary.com/incoder/image/upload/v1525517284/blog/gitpages-redis-serve.png) + + >其他默认即可,不要设置Memory Limit + +## 构建项目 +### 获取源代码 +```sh +git clone git@github.com:thx/RAP.git +git checkout release +``` + +>确保您正确的切换到release分支,否则会出现少包,因为master分支引用一些不对外公开的内部组件,不提供给外部用户使用 +### 导入到IDEA +IDEA==>Open==>RAP + +### 初始化数据库 +执行脚本文件:RAP\src\main\resources\database\\`initialize.sql` + +### 修改配置文件 +文件:RAP\src\main\resources\database\\`config.properties` +修改:数据库`用户名`及`密码` +![update](https://res.cloudinary.com/incoder/image/upload/v1525517302/blog/gitpages-rap1-update-database-config.png) +## 启动项目 +1. Edit config +![config](https://res.cloudinary.com/incoder/image/upload/v1525517326/blog/gitpages-rap1-tomcat-config.png) +2. Create Tomcat +![create](https://res.cloudinary.com/incoder/image/upload/v1525517350/blog/gitpages-rap1-tomcat-create.png) +3. Deploy war +![deploy](https://res.cloudinary.com/incoder/image/upload/v1525517364/blog/gitpages-rap1-tomcat-deploy.png) +4. Deploy success +![success](https://res.cloudinary.com/incoder/image/upload/v1525517384/blog/gitpages-rap1-deploy-success.png) + +注意成功部署后,请`注册`新账号登录 + +至此,RAP1的本机部署已经完成。 + +## 其他 +* [RAP1学习中心](http://thx.github.io/RAP/study.html) + 部分同学无法查看视频,请异步至[issues](https://github.com/thx/RAP/issues/935) +* [RAP1 Wiki](https://github.com/thx/RAP/wiki)文档 +* [Mockjs](http://mockjs.com) +* [RAP2环境搭建教程](https://www.incoder.org/2018/03/27/rap2) \ No newline at end of file diff --git a/source/_posts/rap2.md b/source/_posts/rap2.md new file mode 100644 index 000000000..f5e9aea1f --- /dev/null +++ b/source/_posts/rap2.md @@ -0,0 +1,238 @@ +--- +title: Api 文档管理系统 RAP2环境搭建 +date: 2018-03-27 10:20:10 +update: 2018-08-01 22:10:11 +categories: Api +tag: RAP +--- + +RAP2是采用前后端分离的形式,因此搭建完整的RAP2需要 **服务端:**[rap2-delos](https://github.com/thx/rap2-delos),**客户端:**[rap2-dolores](https://github.com/thx/rap2-dolores) 同时部署 + +部署RAP2需要亲具有Node+Linux+MySQL的运维知识,如果亲对此不是很了解,建议用[http://rap2.taobao.org](http://rap2.taobao.org) 线上版本就可以 + +由于 **客户端:**[rap2-dolores](https://github.com/thx/rap2-dolores) 是建立在 **服务端:**[rap2-delos](https://github.com/thx/rap2-delos) 基础上,因此先搭建服务端应用 + +> * 截至到2018-08-01 delos 并没有发布Tag版本,应该还处于功能开发前期阶段吧。本教程是在CentOS机器上实战部署 +> * 然而安装部署并不是顺利,因此记录踩过的坑(别问我为啥不用Docker,因为我司分配的机器无法满足Docker的最低内核版本),安装环境介绍:Redis,delos,dolores均在一台服务器,MySQL使用已存在的服务 + +## 安装基本工具 +* [Git](https://git-scm.com/downloads) +* [Node 8.9.4+](https://nodejs.org/zh-cn/download) +* [Redis 4.0+](https://redis.io/download) +* [MySQL 5.7+](https://www.mysql.com/cn/downloads) + +以上基本工具请根据自身需要,下载对应系统安装包,请自行解决安装配置等问题,这里不做过多说明 + +> Redis 安装可参考[Linux 常用应用安装](https://incoder.org/2018/05/15/linux-build); +Redis 最好用**非安全**模式启动 + +## 服务端delos环境搭建 + +### 构建项目 + +> 构建项目前,请确认Node,Redis,MySQL服务均能正常使用 + +``` sh +git clone https://github.com/thx/rap2-delos.git +``` + +### 环境配置 + +#### 创建数据库 + +* Mac or Linux + ```sql + mysql -e 'CREATE DATABASE IF NOT EXISTS RAP2_DELOS_APP DEFAULT CHARSET utf8 COLLATE utf8_general_ci'; + ``` +* Windows 环境 + + 进入mysql命令后执行 + ```sql + CREATE DATABASE IF NOT EXISTS RAP2_DELOS_APP DEFAULT CHARSET utf8 COLLATE utf8_general_ci; + ``` +#### 配置文件 + +目录:rap2-delos/src/config +文件:`config.dev.ts`;其中dev,表示开发环境,其他同理 +修改:`config.dev.ts`文件中`db`对象中`username`,`password`参数与**本地**或者**开发环境**的数据库信息匹配 + +### 启动项目 + +#### 安装项目依赖包 + +项目根目录下执行 + +```sh +# 安装项目所需依赖 +npm install +# 全局安装PM2 +npm install -g pm2 +``` + +#### 安装TypeScript编译包 + +```sh +npm install typescript -g +``` + +> 如果下载缓慢,请使用[淘宝npm镜像](https://npm.taobao.org) + +#### 初始化数据库 + +项目根目录下执行(该过程比较慢,耐心等待初始化完成) + +```npm +npm run create-db +``` + +#### 编译启动项目 +执行mocha测试用例和js代码规范检查 +```sh +npm run check +``` + +* 开发模式 +启动开发模式的服务器 监视并在发生代码变更时自动重启(第一次运行比较慢,请耐心等待) + ```sh + npm run dev + ``` +* 生产模式 + 启动生产模式服务器 + ```sh + npm start + ``` + +看到浏览器中如下提示,表示**服务端delos**已经部署成功 +>RAP2后端服务已启动,请从前端服务(rap2-dolores)访问。 RAP2 back-end server is started, please visit via front-end service (rap2-dolores). + +或者在程序控制台出现如下Log,表示**服务端delos**已经部署成功 +![delos](https://res.cloudinary.com/incoder/image/upload/v1525517437/blog/gitpages-rap2-delos-success.png) + +### 常见问题 + +#### 部署问题 +1. Windows下执行`npm run build`,提示`'rm' 不是内部或外部命令,也不是可运行的程序或批处理文件` + + 原因:`rm` 是Linux下命令, + 解决方法:Windows系统可使用 `git bash` 打开该项目,执行该命令 + +2. 执行`npm run create-db`命令,提示`Unable to connect to the database:{ SequelizeAccessDeniedError: Access denied for user 'root'@'localhost' (using password:NO)}` + + 原因:未修改`rap2-delos/src/config`目录下数据库配置文件,或者是与文件中的数据库信息与之连接的数据库信息不匹配 + 解决方法:修改`config.dev.ts`文件数据库配置信息 + >如果修改正确无误后,执行`npm run create-db`依旧出错,那么查看该项目中是否已经存在`dist`目录,如果有,请按照如上修改对应的数据库配置信息 +3. 执行`npm run dev`命令,提示`Error: listen EADDRINUSE :::8080` + 原因:8080端口被占用 + 解决方法:杀掉占用8080端口的应用 +4. 执行`npm install` 命令,提示`hiredis` 编译无法通过 + 原因:无权限操作`rap2-delos/node_modules/hiredis`路径 + 解决方法:`sudo npm install` + > 如果提示`sudo: npm: command not found`,请参考[stackoverflow-npm](https://stackoverflow.com/questions/31472755/sudo-npm-command-not-found),[stackoverflow-node](https://stackoverflow.com/questions/4976658/on-ec2-sudo-node-command-not-found-but-node-without-sudo-is-ok) +5. 执行`npm run dev`可以正常启动,`npm start`命令无法正常启动服务 + 原因:请使用`pm2 logs`查看日志具体定位 + 示例:由于Redis的安全模式,不能正常使用 + ```bash + ReplyError: Ready check failed: DENIED Redis is running in protected mode because protected mode is enabled, no bind address was specified, no authentication password is requested to clients. In this mode connections are only accepted from the loopback interface. If you want to connect from external computers to Redis you may adopt one of the following solutions: + + 1) Just disable protected mode sending the command 'CONFIG SET protected-mode no' from the loopback interface by connecting to Redis from the same host the server is running, however MAKE SURE Redis is not publicly accessible from internet if you do so. Use CONFIG REWRITE to make this change permanent. + 2) Alternatively you can just disable the protected mode by editing the Redis configuration file, and setting the protected mode option to 'no', and then restarting the server. + 3) If you started the server manually just for testing, restart it with the '--protected-mode no' option. + 4) Setup a bind address or an authentication password. + NOTE: You only need to do one of the above things in order for the server to start accepting connections from the outside. + ``` + 解决方法: 使用`--protected-mode no`方式启动 + +## 客户端dolores环境搭建 + +### 构建项目 +#### 获取源代码 +``` sh +git clone https://github.com/thx/rap2-dolores.git +``` + +### 环境配置 + +#### 配置文件 + +目录:rap2-dolores/src/config +文件:`config.dev.ts`;其中dev,表示开发环境,其他同理 +修改:`config.dev.ts`文件,`serve`地址是 **服务端** `rap2-delos` 部署成功后的地址,默认:`'http://localhost:8080'` + +### 启动项目 + +#### 安装项目依赖包 + +项目根目录下执行 + +```sh +npm install +``` + +> 如果下载缓慢,请使用[淘宝npm镜像](https://npm.taobao.org) + +#### 编译启动项目 + +* 开发模式 +自动监视改变后重新编译 + ```sh + npm run dev + ``` + 备注:测试用例 + ```sh + npm run test + ``` +* 生产模式 +编译React生产包 + ```sh + npm run build + ``` + 用serve命令或nginx服务器路由到编译产出的build文件夹作为静态服务器即可 + ```sh + serve -s ./build -p 80 + ``` + +看到浏览器中出现登录页面,表示部署成功 +![dolores](https://res.cloudinary.com/incoder/image/upload/v1525517454/blog/gitpages-rap2-dolores-success.png) + +### 常见问题 + +#### 部署问题 +1. 执行`npm run dev`,提示 + ```sh + return process.dlopen(module,path._makeLong(filename)) + ... + ...node_modules\node-sass\vendor\win32-x64-57\binding.node is not a valid Win32 application... + ``` + + 原因:项目依赖包`node-sass`没有安装完全 + 解决方法:`npm install node-sass` + +2. 项目运行起来,但一直停留在加载动画那里 + + 浏览器控制台输出: + `GET http://127.0.0.1:8080/account/info ==>> + Failed to load http://127.0.0.1:8080/account/info` + + 原因:未修改`rap2-delos/src/config`目录下服务端连接地址,或者修改结果与[rap2-dolores](https://github.com/thx/rap2-dolores)实际提供服务地址不匹配 + 解决方法:修改`config.dev.ts`文件serve配置信息 + >如果Windows系统修改正确无误后,依旧出错,那么查看hosts(路径:C:\Windows\System32\drivers\etc)中127.0.0.1的IP前是否有`#`,如果有请取消注释 + +## 其他 +### MySQL 运行问题 +* 错误一 +![mysql](https://res.cloudinary.com/incoder/image/upload/v1525517475/blog/gitpages-rap2-mysql.png) +原因:MySQL 集成命令没有加入系统的环境变量 +解决方法:将安装的MySQL Service路径加入系统变量 +![path](https://res.cloudinary.com/incoder/image/upload/v1525517495/blog/gitpages-rap2-mysql-path.png) +* 错误二 +![create](https://res.cloudinary.com/incoder/image/upload/v1525517523/blog/gitpages-rap2-mysql-create.png) +原因:没有数据库链接权限 +解决方法:先登录用root数据库,密码具体看自己数据库当时设置的密码 + +### 如何获取更新 +目前请选择`master`分支源码,后续其他分支请看相应分支说明文档。在开发环境中git pull来获取最新的源码更新,每一期更新都会有对应的update.md请关注并按照上面的指示进行升级工作。 + +## 附录 +* [Redis如何后台启动](https://blog.csdn.net/ksdb0468473/article/details/52126009) +* [Redis配置文件介绍](http://www.cnblogs.com/ysocean/p/9074787.html) +* [PM2实用入门指南](https://www.cnblogs.com/chyingp/p/pm2-documentation.html) \ No newline at end of file diff --git a/source/_posts/realm.md b/source/_posts/realm.md new file mode 100644 index 000000000..865f6fa39 --- /dev/null +++ b/source/_posts/realm.md @@ -0,0 +1,193 @@ +--- +title: Realm 数据库快速上手 +date: 2018-04-24 01:11:10 +categories: DataBase +tag: Realm +--- + +![realm-db](https://res.cloudinary.com/incoder/image/upload/v1525517554/blog/gitpages-realm-mobile-db.png) +Android 供了多种选项来保存永久性应用数据。 +* [Shared preferences](https://developer.android.google.cn/guide/topics/data/data-storage.html?hl=zh-cn#pref) +* [Internal file storage](https://developer.android.google.cn/guide/topics/data/data-storage.html?hl=zh-cn#filesInternal) +* [External file storage](https://developer.android.google.cn/guide/topics/data/data-storage.html?hl=zh-cn#filesExternal) +* [Databases](https://developer.android.google.cn/guide/topics/data/data-storage.html?hl=zh-cn#db) +* [Network](https://developer.android.google.cn/guide/topics/data/data-storage.html?hl=zh-cn#netw) + +其中数据库存储是一种必备技能,而衍生的mobile db也是层出不穷,本节主要介绍全平台(除Android,iOS,macOS外还支持web,桌面应用)[Realm](https://realm.io)数据库在Android上的使用 + +## 快速上手 + +* [Android Studio 1.5.1+](https://developer.android.google.cn/studio/index.html?hl=zh-cn) +* JDK1.7+ +* Android API 9+ +* Realm 默认情况下使用内部存储(internal storage),一般来说,这个文件位于`/data/data//files/`,文件名:`default.realm` + +### 集成 + +* 在项目的 build.gradle 文件中添加如下 class path 依赖 + ```groovy + buildscript { + repositories { + jcenter() + } + dependencies { + classpath "io.realm:realm-gradle-plugin:5.0.0" + } + } + ``` +* 在 app 的 build.gradle 文件中应用 realm-android 插件 + ```groovy + apply plugin: 'realm-android' + ``` + +### 初始化 +* 默认初始化 + ```java + public class MyApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + // 默认Realm的配置文件 + Realm.init(this); + } + } + ``` +* 自定义初始化 + ```java + public class MyApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + // 自定义配置Realm + initRealm(); + } + + private void initRealm() { + RealmConfiguration config = new RealmConfiguration.Builder() + .name("myrealm.realm") // 命名文件名:myrealm.realm + .inMemory() // 一个非持久化的、存在于内存中的 Realm 实例 + .encryptionKey(getKey()) // 数据库加密key + .schemaVersion(2) // 数据库结构版本号 + .modules(new MySchemaModule()) // 数据库结构对象 + .migration(new MyMigration()) // 数据库迁移 + .build(); + Realm.setDefaultConfiguration(config); + } + } + ``` + >1. Realm 实例是线程单例化的,也就是说多次在同一线程调用静态构建器会返回同一 Realm 实例 + >2. 使用同样的名称同时创建“内存中的”Realm 和常规的(持久化)Realm 是不允许的 + +### 字段类型 +Realm 支持以下字段类型:`boolean`、`byte`、`short`、`int`、`long`、`float`、`double`、`String`、`Date`和`byte []`。整数类型 `short`、`int` 和 `long` 都被映射到 Realm 内的相同类型(实际上为 `long` )。 + +* @Required修饰类型和空值(null) + >Realm强制禁止空值(null)被存储 + 只有`Boolean`,`Byte`,`Short`,`Integer`,`Long`,`Float`,`Double`,`String`,`byte[]`,`Date`可被修饰 +* @Ignore标识一个字段不应该被保存到 Realm +* @Index为字段增加搜索索引 + > 仅支持索引的属性类型包括:`String`,`byte`,`short`,`int`,`long`,`boolean`和`Date` +* @PrimaryKey + > 必须为字符串(`String`)或整数(`short`,`int`,`long`)以及它们的包装类型(`Short`,`Int`,`Long`) + +### 声明Realm数据模型 + +#### RealmObject +可以把RealmObject 当作POJO使用 + +```java +public class User extends RealmObject { + +} +``` + +#### RealmModel +```java +@RealmClass +public class User implements RealmModel { + +} +``` + +### 关系 + +#### 多对一 +```java +public class Contact extends RealmObject { + private Email email; + // Other fields… +} + +public class Email extends RealmObject { + private String address; + private boolean active; + // ... setters and getters left out +} +``` + +#### 多对多 + +```java +public class Contact extends RealmObject { + public String name; + public RealmList emails; +} + +public class Email extends RealmObject { + public String address; + public boolean active; +} +``` + +### CRUD +* 所有的写操作(添加、修改和删除对象),必须包含在写入事务(transaction)中 +* 在提交期间,所有更改都将被写入磁盘,并且,只有当所有更改可以被持久化时,提交才会成功。通过取消一个写入事务,所有更改将被丢弃。 +* 益于 Realm 的 MVCC 架构,当正在进行一个写入事务时读取操作并不会被阻塞!这意味着,除非你需要从多个线程进行并发写入操作,否则,你可以尽量使用更大的写入事务来做更多的事情而不是使用多个更小的写入事务。 + +#### 增 + +* 事务执行 + ```java + Realm realm = Realm.getDefaultInstance(); + realm.executeTransaction(new Realm.Transaction() { + @Override + public void execute(Realm realm) { + User user = realm.createObject(User.class); + user.setName("John"); + user.setEmail("john@corporation.com"); + } + }); + ``` +* 异步事务 + ```java + Realm realm = Realm.getDefaultInstance(); + realm.executeTransactionAsync(new Realm.Transaction() { + @Override + public void execute(Realm bgRealm) { + User user = bgRealm.createObject(User.class); + user.setName("John"); + user.setEmail("john@corporation.com"); + } + }, new Realm.Transaction.OnSuccess() { + @Override + public void onSuccess() { + // Transaction was a success. + } + }, new Realm.Transaction.OnError() { + @Override + public void onError(Throwable error) { + // Transaction failed and was automatically canceled. + } + }); + ``` + + >OnSuccess 和 OnError 并不是必须重载的,重载了的回调函数会在事务成功或者失败时在被调用发生的线程执行。 +#### 删 + +#### 改 + +#### 查 + +## Realm进阶 + +## Realm云 diff --git a/source/_posts/rxjava.md b/source/_posts/rxjava.md new file mode 100644 index 000000000..a610526e0 --- /dev/null +++ b/source/_posts/rxjava.md @@ -0,0 +1,372 @@ +--- +title: RxJava 入门 +date: 2018-10-02 10:02:00 +categories: RxJava +tag: [RxJava] +--- + +RxJava – Reactive Extensions for the JVM – a library for composing **asynchronous** and **event-based** programs using **observable** sequences for the Java VM.(一个在 Java VM 上使用{% label info@可观测 %}的序列( **观察者模式** )来组成{% label info@异步 %}的、{% label info@基于事件 %}的程序的库). + +在实际开发过程中,RxJava已是一个不可或缺的组件,因此对于RxJava的学习和思考,记录分享是很重要的一个环节 + +本系列文章主要: +1. [RxJava 入门](https://incoder.org/2018/10/02/rxjava/) +2. RxJava 实际应用 +3. RxJava 源码剖析 + +目前来说,RxJava有两个版本,RxJava1 与 RxJava2 两个版本之间虽然存在很多不同,但它们的本质是相同,由于对于RxJava1 **已废弃**,因此建议没有学习或者是使用过,可直接上手学习RxJava2(在学习过程中部分地方还是会有RxJava1相关的说明,但这不是重点) + +文章使用RxJava版本如下: +* `implementation 'io.reactivex:rxjava:1.3.0'` +* `implementation 'io.reactivex.rxjava2:rxjava:2.2.1'` +* 项目示例:[rc-cluster-network](https://github.com/RootCluster/rc-cluster-network) + +>由于一个项目中RxJava1与RxJava2并不能共存,因此实际参考项目中仅RxJava2示例 + +## RxJava 基础 + +### RxJava1 VS RxJava2 + +![rxjava1 vs rxjava2](https://res.cloudinary.com/incoder/image/upload/v1538815280/blog/RxJava1_vs_RxJava2.png) +>以上是列举出不同版本间主要的变换,其它更细节部分,请查看官方[Wiki](https://github.com/ReactiveX/RxJava/wiki/What's-different-in-2.0) + +### 关键词 + +#### RxJava1 +* Observable (可观察者,即被观察者) +* Observer (观察者) +* subscribe (订阅) +* 事件 + +>Observable和Observer通过subscribe()方法实现订阅关系,从而Observable可以在需要的时候发出事件来通知Observer + +#### RxJava2 +* Observable (可观察者,即被观察者) +* Observer (观察者) +* ObservableEmitter (发射器) +* 事件 + +>RxJava2中`Subscrber`被`ObservableEmitter`取代,`Observer`中多了一个回调方法 `onSubscribe()`,传递参数为`Disposable` + +* ObservableEmitter:Emitter是发射器的意思,这个就是用来发出事件,它可以发出三种类型的事件,通过调用`emitter`的`onNext(T value)`,`onComplete()`和`onError(Throwable e)`就可以分别发出`next`事件,`complete`事件和`error`事件 +* Disposable:字面意思是一次性用品,用完即可丢弃。在RxJava中可以理解成两根管道间的阀门,当调用它的的`dispose()`方法时,它就将两根管道切断,从而导致下游收不到事件,即相当于`Subsciption` + +### 基本实现 + +#### Create Observable +![operators](https://raw.githubusercontent.com/wiki/ReactiveX/RxJava/images/rx-operators/legend.png) + +##### RxJava1 + +```java +Observable observable = Observable.unsafeCreate(new Observable.OnSubscribe() { + @Override + public void call(Subscriber subscriber) { + subscriber.onNext("Hello"); + subscriber.onNext("World"); + subscriber.onNext("RxJava1"); + subscriber.onCompleted(); + } +}); +``` +>1.2.7版本后,Observable的`create()`方法已被废弃,如果没有特殊需求,可以使用`unsafeCreate()`代替,构造Obaservable实例 + +##### RxJava2 + +```java +Observable observable = Observable.create(new ObservableOnSubscribe() { + @Override + public void subscribe(ObservableEmitter emitter) throws Exception { + emitter.onNext("Hello"); + emitter.onNext("World"); + emitter.onNext("RxJava2"); + emitter.onComplete(); + } +}); +``` +`unsafeCreate()/create()`方法是RxJava最基本创建时间序列的方法。基于这个方法,RxJava还提供了一些方法来快捷创建事件队列 + +* just(T...):将传入的参数依次发送出来 + ```java + Observable observable = Observable.just("Hello", "World", "RxJava"); + // 将会依次调用: + // onNext("Hello"); + // onNext("World"); + // onNext("RxJava"); + // onCompleted(); + ``` +* from(T[])/from(Iierabble):将传入的数组或Iterable拆分成具体对象后,依次发送出来 + ```java + String[] words = {"Hello", "World", "RxJava"}; + Observable observable = Observable.from(words); + // 将会依次调用: + // onNext("Hello"); + // onNext("World"); + // onNext("RxJava"); + // onCompleted(); + ``` + +##### Flowable +Flowable是RxJava2中新增的类,专门应对背压(Backpressure)问题,但这个概念并不是RxJava2中引入的概念。 + +出现Flowable的原因:即生产者(被观察者发送事件)的速度与消费者(观察者接收所有事件)的速度不匹配,从而导致观察者无法及时响应/处理所有发送过来的事件问题,最终导致缓冲区溢出,事件丢失 & OOM等问题。 + +一般情况,被观察者发送事件速度 > 观察者接收事件速度。比如:点击过快造成等 + +```java +Flowable.create(new FlowableOnSubscribe() { + + @Override + public void subscribe(FlowableEmitter emitter) throws Exception { + emitter.onNext("Hello"); + emitter.onNext("World"); + emitter.onNext("RxJava2"); + emitter.onComplete(); + } +}, BackpressureStrategy.ERROR) + .subscribeOn(Schedulers.computation()) + .observeOn(Schedulers.newThread()) + .subscribe(new Consumer() { + @Override + public void accept(String s) throws Exception { + // 相当于onNext + Thread.sleep(1000); + System.out.println("accept"); + } + }, new Consumer() { + @Override + public void accept(Throwable throwable) throws Exception { + // 相当于onError + System.out.println("accept" + throwable.toString()); + } + }); +``` +Flowable并不是订阅就开始发送数据,而是需等到执行`Subscription.request()`才开始发送数据 + +#### Create Observer + +##### RxJava1 +```java +Observer observer = new Observer() { + @Override + public void onCompleted() { + System.out.println("Completed!"); + } + + @Override + public void onError(Throwable e) { + System.out.println("Error" + e); + } + + @Override + public void onNext(String s) { + System.out.println("Next" + s); + } +}; +``` +除了`Observer`接口之外,RxJava内置了一个实现`Observer`的抽象类`Subscriber`,`Subscriber`对`Observer`接口进行了一些扩展,但它们的基本使用方式是完全一样 +```java +Subscriber subscriber = new Subscriber() { + @Override + public void onCompleted() { + System.out.println("Completed!"); + } + + @Override + public void onError(Throwable e) { + System.out.println("Error" + e); + } + + @Override + public void onNext(String s) { + System.out.println("Next" + s); + } +}; +``` +实际,在RxJava的subscribe过程中,`Observer`也总是会先被转成一个`Subscriber`再使用。对于使用者来说`Observer`与`Subscriber`的主要区别是: +1. onStart():这是`Subscriber`增加的方法。它会再subscribe刚开始,而事件还未发送之前被调用,可以用于做一些准备工作,例如:数据的重置等操作。这是一个可选方法,默认情况下它的实现为空。 +>注意: +>对于准备工作有线程要求,`onStart()`就不适用,因为它总是再subscribe所发生的线程被调用,而不能指定线程。要指定线程来准备工作,可以使用`doOnSubscribe()`方法 +2. unsubscribe():`Subscriber`所实现的另一个接口`Subscription`的方法,用于取消订阅。在这个方法被调用后,`Subscriber`将不再接收事件。 +>注意: +>* 一般需要在调用`unsubscribe()`方法前,需要使用`isUnsubscribed()`先判断状态。 +>* 不再使用的时候尽快在合适的地方调用`unsubscribe()`来解除引用关系,以避免内存泄漏 + +##### RxJava2 +```java +Observer observer = new Observer() { + @Override + public void onSubscribe(Disposable d) { + System.out.println("Subscribe: " + d); + } + + @Override + public void onNext(String s) { + System.out.println("Next: " + s); + } + + @Override + public void onError(Throwable e) { + System.out.println("Error: " + e); + } + + @Override + public void onComplete() { + System.out.println("Complete !"); + } +}; +``` + +#### Subscribe +创建好`Observable`和`Observer`之后,再用`subscribe()`方法将它们联结起来 +```java +observable.subscribe(observer); +// 或者(仅支持RxJava1) +observable.subscribe(subscriber); +``` + +#### chain calls +以上三步是使用RxJava进行异步操作的基本过程,创建`被观察者`,创建`观察者`,`被观察者`订阅`观察者`,我们可以通过链式调用形式完成操作 + +```java +Observable.unsafeCreate(new Observable.OnSubscribe() { + @Override + public void call(Subscriber subscriber) { + subscriber.onNext("Hello"); + subscriber.onNext("World"); + subscriber.onNext("RxJava1"); + subscriber.onCompleted(); + } +}).subscribe(new Observer() { + @Override + public void onCompleted() { + System.out.println("Completed!"); + } + + @Override + public void onError(Throwable e) { + System.out.println("Error" + e); + } + + @Override + public void onNext(String s) { + System.out.println("Next" + s); + } +}); +``` +#### 简化订阅 +除了`subscribe(Observer)`和`subscribe(Subscriber)(仅支持RxJava1)`,`subscribe()`还支持不完整的简化订阅回调 + +```java +// RxJava1 +Action1 onNextAction = new Action1() { + @Override + public void call(String s) { + System.out.println("onNext" + s); + } +}; + +Action1 onErrorAction = new Action1() { + @Override + public void call(Throwable throwable) { + System.out.println("onError" + throwable); + } +}; + +Action0 onCompletedAction = new Action0() { + @Override + public void call() { + System.out.println("completed"); + } +}; + +// RxJava2 +Consumer onNextAction = new Consumer() { + @Override + public void accept(String s) throws Exception { + System.out.println("onNext" + s); + } +}; + +Consumer onErrorAction = new Consumer() { + @Override + public void accept(Throwable throwable) throws Exception { + System.out.println("onError" + throwable); + } +}; + +Action onCompleteAction = new Action() { + @Override + public void run() throws Exception { + System.out.println("complete"); + } +}; + +// 自动创建 Subscriber ,并使用 onNextAction 来定义 onNext() +observable.subscribe(onNextAction); +// 自动创建 Subscriber ,并使用 onNextAction 和 onErrorAction 来定义 onNext() 和 onError() +observable.subscribe(onNextAction, onErrorAction); +// 自动创建 Subscriber ,并使用 onNextAction、 onErrorAction 和 onCompletedAction 来定义 onNext()、 onError() 和 onCompleted() +observable.subscribe(onNextAction, onErrorAction, onCompletedAction/onCompleteAction); + +``` + +## RxJava 线程 +在RxJava的默认规则中,事件的发出和消费都是在同一个线程(在哪个线程条用`subscriber()`,就在哪个线程生产事件;在哪个线程生产事件,就在哪个线程消费事件),也就是说,以上RxJava基本操作,实现出来的只是一个`同步`的观察者模式。而观察者模式本身的目的是“后台处理,前台回调”的`异步`机制,因此在RxJava中通过`Scheduler`来对线程进行管理 + +### Scheduler API +Scheduler相当于线程控制器,RxJava通过它指定代码应该运行在什么样的线程,其中RxJava中内置了几个Scheduler +* Schedulers.computation():计算所使用的`Scheduler`。这个计算值的是CPU密集型计算,即不会被I/O操作等限制性能的操作。不要把I/O操作放在`computation()`中,否则I/O操作的等待时间会浪费CPU。 +* Schedulers.form(Executor): +* Schedulers.immediate():直接在当前线程运行,相当于不指定线程,这也是默认的Scheduler. +* Schedulers.io():I/O操作(读写文件,读写数据库,网络信息交换等)所使用的Scheduler。行为模式和newThread()差不多,区别在于io()的内部实现是一个无数量上限的线程池,可以重用空闲的线程,因此多数情况下io()比newThread()更高效 +* Schedulers.newThread():总是启用新线程,并在新线程执行操作 +* Schedulers.single()『仅RxJava2中存在』: +* Schedulers.test()『仅RxJava1中存在』:顾名思义,这是一个测试 +* Schedulers.trampoline(): +* AndoroidSchedulers.mainThread():指定操作在Android的主线程 + +有了Scheduler,我们可以使用`subscribeOn()`和`observeOn()`方法来对线程进行控制 +* subscribeOn():指定subscribe()所发生的线程,即Observable.OnSubscribe被激活时所处的线程,或者叫做事件的产生的线程 +* observeOn():指定Subscriber所运行的线程。或者叫做事件的消费线程 + + ```java + // RxJava2 + Observable.create(new ObservableOnSubscribe() { + @Override + public void subscribe(ObservableEmitter emitter) throws Exception { + emitter.onNext("Hello"); + emitter.onNext("World"); + emitter.onNext("RxJava2"); + emitter.onComplete(); + } + }) + // 指定 subscribe() 发生在 IO 线程 + .subscribeOn(Schedulers.io()) + // 指定 Subscriber 的回调发生在主线程 + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new Consumer() { + @Override + public void accept(String s) throws Exception { + System.out.println(s); + } + }); + ``` + +## 操作符 +说RxJava好用,还有一个原因是RxJava提供了大量的操作符,这些操作符保证了在面都复杂的逻辑下,依旧可以是逻辑清晰的链式调用 + +![RxJava_action](https://res.cloudinary.com/incoder/image/upload/v1538815494/blog/RxJava_action.png) + +## 总结 +本篇文章作为RxJava系列的学习的入门,不会讲解相关操作的原理等 +学习目的 +* 了解RxJava1与RxJava2之间的不同点, +* 了解RxJava的线程管理, +* 掌握完成RxJava的基本操作, +* 清楚RxJava操作符,以及分别适用于什么样的场景 + +## 附录 +文章中部分原话引用了参考学习文章的原话,在这里向那些无私分享的大佬致敬 +* [给 Android 开发者的 RxJava 详解](https://gank.io/post/560e15be2dca930e00da1083) +* [RxJava系列教程](https://www.jianshu.com/nb/14302692) \ No newline at end of file diff --git a/source/_posts/security-rsa.md b/source/_posts/security-rsa.md new file mode 100644 index 000000000..f76a434c0 --- /dev/null +++ b/source/_posts/security-rsa.md @@ -0,0 +1,74 @@ +--- +title: 非对称加密——RSA +date: 2018-07-03 20:28:51 +categories: Security +tag: RSA +--- + +这是常用加密技术的系列文章,主要包含`非对称`,`对称`,`JWT`三类常用技术的应用 + +## RSA +[RSA](https://zh.wikipedia.org/wiki/RSA%E5%8A%A0%E5%AF%86%E6%BC%94%E7%AE%97%E6%B3%95):RSA加密算法是一种 **非对称** 加密算法。在公开密钥加密和电子商业中RSA被广泛使用。RSA是1977年由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的。RSA就是他们三人姓氏开头字母拼在一起组成的。 + +### RSA加密解密 +公钥 **加密** 私钥 **解密**,持有公钥(多人持有,**客户端**)可以对数据加密,但是只有持有私钥(一人持有,**服务端**)才可以解密并查看数据 + +### RSA加签验签 +私钥 **加签** 公钥 **验签**,持有私钥(一人持有,**服务端**)可以加签,持有公钥(多人持有,**客户端**)可以验签 + +### RSA过程示意图 + +![security-rsa](https://res.cloudinary.com/incoder/image/upload/v1530793864/blog/security-rsa.png) + +如上图,具体表述两个场景过程 + +#### 结果不需加密 +场景:返回的数据不需要加密(例如:绑定银行卡的时候) +* 客户端`Client A`发送使用服务端`Serve publicKey` **加密** 的密文`cipher A(包含用户的银行卡号,手机号等重要信息)`到服务器 +* 服务器`Serve` 通过 `Serve privateKey`**解密** +* 服务端业务处理完成,直接返回数据(一些普通信息,比如状态码code,提示信息msg,提示操作是成功还是失败)给客户端`Client A` + +#### 结果需加密 +场景:返回的数据需要加密(例如:用户登录) +* 客户端`Client B`发送使用服务端`Serve publicKey` **加密** 的密文`cipher B(包含用户名和密码等重要信息)`以及客户端`Client B`的`Client B publicKey`到服务器 +* 服务器`Serve` 通过 `Serve privateKey`**解密** +* 服务端业务处理完成,直接返回数据(一般为token,token使用客户端`Client B`的`Client B publicKey`加密)给客户端`Client B` +* 客户端`Client B`使用`Client B privateKey`进行 **解密** 获取相应的用户信息等 + +## 密钥对 +在使用RSA加密解密之前,首先要生成密钥对。所谓的密钥对,指的是公钥和私钥。RSA算法的密钥可以通过两个途径生成,一是借助`openssl`命令终端,二是使用`JDK`生成。 +本篇采用`JDK`方式生成密钥对,`openssl`方式可自行尝试 + +### JDK + +#### Serve端密钥对 + +#### Client端密钥对 + +##### Android密钥对 + +##### Web密钥对 + +##### iOS密钥对 + +### OpenSSL + +略... + +## RSA加密 + +## RSA解密 + +## RSA缺点 +虽然RSA是一种较高级别加密机制,但也存在一些缺点 +1. 产生密钥很麻烦,受到素数产生技术的限制,因而难以做到一次一密。 +2. 安全性,RSA的安全性依赖于大数的因子分解,但并没有从理论上证明破译RSA的难度与大数分解难度等价,而且密码学界多数人士倾向于因子分解不是NP问题。 +3. 速度太慢,由于`RSA`的分组长度太大,为保证安全性,n 至少也要 `600 bit` 以上,使运算代价很高,尤其是速度较慢,较对称密码算法慢几个数量级;且随着大数分解技术的发展,这个长度还在增加,不利于数据格式的标准化。 + +## 附录 +参考学习文章 +* [一张图了解RSA加解密与加验签](https://blog.csdn.net/zhshulin/article/details/71573542) +* [RSA加密解密及RSA加签验签](https://www.cnblogs.com/loveyou/p/7299524.html) +* [RSA加解密和加签验签](https://www.jianshu.com/p/ff9bd897e96a) +* [RSA加密解密样例](https://www.jianshu.com/p/283fff43a948) +* [RSA加密解密实现](https://blog.csdn.net/hustpzb/article/details/72734578) \ No newline at end of file diff --git a/source/_posts/soa.md b/source/_posts/soa.md new file mode 100644 index 000000000..db17fe8d1 --- /dev/null +++ b/source/_posts/soa.md @@ -0,0 +1,263 @@ +--- +title: 【译】• 面向服务的架构 +date: 2019-06-19 21:20:40 +categories: + - [Translation] + - [SpringBoot] +tag: [SOA,SpringBoot] +--- + +在学习过程中,我们首先需要将学习知识的基本概念搞清楚,而搞清楚概念最权威的方式是查阅 **[英文版 • 维基百科](https://en.wikipedia.org)** ,或者是对应知识的官方文档上面查找相关的知识。这样学习才能学习到知识的精华,而不是阅读经过别人转译过的文章。因此,这篇文章仅是本人在学习 SOA 基本概念时,对维基百科知识的一个汇总翻译记录,不建议朋友把这篇文章当做你的学习资料,具体请查阅[Service-oriented architecture](https://en.wikipedia.org/wiki/Service-oriented_architecture)。 + +面向服务的架构(SOA)是一种[软件设计](https://en.wikipedia.org/wiki/Software_design)风格。 SOA 服务通过[应用组件](https://en.wikipedia.org/wiki/Application_components),通过网络[通信协议](https://en.wikipedia.org/wiki/Communications_protocol)的方式向其他组件提供服务。SOA 的基本原则是独立于厂商,独立于产品以及独立于技术[^1]。服务是一种功能的离散独立单元,可以远程访问并独立运行与更新,例如在线查询信用卡账单。 + +一个服务在诸多 SOA 定义中有 4 个属性[^2]: +1. 它逻辑上代表具有指定结果的业务活动 +2. 它是自包含的 +3. 它对于消费者来说是[黑盒](https://en.wikipedia.org/wiki/Black_box)(不可见) +4. 它可能包含其他基础服务[^3] + +不同的服务可以联合起来构建大型的[软件应用](https://en.wikipedia.org/wiki/Software_applications)[^4],SOA 遵循模块化[编程思想](https://en.wikipedia.org/wiki/Modular_programming),SOA 集成了分布式,独立维护和独立部署的软件组件,它通过技术和标准促使组件通过网络进行通信和协作,尤其是通过 IP 网络 + +## 概览 + +在 SOA 中,服务的使用是描述怎样通过[元数据](https://en.wikipedia.org/wiki/Metadata)[传递消息](https://en.wikipedia.org/wiki/Message_passing)和解析消息的协议。该元数据描述了服务的功能特性和服务质量特征。SOA 目标旨在允许用户将大块的功能组合在一起来去构成一个应用,形成纯粹由现有服务构建并以临时方式组合的应用程序。一个服务会向调用者提供一个简单的接口,它抽象出作为黑盒子的底层复杂性。其他用户可以在不了解其内部实现的情况下访问这些独立服务[^5]。 + +## 定义概念 + +相关的流行语服务导向促进了[面向服务](https://en.wikipedia.org/wiki/Service-orientation)间的[松耦合](https://en.wikipedia.org/wiki/Loose_coupling)。SOA 将功能分为不同的单元或服务,哪些开发人员可以通过网络访问,以便允许用户在应用程序的生产中组合和重用它们。这些服务及其相应的消费者通过明确定义的共享格式,传递数据或通过协调两个或更多服务之间的活动来互相通信 + +2009 年 10 月发布了关于 SOA 的宣言,其中提出了 6 个核心价值,如下所示 +1. **商业价值**比技术战略更重要 +2. **战略目标**比项目特定的利益更重要 +3. **内在的互操作**性比定制集成更重要 +4. **共享服务**比特定用途实现更重要 +5. **灵活性**比优化更重要 +6. **演进式**比追求初始化完美更重要 + +SOA 可看作是连续统一体的一部分,其范围从旧的[分布式计算](https://en.wikipedia.org/wiki/Distributed_computing)概念和[模块化编程](https://en.wikipedia.org/wiki/Modular_programming)[^6] [^9],通过 SOA,以及 [mashups](https://en.wikipedia.org/wiki/Mashup_(web_application_hybrid)),[SaaS](https://en.wikipedia.org/wiki/SaaS) 和[云计算](https://en.wikipedia.org/wiki/Cloud_computing)的当前实践(有些人认为是 SOA 的后代)[^10] + +## 原理 + +尽管许多行业已发布了自己的原则,但没有与 SOA 确切相关的行业标准,其中一些[^11] [^12] [^13] [^14]包括以下内容 + +### [标准地服务契约](https://en.wikipedia.org/wiki/Standardized_service_contract) + +服务遵循标准通信协议,有一组给定服务中的一个或多个服务描述文档共同定义 + +### [服务自治](https://en.wikipedia.org/w/index.php?title=Service_reference_autonomy&action=edit&redlink=1) + +服务之间的关系被最小化到它们只知道存在的等级 + +### [服务松耦合](https://en.wikipedia.org/w/index.php?title=Service_location_transparency&action=edit&redlink=1) + +无论网络位于何处,都可以从网络中的任何位置调用服务 + +### [服务长寿](https://en.wikipedia.org/w/index.php?title=Service_longevity&action=edit&redlink=1) + +服务应该设计为长寿,在可能的情况下,如果不需要新功能,服务应该避免强迫消费者进行更改。如果今天能调用的服务,到明天也应该能调用统一的服务 + +### [服务抽象化](https://en.wikipedia.org/wiki/Service_abstraction) + +服务充当黑盒,它们内在的逻辑对消费者是隐藏的 + +### [服务自治](https://en.wikipedia.org/wiki/Service_autonomy_principle) + +服务是独立的,从设计时和运行时的角度控制它们封装的功能 + +### [服务无状态化](https://en.wikipedia.org/wiki/Service_statelessness_principle) + +服务是无状态的,即返回请求的值或提供异常,从而最大限度的减少资源使用 + +### [服务粒度](https://en.wikipedia.org/wiki/Service_granularity_principle) + +确保服务具有足够的规模和范围的原则。服务向用户提供的功能必修三相关的 + +### 服务规范化 + +服务被分解或合并作为最小化冗余。在某些情况下,可能无法完成,这些是需要性能优化,访问和聚合的情况[^15] + +### [服务可组合性](https://en.wikipedia.org/wiki/Service_composability_principle) + +服务可用于组成其他服务 + +### [服务发现](https://en.wikipedia.org/wiki/Service_discovery) + +服务补充了交流元数据,通过它可以有效地发现和解释它们 + +### [服务可重用性](https://en.wikipedia.org/wiki/Service_reusability_principle) + +将逻辑分为多个服务,以促进代码的复用 + +### 服务[封装](https://en.wikipedia.org/wiki/Encapsulation_(computer_science)) + +许多最初未在 SOA 下计划的服务可能会被封装或成为 SOA 的一部分 + +## 模式 + +每个SOA构建块都可以扮演以下三种角色中的任何一种: + +### 服务提供者 + +它创建 Web 服务并将其信息提供给服务注册。每个提供者都会讨论大量的方法,以及为什么要公开哪些服务,哪些更重要:安全性或易用性,提供服务的价格等等。提供者还必须决定应该为给定的代理服务列出服务的类别[^16]以及使用该服务需要那种协议 + +### 服务代理,服务注册或服务存储 + +其主要功能是使用任何潜在的请求者都能获取有关 Web 服务的信息。实施的人决定代理的范围。公开的代理随处可见,但私有的代理只能向有限的公开代理开放。UDDI 是一种早期的,不再主动支持的 [Web 服务发现](https://en.wikipedia.org/wiki/Web_Services_Discovery)。 + +### 服务消费者 + +它使用各种查找操作在代理注册中查找,然后绑定到服务提供者以调用其中一个 Web 服务。无论服务消费者需要哪种服务,它们都必须通过代理,将其与相应的服务绑定,然后使用它。如果服务提供多种服务,它们可以访问多种服务。 + +服务消费者-提供者关系由[标准化服务契约](https://en.wikipedia.org/wiki/Standardized_service_contract)[^17]管理,其中包括业务部分,功能部分和技术部分。 + +[服务组合模式](https://en.wikipedia.org/wiki/Service_composability_principle)有两种广泛的高级架构风格:[服务编排](https://en.wikipedia.org/wiki/Service_choreography#Service_choreography_and_service_orchestration)。不受特定体系结构风格约束的较低级别的企业集成模式在 SOA 设计中任然具有相关性和合格性[^18] [^19] [^20]。 + +## 实现方法 + +SOA 可以通过 [Web 服务](https://en.wikipedia.org/wiki/Web_service)[^21]实现。这样做是为了使功能模块可以通过独立于平台和编程语言的标准协议访问。这些服务既可以代表新应用程序,也可以代表现有遗留系统的包装,使其具备网络功能。[^22] + +实现通用使用 Web 服务标准构建 SOA。一个例子是 [SOAP](https://en.wikipedia.org/wiki/SOAP),它在 2003 年从 W3C[^23] 推荐 1.2 版本后获得广泛的行业认可。这些标准(也称为 [Web 服务规范](https://en.wikipedia.org/wiki/List_of_web_service_specifications))还提供了更强的互操作性以及对锁定到专有供应商软件的一些保护。但是,也可以使用任何其他基于服务的技术(如 [Jini](https://en.wikipedia.org/wiki/Jini),[CORBA](https://en.wikipedia.org/wiki/CORBA) 或者 [REST](https://en.wikipedia.org/wiki/Representational_State_Transfer))实现 SOA + +架构可以独立于特定技术运行,因此可以使用多种技术实现,包括: +* 基于 WSDL 和 [SOAP](https://en.wikipedia.org/wiki/SOAP) 的 [Web 服务](https://en.wikipedia.org/wiki/Web_services) +* 消息传递,例如,使用 ActiveMQ, JMS, RabbitMQ +* RESTful HTTP,具有 [Representational 状态转移](https://en.wikipedia.org/wiki/Representational_state_transfer)(REST),构成自己的基于约束的架构风格 +* [OPC-UA](https://en.wikipedia.org/wiki/OPC_Unified_Architecture) +* [WCF](https://en.wikipedia.org/wiki/Windows_Communication_Foundation)(Microsoft 的 Web 服务实现,构成 WCF 的一部分) +* [Apache Thrift](https://en.wikipedia.org/wiki/Apache_Thrift) +* [gRPC](https://en.wikipedia.org/wiki/GRPC) +* [SORCER](https://en.wikipedia.org/wiki/SORCER) + +实现可以使用这些协议中的一个或多个,例如,可以使用文件系统机制来遵循符合 SOA 概念的进程间定义的接口规范来传递数据。关键是具有已定义接口的独立服务,可以调用它们以标准方式执行其任务,而无需预先知道调用应用程序的服务,并且没有应用程序具有或需要知道服务如何实际执行其任务。SOA 支持开发通过松耦合和可[互操作](https://en.wikipedia.org/wiki/Interoperable)的服务构建的应用程序 + +这些服务独立于底层平台和编程语言的正式定义(或契约,例如 WSDL)进行互操作。接口定义[隐藏了实施](https://en.wikipedia.org/wiki/Information_hiding)特定语言的服务实现。因此,基于 SOA 的系统可以独立于开发技术和平台(例如Java,.NET等)运行。例如,运行在.NET平台上的 C# 和 用 [JavaEE](https://en.wikipedia.org/wiki/Java_Platform,_Enterprise_Edition) 平台上运行的 Java 编写的服务都可以公共复合应用程序(或客户端)使用。在任一平台上运行的应用程序也可以使用在另一个平台上运行的服务作为重用的 Web 服务。托管环境还可以包括 COBOL 遗留系统并将其作为软件服务提供。[^24] + +诸如 [BPEL](https://en.wikipedia.org/wiki/BPEL) 之类的[高级编程语言](https://en.wikipedia.org/wiki/High-level_programming_language)以及诸如 [WS-CDL](https://en.wikipedia.org/wiki/WS-CDL) 和 [WS-Coordination](https://en.wikipedia.org/wiki/WS-Coordination) 之类的规范通过提供一种定义和支持将细粒度服务编排成更粗粒度的业务服务的方法来扩展服务的概念,架构师可以将其合并到[复合应用](https://en.wikipedia.org/wiki/Composite_applications)程序或[门户](https://en.wikipedia.org/wiki/Enterprise_portal)中实现的工作流和业务流中。 + +[面向服务的建模](https://en.wikipedia.org/wiki/Service-oriented_modeling)是一个 SOA 架构,可识别指导 SOA 从业者对其面向服务的资产进行概念化,分析,设计和构建的各种规程。[面向服务的建模框架(SOMF)](https://en.wikipedia.org/wiki/Service-oriented_modeling#Service-oriented_modeling_framework)提供了一种建模语言和一个工作架构映射,描述了有助于成功的面向服务的建模方法的各种组件。它说明了识别服务开发方案的“做什么”方面的主要元素。该模型使从业者能够制定[项目计划](https://en.wikipedia.org/wiki/Project_plan)并确定面向服务的计划的里程碑。SOMF 还提供了一种通用的建模符号,已解决业务和 IT 组织之间的一致性问题。 + +## 组织利益 + +一些[企业架构师](https://en.wikipedia.org/wiki/Enterprise_architect)认为,SOA 可以帮助企业更快,更经济地响应不断变化的市场条件。[^26]这种体系结构促进了宏(服务)级别的重用,而不是微(类)级别的重用。它还可以简化现有 IT(传统)资产的互联和使用。 + +![SOA的元素,由Dirk Krafzig,Karl Banke和Dirk Slama撰写 [^25]](https://res.cloudinary.com/incoder/image/upload/v1561944855/blog/elements_of_soa.png) + +使用SOA,我们的想法是组织可以从整体上看待问题。企业拥有更多地整体控制权。从理论上讲,不会有大量的开发人员使用任何工具集让他们满意,但他们将编码为业务中设定标准。他们还可以开发企业级 SOA,封装面向业务的基础架构。SOA 被描述为汽车驾驶员提供效率的高速公路系统。关键在于,如果每个人都有车,但在任何地方都没有高速公路,那么事情就会受到限制和混乱,无论是视图快速或有效地到达任何地方。IBM Web 服务副总裁 Michael Liebow 表示 SOA 是“建设的高速公路”。[^27] + +![SOA元模型,The Linthicum Group,2007](https://res.cloudinary.com/incoder/image/upload/v1561944919/blog/soa_meta-model.svg) + +在某些方面,SOA可以被视为架构演变而不是革命。它捕获了以前软件架构的许多[最佳实践](https://en.wikipedia.org/wiki/Best_practice)。例如,在通信系统中,很少开发使用真正静态绑定与网络中的其他设备通信的解决方案。通过采用 SOA 方法,此类系统可以将自己定位为强调定义明确,高度可互操作的接口的重要性。SOA 的其他前身包括[基于组件的软件工程](https://en.wikipedia.org/wiki/Component-based_software_engineering)和远程对象的面向对象分析和设计(OOAD),例如,在 [CORBA](https://en.wikipedia.org/wiki/CORBA) 中。 + +服务包括仅通过正式定义的页面可用的独立功能单元。服务可以是某种易于生产和改进的“纳米企业”。服务也可以是作为子下属服务的协调工作而构建的“大型企业”。SOA 的成熟部署有效地定义了组织的 API。 + +将服务实施视为大型项目的单独项目的原因包括: +1. 分离将业务概念推广到业务,即服务可以快速独立地从组织中常见的较大且移动较慢的项目中提供。业务开始了解回调服务的系统和简化的用户界面。这提倡[敏捷](https://en.wikipedia.org/wiki/Agility)。也就是说,它促进了业务创新并加快了产品上市时间[^28]。 +2. 分离促进了服务于消费项目的脱钩。这样可以鼓励良好的设计,因为服务的设计不需要知道消费者是谁。 +3. 服务的文档和测试文件未嵌入较大项目的详细信息中。当服务需要在后续需要重用时,这很重要。 + +SOA 承诺间接简化测试。服务是自治的,无状态的,具有完全记录的接口,并且与实现的关注点是分开的。如果组织拥有适当定义的测试数据,则会构建响应的存根,以便在构建服务时对测试数据做出反应。可以构建测试环境,其中原始和超出范围的服务是存根,而网格的其余ubuf 是完整服务的测试部署。由于每个接口都有完整的文档,并附有完整的回归测试文档,因此可以轻松识别测试服务中的问题。测试演变为仅仅验证测试服务是否根据其文档运行,并发现环境中所有服务的文档和测试用例存在的差距。管理[幂等](https://en.wikipedia.org/wiki/Agility)服务的数据状态是唯一的复杂性。 + +实例可能有助于将服务记录到有用的级别。Java community Process 中的一些 API 文档提供了良好的示例。由于这些是详尽无遗漏的,工作人员通常只使用重要的子集。JSR-89 的 ossjsa.pdf 文件中举例说明了这样做一个文件[^29]。 + +## 批评 + +SOA 已与 [Web 服务](https://en.wikipedia.org/wiki/Web_service)混淆[^30],但是,Web 服务只是实现构成 SOA 风格的模式的一种选择。在非本机或二进制形式的远程过程调用(RPC)的情况下,应用程序可能运行的更慢并且需要更多地处理能力,从而增加了成本。大多数实现都会产生这些开销,但 SOA 可以使用技术实现(例如,[Java Business Integration(JBI)](https://en.wikipedia.org/wiki/Java_Business_Integration),[Windows Communication Foundation(WCF)](https://en.wikipedia.org/wiki/Windows_Communication_Foundation)和 [data distribution service(DDS)](https://en.wikipedia.org/wiki/Data_distribution_service)),它们不依赖与远程过程调用或通过 XML 进行转换。与此同时,新兴的开源 XML 解析技术(如 [VTD-XML](https://en.wikipedia.org/wiki/VTD-XML))和各种 XML 兼容的二进制格式有望显著提高 SOA 性能。使用 [JSON](https://en.wikipedia.org/wiki/JSON) 而不是 XML 实现的服务不会受到这种性能的问题的影响[^31] [^32] [^33]。 + +有状态服务要求消费者和提供者共享相同的特定于消费者的上下文,该上下文包含在提供者和消费者之间交换的消息中或由其引入。如果服务提供者需要为每个消费者保留共享上下文,则此约束的缺点是它可能会降低服务提供者的整体可伸缩性。它还增加了服务提供者和消费者之间的耦合,使交换服务提供者更加困难[^34]。最终,一些批评者认为 SOA 服务仍然受到他们所代表的应用程序的限制[^35]。 + +SOA 的体系结构面临的主要挑战是管理元数据。基于 SOA 的环境包括许多彼此之间进行通信以执行任务的服务。由于设计可能涉及多个服务一起工作,因此应用程序可能会产生数百万条消息。进一步的服务可能属于不同的组织甚至是竞争公司,造成巨大的信任问题。因此 SOA 治理进入了事务的计划[^36]。 + +SOA 面临的另一个主要问题是缺乏统一的测试架构。没有工具可以提供在 SOA 的体系结构中测试这些服务所需的功能。困难的主要原因是:[^37] +* 异质性和解决方案的复杂性 +* 由于自主服务的集成,大量的测试组合 +* 包含来自不同和竞争供应商的服务 +* 由于新功能和服务的可用性,[平台](https://en.wikipedia.org/wiki/Platform_as_a_service)不断变化 + +请参阅 drops.dagstuhl.de[^38],了解有关[软件服务工程](https://en.wikipedia.org/wiki/Service-oriented_modeling)的其他挑战,部分解决方案和研究路线图 + +## 扩展和变体 + +### 事件驱动的体系结构 + +主要文章:[事件驱动的架构](https://en.wikipedia.org/wiki/Event-driven_architecture) + +### Web2.0 + +[Tim O'Reilly](https://en.wikipedia.org/wiki/Tim_O%27Reilly) 创造了“[Web2.0](https://en.wikipedia.org/wiki/Web_2.0)”一词来描述一种快速增长的基于网络的应用程序[^39]。经历了广泛报道的主题涉及 Web2.0与 SOA 体系机构之间的关系。 + +SOA 是将应用程序逻辑封装在具有统一定义的接口的服务中并通过发现机制公开可用的哲学。复杂性-隐藏和重用的概念,以及松耦合服务的概念,激发了研究人员详细阐述两种哲学,SOA 和 Web2.0及其各自应用之间的相似性。一些人认为 Web2.0和 SOA 具有显著不同的元素,因此不能被视为“平行哲学”,而其他人认为这两个概念是互补的,并将 Web2.0视为全球 SOA[^40]。 + +Web2.0和 SOA 的理念满足了不同的用户需求,从而暴露了设计方面的差异以及实际应用中使用的技术。但是,截止 2008 年,用例展示了结合 Web2.0和 SOA 技术和原则的潜力[^40]。 + +### 微服务 + +主要文章:[微服务](https://en.wikipedia.org/wiki/Microservices) + +微服务是对用于构建[分布式软件系统](https://en.wikipedia.org/wiki/Distributed_computing)的面向服务的体系结构的现代解释。微服务架构[^41]中的服务是通过[网络](https://en.wikipedia.org/wiki/Computer_network)互相通信以实现目标的[过程](https://en.wikipedia.org/wiki/Process_(computing))。这些服务使用技术不可知[协议](https://en.wikipedia.org/wiki/Communications_protocol)[^42],这有助于封装语言和框架的选择,使他们的选择成为服务内部的一个问题。微服务是 SOA 的一种新的实现方法,自 2014 年(以及 [DevOps](https://en.wikipedia.org/wiki/DevOps) 推出以后)开始流行,并且强调持续部署和其他的=敏捷实践[^43]。 + +微服务没有一个共同商定的定义。在文献中可以找到以下特征和原理: +* 细粒度接口(可独立部署的服务) +* 业务驱动的开发(例如域驱动设计) +* IDEAL 云应用架构 +* 多语言编程和持久化存储 +* 轻量级容器部署 +* 分散的持续交付 +* DevOps 提供全面的服务监控 + +## 其他 + +* [松耦合](https://en.wikipedia.org/wiki/Loose_coupling) +* [OASIS SOA 参考模型](https://en.wikipedia.org/wiki/OASIS_SOA_Reference_Model) +* [服务粒度原则](https://en.wikipedia.org/wiki/Service_granularity_principle) +* [SOA 治理](https://en.wikipedia.org/wiki/SOA_governance) +* [软件架构](https://en.wikipedia.org/wiki/Software_architecture) +* [面向服务的通信](https://en.wikipedia.org/wiki/Service-oriented_communications) +* [面向服务的应用程序开发](https://en.wikipedia.org/wiki/Service-oriented_development_of_applications) +* [面向服务的分布式应用程序](https://en.wikipedia.org/wiki/Service-oriented_distributed_applications) + +## 参考 + +[^1]: "[Chapter 1: Service Oriented Architecture (SOA)](https://web.archive.org/web/20160206132542/https://msdn.microsoft.com/en-us/library/bb833022.aspx)". msdn.microsoft.com. Archived from [the original](https://msdn.microsoft.com/en-us/library/bb833022.aspx) on February 6, 2016. Retrieved September 21, 2016. +[^2]: "[Service-Oriented Architecture Standards - The Open Group](https://publications.opengroup.org/standards/soa)". www.opengroup.org. +[^3]: "[What Is SOA?](https://web.archive.org/web/20160819141303/http://opengroup.org/soa/source-book/soa/soa.htm)". www.opengroup.org. Archived from [the original](http://www.opengroup.org/soa/source-book/soa/soa.htm) on August 19, 2016. Retrieved September 21, 2016. +[^4]: Velte, Anthony T. (2010). Cloud Computing: A Practical Approach. McGraw Hill. [ISBN](https://en.wikipedia.org/wiki/International_Standard_Book_Number) [978-0-07-162694-1](https://en.wikipedia.org/wiki/Special:BookSources/978-0-07-162694-1). +[^5]: "[Migrating to a service-oriented architecture, Part 1](https://web.archive.org/web/20081209120916/http://www-128.ibm.com/developerworks/library/ws-migratesoa/)". December 9, 2008. Archived from the original on December 9, 2008. Retrieved September 21, 2016. +[^6]: Michael Bell (2008). "Introduction to Service-Oriented Modeling". Service-Oriented Modeling: Service Analysis, Design, and Architecture. Wiley & Sons. p. 3. [ISBN](https://en.wikipedia.org/wiki/International_Standard_Book_Number) [978-0-470-14111-3](https://en.wikipedia.org/wiki/Special:BookSources/978-0-470-14111-3). +[^7]: Michael Bell (2010). SOA Modeling Patterns for Service-Oriented Discovery and Analysis. Wiley & Sons. p. 390. [ISBN](https://en.wikipedia.org/wiki/International_Standard_Book_Number) [978-0-470-48197-4](https://en.wikipedia.org/wiki/Special:BookSources/978-0-470-48197-4). +[^8]: "[SOA Manifesto](http://www.soa-manifesto.org/)". www.soa-manifesto.org. Retrieved September 21, 2016. +[^9]: Thomas Erl (June 2005). About the Principles. Serviceorientation.org +[^10]: "[Application Platform Strategies Blog: SOA is Dead; Long Live Services](http://apsblog.burtongroup.com/2009/01/soa-is-dead-long-live-services.html)". Apsblog.burtongroup.com. January 5, 2009. Retrieved August 13, 2012. +[^11]: Yvonne Balzer [Improve your SOA project plans](http://www-128.ibm.com/developerworks/webservices/library/ws-improvesoa/), IBM, July 16, 2004 +[^12]: Microsoft Windows Communication Foundation team (2012). "[Principles of Service Oriented Design](http://msdn.microsoft.com/en-us/library/bb972954.aspx)". msdn.microsoft.com. Retrieved September 3, 2012. +[^13]: Principles by [Thomas](https://en.wikipedia.org/wiki/Thomas_Erl) Erl of SOA Systems Inc. [eight specific service-orientation principles](http://soaprinciples.com) +[^14]: M. Hadi Valipour; Bavar AmirZafari; Kh. Niki Maleki; Negin Daneshpour (2009). "A brief survey of software architecture concepts and service oriented architecture". 2009 2nd IEEE International Conference on Computer Science and Information Technology. pp. 34–38. [doi:10.1109/ICCSIT.2009.5235004](https://doi.org/10.1109%2FICCSIT.2009.5235004). [ISBN](https://en.wikipedia.org/wiki/International_Standard_Book_Number) [978-1-4244-4519-6](https://en.wikipedia.org/wiki/Special:BookSources/978-1-4244-4519-6). +[^15]: Tony Shan (2004). "Building a service-oriented e Banking platform". IEEE International Conference on Services Computing, 2004. (SCC 2004). Proceedings. 2004. pp. 237–244. [doi:10.1109/SCC.2004.1358011](https://doi.org/10.1109%2FSCC.2004.1358011). [ISBN](https://en.wikipedia.org/wiki/International_Standard_Book_Number) [978-0-7695-2225-8.2004](https://en.wikipedia.org/wiki/Special:BookSources/978-0-7695-2225-8) +[^16]: Duan, Yucong; Narendra, Nanjangud; Du, Wencai; Wang, Yongzhi; Zhou, Nianjun. "[Exploring Cloud Service Brokering from an Interface Perspective](http://ieeexplore.ieee.org/document/6928915/)". [IEEE](https://en.wikipedia.org/wiki/IEEE). +[^17]: Duan, Yucong. "[A Survey on Service Contract](http://ieeexplore.ieee.org/document/6299375/)". [IEEE](https://en.wikipedia.org/wiki/IEEE). +[^18]: Olaf Zimmermann, Cesare Pautasso, Gregor Hohpe, Bobby Woolf (2016). "[A Decade of Enterprise Integration Patterns](http://ieeexplore.ieee.org/document/7368007/)". IEEE Software. 33 (1): 13–19. [doi](https://en.wikipedia.org/wiki/Digital_object_identifier):[10.1109/MS.2016.11](https://doi.org/10.1109%2FMS.2016.11). +[^19]: Rotem-Gal-Oz, Arnon (2012). SOA Patterns. Manning Publications. [ISBN](https://en.wikipedia.org/wiki/International_Standard_Book_Number) [978-1933988269](https://en.wikipedia.org/wiki/Special:BookSources/978-1933988269). +[^20]: K. Julisch et al., [Compliance by Design – Bridging the Chasm between Auditors and IT Architects](http://soadecisions.org/download/ComplianceByDesign-AAM.pdf). Computers & Security, Elsevier. Volume 30, Issue 6-7, Sep.-Oct. 2011. +[^21]: Brandner, M., Craes, M., Oellermann, F., Zimmermann, O., Web Services-Oriented Architecture in Production in the Finance Industry, Informatik-Spektrum 02/2004, Springer-Verlag, 2004 +[^22]: "[www.ibm.com](http://www.ibm.com/support/knowledgecenter/en/SSEQTP_6.1.0/com.ibm.websphere.base.iseries.doc/info/iseries/ae/cwbs_soawbs.html)". Retrieved September 10, 2016. +[^23]: "[SOAP Version 1.2 の公開について (W3C 勧告)](http://www.w3.org/2003/06/soap12-pressrelease)" (in Japanese). W3.org. Retrieved August 13, 2012. +[^24]: Okishima, Haruhiru (2006). ". ["Case Study of System Architecture that use COBOL assets"](http://www.fujitsu.com/global/documents/about/resources/publications/fstj/archives/vol42-3/paper18.pdf)" (PDF). +[^25]: Enterprise SOA. Prentice Hall, 2005 +[^26]: Christopher Koch [A New Blueprint For The Enterprise](http://www.cio.com.au/index.php/id;1350140708), CIO Magazine, March 1, 2005 +[^27]: Elizabeth Millard (January 2005). "Building a Better Process". Computer User. Page 20. +[^28]: Brayan Zimmerli (November 11, 2009) [Business Benefits of SOA](https://web.archive.org/web/20101105063545/http://www.brayan.com/projects/BenefitsOfSOA/default.htm), University of Applied Science of Northwestern Switzerland, School of Business +[^29]: J[SR-000089 OSS Service Activation API Specification 1.0 Final Release](https://web.archive.org/web/20110726070810/https://cds.sun.com/is-bin/INTERSHOP.enfinity/WFS/CDS-CDS_Developer-Site/en_US/-/USD/ViewProductDetail-Start?ProductRef=7854-oss_service_activation-1.0-fr-spec-oth-JSpec%40CDS-CDS_Developer). sun.com +[^30]: Joe McKendrick. "[Bray: SOA too complex; 'just vendor BS'](http://www.zdnet.com/blog/service-oriented/bray-soa-too-complex-just-vendor-bs/597)". ZDNet. +[^31]: Jimmy Zhang (February 20, 2008) "[Index XML Documents with VTD-XML](http://xml.sys-con.com/read/453082.htm)". XML Journal. +[^32]: Jimmy Zhang (August 5, 2008) "[i-Technology Viewpoint: The Performance Woe of Binary XML](http://soa.sys-con.com/read/250512.htm)". Microservices Journal. +[^33]: Jimmy Zhang (January 9, 2008) "[Manipulate XML Content the Ximple Way](http://www.devx.com/xml/Article/36379)". devx.com. +[^34]: "[The Reason SOA Isn't Delivering Sustainable Software](http://www.jpmorgenthal.com/morgenthal/?p=31)". jpmorgenthal.com. June 19, 2009. Retrieved June 27, 2009. +[^35]: "[SOA services still too constrained by applications they represent](http://www.zdnet.com/article/soa-services-still-too-constrained-by-applications-they-represent/)". zdnet.com. June 27, 2009. Retrieved June 27, 2009. +[^36]: "[Governance Layer](https://www.opengroup.org/soa/source-book/soa_refarch/governance.htm)". www.opengroup.org. Retrieved September 22, 2016. +[^37]: "[How to Efficiently Test Service Oriented Architecture | WSO2 Inc](http://wso2.com/library/articles/2014/04/how-to-efficiently-test-service-oriented-architecture/)". wso2.com. Retrieved September 22, 2016. +[^38]: http://drops.dagstuhl.de/opus/volltexte/2009/2046/pdf/09021_abstracts_collection.2046.pdf +[^39]: "[What Is Web 2.0](http://www.oreillynet.com/pub/a/oreilly/tim/news/2005/09/30/what-is-web-20.html)". Tim O'Reilly. September 30, 2005. Retrieved June 10, 2008. +[^40]: Christoph Schroth & Till Janner (2007). "[Web 2.0 and SOA: Converging Concepts Enabling the Internet of Services](http://www.alexandria.unisg.ch/Publikationen/37270)". IT Professional 9 (2007), Nr. 3, pp. 36–41, IEEE Computer Society. Retrieved February 23, 2008. +[^41]: Dragoni, Nicola; Giallorenzo, Saverio; Alberto Lluch Lafuente; Mazzara, Manuel; Montesi, Fabrizio; Mustafin, Ruslan; Safina, Larisa (2016). "Microservices: yesterday, today, and tomorrow". [arXiv](https://en.wikipedia.org/wiki/ArXiv):[1606.04036v1](https://arxiv.org/abs/1606.04036v1) [cs.SE](https://arxiv.org/archive/cs.SE). +[^42]: James Lewis and Martin Fowler. "[Microservices](http://martinfowler.com/articles/microservices.html)". +[^43]: Balalaie, A.; Heydarnoori, A.; Jamshidi, P. (May 1, 2016). "[Microservices Architecture Enables DevOps: Migration to a Cloud-Native Architecture](http://ieeexplore.ieee.org/lpdocs/epic03/wrapper.htm?arnumber=7436659)". IEEE Software. 33 (3): 42–52. [doi](https://en.wikipedia.org/wiki/Digital_object_identifier):[10.1109/MS.2016.64](https://doi.org/10.1109%2FMS.2016.64). [hdl](https://en.wikipedia.org/wiki/Handle_System):[10044/1/40557](https://hdl.handle.net/10044%2F1%2F40557). [ISSN](https://en.wikipedia.org/wiki/International_Standard_Serial_Number) [0740-7459](https://www.worldcat.org/issn/0740-7459). diff --git a/source/_posts/springboot1.md b/source/_posts/springboot1.md new file mode 100644 index 000000000..29920fa5a --- /dev/null +++ b/source/_posts/springboot1.md @@ -0,0 +1,148 @@ +--- +title: SpringBoot(一) 初识 +date: 2019-06-23 09:10:11 +categories: SpringBoot +tag: [SpringBoot] +--- + +![springboot](https://res.cloudinary.com/incoder/image/upload/v1561900597/blog/springboot.jpg) + +从本篇文章开始,记录学习 SpringBoot框架在实践,源码方面的知识,本节是第一篇,因此不涉及相关复杂知识的学习。众所周知,随着微服务的广泛流行,Spring 系列的 SpringBoot 和 SpringCloud 的应用也更受欢迎,那么请跟随我的脚本来一步步解开 SpringBoot 她神秘的面纱 + + + +熟悉后端服务开发的小伙伴,在使用 SpringBoot 时一定会有这样的感受,咦,以前繁琐的配置,现在都不用再去配置一大堆东西了,以前跑起来一个 demo,感觉真是千辛万苦,错一步就 game over,以前服务基本都是已 war 包的形式运行在 Tomcat 中,而现在,你基本不需要手动写太多的代码,一个应用服务就可以运行起来,其次现在应用基本已 jar 包方式直接运行,虽然本质还是运行在 Tomcat 中,但现在 jar 包中已经有了服务运行的基础环境,可以直接使用 jar 相关的运行命令就可以运行起服务。好了,废话了这么多,先看看我们如何运行起一个 DEMO 应用。 + +## 环境及版本 +* SpringBoot Version:2.1.6.RELEASE +* System:macOS Mojave +* JDK Version:1.8 +* Gradle:5.4.1 +* IDE:IntelliJ IDEA + +>本系列应用使用如上环境,其次应用包管理,小伙伴可以选择自己熟悉的 Maven 进行管理,而这里都使用 Gradle 进行管理 + +## Demo + +### [Spring Initializr](https://start.spring.io) + +为了让开发者快速上手,官方提供了一建生成 SpringBoot 项目,你按需选择你需要的依赖即可。操作步骤如下截图 +![spring-initializ](https://res.cloudinary.com/incoder/image/upload/v1561906733/blog/spring-initializr.png) + +### IDEA Init + + +## Spring 运行 + +### 命令 + +#### Mac or Linux + +```bash +# 项目路径下(spring-start) +gradle bootRun +``` + +#### Windows + +```bash +# 项目路径下(spring-start) +./gradle bootRun +``` + +### 运行说明 + +![spring-running-logo](https://res.cloudinary.com/incoder/image/upload/v1562167001/blog/spring-running-logo.png) + + +## Spring 打包 + +### jar 分析 + +![springboot-deploy-jar-unzip](https://res.cloudinary.com/incoder/image/upload/v1561259381/blog/springboot-deploy-jar-unzip.png) + +目录说明 +``` +project/ +├── BOOT-INF/ +│ ├── classes # 当前项目结果文件放置在 classes 路径下 +│ │ │ └── application.properties # 项目中配置文件 +│ │ ├── org/ # 项目中 java 路径下,编译成 class 文件路径 +│ │ ├── static/ # 项目中 resources 路径下的静态文件夹 +│ │ └── templates/ # 项目中 resources 路径下的模板文件夹 +│ └── lib/ # 项目所依赖的第三方 jar(Tomcat,SpringBoot 等) +├── META-INF/ +│ └── MANIFEST.MF # 清单文件,用于描述可执行 jar 的一些基本信息 +└── org/springframework/boot/loader/ # jar 包启动相关的引导 + ├── archive/ + ├── data + ├── ExectableArchiveLauncher.class + ├── jar/ + ├── JarLauncher.class + ├── LaunchedURLClassLoader.class + ├── LaunchedURLClassLoader$UseFastConnectionExceptionsEnumeration.class + ├── Launcher.class + ├── MainMethodRunner.class + ├── PropertiesLauncher.class + ├── PropertiesLauncher$1.class + ├── PropertiesLauncher$ArchiveEntryFilter.class + ├── PropertiesLauncher$PrefixMatchingArchiveFilter.class + ├── PropertiesLauncher$ArchiveEntryFilter.class + ├── util/ + └── WarLauncher.class +``` + +#### MANIFEST.MF + +```jar +Manifest-Version: 1.0 # 清单版本号 +Start-Class: org.incoder.start.SpringbootStartApplication # 项目 main 方法所在的类 +Spring-Boot-Classes: BOOT-INF/classes/ # 项目相关代码在打包后 jar 中的路径 +Spring-Boot-Lib: BOOT-INF/lib/ # 项目中所依赖的第三方 jar 在打包后 jar 中的路径 +Spring-Boot-Version: 2.1.6.RELEASE # 项目 SpringBoot 版本 +Main-Class: org.springframework.boot.loader.JarLauncher # 当前 jar 文件的执行入口类(main 方法所在的类) +回车换行(在清单文件中,必须有,否则会出错) +``` + +#### org/springframework/……目录 +项目中引入的第三方 jar 中并不包含`org/springframework/boot/loader`内容,那这个目录是从哪里来的呢? + +寻找最终发现是项目中我们的`build.gradle`文件中,引入的`org.springframework.boot:spring-boot-gradle-plugin`依赖,而这个依赖位于`classpath`下,说明引入的这个插件 **仅仅** 是在项目构建时才起作用,当项目进行打包后,并不会把插件包打入到项目的依赖库中,也就是`BOOT-INF/lib/`路径下 + +如何去研究在`org/springframework/boot/loader`下的源码内容呢? +最好的方式是在项目的依赖中导入`org.springframework.boot:spring-boot-loader`依赖 + +>原则上,在项目开发过程中是不需要引入`org.springframework.boot:spring-boot-loader`依赖,这里只是为了方便阅读源码进行学习 + +## Spring 其他 + +### 配置文件格式 + +* [properties](https://en.wikipedia.org/wiki/.properties) +* **推荐** [yml](https://en.wikipedia.org/wiki/YAML) + +### 常用命令 + +#### gradle tasks + +表示获取当前工程可用的 gradle tasks命令 + +##### Application tasks + +* bootRun:Runs this project as a Spring Boot application.(以 SpringBoot 的形式运行当前项目) + +##### Build tasks + +* bootJar:Assembles an executable jar archive containing the main classes and their dependencies.(装配一个可执行的 jar(自包含的 jar 包,不依赖其他容器) 归档,这个归档 jar 中包含了所需的依赖以及主类等) + +##### Run jar + +```bash +java -jar jar-name.jar +``` + +##### Other +``` +# 解压 jar 到当前 start 目录下 +unzip start-0.0.1-SNAPSHOT.jar -d ./start +``` \ No newline at end of file diff --git a/source/_posts/springboot2.md b/source/_posts/springboot2.md new file mode 100644 index 000000000..2875738b1 --- /dev/null +++ b/source/_posts/springboot2.md @@ -0,0 +1,381 @@ +--- +title: SpringBoot(二) 启动分析JarLauncher +date: 2019-07-05 11:10:11 +categories: SpringBoot +tag: [SpringBoot] +--- + +我们在开发过程中,使用 {% label info@java -jar you-jar-name.jar %} 命令来启动应用,它是如何启动?以及它如何去寻找`.class`文件并执行这些文件?本节就带着这两个问题,让我们一层层解开 SpringBoot 项目的 jar 启动过程,废话不多说,跟着我的脚步一起去探索`spring-boot-load`的秘密。 + +在[SpringBoot(一) 初识]()已经解释了为什么在编译后的 jar 中根目录存在`org/springframework/boot/loader`内容,以及为了方便学习研究,我们需要在项目的依赖中导入`org.springframework.boot:spring-boot-loader`依赖。同时我们在解压的`you-jar-name.jar`文件中,查看对应的清单文件 {% label primary@MANIFEST.MF %} 内容,其中明确指出了应用的入口`org.springframework.boot.loader.JarLauncher `因此我们就从`JarLauncher`开始一步步深入 +![spring-boot-loader-jarlauncher](https://res.cloudinary.com/incoder/image/upload/v1562394534/blog/spring-boot-loader-jarlauncher.png) + +## 结构 + +先用Diagrams来表述`JarLauncher`类之间的结构及方法等相关信息 +![jarlauncher](https://res.cloudinary.com/incoder/image/upload/v1562399159/blog/jarlauncher.png) + +从Diagrams可知 +* 继承关系:JarLauncher extends ExecutableArchiveLauncher extends Launcher +* 启动入口:JarLauncher {% label success@main %} 方法 +* + +>关于图上图标含义,这里就不再赘述,烦请移步[IntelliJ IDEA Icon reference](https://www.jetbrains.com/help/idea/symbols.html) + +## 流程分析 + +### jar规范 +对于 Java 标准的 jar 文件来说,规定在一个 jar 文件中,我们必须要将指定 {% label success@main.class %} 的类直接放置在文件的顶层目录中(也就是说,它不予许被嵌套),否则将无法加载,对于 BOOT-INF/class/路径下的 class 因为不在顶层目录,因此也是无法直接进行加载, 而对于BOOT-INF/lib/ 路径的 jar 属于嵌套的(Fatjar),也是不能直接加载,因此Spring要想启动加载,就需要自定义实现自己的类加载器去加载。 + +>关于 jar **官方标准**说明请移步 +>* [JAR File Specification](https://docs.oracle.com/javase/8/docs/technotes/guides/jar/jar.html#Signed_JAR_File) +>* [JAR (file format)](https://en.wikipedia.org/wiki/JAR_(file_format)) + +### 源码分析 + +#### main 方法 + +根据清单文件{% label primary@MANIFEST.MF %}中 `Main-Class` 的描述,我们知道入口类就是`JarLauncher`;先看下这个类的 javadoc 介绍 +```java +/** + * {@link Launcher} for JAR based archives. This launcher assumes that dependency jars are + * included inside a {@code /BOOT-INF/lib} directory and that application classes are + * included inside a {@code /BOOT-INF/classes} directory. + * + * 用于基于JAR的归档。这个启动程序假设依赖jar包含在{@code /BOOT-INF/lib}目录中, + * 应用程序类包含在{@code /BOOT-INF/classes}目录中 + * + * @author Phillip Webb + * @author Andy Wilkinson + */ +``` + +紧接着,要进行源码分析,那肯定是找到入口,一步步深入,那么对于`JarLauncher`就是它的 {% label success@main %} 方法了 + +```java +public static void main(String[] args) throws Exception { + // launch 方法是调用父类 Launcher 的 launch 方法 + new JarLauncher().launch(args); +} +``` + +那我们去看一看`Launcher` 的 {% label success@launch %} 方法 +```java +/** + * Launch the application. This method is the initial entry point that should be + * called by a subclass {@code public static void main(String[] args)} method. + * + * 启动一个应用,这个方法应该被初始的入口点,这个入口点应该是一个Launcher的子类的 + * public static void main(String[] args)这样的方法调用 + * + * @param args the incoming arguments + * @throws Exception if the application fails to launch + */ +protected void launch(String[] args) throws Exception { + // 1. 注册一些 URL的属性 + JarFile.registerUrlProtocolHandler(); + // 2. 创建类加载器(LaunchedURLClassLoader),加载得到集合要么是BOOT-INF/classes/ + // 或者BOOT-INF/lib/的目录或者是他们下边的class文件或者jar依赖文件 + ClassLoader classLoader = createClassLoader(getClassPathArchives()); + // 3. 启动给定归档文件和完全配置的类加载器的应用程序 + launch(args, getMainClass(), classLoader); +} +``` +#### getClassPathArchives 方法 +`launch`方法的第一步的相关内容比较简单,这里不做过多说明,主要后面两步,我们先看第二步,创建一个类加载器(ClassLoader),其中`getClassPathArchives()`方法是一个抽象方法,具体的实现有(“ExecutableArchiveLauncher”和“PropertiesLauncher”,因为我们研究的`JarLauncher`是继承`ExecutableArchiveLauncher`,因此我们这里看`ExecutableArchiveLauncher`类中`getClassPathArchives()`方法的实现)我们要看看这个方法中它做了什么 +```java +@Override +protected List getClassPathArchives() throws Exception { + // 1. 得到一个Archive的集合(BOOT-INF/classes/)和(BOOT-INF/lib/)目录所有的文件 + // a. this.archive 中当前类的 archive 是怎么来的? + // b. getNestedArachives()是如何获得一个嵌套的 jar 归档? + // c. this::isNestedArchive 这个方法引用它做了什么? + List archives = new ArrayList<>(this.archive.getNestedArchives(this::isNestedArchive)); + // 一个事后处理的方法 + postProcessClassPathArchives(archives); + return archives; +} +``` +`this.archive`位于当前类(`ExecutableArchiveLauncher`)的构造方法中 +```java +public ExecutableArchiveLauncher() { + try { + // 调用 createArchive() 方法得到Archive + this.archive = createArchive(); + } + catch (Exception ex) { + throw new IllegalStateException(ex); + } +} + +///////////////////////////////////////////////////////////// +// 紧接着我们查看 createArchive() 方法都做了什么 // +///////////////////////////////////////////////////////////// + +// Launcher.class 中的 createArchive()方法 +// 得到我们运行文件的Archive相关的信息 +protected final Archive createArchive() throws Exception { + ProtectionDomain protectionDomain = getClass().getProtectionDomain(); + CodeSource codeSource = protectionDomain.getCodeSource(); + URI location = (codeSource != null) ? codeSource.getLocation().toURI() : null; + String path = (location != null) ? location.getSchemeSpecificPart() : null; + if (path == null) { + throw new IllegalStateException("Unable to determine code source archive"); + } + // 返回我们要执行的jar文件的绝对路径(java -jar xxx.jar中 xxx.jar的绝对路径) + File root = new File(path); + if (!root.exists()) { + throw new IllegalStateException("Unable to determine code source archive from " + root); + } + return (root.isDirectory() ? new ExplodedArchive(root) : new JarFileArchive(root)); +} +``` +对于`getNestedArachives()`方法,它是Archive的接口 +```java +/** + * Returns nested {@link Archive}s for entries that match the specified filter. + * + * 返回与过滤器相匹配的嵌套归档文件 + * + * @param filter the filter used to limit entries + * @return nested archives + * @throws IOException if nested archives cannot be read + */ +List getNestedArchives(EntryFilter filter) throws IOException; + +///////////////////////////////////////////////////////////// +// 紧接着我们查看 getNestedArchives() 的实现 // +///////////////////////////////////////////////////////////// + +// 这里的参数 EntryFilter类型中有一个 matches(Entry entry) 方法, +// 这也是this::isNestedArchive所对应的实际方法 +@Override +public List getNestedArchives(EntryFilter filter) throws IOException { + List nestedArchives = new ArrayList<>(); + for (Entry entry : this) { + if (filter.matches(entry)) { + nestedArchives.add(getNestedArchive(entry)); + } + } + return Collections.unmodifiableList(nestedArchives); +} +``` + +而{% label primary@this::isNestedArchive %}方法引用,我们查看`isNestedArchive`抽象方法 +```java +/** + * Determine if the specified {@link JarEntry} is a nested item that should be added + * to the classpath. The method is called once for each entry. + * + * 确定指定的{@link JarEntry}是否是应该添加到类路径的嵌套项。对每个条目调用该方法一次 + * + * @param entry the jar entry + * @return {@code true} if the entry is a nested item (jar or folder) + */ +protected abstract boolean isNestedArchive(Archive.Entry entry); + +///////////////////////////////////////////////////////////// +// 紧接着我们查看 isNestedArchive() 实现 // +///////////////////////////////////////////////////////////// + +// JarLauncher.class 中的 isNestedArchive()方法 +@Override +protected boolean isNestedArchive(Archive.Entry entry) { + // 如果是目录判断是不是BOOT-INF/classes/目录 + if (entry.isDirectory()) { + return entry.getName().equals(BOOT_INF_CLASSES); + } + // 如果是文件判断文件的前缀是不是BOOT-INF/lib/开头 + return entry.getName().startsWith(BOOT_INF_LIB); +} +``` + +#### createClassLoader 方法 +把符合条件的 `Archives` 作为参数传入到 `createClassLoader()` 方法,创建一个类加载器,我们跟进去,查看`createClassLoader()` 方法 +```java +/** + * Create a classloader for the specified archives. + * + * 创建一个所指定归档文件的类加载器 + * + * @param archives the archives + * @return the classloader + * @throws Exception if the classloader cannot be created + */ +protected ClassLoader createClassLoader(List archives) throws Exception { + List urls = new ArrayList<>(archives.size()); + // 遍历传进来的 archives,将每一个 Archive 的 URL(归档文件在磁盘上的完整路径)添加到 urls 集合中 + for (Archive archive : archives) { + urls.add(archive.getUrl()); + } + // + return createClassLoader(urls.toArray(new URL[0])); +} + + +/** + * Create a classloader for the specified URLs. + * + * 创建指定 URL 的类加载器 + * + * @param urls the URLs + * @return the classloader + * @throws Exception if the classloader cannot be created + */ +protected ClassLoader createClassLoader(URL[] urls) throws Exception { + // 这里的 LaunchedURLClassLoader 是 SpringBoot loader 给我们提供的一个全新的类加载器 + // 参数 urls 是 class 文件或者资源配置文件的路径地址 + // 参数 getClass().getClassLoader() 是应用类加载器 + return new LaunchedURLClassLoader(urls, getClass().getClassLoader()); +} + + +/** + * Create a new {@link LaunchedURLClassLoader} instance. + * @param urls the URLs from which to load classes and resources + * @param parent the parent class loader for delegation + */ +public LaunchedURLClassLoader(URL[] urls, ClassLoader parent) { + super(urls, parent); +} +``` +super()方法是调用父类的方法,这样一层层跟进去,最终到了 JDK 的`ClassLoader`类,它也是所有类加载器的顶类 + +#### launch 方法 + +launch 方法的第二个参数,`getMainClass()`是一个抽象方法 +```java +/** + * Returns the main class that should be launched. + * @return the name of the main class + * @throws Exception if the main class cannot be obtained + */ +protected abstract String getMainClass() throws Exception; + +///////////////////////////////////////////////////////////// +// 紧接着我们查看 getMainClass() 实现 // +///////////////////////////////////////////////////////////// + +@Override +protected String getMainClass() throws Exception { + Manifest manifest = this.archive.getManifest(); + String mainClass = null; + if (manifest != null) { + // 获取到 Manifest 文件中属性为`Start-Class`对应的值,也就是当前项目工程启动的类的完整路径 + mainClass = manifest.getMainAttributes().getValue("Start-Class"); + } + if (mainClass == null) { + throw new IllegalStateException("No 'Start-Class' manifest entry specified in " + this); + } + return mainClass; +} + +``` +接着我们看launch 方法 +```java +/** + * Launch the application given the archive file and a fully configured classloader. + * + * 加载指定存档文件和完全配置的类加载器的应用程序 + * + * @param args the incoming arguments + * @param mainClass the main class to run + * @param classLoader the classloader + * @throws Exception if the launch fails + */ +protected void launch(String[] args, String mainClass, ClassLoader classLoader) throws Exception { + // 将应用的加载器换成了自定义的 LaunchedURLClassLoader 加载器,然后入到线程类加载器中 + // 最终在未来的某个地方,通过线程的上下文中取出类加载进行加载 + Thread.currentThread().setContextClassLoader(classLoader); + // 创建一个主方法运行器运行 + createMainMethodRunner(mainClass, args, classLoader).run(); +} + +/** + * Create the {@code MainMethodRunner} used to launch the application. + * + * 创建一个 MainMethodRunner 用于启动这个应用 + * + * @param mainClass the main class + * @param args the incoming arguments + * @param classLoader the classloader + * @return the main method runner + */ +protected MainMethodRunner createMainMethodRunner(String mainClass, String[] args, ClassLoader classLoader) { + return new MainMethodRunner(mainClass, args); +} +``` +返回一个`MainMethodRunner`对象,我们紧接着去看看这个对象, + +```java +/** + * Utility class that is used by {@link Launcher}s to call a main method. The class + * containing the main method is loaded using the thread context class loader. + * + * 被 Launcher 使用来调用 main 方法的辅助类,使用线程类加载来加载包含 main 方法的类 + * + * @author Phillip Webb + * @author Andy Wilkinson + */ +public class MainMethodRunner { + + private final String mainClassName; + + private final String[] args; + + /** + * Create a new {@link MainMethodRunner} instance. + * @param mainClass the main class + * @param args incoming arguments + */ + public MainMethodRunner(String mainClass, String[] args) { + this.mainClassName = mainClass; + this.args = (args != null) ? args.clone() : null; + } + + // 关键方法 + public void run() throws Exception { + // 获取到当前线程上下文的类加载器,实际就是 springboot 自定义的加载器(LaunchedURLClassLoader) + // 加载 this.mainClassName所对应的类,实际也就是清单文件中对应 Start-Class 属性的类 + Class mainClass = Thread.currentThread().getContextClassLoader().loadClass(this.mainClassName); + // 通过反射获取到 main 方法和参数 + Method mainMethod = mainClass.getDeclaredMethod("main", String[].class); + // 调用目标方法运行 + // invoke 方法参数一:是被调用方法所在对象,这里为 null,原因是我们所调用的目标方法是一个静态方法 + // invoke 方法参数二:被调用方法所接收的参数 + mainMethod.invoke(null, new Object[] { this.args }); + } + +} +``` + +到此为止,invoke 方法成功调用,那么我们项目中的main 方法就执行了,这时我们的所编写的 springboot 应用就正式的启动了。那么关于 springboot 的 loader加载过程已经分析完 + +## 总结 +![summary-jarlauncher](https://res.cloudinary.com/incoder/image/upload/v1562509446/blog/summary-jarlauncher.jpg) + +从 jar 规范的角度出发,我们深入分析了 springboot 项目启动的整个过程,这个过程到底对不对,我们口说无凭,需要实际检验我们分析 +首先,我们先思考,项目的应用启动入口是不是必须是 {% label success@main.class %} 方法,以及为什么要默认这么做? +其次,我们再思考,在编辑器中通过图标运行启动程序(或者是通过命令启动程序),比较将程序编译成 jar 包,然后通过命令启动程序他们之间是否相同,如果不同请解释为什么? + +### 问题一 +项目的应用启动入口可以不是 {% label success@main.class %} 方法,只是为什么会默认为 {% label success@main.class %} 方法,原因是在 springboot 的 MainMethodRunner类的 run 方法中,是固定写死的 `main`,为什么要这么写,答案是,我们可以在编辑器中已右键或其他图标启动的方式快速启动 springboot 项目(就像是在运行一个 Java 的 main 方法一样,不再向之前需要乱七八糟各种的配置)。 + +### 问题二 +答案是不相同,我们可以在项目的应用启动 {% label success@main.class %} 方法中,打印出加载类`System.out.println("项目启动加载类" + SpringbootStartApplication.class.getClassLoader());`,这样就可以检验我们的分析是否正确。分别使用两种不同的方式 +* 方式一:在编辑器中之间运行(右键,或者控制台输入命令`gradle bootRun`)或者使用 IDEA 上的运行应用运行按钮,结果如下 + ```java + 项目启动加载类sun.misc.Launcher$AppClassLoader@18b4aac2 + ``` +* 方式二:先编译成 jar 包,然后通过`java -jar build-name.jar`命令运行 + ```java + 项目启动加载类org.springframework.boot.loader.LaunchedURLClassLoader@439f5b3d + ``` + +通过打印出来的信息,可以验证我们的分析,方式一的运行,实际上是应用类加载器启动,而方式二是`spring-boot-loader`包中自定义的`LaunchedURLClassLoader`来启动项目 + +在实际的生产开发中,有时我们的分析需要进行验证(或者找问题),而此时服务又部署在生成环境或者非本机上,通常用的方式是看应用的日志输出,在日志中去定位问题,而有时我们需要断点的方式去找问题,那该如何去操作呢?对于这个问题,在实际开发中是有方法去处理,请看下篇[《SpringBoot(三) JDWP远程调用》](/springboot3.md) + +## 附录 +* [spring_boot_cloud(2)Spring_Boot打包文件结构深入分析源码讲解](https://1156721874.github.io/2019/06/07/spring_boot_and_cloud/spring_boot_cloud(2)Spring_Boot%E6%89%93%E5%8C%85%E6%96%87%E4%BB%B6%E7%BB%93%E6%9E%84%E6%B7%B1%E5%85%A5%E5%88%86%E6%9E%90%E6%BA%90%E7%A0%81%E8%AE%B2%E8%A7%A3/) +* [校验者•CeaserWang](https://1156721874.github.io) \ No newline at end of file diff --git a/source/_posts/springboot3.md b/source/_posts/springboot3.md new file mode 100644 index 000000000..921c01f80 --- /dev/null +++ b/source/_posts/springboot3.md @@ -0,0 +1,27 @@ +--- +title: SpringBoot(三) JDWP远程调用 +date: 2019-07-11 22:20:11 +categories: SpringBoot +tag: [SpringBoot] +--- + +在 SpringBoot 系列的第二篇文章中,已经详细分析了 SpringBoot 的启动过程,那么这篇文章,我们通过源码调试的方式来验证我们的分析,首先我们在控制台中输入 `java` 命令,可用输出 JDK 给我们提供了一些命令,其中`-agentlib`命令就是本篇文章所介绍,用于我们进行源码调试 + + + +![springboot-java-agentlib](https://res.cloudinary.com/incoder/image/upload/v1562858657/blog/springboot-java-agentlib.png) +我们继续查看`-agentlib`详细的命令说明,输入`java -agentlib:jdwp=help` 查看帮助文档 +![springboot-java-agentlib-help](https://res.cloudinary.com/incoder/image/upload/v1562859131/blog/springboot-java-agentlib-help.png) + +## 远程 + +```java +# 在远程机器上添加代理模式的方式启动 +# 使用 socket 协议来进行远程调试,当服务启动就开始在 6666 端口等待连接 +java -agentlib:jdwp=transport=dt_socket,server=y,address=6666 -jar start-1.0-SNAPSHOT.jar +``` + +## 本机 + +在本机上,我们直接使用 IDEA 编辑器,新建一个 Remote 应用服务,运行,创建步骤如下 9 步骤 +![springboot-java-remote](https://res.cloudinary.com/incoder/image/upload/v1562860397/blog/springboot-java-remote.png) \ No newline at end of file diff --git a/source/_posts/springboot4.md b/source/_posts/springboot4.md new file mode 100644 index 000000000..5f509cde2 --- /dev/null +++ b/source/_posts/springboot4.md @@ -0,0 +1,157 @@ +--- +title: SpringBoot(四)配置文件 +date: 2019-07-28 21:20:01 +categories: SpringBoot +tag: [SpringBoot] +--- + +关于 SpringBoot 配置文件,在之前的文章中已经提到[配置文件格式](https://incoder.org/2019/06/23/springboot1/#%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6%E6%A0%BC%E5%BC%8F),主要是两种格式的配置,这里并没有哪个配置写法一定优于另一种写法,对于配置文件名(application.yml 或者 application.properties),可以更改,为了减少不必要的麻烦,不建议修改,本篇文章以 yml 文件作为示例 + +## YAML + +[YAML](https://en.wikipedia.org/wiki/YAML)是JSON的超集,因此是用于指定分层配置数据的便捷格式。只要在类路径上有SnakeYAML库,SpringApplication类就会自动支持YAML作为属性的替代 。 + +### 语法规则 + +* 大小写敏感 +* 缩进(只能使用空格,空格数量不重要)表示层级 +* 注释用 `#` 符号 + +### 数据结构 + +1. 变量,不可再分的单个的值,如数字,字符串等。 + ```yml + name: Jerry + age: 20 + # ~表示NULL值 + email: ~ + # 多行字符串可以使用 | 保留换行符,也可以使用 > 折叠换行 + # + 表示保留文字块末尾的换行,- 表示删除字符串末尾的换行 + message: |- + hello world + # 双引号 + # 不会转义字符串里面的特殊字符,特殊字符会作为本身想表示的意思 + # 输出: + # A + # B + name1: "A n B" + # 单引号 + # 会转义特殊字符,特殊字符最终只是一个普通的字符串数据 + name2: A n B + + ``` +2. 数组,一组按次序排列的值 + ```yml + lang: + - java + - golang + - c + # 或者行内写法 + lang: [java, golang, c] + ``` +3. 对象,键值对的集合 + ```yml + person: + name: Jerry + age: 20 + # 或者行内写法 + person: {name: Jerry, age: 20} + ``` +4. 随机数 + ```yml + bootapp + secret: ${random.value} + number: ${random.int} + bignumber: ${random.long} + uuid: ${random.uuid} + ``` +5. 默认值,占位符获取之前配置的值,如果没有可以是用:指定默认值 + ```yml + bootapp.name: SpringBoot + description: ${bootapp.name}是一个spring应用程序 + ``` + +> `:` 号后面有空格,YAML 文件不能使用`@PropertySource`注解 + +## 配置 + +为了在配置自定义属性时,向配置 springboot 属性自动提示的功能,导入如下的包 +```xml + + + org.springframework.boot + spring-boot-configuration-processor + true + +``` +或者在 gradle 配置文件中添加依赖 +```gradle +implementation 'org.springframework.boot:spring-boot-configuration-processor' +``` +如果任然无法自动提示,请查看你的编辑器 IDEA 中是否开启了 `Annonation Processing` +![idea-annotation-processors](https://res.cloudinary.com/incoder/image/upload/v1566701581/blog/idea-annotation-processors.png) + +### 定义配置 + +#### 默认配置 + +[Common application properties](https://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html),是 SpringBoot 官方提供的一些默认配置属性说明,如果需要更改,只需要在 application.yml 文件中重写该属性即可,比如重新设置服务的启动端口为 9090 +```yml +server: + port: 9090 +``` + +#### 自定义配置 +首先在 application.yml 文件中根据上面所述的规则写法进行自定义字段的声明 +```yml +myConfig: + maps: + key: value +``` + +### 配置的使用 + +#### ConfigurationProperties + +`@ConfigurationProperties` 注解是 SpringBoot提供的一种使用属性的注入方法,不仅可以方便的把配置文件中属性值与所注解类绑定,还支持松散绑定,JSR-303 数据校验等功能 + +#### Value + +`@Value` 注解支持直接从配置文件中读取值,同时支持 SpEL表达式,但是不支持复杂数据类型和数据验证 + +#### PropertySource + +`@PropertySource` 注解加载自定义配置文件,由于 `@PropertySource` 指定的文件会优先加载,所以如果在 `applocation.properties` 文件中存在相同的属性配置,会覆盖前者中对应的值,且 `@PropertySource` 不支持 yml 文件注入 + +### 对比 + +| 注解 | @ConfigurationProperties | @Value | @PropertySource | +| ---------------------- | ------------------------ | ------------ | --------------- | +| 支持文件类型 | | | | +| 功能 | 批量注入配置文件属性 | 一个一个注入 | | +| 松散绑定(松散的语法) | 支持 | 不支持 | | +| SpEL | 不支持 | 支持 | | +| JSR-303 数据校验 | 支持 | 不支持 | | +| 复杂类型 | 支持 | 不支持 | | +| 应用场景 | | | | + +### 多环境配置 + +在实际的开发中,不同环境对应不同的配置,因此我们需要根据环境来配置不同的项目配置信息,SpringBoot 也是支持我们进行多环境的配置,通常情况下,我们命名为 `application-{profile}.properties/yml` ,其中 +`{profile}`表示不同的环境,比如:dev(开发),release(线上) 等 + +## 配置文件加载顺序 + +Spring Boot 启动会扫描以下位置的配置文件(application.properties 或 application.yml) 作为Spring Boot 的默认配置文件 + +* -file:./config/ +* -file:./ +* -classpath:/config/ +* -classpath:/ + +优先级从高到低,高优先级的配置会覆盖低优先级的配置 + +## 附录 +* [Spring Boot 配置文件](https://www.codingme.net/2019/01/springboot/springboot02-config/) +* [最全面的SpringBoot配置文件详解](https://zhuanlan.zhihu.com/p/57693064) +* [Properties and Configuration](https://docs.spring.io/spring-boot/docs/current/reference/html/howto-properties-and-configuration.html) \ No newline at end of file diff --git a/source/_posts/ssm.md b/source/_posts/ssm.md new file mode 100644 index 000000000..82e177d0e --- /dev/null +++ b/source/_posts/ssm.md @@ -0,0 +1,52 @@ +--- +title: 构建基础SSM框架 +date: 2018-05-20 09:39:10 +categories: Frame +tag: + - Spring + - SpringMVC + - Mybatis +--- + +## SSM结构 + +![SSM](https://res.cloudinary.com/incoder/image/upload/v1528039004/blog/ssm-structure.png) + +## SSM框架整合 +所谓的SSM即:Spring,SpringMVC,Mybatis +* [Spring](https://spring.io):一个轻量级的框架,有很多的拓展功能,最主要的我们一般项目使用的就是IOC和AOP。 +* [SpringMVC](https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html):Spring实现的一个Web层,相当于Struts的框架,但是比Struts更加灵活和强大. +* [Mybatis](http://www.mybatis.org/mybatis-3):一个持久层的框架,在使用上相比Hibernate更加灵活,可以控制SQL的编写,使用 XML或注解进行相关的配置. + +## 实战项目 +![ssm-practice](https://res.cloudinary.com/incoder/image/upload/v1528647074/blog/ssm-practice.png) + +项目功能: +1. Spring,SpringMVC,Mybatis框架整合 +2. Create Features +3. Retrieve Features +4. Update Features +5. Delete Features + +> 项目示例:[rc-ssm](https://github.com/RootCluster/rc-ssm/tree/example) + +## 其他 +### ajax之PUT请求 +客户端ajax方式发送PUT请求,Tomcat默认不会对请求进行处理; +Tomcat: +1. 将请求体中的数据,封装成一个map +2. request.getParameter("fileName")就会从这个map中取值 +3. springMVC封装POJO对象时,会把POJO中的属性的值,request.getParameter("fileName") + + 解决方式: + - 方式一:Ajax发送POST请求 + Ajax中type:"POST" + data: $("").serialize()+"&_method=PUT" + + - 方式二:web配置中添加HttpPutFormContentFilter过滤器 + 1.HttpPutFormContentFilter将请求体中的数据解析包装成一个map + 2.request被重新包装,request.getParameter()被重写,从自己封装的map中取出数据 + +### 获取属性的值 +prop修改和读取DOM原生属性的值 +attr修改和读取自定义属性的值 diff --git a/source/_posts/syncing-a-fork.md b/source/_posts/syncing-a-fork.md new file mode 100644 index 000000000..96c74eabd --- /dev/null +++ b/source/_posts/syncing-a-fork.md @@ -0,0 +1,103 @@ +--- +title: Git 同步 Fork 项目 +date: 2018-08-01 16:09:50 +categories: Git +tag: Syncing +--- + +[Github](https://www.github.com) 全球最大的同性交友网站,这里拥有最前沿的IT技术创新,拥有最流行的开源项目,等等...,总之这里是我的知识仓库,每天都会在上面寻找,学习知识 + +扯远了,本篇解决对于fork的项目,如何进行源项目的更新和同步问题 + +## 远程仓库 +1. 查看fork项目的远程仓库信息 + ```bash + git remote -v + origin https://github.com/YOUR_USERNAME/YOUR_FORK.git (fetch) + origin https://github.com/YOUR_USERNAME/YOUR_FORK.git (push) + ``` +2. 设置源项目仓库地址 + ```bash + git remote add upstream https://github.com/ORIGINAL_OWNER/ORIGINAL_REPOSITORY.git + ``` +3. 检查远程地址信息 + ```bash + git remote -v + origin https://github.com/YOUR_USERNAME/YOUR_FORK.git (fetch) + origin https://github.com/YOUR_USERNAME/YOUR_FORK.git (push) + upstream https://github.com/ORIGINAL_OWNER/ORIGINAL_REPOSITORY.git (fetch) + upstream https://github.com/ORIGINAL_OWNER/ORIGINAL_REPOSITORY.git (push) + ``` + +## 同步源仓库信息 + +1. 获取源仓库更新 + ```bash + git fetch upstream + remote: Counting objects: 75, done. + remote: Compressing objects: 100% (53/53), done. + remote: Total 62 (delta 27), reused 44 (delta 9) + Unpacking objects: 100% (62/62), done. + From https://github.com/ORIGINAL_OWNER/ORIGINAL_REPOSITORY + * [new branch] master -> upstream/master + ``` +2. 查看本地master分支 + ```bash + git checkout master + Switched to branch 'master' + ``` +3. 合并源仓库更新到本地master分支 + ```bash + git merge upstream/master + Updating a422352..5fdff0f + Fast-forward + README | 9 ------- + README.md | 7 ++++++ + 2 files changed, 7 insertions(+), 9 deletions(-) + delete mode 100644 README + create mode 100644 README.md + ``` + +## 同步源仓库branch +在git中master实质是一个特殊的branch,其它的branch的同步和master同步操作并不一样 + +```bash +# 查看项目的所有分支 +git branch -v +# 当前项目在master分支,origin/HEAD类似指针,表示项目默认分支是origin/master +# origin/dev,origin/i18n,origin/ivan/feat-custom-lang,origin/master这四个分支是fork项目目前拥有分支 +# upstream/dev,upstream/i18n,upstream/master表示源仓库项目所拥有的分支 +* master + remotes/origin/HEAD -> origin/master + remotes/origin/dev + remotes/origin/i18n + remotes/origin/ivan/feat-custom-lang + remotes/origin/master + remotes/upstream/dev + remotes/upstream/i18n + remotes/upstream/master + +# 切换到dev分支,同步源仓库dev分支到fork项目的dev分支 +git checkout -b dev upstream/dev +# 推送修改到fork项目dev分支 +git push origin dev +``` + +> 如果源仓库分支已被删除,那么可以在fork项目中删除源仓库已被删除的分支 +```bash +# 删除指定分支,并推送到远程仓库 +git push origin --delete branch_name +``` + +## 同步源仓库tag +```bash +# 获取源仓库的tag +git fetch upstream --tags +# 将新的的tag推送到fork项目 +git push --tags +``` + +## 附录 +* [同步你的 Fork 仓库](http://wiki.jikexueyuan.com/project/github-basics/fork-synced.html) +* [Configuring a remote for a fork](https://help.github.com/articles/configuring-a-remote-for-a-fork/) +* [Syncing a fork](https://help.github.com/articles/syncing-a-fork) \ No newline at end of file diff --git a/source/_posts/travel-zjj.md b/source/_posts/travel-zjj.md new file mode 100644 index 000000000..84cc46332 --- /dev/null +++ b/source/_posts/travel-zjj.md @@ -0,0 +1,119 @@ +--- +title: 行·张家界 +date: 2018-05-20 22:39:10 +categories: Travel +tag: 张家界 +--- + +{% note %} +* 时间:2018.06.16——2018.06.19 +* 地点:杭州——张家界 +* 目标:武陵源景区,天门山景区,大峡谷景区 +{% endnote %} + +听说张家界是人间仙境,鬼斧神工,嗯,今年端午就去一探究竟,慌慌张张,匆匆忙忙做一份旅行攻略,翻遍百度,爬烂谷歌,都没有找到匹配的攻略,哎,可能是我姿势不对?! + +张家界,张家界景区共分为四块:**张家界国家森林公园**,**杨家界自然保护区**,**天子山自然保护区**,**索溪峪自然保护区**四大景区,统称为武陵源风景名胜。 + +**最受欢迎** 的四大景区 +1. 武陵源景区(森林公园、金鞭溪、袁家界、杨家界、天子山、十里画廊等) +2. 天门山景区(亚州最长的索道、世界公路奇观、玻璃栈道等) +3. 大峡谷风景区(新开发的玻璃桥) +4. 凤凰古城 + +## 出行准备 + +1. 身份证件等相关证件 +2. 数码产品,雨具等 +3. 简单洗漱用品及换洗衣物 +4. 现金若干(不必太多) +5. 零食(必备:辣条) + +## 注意事项 + +由于是自由行的方式,因此提醒以下几点 +1. 到达张家界后,**拒绝** 和 **一切** 人搭话,避免一些麻烦,给行程带来不愉快 +2. 保管好自己的物品 +3. 张家界火车站出站后即可到汽车站乘坐大巴去武陵源景区,50分钟左右,10(森林公园)—12元(武陵源) +4. 大峡谷,天门山景区玻璃桥都需要提前5天在网上预定 + +## 出行路线 + +### 整体路线图 + +路线一: + * Day1(16):天门山景区 + * Day2.Day3(17-18):武陵源景区 + * Day4(19):大峡谷风景区 + +路线二(推荐) + * Day1.Day2(16-17):武陵源景区 + * Day2.Day3(18):大峡谷风景区 + * Day4(19):天门山景区 + +![扼要路线图](https://res.cloudinary.com/incoder/image/upload/v1527342618/blog/gitpages-zjj-road.png) + +{% note info %} +标记说明 +1. 张家界火车站 +2. 武陵源景区 +3. 大峡谷风景区 +4. 天门山景区 +{% endnote %} + +### 武陵源景区路线 + +门票:245 元+保险费3 元(3天内多次进出有效,含环保车票价) +开放时间:8:00-17:00 +Day1:森林公园-金鞭溪-杨家界 +Day2:大观台-天子山-十里画廊-索溪湖-武陵源门票站 +从森林公园进,从武陵源出,不走回头路。需要在 **丁香榕** 住一宿 +![武陵源景区](https://res.cloudinary.com/incoder/image/upload/v1527324112/blog/gitpages-zjj.gif) + +### 大峡谷风景区路线 + +门票:大峡谷(门票122元)+玻璃桥(门票138元) +开放时间:08:00-17:00 +Day3:玻璃桥-大峡谷 + +### 天门山景区路线 + +门票:258.00元(含往返索道、环保车)【旺季】 +开放时间:08:00~16:00 +路线Day4:玻璃栈道-天门山寺-天门洞(坐索道上山顶——走西线——再到天门翻水处坐自动扶梯到天门洞——爬999级阶梯——最终坐环保车返回至市区) +**自备中午餐** + +![天门山景区路线图](https://res.cloudinary.com/incoder/image/upload/v1528189150/blog/gitpages-zjj-tms.png.jpg) + +## 住宿 + +现在还未确定路线,个人推荐路线二;其次,16,17,18号需要住宿,要提前预定旅店 + +## 美食 + +### 胡师傅三下锅 + +三下锅,所谓的三下锅其实就是一种很方便的干锅,它是由三种主料做成的,炖着不放汤的火锅,三角坪附近的那个“胡师傅三下锅”味道不错,三下锅50元一份,分量很够吃的,包你吃够吃好!推荐的就是干煸肠子,干煸核桃肉和湘西腊肉三种混在一起炖,吃的同时还可以点一份酸萝卜,又脆又酸。真的是极品哦!(吃过后,发现并没有网上说的这么好吃,就是大烩菜,哈哈哈) + +等等。。。 + +## 汇总 + +![汇总](https://res.cloudinary.com/incoder/image/upload/v1527434516/blog/gitpages-zjj-summary.png) + +## 游记 + +废话不说,**武陵源景区**不用去,虽说是5A景区,除了山还是山,而且商业气息很重,很多地方都不能步行,需要坐缆车,电梯等交通工具,况且这次去森林公园那边在修路,说是在修高铁,建议直接去 **大峡谷风景区** 和 **天门山景区** + +### 武陵源景区 + +整个武陵 +![武陵源](https://res.cloudinary.com/incoder/image/upload/v1530682536/blog/travel/travel-zjj-wly.jpg) + +### 大峡谷风景区 + +![大峡谷](https://res.cloudinary.com/incoder/image/upload/v1530682775/blog/travel/travel-zjj-dxg.jpg) + +### 天门山景区 + + \ No newline at end of file diff --git a/source/_posts/treasure.md b/source/_posts/treasure.md new file mode 100644 index 000000000..96fd58eec --- /dev/null +++ b/source/_posts/treasure.md @@ -0,0 +1,157 @@ +--- +title: 藏经阁 +date: 2018-07-16 23:00:10 +categories: Resources +tag: DevTool +--- + +{% cq %}工欲善其事,必先利其器{% endcq %} + +记录汇总一些资源库 + +{% tabs Tags %} + + +**快速满足你所需各种资源汇总** +[Hi World](http://www.shandowsocks.info) +[创造师导航](http://chuangzaoshi.com) +[UI设计师导航](http://so.uigreat.com) +[Devdocs](https://devdocs.io) + + + +**DevTools** + +{% subtabs devtool %} + +**集齐宇宙IDE,可以召唤神龙::>_<::** +[Jetbrains 全家桶](http://www.jetbrains.com) +[Android Studio](https://developer.android.google.cn/studio) +[Xcode](https://developer.apple.com/xcode/ide) +[Eclipse](http://www.eclipse.org/downloads/eclipse-packages) +[Visual Studio Code](https://code.visualstudio.com) +[Sublime](http://www.sublimetext.com) +[PostMan](https://www.getpostman.com/apps) +[Xshell Xftp](http://www.netsarang.com/products/xsh_overview.html) + + + +**必备的一些辅助插件,让你效率翻倍** +[Alibaba Java Coding Guidelines](https://github.com/alibaba/p3c) +[Android ButterKnife Zelezny](https://github.com/avast/android-butterknife-zelezny) +[Android Material Design Icon Generator](https://github.com/konifar/android-material-design-icon-generator-plugin) +[Android Parcelable code generator](https://github.com/mcharmas/android-parcelable-intellij-plugin) +[Android Postfix Completion](https://plugins.jetbrains.com/plugin/7775-android-postfix-completion) +[Android Resource Usage Count](https://github.com/niorgai/Android-Resource-Usage-Count) +[Android Studio Prettify](https://github.com/Haehnchen/idea-android-studio-plugin) +[ADB Idea](http://www.developerphil.com/renaming-your-gradle-build-files) +[EventBus3 Intellij Plugin](https://plugins.jetbrains.com/plugin/8603-eventbus3-intellij-plugin) +[GrepConsole](https://github.com/krasa/GrepConsole) +[GsonFormat](https://github.com/zzz40500/GsonFormat) +[Jetbrains Plugins](https://plugins.jetbrains.com/) +[Jrebel](https://zeroturnaround.com/software/jrebel) +[ignore](http://ignore.hsz.mobi) +[LayoutFormatter](https://github.com/drakeet/LayoutFormatter) +[Markdown Navigator](https://github.com/vsch/idea-multimarkdown) +[PlantUML integration](https://github.com/esteinberg/plantuml4idea) +[SQLScout](https://plugins.jetbrains.com/plugin/8322-sqlscout-sqlite-support-) +[Translation](http://yiiguxing.github.io/TranslationPlugin) + + + +**常用的代码托管平台,设备可以坏,代码不能丢** +[Github](https://www.github.com) +[Gitlab](https://www.gitlab.com) +[Gitee](https://www.gitee.com) +[Coding](https://coding.net) + + +{% endsubtabs %} + + + +**开发者常用的官方网站** + +{% subtabs website %} + +**一线大厂开发者网站** +[Google Developer](https://developers.google.com) +[Apple Developer](https://developer.apple.com) +[Microsoft Developer](https://developer.microsoft.com) +[Facebook Developer](https://developers.facebook.com) +[Twitter Developer](https://developer.twitter.com) +[Github Developer](https://developers.github.com) +~~[Baidu Developer](https://developer.baidu.com)~~ +[Alibaba Developer](https://dev.aliyun.com) +[Tencent Developer](http://open.qq.com) + + + +**手机厂商** +[Android Developer](https://developer.android.com) +[iOS Developer](https://developer.apple.com/ios) +[Samsung Developer](https://developer.samsung.com) +[Huawei Developer](http://developer.huawei.com/cn) +[XiaoMi Developer](https://dev.mi.com) +[HTC Developer](https://www.htcdev.com/) +[Flyme Developer](https://open.flyme.cn/) +[Oppo Developer](https://open.oppomobile.com) +[Vivo Developer](https://dev.vivo.com.cn) +[Smartisan Developer](http://dev.smartisan.com) +[360 Developer](http://dev.360.cn) + + + +**应用市场** +[Google Play](https://play.google.com) +[App Store](https://play.google.com) +[XiaoMi 应用市场](http://app.mi.com) +[Huawei 应用市场](http://developer.huawei.com/consumer/cn/devunion/ui/server/appMarket.html) +[360 应用市场](http://zhushou.360.cn) +[酷安市场](https://www.coolapk.com) +[应用宝](http://sj.qq.com) + + + +**小程序** +[PWA](https://developers.google.cn/web/progressive-web-apps) +[微信小程序](https://mp.weixin.qq.com/cgi-bin/wx) +[支付宝小程序](https://docs.alipay.com/mini/developer/getting-started) +[快应用](https://www.quickapp.cn) + + + +**要折腾,来呀~** +[LineageOS](https://lineageos.org) +[XDA](https://forum.xda-developers.com) +[Mokee](https://www.mokeedev.com) +[MoDaCo](https://www.modaco.com) +[机锋](http://bbs.gfan.com/forum.php) +[智友](http://bbs.zhiyoo.com) +[MiUi](http://rom.xiaomi.cn) +[0pengApps](https://opengapps.org) + + +{% endsubtabs %} + + + +**cloud service** +[Google Cloud](https://console.cloud.google.com) +[Microsoft Azure](https://azure.microsoft.com) +[Amazon Web Services](https://aws.amazon.com) +[Aliyun](https://www.aliyun.com) +[Tencent Cloud](https://cloud.tencent.com) +[DiDi Cloud](https://www.didiyun.com) +[MT Cloud](https://www.mtyun.com) +[NetEase Cloud](https://www.163yun.com) + + + +**常用镜像** +[Tsinghua](https://mirrors.tuna.tsinghua.edu.cn) +[Gradle](http://services.gradle.org/distributions) +[Firfox](https://download-installer.cdn.mozilla.net/pub/firefox/releases) + + +{% endtabs %} \ No newline at end of file diff --git a/source/_posts/windows-devtool.md b/source/_posts/windows-devtool.md new file mode 100644 index 000000000..5d910b6af --- /dev/null +++ b/source/_posts/windows-devtool.md @@ -0,0 +1,93 @@ +--- +title: Windows 之 常用应用安装 +date: 2019-09-25 21:08:10 +categories: Windows +tag: DevTool +--- + +这是一篇在Windows系统下,持续更新常用开发软件安装汇总,当然一些简单得安装就在这里记录,不废话了 + +## JDK + +[官方下载地址](https://www.oracle.com/technetwork/java/javase/downloads/index.html),选择需要的版本下载安装包 + +安装完成,设置环境变量,右击`我的电脑`-->`属性`-->`高级系统设置`-->`高级`-->`环境变量` + + + +1. 在系统变量里新建 **`JAVA_HOME`** 变量,变量值为你的JDK的安装路径,比如:C:\Program Files\Java\jdk1.8.0_60 +2. 在系统变量里新建 **`CLASSPATH`** 变量 + ```bash + .;%JAVA_HOME%\lib;%JAVA_HOME%\lib\tools.jar + ``` +3. 找到 **`path`** 变量(已存在不用新建)添加变量值 + ```bash + %JAVA_HOME%\bin;%JAVA_HOME%\jre\bin + ``` +4. 保存修改,并启动 CMD 进行验证,输出安装的 Java 版本表示安装成功 + ```bash + java -version + ``` +>变量值之间用 **`;`** 隔开。注意原来Path的变量值末尾有没有 **`;`** 号,如果没有,先输入 **`;`** 号再输入 + +## MySQL + +* [官方下载地址](https://dev.mysql.com/downloads/) +* 下载`MySQL Community Server`或者`MySQL Installer for Windows`都可以,这里我下载的是`MySQL Community Server` + ![](https://res.cloudinary.com/incoder/image/upload/v1569640711/blog/windows-mysql-download.png) + +安装步骤请看截图所示 +![windows-mysql-install](https://res.cloudinary.com/incoder/image/upload/v1569640478/blog/windows-mysql-install.png) + +## Tomcat + +[官方下载地址](http://tomcat.apache.org/),选择需要的版本下载 + +### 安装 + +Tomcat 和 JDK 一样为了方便使用都需要配置环境变量,右击`我的电脑`-->`属性`-->`高级系统设置`-->`高级`-->`环境变量` +1. 在系统变量里新建 **`CATALINA_BASE`** 变量,变量值为你的Tomcat路径,比如:C:\Program Files\apache-tomcat-9.0.26 +2. 在系统变量里新建 **`CATALINA_HOME`** 变量,变量值为你的Tomcat路径,比如:C:\Program Files\apache-tomcat-9.0.26 +3. 找到 **`path`** 变量(已存在不用新建)添加变量值 + ```bash + ;%CATALINA_HOME%\lib;%CATALINA_HOME%\bin; + ``` +4. 保存修改,并启动 CMD 进行验证,输出安装的 Java 版本表示安装成功 + ```bash + statrup + ``` +>变量值之间用 **`;`** 隔开。注意原来Path的变量值末尾有没有 **`;`** 号,如果没有,先输入 **`;`** 号再输入 + +### 配置 + +#### 乱码 + +Tomcat 控制台中中文乱码,需要修改 Tomcat 配置文件 **`logging.properties`** 中的字符编码,将默认的 **UTF-8** 改为 **GBK**,文件路径`\conf` +![windows-tomcat-encode](https://res.cloudinary.com/incoder/image/upload/v1569644342/blog/windows-tomcat-encode.png) + +#### 缓存 + +文件路径`\conf`,修改 **`context.xml`** 文件,在 `` 标签中添加如下配置即可 +```xml + +``` + +## CMD + +### 常用命令 + +1. IP地址 + ```bash + ipconfig + ``` +2. 查看端口 + ```bash + # 查看端口号:netstat -ano | findstr 端口号 + netstat -ano | findstr 8080 + # 查看占用端口号进程 :tasklist | findstr 进程号 + tasklist | findstr 12836 + # kill 指定进程:taskkill -PID 进程号 -F + taskkill -PID 12836 -F + ``` + 截图如下: + ![windows-task](https://res.cloudinary.com/incoder/image/upload/v1569655372/blog/windows-task.png) diff --git a/source/_posts/zxing1.md b/source/_posts/zxing1.md new file mode 100644 index 000000000..58b232559 --- /dev/null +++ b/source/_posts/zxing1.md @@ -0,0 +1,96 @@ +--- +title: Zxing(一)二维码基础知识 +date: 2019-05-01 09:01:22 +categories: Android +tag: [Zxing] +--- + +移动端开发,一个避不开的老生常谈功能开发,二维码扫描识别(主要)及二维码生成(辅助),虽然已有现成的开源项目提供了功能,仅仅作为功能的开发集成和调试,其实远远不够,应该在完成功能开发的基础上去学习背后的技术点和原理,让我们更加完整的掌握该技术。废话不多说,本篇是 Zxing 相关技术的第一篇文章,本篇不会涉及到应用相关,仅仅是二维码基础知识的学习记录。 + +## QRcode +QRcode(全称:Quick Response Code,快速响应矩阵图码) +* 1994 年由[日本 DENSO WAVE](https://zh.wikipedia.org/wiki/%E9%9B%BB%E8%A3%9D)公司发明, +* QR 码使用`四种`标准化编码模式(数字,字母数字,字节(二进制)和汉字)来存储数据 +* QR 码可以存储更多信息,可在小空间内打印,可以从 360°任一方向读取,可以对变脏和破损的图码有一定的容错能力,并且可以有效处理各种数据,支持数据合并等 +* QR 码的种类:[QR 码(模型1,模型2)](https://www.qrcode.com/zh/codes/model12.html);[Micro QR 码](https://www.qrcode.com/zh/codes/microqr.html);[iQR 码](https://www.qrcode.com/zh/codes/iqr.html);[SQRC](https://www.qrcode.com/en/codes/sqrc.html);[Frame QR](https://www.qrcode.com/en/codes/frameqr.html) + +>QR 码(模型1,模型2): +>模型1:最早制作的 QR 码。最高版本为 14(73x73 码元),最多可以处理 1167 位数字 +>模型2:是模型1的改良版,最高版本为 40(177x177 码元),最多可以处理 7089 位数字,现在我们通常所说的 QR 码一般指模型2 +>Micro QR 码:该码只有 1 个定位图案,可以在更小的空间内打印,最高版本为 M4(17x17 码元),最多可以因 35 位数字 +>iQR码:可生成正方形或长方形,可以支持内外翻转,黑白反色,圆点图案(直接打标在部件上)。理论上的最高版本为 61(422x422 码元),最多大约可以处理 4万位数字 +>SQRC:安全快速响应代码(Secure Quick Response code,简写SQRC)是一种QR代码,在终结符之后包含“私有数据”段而不是指定的填充字节“ec 11”。必须使用加密密钥对此专用数据段进行解密。这可用于存储私人信息和管理公司的内部信息。 +>Frame QR:FrameQR是具有“画布区域”的QR码,可以灵活使用。在这个代码的中心是画布区域,其中可以灵活地安排图形,字母等,使得可以布置代码而不会丢失插图,照片等的设计 + +## 标准及发展 +* 1997年10月:AIM(自动识别和流动协会)国际 +* 1999年1月:JIS X 0510 +* 2000年6月 + * ISO / IEC 18004:2000信息技术 - 自动识别和数据捕获技术 - 条形码符号 - QR码(现已撤销) + * 定义QR码模型1和2符号 +* 2006年9月1日: + * ISO / IEC 18004:2006信息技术 - 自动识别和数据捕获技术 - QR码2005条形码符号规范(现已撤销) + * 定义QR码2005符号,QR码模型2的扩展。不指定如何读取QR码模型1符号,或要求符合性。 +* 2015年2月1日: + * ISO / IEC 18004:2015信息 - 自动识别和数据捕获技术 - QR码条形码符号规范 + * 将QR Code 2005符号重命名为QR Code,并对某些程序和次要更正添加说明 + +## 结构 +![qrcode-structure](https://res.cloudinary.com/incoder/image/upload/v1556733911/blog/QR_Code_Structure_Example.png) +>图片来自[维基百科](https://zh.wikipedia.org/wiki/QR%E7%A2%BC),Version7 + +如图所示,QR码由 5 部分组成 +1. 版本信息:记录具体的版本信息(仅存在 Version7 以上) + * version1 是 21x21 的矩阵 + * 最高 version40 是 177x177 的矩阵 + * 计算公式:(V-1)*4+21,V 代表版本号 +2. 格式信息:记录使用的`掩码`和`纠错等级` +3. 数据及容错密钥 +4. 数据需求模块 +5. 静态区域 + +### IEC 18004 +![qr-iec-18004](https://res.cloudinary.com/incoder/image/upload/v1556802979/blog/qr-iec-18004.png) +IEC 18004标准中给出了详细的说明 +* 位置探测图形、位置探测图形分隔符、定位图形:用于对二维码的定位,对每个QR码来说,位置都是固定存在的,只是大小规格会有所差异; +* 校正图形:规格确定,校正图形的数量和位置也就确定了; +* 格式信息:表示改二维码的纠错级别,分为L、M、Q、H; +* 版本信息:即二维码的规格,QR码符号共有40种规格的矩阵(一般为黑白色),从21x21(版本1),到177x177(版本40),每一版本符号比前一版本 每边增加4个模块。 +* 数据和纠错码字:实际保存的二维码信息,和纠错码字(用于修正二维码损坏带来的错误) + +### 掩码 +掩码的作用 +1. 为了对数据区域进行掩模以利于扫描仪识别,可以避免数据区域出现连续的空白或连续的黑色区, +2. 避免了数据区出现类似定位点样式的正方形出现。掩模图案在整个数据区域的网格内不断重复进行掩模计算(功能图形不进行掩模),数据区上对应掩模黑色模块的单元将会反转。 +3. 每个二维码上会有两组相同的格式信息出现,并且带有 BCH 纠错 + +> 在计算机科学中,掩码就是一个二进制串,通过和数据进行`异或运算`来变换数据。在 QR 码中,掩码也是通过异或运算来变换数据矩阵,所以 QR 码掩码就是预先定义好的矩阵 + +### 纠错等级 +相对而言,容错率愈高,QR 码图形面积愈大,所以一般折中使用 15% 容错能力 + +| 错误修正容量 | +| --- | --- | +| L 等级 | 7%的字码可被修正 | +| M 等级 | 15%的字码可被修正 | +| Q 等级 | 25%的字码可被修正 | +| H 等级 | 30%的字码可被修正 | + +### 编码 QR 码步骤 +1. 数据分析(data analysis):分析输入数据,根据数据决定要使用的 QR 码版本、容错等级和编码模式 +2. 编码数据(data encoding):根据选择的编码模式,将输入的字符串转变成比特流,插入模式标识码(mode indicator)和终止标识符(terminator),将比特流切分成 8 比特的字节,加入填充字节来满足标准的数据字码数要求 +3. 计算容错码(error correction coding):对步骤二产生的比特流计算容错码,附在比特流之后。高版本的编码方式可能需要将数据流切分成块再分别进行容错码计算 +4. 组织数据(structure final message):根据结构图把步骤三得到的有容错的数据切分,准备填充 +5. 填充(module placement in matrix):把数据和功能性图样根据标准填充到矩阵中 +6. 应用数据掩码(data masking):应用标准中的 8 个数据掩码来变换编码区域的数据,选择最优的掩码应用 +7. 填充格式和版本信息(format and version information):计算格式和版本信息填入矩阵,完成 QR 码 + +## 附录 +* [维基百科·QR码·中文](https://zh.wikipedia.org/wiki/QR%E7%A2%BC) +* [维基百科·QR码·英文·推荐](https://en.wikipedia.org/wiki/QR_code) +* [二维码(QR code)基本结构及生成原理](https://blog.csdn.net/u012611878/article/details/53167009) +* [QRcode](https://www.qrcode.com) +* [二维码的生成细节和原理](https://coolshell.cn/articles/10590.html) +* [为程序员写的Reed-Solomon码解释](https://www.jianshu.com/p/8208aad537bb) +* [ISO/IEC 18004:2015·PDF](https://coolshell.cn/articles/10590.html) +* [ISO/IEC 18004:2015·PDF](https://coolshell.cn/articles/10590.html) \ No newline at end of file diff --git a/source/_posts/zxing2.md b/source/_posts/zxing2.md new file mode 100644 index 000000000..5a04d8b93 --- /dev/null +++ b/source/_posts/zxing2.md @@ -0,0 +1,131 @@ +--- +title: Zxing(二)Android 模块应用源码探索 +date: 2019-05-02 22:41:10 +categories: Android +tag: [Zxing] +--- + +[ZXing(“Zebra Crossing”](https://github.com/zxing/zxing))用于Java,Android的条形码扫描库。虽然当前开源库仅处于维护模式,意味着更改是由贡献的补丁来驱动,只会考虑错误修复和次要的增强功能 + +本篇开启 [ZXing项目Android](https://github.com/zxing/zxing/tree/master/android) 模块的探索学习之路,那么首先我们要集成该模块到项目中 + +## 模块集成 +* 下载官方项目[Zxing](https://github.com/zxing/zxing) +* 使用 AS 创建一个新的 Project + +>编译环境 +* Android studio:3.4 +* gradle:5.1.1 +* SDK:28 +* JDK:1.8 + +演示项目[rc-android-zxing](https://github.com/RootCluster/rc-android-zxing) + +### 导入步骤 +* 导入 module + ![import_module](https://raw.githubusercontent.com/RootCluster/rc-android-zxing/zxing/images/import_module.png) +* 选择 module + ![select_import_module](https://github.com/RootCluster/rc-android-zxing/raw/zxing/images/select_import_module.png) +* 移除最小及目标版本设置 + ![remove_min_target_version](https://github.com/RootCluster/rc-android-zxing/raw/zxing/images/remove_min_target_version.png) +* 添加项目核心依赖 + ![import_dependencies](https://github.com/RootCluster/rc-android-zxing/raw/zxing/images/import_dependencies.png) +`com.google.zxing:android-core:3.3.0`:实质是[android-core](https://github.com/zxing/zxing/tree/master/android-core)模块 +`com.google.zxing:core:3.3.3`:实质是[core](https://github.com/zxing/zxing/tree/master/core)模块 +* 删除`app`module(可选) + +### 项目展示 +![zxing](https://github.com/RootCluster/rc-android-zxing/raw/zxing/images/zxing.gif) + +当然你也可以下载官方提供的应用[google play](https://play.google.com/store/apps/details?id=com.google.zxing.client.android) + +### 异常问题处理 + +#### 相机出现问题 + +##### 表现 +如果你运行的设备是 Android 6.0 以上版本,那么在启动应用程序后,应该会提示你“很遗憾,Android 相机出现问题,你可能需要重启设备”,如下图 +![project_problem](https://github.com/RootCluster/rc-android-zxing/raw/zxing/images/project_problem.png) + +##### 分析 +分析运行日志,进行定位`CaptureActivity.java`类,在初始化相机时,由于没有相机权限,因此无法正常运行应用 +![zxing_error_log](https://github.com/RootCluster/rc-android-zxing/raw/zxing/images/zxing_error_log.png) + +##### 解决方式 + +```java +// CaptureActivity.jaca +// line 266 && line 443 +mHolder = surfaceHolder; +if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1) { + if (ContextCompat.checkSelfPermission(CaptureActivity.this, + android.Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { + // 先判断有没有权限 ,没有就在这里进行权限的申请 + ActivityCompat.requestPermissions(CaptureActivity.this, + new String[]{Manifest.permission.CAMERA}, CAMERA_OK); + } else { + // 说明已经获取到摄像头权限了 + initCamera(surfaceHolder); + } + } else { + initCamera(surfaceHolder); + } + +// line 803 +@Override +public void onRequestPermissionsResult(int requestCode + , @NonNull String[] permissions, @NonNull int[] grantResults) { + // If request is cancelled, the result arrays are empty. + if (requestCode == CAMERA_OK) { + if (grantResults.length > 0 + && grantResults[0] == PackageManager.PERMISSION_GRANTED) { + // permission was granted, yay! Do the + // contacts-related task you need to do. + initCamera(mHolder); + } + } +} +``` +#### 其他问题 +同样我们在`EncodeActivity.java`文件中加入读取内存卡的权限`READ_EXTERNAL_STORAGE` + +## 项目分析 + +### 项目概要 + +``` +rc-android-zxing + ├── book/ + ├── camera/ + ├── clipboard/ + ├── encode/ + ├── history/ + ├── result/ + ├── share/ + ├── wifi/ + ├── AmbientLightManager + ├── BeepManager + ├── CaptureActivity + ├── CaptureActivityHandler + ├── Contents + ├── DecodeFormatManager + ├── DecodeHandler + ├── DecodeHintManager + ├── DecodeThread + ├── FinishListener + ├── HelpHelper + ├── InactivityTimer + ├── Intents + ├── IntentSource + ├── LocaleManager + ├── PreferencesActivity + ├── PreferencesFragment + ├── ScanFromWebPageManager + ├── ViewfinderResultPointCallback + └── ViewfinderView + +``` + +## 项目源码 + +## 总结 \ No newline at end of file diff --git a/source/about/index.md b/source/about/index.md new file mode 100644 index 000000000..3ae0dc763 --- /dev/null +++ b/source/about/index.md @@ -0,0 +1,31 @@ +--- +title: 关于 +date: 2018-05-04 17:50:34 +comments: false +--- + + + +## 关于我 + +>Life's a struggle!(生命不息,折腾不止,当然这不能是瞎折腾)~ + +陕西汉中,现居浙江杭州,理工男一枚 +机械制造与自动化专业,14年毕业后投奔于互联网世界 +16年开始自学Android开发,现从事Android开发工作 + +喜欢Coding,音乐,电影 + +## 关于本站 + +> 本站已开启HTTPS + +资源:便捷,高效,有趣的工具资源 + +经验:工作中一些问题解决方式及思考 + +阅读:阅读一些书籍的收获以及感兴趣的文字 + +学习:编程语言,热门开源框架的学习过程记录 + +影音:视觉,听觉的享受分享 \ No newline at end of file diff --git a/source/categories/index.md b/source/categories/index.md new file mode 100644 index 000000000..dea1cbcc2 --- /dev/null +++ b/source/categories/index.md @@ -0,0 +1,6 @@ +--- +title: 分类 +type: categories +date: 2018-03-24 22:38:58 +comments: false +--- diff --git a/source/tags/index.md b/source/tags/index.md new file mode 100644 index 000000000..286c05569 --- /dev/null +++ b/source/tags/index.md @@ -0,0 +1,6 @@ +--- +title: 标签 +type: tags +date: 2018-03-24 22:36:28 +comments: false +--- diff --git a/.all-contributorsrc b/themes/next/.all-contributorsrc similarity index 100% rename from .all-contributorsrc rename to themes/next/.all-contributorsrc diff --git a/.editorconfig b/themes/next/.editorconfig similarity index 100% rename from .editorconfig rename to themes/next/.editorconfig diff --git a/.eslintrc.json b/themes/next/.eslintrc.json similarity index 100% rename from .eslintrc.json rename to themes/next/.eslintrc.json diff --git a/.gitattributes b/themes/next/.gitattributes similarity index 100% rename from .gitattributes rename to themes/next/.gitattributes diff --git a/.github/CODE_OF_CONDUCT.md b/themes/next/.github/CODE_OF_CONDUCT.md similarity index 100% rename from .github/CODE_OF_CONDUCT.md rename to themes/next/.github/CODE_OF_CONDUCT.md diff --git a/.github/CONTRIBUTING.md b/themes/next/.github/CONTRIBUTING.md similarity index 100% rename from .github/CONTRIBUTING.md rename to themes/next/.github/CONTRIBUTING.md diff --git a/.github/ISSUE_TEMPLATE/bug-report.md b/themes/next/.github/ISSUE_TEMPLATE/bug-report.md similarity index 100% rename from .github/ISSUE_TEMPLATE/bug-report.md rename to themes/next/.github/ISSUE_TEMPLATE/bug-report.md diff --git a/.github/ISSUE_TEMPLATE/custom-issue-template.md b/themes/next/.github/ISSUE_TEMPLATE/custom-issue-template.md similarity index 100% rename from .github/ISSUE_TEMPLATE/custom-issue-template.md rename to themes/next/.github/ISSUE_TEMPLATE/custom-issue-template.md diff --git a/.github/ISSUE_TEMPLATE/feature-request.md b/themes/next/.github/ISSUE_TEMPLATE/feature-request.md similarity index 100% rename from .github/ISSUE_TEMPLATE/feature-request.md rename to themes/next/.github/ISSUE_TEMPLATE/feature-request.md diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/themes/next/.github/PULL_REQUEST_TEMPLATE.md similarity index 100% rename from .github/PULL_REQUEST_TEMPLATE.md rename to themes/next/.github/PULL_REQUEST_TEMPLATE.md diff --git a/.github/auto_assign.yml b/themes/next/.github/auto_assign.yml similarity index 100% rename from .github/auto_assign.yml rename to themes/next/.github/auto_assign.yml diff --git a/.github/config.yml b/themes/next/.github/config.yml similarity index 100% rename from .github/config.yml rename to themes/next/.github/config.yml diff --git a/.github/eslint-disable-bot.yml b/themes/next/.github/eslint-disable-bot.yml similarity index 100% rename from .github/eslint-disable-bot.yml rename to themes/next/.github/eslint-disable-bot.yml diff --git a/.github/issue_label_bot.yaml b/themes/next/.github/issue_label_bot.yaml similarity index 100% rename from .github/issue_label_bot.yaml rename to themes/next/.github/issue_label_bot.yaml diff --git a/.github/lock.yml b/themes/next/.github/lock.yml similarity index 100% rename from .github/lock.yml rename to themes/next/.github/lock.yml diff --git a/.github/mergeable.yml b/themes/next/.github/mergeable.yml similarity index 100% rename from .github/mergeable.yml rename to themes/next/.github/mergeable.yml diff --git a/.github/release-drafter.yml b/themes/next/.github/release-drafter.yml similarity index 100% rename from .github/release-drafter.yml rename to themes/next/.github/release-drafter.yml diff --git a/.github/stale.yml b/themes/next/.github/stale.yml similarity index 100% rename from .github/stale.yml rename to themes/next/.github/stale.yml diff --git a/.github/support.yml b/themes/next/.github/support.yml similarity index 100% rename from .github/support.yml rename to themes/next/.github/support.yml diff --git a/themes/next/.gitignore b/themes/next/.gitignore new file mode 100644 index 000000000..587c07503 --- /dev/null +++ b/themes/next/.gitignore @@ -0,0 +1,19 @@ +.DS_Store +.idea/ +*.log +*.iml +yarn.lock +package-lock.json +node_modules/ + +# Ignore optional external libraries +source/lib/* + +# Track internal libraries & Ignore unused verdors files +source/lib/font-awesome/less/ +source/lib/font-awesome/scss/ +!source/lib/font-awesome/ + +!source/lib/anime.min.js + +!source/lib/velocity/ diff --git a/.stylintrc b/themes/next/.stylintrc similarity index 100% rename from .stylintrc rename to themes/next/.stylintrc diff --git a/themes/next/.travis.yml b/themes/next/.travis.yml new file mode 100644 index 000000000..9591f0b23 --- /dev/null +++ b/themes/next/.travis.yml @@ -0,0 +1,18 @@ +language: node_js +#node_js: node +node_js: lts/* + +cache: + directories: + - node_modules + +install: npm install + +before_script: + - npm install -g gulp + +addons: + browserstack: + username: "ivannginx1" + access_key: + secure: "NutOhdgtUdBUXMPZhy8X1F1Jq+tan1LeNOV0FArBt15SNlxtNArqhiyTi4XnG9MPruX4306aGF2RBrKso+OiGNRdGtRGngH613Q0GWNtlC/boMqnI7fHqLIyCs6S12y2uA8PK4Ifxg9bZ0VtCTYYbMy+p1KvBM//L12vmtfdnby8z5Qvex3tB3dLoPOR50CKkINHJVDLm+iVRFrdz4/83oDsulZSRRGIaxu5taDWPIcp3fYZtre2Nc+RXcsyFDyjN7U0Hvr5tKBbloJxXEQEBv2xLkMOtp85nmCPD06s1Il8Wus1ux3raVsfUyaW5FpNX37Jeb5e00RQUM1wgU5m75H6qiGwDvQswbugJG0i/a2nNfsgVmbrSZdMnkHcx2Uxmrw4ejyEP5NSrJSBi05Ck1fQ4UsZ4Qkdf1fd04SI0LpLWt43eoNO/7rHKsQoP4LCX9gxKUuC075NEBLODyJ529RYfA6dKKwwH6o0ZbOgASmCoAWaM65g4+FHRnJcKL/Kj9ZWklQtRa7/ynlHaA65jefFS2lB8Ut6d3rXDDBih9mIrwV1uUaEH96xgAN42bgU/vY6FGzNkDOYZqj4YfsepDM0wbOsslFie7JZq7iFjsYvrXqLvYUMk37AZwQ2Sb6uH4tIT4Qw/4oZfDzA1En3/8HdZJ28nKW/lzjwMSqheIY=" diff --git a/LICENSE.md b/themes/next/LICENSE.md similarity index 100% rename from LICENSE.md rename to themes/next/LICENSE.md diff --git a/themes/next/README.md b/themes/next/README.md new file mode 100644 index 000000000..740251b2a --- /dev/null +++ b/themes/next/README.md @@ -0,0 +1,93 @@ +
官方文档: +:cn: +:ru:
+ +#
e x T
+ +

«NexT» is a high quality elegant Hexo theme. It is crafted from scratch, with love.

+ +

+ + + + + + + + +

+ +## 前言 +这是一个fork项目,在[源项目](https://github.com/theme-next/hexo-theme-next)的基础上,集成了以下第三方常用的工具库 +* ~~[theme-next-algolia-instant-search](https://github.com/theme-next/theme-next-algolia-instant-search):即时搜索~~ +* ~~[theme-next-bookmark](https://github.com/theme-next/theme-next-bookmark):书签,用户可以保存他们的阅读位置~~ +* ~~[theme-next-fancybox3](https://github.com/theme-next/theme-next-fancybox3):图片预览~~ +* ~~[theme-next-reading-progress](https://github.com/theme-next/theme-next-reading-progress):页面阅读进度加载~~ +* ~~[theme-next-pace](https://github.com/theme-next/theme-next-pace):顶部装载栏~~ +* ~~[theme-next-pangu](https://github.com/theme-next/theme-next-pangu):字符间空格处理~~ +* [theme-next-pdf](https://github.com/theme-next/theme-next-pdf):PDF文件预览支持 + +## 使用 + +### 安装主题 +在你的hexo项目中,安装已集成好的[NexT](https://github.com/RootCluster/hexo-theme-next)主题 +```bash +# 在你的 blog 根目录下执行 +git clone https://github.com/RootCluster/hexo-theme-next.git themes/next +``` + +### 个性化配置 +在你的 blog 项目的根目录 `source/_data`中,创建`next.yml` + +copy`/themes/next/`路径下`_config.yml`的内容到`/source/_data/`路径的`next.yml`文件中 + +以下配置均在`next.yml`文件中 +* algolia-instant-search +``` +algolia_search: +enable: true +``` +* bookmark +``` +bookmark: true +``` +* fancybox +``` +fancybox: true +``` +* reading_progress +``` +reading_progress: +enable: true +color: "#37c6c0" +height: 2px +``` +* pace +``` +pace: true +``` +* pangu +``` +pangu: true +``` +* pdf +``` +# PDF Support +pdf: +enable: true + +# Default(true) will load PDFObject/PDF.js script on demand +# That is it only render those page who has 'pdf: true' in Front Matter. +# If you set it to false, it will load PDFObject/PDF.js srcipt EVERY PAGE. +per_page: true + +height: 500px + +pdfobject: +# Use 2.1.1 as default, cloudflare as default CDN +cdn: //cdnjs.cloudflare.com/ajax/libs/pdfobject/2.1.1/pdfobject.min.js +``` + +## 更新 +* 具体操作查看[Git 子仓库管理](https://incoder.org/2018/05/17/git-sub/#git-subtree-%E5%B8%B8%E7%94%A8%E6%93%8D%E4%BD%9C-%E9%87%8D%E7%82%B9) +* [Github上fork项目后保持与源项目更新](https://segmentfault.com/a/1190000008401427) \ No newline at end of file diff --git a/themes/next/_config.yml b/themes/next/_config.yml new file mode 100644 index 000000000..699b2ea42 --- /dev/null +++ b/themes/next/_config.yml @@ -0,0 +1,1121 @@ +# --------------------------------------------------------------- +# Theme Core Configuration Settings +# See: https://theme-next.org/docs/theme-settings/ +# --------------------------------------------------------------- + +# If false, merge configs from `_data/next.yml` into default configuration (rewrite). +# If true, will fully override default configuration by options from `_data/next.yml` (override). Only for NexT settings. +# And if true, all config from default NexT `_config.yml` must be copied into `next.yml`. Use if you know what you are doing. +# Useful if you want to comment some options from NexT `_config.yml` by `next.yml` without editing default config. +override: false + +# Console reminder if new version released. +reminder: false + +# Allow to cache content generation. Introduced in NexT v6.0.0. +cache: + enable: true + +# Remove unnecessary files after hexo generate. +minify: false + +# Define custom file paths. +# Create your custom files in site directory `source/_data` and uncomment needed files below. +custom_file_path: + #head: source/_data/head.swig + #header: source/_data/header.swig + #sidebar: source/_data/sidebar.swig + #postMeta: source/_data/post-meta.swig + #postBodyEnd: source/_data/post-body-end.swig + #footer: source/_data/footer.swig + #bodyEnd: source/_data/body-end.swig + #variable: source/_data/variables.styl + #mixin: source/_data/mixins.styl + #style: source/_data/styles.styl + + +# --------------------------------------------------------------- +# Site Information Settings +# See: https://theme-next.org/docs/getting-started/ +# --------------------------------------------------------------- + +favicon: + small: /images/favicon-16x16-next.png + medium: /images/favicon-32x32-next.png + apple_touch_icon: /images/apple-touch-icon-next.png + safari_pinned_tab: /images/logo.svg + #android_manifest: /images/manifest.json + #ms_browserconfig: /images/browserconfig.xml + +# hexo-generator-feed required for rss support. Leave rss as blank to use site's feed link. +# Set rss to false to disable feed link. Set rss to specific value if you have burned your feed already. +rss: + +footer: + # Specify the date when the site was setup. If not defined, current year will be used. + #since: 2015 + + # Icon between year and copyright info. + icon: + # Icon name in Font Awesome. See: https://fontawesome.com/v4.7.0/icons/ + # `heart` is recommended with animation in red (#ff0000). + name: user + # If you want to animate the icon, set it to true. + animated: false + # Change the color of icon, using Hex Code. + color: "#808080" + + # If not defined, `author` from Hexo `_config.yml` will be used. + copyright: + + powered: + # Hexo link (Powered by Hexo). + enable: true + # Version info of Hexo after Hexo link (vX.X.X). + version: true + + theme: + # Theme & scheme info link (Theme - NexT.scheme). + enable: true + # Version info of NexT after scheme info (vX.X.X). + version: true + + # Beian ICP and gongan information for Chinese users. See: http://www.beian.miit.gov.cn, http://www.beian.gov.cn + beian: + enable: false + icp: + # The digit in the num of gongan beian. + gongan_id: + # The full num of gongan beian. + gongan_num: + # The icon for gongan beian. See: http://www.beian.gov.cn/portal/download + gongan_icon_url: + +# Creative Commons 4.0 International License. +# See: https://creativecommons.org/share-your-work/licensing-types-examples +# Available values of license: by | by-nc | by-nc-nd | by-nc-sa | by-nd | by-sa | zero +# You can set a language value if you prefer a translated version of CC license, e.g. deed.zh +# CC licenses are available in 39 languages, you can find the specific and correct abbreviation you need on https://creativecommons.org +creative_commons: + license: by-nc-sa + sidebar: false + post: false + language: + + +# --------------------------------------------------------------- +# Scheme Settings +# --------------------------------------------------------------- + +# Schemes +scheme: Muse +#scheme: Mist +#scheme: Pisces +#scheme: Gemini + + +# --------------------------------------------------------------- +# Menu Settings +# --------------------------------------------------------------- + +# Usage: `Key: /link/ || icon` +# Key is the name of menu item. If the translation for this item is available, the translated text will be loaded, otherwise the Key name will be used. Key is case-senstive. +# Value before `||` delimiter is the target link. +# Value after `||` delimiter is the name of Font Awesome icon. If icon (with or without delimiter) is not specified, question icon will be loaded. +# When running the site in a subdirectory (e.g. domain.tld/blog), remove the leading slash from link value (/archives -> archives). +# External url should start with http:// or https:// +menu: + home: / || home + #about: /about/ || user + #tags: /tags/ || tags + #categories: /categories/ || th + archives: /archives/ || archive + #schedule: /schedule/ || calendar + #sitemap: /sitemap.xml || sitemap + #commonweal: /404/ || heartbeat + +# Enable / Disable menu icons / item badges. +menu_settings: + icons: true + badges: false + + +# --------------------------------------------------------------- +# Sidebar Settings +# See: https://theme-next.org/docs/theme-settings/sidebar +# --------------------------------------------------------------- + +sidebar: + # Sidebar Position. + position: left + #position: right + + # Manual define the sidebar width. If commented, will be default for: + # Muse | Mist: 320 + # Pisces | Gemini: 240 + #width: 300 + + # Sidebar Display (only for Muse | Mist), available values: + # - post expand on posts automatically. Default. + # - always expand for all pages automatically. + # - hide expand only when click on the sidebar toggle icon. + # - remove totally remove sidebar including sidebar toggle. + display: post + + # Sidebar offset from top menubar in pixels (only for Pisces | Gemini). + offset: 12 + # Enable sidebar on narrow view (only for Muse | Mist). + onmobile: false + +# Sidebar Avatar +avatar: + # In theme directory (source/images): /images/avatar.gif + # In site directory (source/uploads): /uploads/avatar.gif + # You can also use other linking images. + url: #/images/avatar.gif + # If true, the avatar would be dispalyed in circle. + rounded: false + # If true, the avatar would be rotated with the cursor. + rotated: false + +# Posts / Categories / Tags in sidebar. +site_state: true + +# Social Links +# Usage: `Key: permalink || icon` +# Key is the link label showing to end users. +# Value before `||` delimiter is the target permalink. +# Value after `||` delimiter is the name of Font Awesome icon. If icon (with or without delimiter) is not specified, globe icon will be loaded. +social: + #GitHub: https://github.com/yourname || github + #E-Mail: mailto:yourname@gmail.com || envelope + #Weibo: https://weibo.com/yourname || weibo + #Google: https://plus.google.com/yourname || google + #Twitter: https://twitter.com/yourname || twitter + #FB Page: https://www.facebook.com/yourname || facebook + #VK Group: https://vk.com/yourname || vk + #StackOverflow: https://stackoverflow.com/yourname || stack-overflow + #YouTube: https://youtube.com/yourname || youtube + #Instagram: https://instagram.com/yourname || instagram + #Skype: skype:yourname?call|chat || skype + +social_icons: + enable: true + icons_only: false + transition: false + +# Blog rolls +links_settings: + icon: link + title: Links + # Available values: block | inline + layout: block + +links: + #Title: http://example.com + +# Table Of Contents in the Sidebar +toc: + enable: true + # Automatically add list number to toc. + number: true + # If true, all words will placed on next lines if header width longer then sidebar width. + wrap: false + # If true, all level of TOC in a post will be displayed, rather than the activated part of it. + expand_all: false + # Maximum heading depth of generated toc. You can set it in one post through `toc_max_depth` in Front-matter. + max_depth: 6 + +# A button to open designated chat widget in sidebar. +# Firstly, you need enable the chat service you want to activate its sidebar button. +chat: + enable: false + #service: chatra + #service: tidio + icon: comment # Icon name in Font Awesome, set false to disable icon. + text: Chat # Button text, change it as you wish. + + +# --------------------------------------------------------------- +# Post Settings +# See: https://theme-next.org/docs/theme-settings/posts +# --------------------------------------------------------------- + +# Automatically scroll page to section which is under mark. +scroll_to_more: true + +# Automatically excerpt description in homepage as preamble text. +excerpt_description: true + +# Automatically excerpt (Not recommend). +# Use in the post to control excerpt accurately. +auto_excerpt: + enable: false + length: 150 + +# Read more button +# If true, the read more button would be displayed in excerpt section. +read_more_btn: true + +# Post meta display settings +post_meta: + item_text: true + created_at: true + updated_at: + enable: true + another_day: true + categories: true + +# Post wordcount display settings +# Dependencies: https://github.com/theme-next/hexo-symbols-count-time +symbols_count_time: + separated_meta: true + item_text_post: true + item_text_total: false + awl: 4 + wpm: 275 + +# Use icon instead of the symbol # to indicate the tag at the bottom of the post +tag_icon: false + +# Wechat Subscriber +wechat_subscriber: + enable: false + qcode: #/uploads/wechat-qcode.jpg + #description: Subscribe to my blog by scanning my public wechat account. + +# Reward (Donate) +reward_settings: + # If true, reward would be displayed in every article by default. + # You can show or hide reward in a specific article throuth `reward: true | false` in Front-matter. + enable: false + animation: false + #comment: Donate comment here. + +reward: + #wechatpay: /images/wechatpay.png + #alipay: /images/alipay.png + #bitcoin: /images/bitcoin.png + +# Related popular posts +# Dependencies: https://github.com/tea3/hexo-related-popular-posts +related_posts: + enable: false + title: # Custom header, leave empty to use the default one + display_in_home: false + params: + maxCount: 5 + #PPMixingRate: 0.0 + #isDate: false + #isImage: false + #isExcerpt: false + +# Post edit +# Dependencies: https://github.com/hexojs/hexo-deployer-git +post_edit: + enable: false + url: https://github.com/user-name/repo-name/tree/branch-name/subdirectory-name # Link for view source + #url: https://github.com/user-name/repo-name/edit/branch-name/subdirectory-name # Link for fork & edit + + +# --------------------------------------------------------------- +# Custom Page Settings +# See: https://theme-next.org/docs/theme-settings/custom-pages +# --------------------------------------------------------------- + +# Enable "cheers" for archive page. +cheers: true + +# TagCloud settings for tags page. +tagcloud: + # All values below are same as default, change them by yourself + min: 12 # Minimun font size in px + max: 30 # Maxium font size in px + start: "#ccc" # Start color (hex, rgba, hsla or color keywords) + end: "#111" # End color (hex, rgba, hsla or color keywords) + amount: 200 # Amount of tags, change it if you have more than 200 tags + +# Google Calendar +# Share your recent schedule to others via calendar page. +# API Documentation: https://developers.google.com/google-apps/calendar/v3/reference/events/list +# To get api_key: https://console.developers.google.com +# Create & manage a public Google calendar: https://support.google.com/calendar/answer/37083 +calendar: + calendar_id: # Your Google account E-Mail + api_key: + orderBy: startTime + offsetMax: 24 # Time Range + offsetMin: 4 # Time Range + showDeleted: false + singleEvents: true + maxResults: 250 + + +# --------------------------------------------------------------- +# Misc Theme Settings +# --------------------------------------------------------------- + +# Set the text alignment in posts / pages. +text_align: + # Available values: start | end | left | right | center | justify | justify-all | match-parent + desktop: justify + mobile: justify + +# Reduce padding / margin indents on devices with narrow width. +mobile_layout_economy: false + +# Android Chrome header panel color ($brand-bg / $headband-bg => $black-deep). +android_chrome_color: "#222" + +# Hide sticky headers and color the menu bar on Safari (iOS / macOS). +safari_rainbow: false + +# Optimize the display of scrollbars on webkit based browsers. +custom_scrollbar: false + +# Custom Logo (Do not support scheme Mist) +custom_logo: #/uploads/custom-logo.jpg + +codeblock: + # Code Highlight theme + # Available values: normal | night | night eighties | night blue | night bright | solarized | solarized dark | galactic + # See: https://github.com/chriskempson/tomorrow-theme + highlight_theme: normal + # Add copy button on codeblock + copy_button: + enable: false + # Show text copy result. + show_result: false + # Available values: default | flat | mac + style: + +back2top: + enable: true + # Back to top in sidebar. + sidebar: false + # Scroll percent label in b2t button. + scrollpercent: false + +# Reading progress bar +reading_progress: + enable: false + # Available values: top | bottom + position: top + color: "#37c6c0" + height: 2px + +# Bookmark Support +bookmark: + enable: false + # Customize the color of the bookmark. + color: "#222" + # If auto, save the reading progress when closing the page or clicking the bookmark-icon. + # If manual, only save it by clicking the bookmark-icon. + save: auto + +# `Follow me on GitHub` banner in the top-right corner. +github_banner: + enable: false + permalink: https://github.com/yourname + title: Follow me on GitHub + + +# --------------------------------------------------------------- +# Font Settings +# See: https://theme-next.org/docs/theme-settings/#Fonts-Customization +# --------------------------------------------------------------- +# Find fonts on Google Fonts (https://www.google.com/fonts) +# All fonts set here will have the following styles: +# light | light italic | normal | normal italic | bold | bold italic +# Be aware that setting too much fonts will cause site running slowly +# --------------------------------------------------------------- +# To avoid space between header and sidebar in scheme Pisces / Gemini, Web Safe fonts are recommended for `global` (and `title`): +# Arial | Tahoma | Helvetica | Times New Roman | Courier New | Verdana | Georgia | Palatino | Garamond | Comic Sans MS | Trebuchet MS +# --------------------------------------------------------------- + +font: + # Use custom fonts families or not. + # Depended options: `external` and `family`. + enable: false + + # Uri of fonts host, e.g. //fonts.googleapis.com (Default). + host: + + # Font options: + # `external: true` will load this font family from `host` above. + # `family: Times New Roman`. Without any quotes. + # `size: x.x`. Use `em` as unit. Default: 1 (16px) + + # Global font settings used for all elements inside . + global: + external: true + family: Lato + size: + + # Font settings for site title (.site-title). + title: + external: true + family: + size: + + # Font settings for headlines (

to

). + headings: + external: true + family: + size: + + # Font settings for posts (.post-body). + posts: + external: true + family: + + # Font settings for and code blocks. + codes: + external: true + family: + + +# --------------------------------------------------------------- +# SEO Settings +# --------------------------------------------------------------- + +# Disable Baidu transformation on mobile devices. +disable_baidu_transformation: false + +# Set a canonical link tag in your hexo, you could use it for your SEO of blog. +# See: https://support.google.com/webmasters/answer/139066 +# Remember to set up your URL in Hexo `_config.yml` (e.g. url: http://yourdomain.com) +canonical: true + +# Change headers hierarchy on site-subtitle (will be main site description) and on all post / page titles for better SEO-optimization. +seo: false + +# If true, will add site-subtitle to index page. +# Remember to set up your site-subtitle in Hexo `_config.yml` (e.g. subtitle: Subtitle) +index_with_subtitle: false + +# Automatically add external URL with Base64 encrypt & decrypt. +exturl: false + +# Google Webmaster tools verification. +# See: https://www.google.com/webmasters +google_site_verification: + +# Bing Webmaster tools verification. +# See: https://www.bing.com/webmaster +bing_site_verification: + +# Yandex Webmaster tools verification. +# See: https://webmaster.yandex.ru +yandex_site_verification: + +# Baidu Webmaster tools verification. +# See: https://ziyuan.baidu.com/site +baidu_site_verification: + +# Enable baidu push so that the blog will push the url to baidu automatically which is very helpful for SEO. +baidu_push: false + + +# --------------------------------------------------------------- +# Third Party Plugins & Services Settings +# See: https://theme-next.org/docs/third-party-services/ +# You may need to install dependencies or set CDN URLs in `vendors` +# There are two different CDN providers by default: +# - jsDelivr (cdn.jsdelivr.net), works everywhere even in China +# - CDNJS (cdnjs.cloudflare.com), provided by cloudflare +# --------------------------------------------------------------- + +# Math Formulas Render Support +math: + enable: false + + # Default (true) will load mathjax / katex script on demand. + # That is it only render those page which has `mathjax: true` in Front-matter. + # If you set it to false, it will load mathjax / katex srcipt EVERY PAGE. + per_page: true + + # hexo-renderer-pandoc (or hexo-renderer-kramed) required for full MathJax support. + mathjax: + enable: false + # See: https://mhchem.github.io/MathJax-mhchem/ + mhchem: false + + # hexo-renderer-markdown-it-plus (or hexo-renderer-markdown-it with markdown-it-katex plugin) required for full Katex support. + katex: + enable: false + # See: https://github.com/KaTeX/KaTeX/tree/master/contrib/copy-tex + copy_tex: false + +# Easily enable fast Ajax navigation on your website. +# Dependencies: https://github.com/theme-next/theme-next-pjax +# For moreinformation: https://github.com/MoOx/pjax +pjax: false + +# FancyBox is a tool that offers a nice and elegant way to add zooming functionality for images. +# For more information: https://fancyapps.com/fancybox +fancybox: false + +# A JavaScript library for zooming images like Medium. +# Do not enable both `fancybox` and `mediumzoom`. +# For more information: https://github.com/francoischalifour/medium-zoom +mediumzoom: false + +# Vanilla JavaScript plugin for lazyloading images. +# For more information: https://github.com/ApoorvSaxena/lozad.js +lazyload: false + +# Pangu Support +# For more information: https://github.com/vinta/pangu.js +pangu: false + +# Quicklink Support +# For more information: https://github.com/GoogleChromeLabs/quicklink +quicklink: + enable: false + + # Quicklink (quicklink.umd.js script) is loaded on demand. + # Add `quicklink: true` in Front-matter of the page or post you need. + # Home page and archive page can be controlled through home and archive options below. + home: true + archive: true + + # Default (true) will initialize quicklink after the load event fires. + delay: true + # Custom a time in milliseconds by which the browser must execute prefetching. + timeout: 3000 + # Default (true) will enable fetch() or falls back to XHR. + priority: true + + # For more flexibility you can add some patterns (RegExp, Function, or Array) to ignores. + # See: https://github.com/GoogleChromeLabs/quicklink#custom-ignore-patterns + ignores: + + +# --------------------------------------------------------------- +# Comments Settings +# See: https://theme-next.org/docs/third-party-services/comments +# --------------------------------------------------------------- + +# Multiple Comment System Support +comments: + # Available values: tabs | buttons + style: tabs + # Choose a comment system to be displayed by default. + # Available values: changyan | disqus | disqusjs | facebook_comments_plugin | gitalk | livere | valine | vkontakte + active: + # Setting `true` means remembering the comment system selected by the visitor. + storage: true + # Modify texts or order for any navs, here are some examples. + nav: + #disqus: + # text: Load Disqus + # order: -1 + #facebook_comments_plugin: + # text: facebook + #gitalk: + # order: -2 + +# Disqus +disqus: + enable: false + shortname: + count: true + lazyload: false + #post_meta_order: 0 + +# DisqusJS +# Alternative Disqus - Render comment component using Disqus API. +# Demo: https://suka.js.org/DisqusJS/ +# For more information: https://github.com/SukkaW/DisqusJS +disqusjs: + enable: false + # API Endpoint of Disqus API (https://disqus.com/api/). + # Leave api empty if you are able to connect to Disqus API. + # Otherwise you need a reverse proxy for Disqus API. + # For example: + # api: https://disqus.skk.moe/disqus/ + api: + apikey: # Register new application from https://disqus.com/api/applications/ + shortname: # See: https://disqus.com/admin/settings/general/ + +# Changyan +changyan: + enable: false + appid: + appkey: + #post_meta_order: 0 + +# Valine +# You can get your appid and appkey from https://leancloud.cn +# For more information: https://valine.js.org, https://github.com/xCss/Valine +valine: + enable: false # When enable is set to be true, leancloud_visitors is recommended to be closed for the re-initialization problem within different leancloud adk version + appid: # Your leancloud application appid + appkey: # Your leancloud application appkey + notify: false # Mail notifier. See: https://github.com/xCss/Valine/wiki + verify: false # Verification code + placeholder: Just go go # Comment box placeholder + avatar: mm # Gravatar style + guest_info: nick,mail,link # Custom comment header + pageSize: 10 # Pagination size + language: # Language, available values: en, zh-cn + visitor: false # leancloud-counter-security is not supported for now. When visitor is set to be true, appid and appkey are recommended to be the same as leancloud_visitors' for counter compatibility. Article reading statistic https://valine.js.org/visitor.html + comment_count: true # If false, comment count will only be displayed in post page, not in home page + recordIP: false # Whether to record the commenter IP + serverURLs: # When the custom domain name is enabled, fill it in here (it will be detected automatically by default, no need to fill in) + #post_meta_order: 0 + +# LiveRe comments system +# You can get your uid from https://livere.com/insight/myCode (General web site) +livere_uid: # + +# Gitalk +# Demo: https://gitalk.github.io +# For more information: https://github.com/gitalk/gitalk +gitalk: + enable: false + github_id: # GitHub repo owner + repo: # Repository name to store issues + client_id: # GitHub Application Client ID + client_secret: # GitHub Application Client Secret + admin_user: # GitHub repo owner and collaborators, only these guys can initialize gitHub issues + distraction_free_mode: true # Facebook-like distraction free mode + # Gitalk's display language depends on user's browser or system environment + # If you want everyone visiting your site to see a uniform language, you can set a force language value + # Available values: en | es-ES | fr | ru | zh-CN | zh-TW + language: + + +# --------------------------------------------------------------- +# Post Widgets & Content Sharing Services +# See: https://theme-next.org/docs/third-party-services/post-widgets +# --------------------------------------------------------------- + +# Facebook SDK Support +facebook_sdk: + enable: false + app_id: # + fb_admin: # + like_button: # true + webmaster: # true + +# Facebook comments plugin +# This plugin depends on Facebook SDK. +# If facebook_sdk.enable is false, Facebook comments plugin is unavailable. +facebook_comments_plugin: + enable: false + num_of_posts: 10 # Minimum posts num is 1 + width: 100% # Default width is 550px + scheme: light # Default scheme is light (light or dark) + #post_meta_order: 0 + +# VKontakte API Support +# To get your AppID visit https://vk.com/editapp?act=create +vkontakte_api: + enable: false + app_id: # + like: true + comments: true + num_of_posts: 10 + +# Star rating support to each article. +# To get your ID visit https://widgetpack.com +rating: + enable: false + id: # + color: fc6423 + +# AddThis Share. See: https://www.addthis.com +# Go to https://www.addthis.com/dashboard to customize your tools. +add_this_id: + + +# --------------------------------------------------------------- +# Statistics and Analytics +# See: https://theme-next.org/docs/third-party-services/statistics-and-analytics +# --------------------------------------------------------------- + +# Baidu Analytics +baidu_analytics: # + +# Growingio Analytics +# Copyright 2015-2018 GrowingIO, Inc. More info available at https://www.growingio.com +growingio_analytics: # + +# Google Analytics +google_analytics: + tracking_id: # + localhost_ignored: true + +# CNZZ count +cnzz_siteid: + +# Application Insights +# See: https://azure.microsoft.com/en-us/services/application-insights +application_insights: + +# Show number of visitors to each article. +# You can visit https://leancloud.cn to get AppID and AppKey. +leancloud_visitors: + enable: false + app_id: # + app_key: # + # Dependencies: https://github.com/theme-next/hexo-leancloud-counter-security + # If you don't care about security in leancloud counter and just want to use it directly + # (without hexo-leancloud-counter-security plugin), set `security` to `false`. + security: true + betterPerformance: false + +# Another tool to show number of visitors to each article. +# Visit https://console.firebase.google.com/u/0/ to get apiKey and projectId. +# Visit https://firebase.google.com/docs/firestore/ to get more information about firestore. +firestore: + enable: false + collection: articles # Required, a string collection name to access firestore database + apiKey: # Required + projectId: # Required + +# Show Views / Visitors of the website / page with busuanzi. +# Get more information on http://ibruce.info/2015/04/04/busuanzi +busuanzi_count: + enable: false + total_visitors: true + total_visitors_icon: user + total_views: true + total_views_icon: eye + post_views: true + post_views_icon: eye + +# Tencent analytics +tencent_analytics: # + +# Tencent MTA +tencent_mta: # + + +# --------------------------------------------------------------- +# Search Services +# See: https://theme-next.org/docs/third-party-services/search-services +# --------------------------------------------------------------- + +# Algolia Search +# For more information: https://www.algolia.com +algolia_search: + enable: false + hits: + per_page: 10 + labels: + input_placeholder: Search for Posts + hits_empty: "We didn't find any results for the search: ${query}" + hits_stats: "${hits} results found in ${time} ms" + +# Local Search +# Dependencies: https://github.com/wzpan/hexo-generator-search +local_search: + enable: false + # If auto, trigger search by changing input. + # If manual, trigger search by pressing enter key or search button. + trigger: auto + # Show top n results per article, show all results by setting to -1 + top_n_per_article: 1 + # Unescape html strings to the readable one. + unescape: false + # Preload the search data when the page loads. + preload: false + +# Swiftype Search API Key +swiftype_key: + + +# --------------------------------------------------------------- +# Chat Services +# See: https://theme-next.org/docs/third-party-services/chat-services +# --------------------------------------------------------------- + +# Chatra Support +# See: https://chatra.io +# Dashboard: https://app.chatra.io/settings/general +chatra: + enable: false + async: true + id: # Visit Dashboard to get your ChatraID + #embed: # Unfinished experimental feature for developers. See: https://chatra.io/help/api/#injectto + +# Tidio Support +# See: https://www.tidiochat.com +# Dashboard: https://www.tidiochat.com/panel/dashboard +tidio: + enable: false + key: # Public Key, get it from dashboard. See: https://www.tidiochat.com/panel/settings/developer + + +# --------------------------------------------------------------- +# Tags Settings +# See: https://theme-next.org/docs/tag-plugins/ +# --------------------------------------------------------------- + +# Note tag (bs-callout) +note: + # Note tag style values: + # - simple bs-callout old alert style. Default. + # - modern bs-callout new (v2-v3) alert style. + # - flat flat callout style with background, like on Mozilla or StackOverflow. + # - disabled disable all CSS styles import of note tag. + style: simple + icons: false + border_radius: 3 + # Offset lighter of background in % for modern and flat styles (modern: -12 | 12; flat: -18 | 6). + # Offset also applied to label tag variables. This option can work with disabled note tag. + light_bg_offset: 0 + +# Tabs tag +tabs: + transition: + tabs: false + labels: true + border_radius: 0 + +# PDF tag, requires two plugins: pdfObject and pdf.js +# pdfObject will try to load pdf files natively, if failed, pdf.js will be used. +# The following `cdn` setting is only for pdfObject, because cdn for pdf.js might be blocked by CORS policy. +# So, you must install the dependency of pdf.js if you want to use pdf tag and make it available to all browsers. +# See: https://github.com/theme-next/theme-next-pdf +pdf: + enable: false + # Default height + height: 500px + +# Mermaid tag +mermaid: + enable: false + # Available themes: default | dark | forest | neutral + theme: forest + + +# --------------------------------------------------------------- +# Animation Settings +# --------------------------------------------------------------- + +# Use velocity to animate everything. +# For more information: http://velocityjs.org +motion: + enable: true + async: false + transition: + # Transition variants: + # fadeIn | fadeOut | flipXIn | flipXOut | flipYIn | flipYOut | flipBounceXIn | flipBounceXOut | flipBounceYIn | flipBounceYOut + # swoopIn | swoopOut | whirlIn | whirlOut | shrinkIn | shrinkOut | expandIn | expandOut + # bounceIn | bounceOut | bounceUpIn | bounceUpOut | bounceDownIn | bounceDownOut | bounceLeftIn | bounceLeftOut | bounceRightIn | bounceRightOut + # slideUpIn | slideUpOut | slideDownIn | slideDownOut | slideLeftIn | slideLeftOut | slideRightIn | slideRightOut + # slideUpBigIn | slideUpBigOut | slideDownBigIn | slideDownBigOut | slideLeftBigIn | slideLeftBigOut | slideRightBigIn | slideRightBigOut + # perspectiveUpIn | perspectiveUpOut | perspectiveDownIn | perspectiveDownOut | perspectiveLeftIn | perspectiveLeftOut | perspectiveRightIn | perspectiveRightOut + post_block: fadeIn + post_header: slideDownIn + post_body: slideDownIn + coll_header: slideLeftIn + # Only for Pisces | Gemini. + sidebar: slideUpIn + +# Progress bar in the top during page loading. +# Dependencies: https://github.com/theme-next/theme-next-pace +# For more information: https://github.com/HubSpot/pace +pace: + enable: false + # Themes list: + # big-counter | bounce | barber-shop | center-atom | center-circle | center-radar | center-simple + # corner-indicator | fill-left | flat-top | flash | loading-bar | mac-osx | material | minimal + theme: minimal + +# JavaScript 3D library. +# Dependencies: https://github.com/theme-next/theme-next-three +three: + enable: false + three_waves: false + canvas_lines: false + canvas_sphere: false + +# Canvas-nest +# Dependencies: https://github.com/theme-next/theme-next-canvas-nest +# For more information: https://github.com/hustcc/canvas-nest.js +canvas_nest: + enable: false + onmobile: true # Display on mobile or not + color: "0,0,255" # RGB values, use `,` to separate + opacity: 0.5 # The opacity of line: 0~1 + zIndex: -1 # z-index property of the background + count: 99 # The number of lines + +# Canvas-ribbon +# Dependencies: https://github.com/theme-next/theme-next-canvas-ribbon +# For more information: https://github.com/zproo/canvas-ribbon +canvas_ribbon: + enable: false + size: 300 # The width of the ribbon + alpha: 0.6 # The transparency of the ribbon + zIndex: -1 # The display level of the ribbon + + +#! --------------------------------------------------------------- +#! DO NOT EDIT THE FOLLOWING SETTINGS +#! UNLESS YOU KNOW WHAT YOU ARE DOING +#! See: https://theme-next.org/docs/advanced-settings +#! --------------------------------------------------------------- + +# Script Vendors. Set a CDN address for the vendor you want to customize. +# Be aware that you would better use the same version as internal ones to avoid potential problems. +# Please use the https protocol of CDN files when you enable https on your site. +vendors: + # Internal path prefix. Please do not edit it. + _internal: lib + + # Internal version: 3.1.0 + # Example: + # anime: //cdn.jsdelivr.net/npm/animejs@3.1.0/lib/anime.min.js + anime: + + # Internal version: 4.7.0 + # Example: + # fontawesome: //cdn.jsdelivr.net/npm/font-awesome@4/css/font-awesome.min.css + # fontawesome: //cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css + fontawesome: + + # MathJax + # Example: + # mathjax: //cdn.jsdelivr.net/npm/mathjax@2/MathJax.js?config=TeX-AMS-MML_HTMLorMML + # mathjax: //cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-MML-AM_CHTML + # mhchem: //cdn.jsdelivr.net/npm/mathjax-mhchem@3 + # mhchem: //cdnjs.cloudflare.com/ajax/libs/mathjax-mhchem/3.3.0 + mathjax: + mhchem: + + # KaTeX + # Example: + # katex: //cdn.jsdelivr.net/npm/katex@0/dist/katex.min.css + # katex: //cdnjs.cloudflare.com/ajax/libs/KaTeX/0.7.1/katex.min.css + # copy_tex_js: //cdn.jsdelivr.net/npm/katex@0/dist/contrib/copy-tex.min.js + # copy_tex_css: //cdn.jsdelivr.net/npm/katex@0/dist/contrib/copy-tex.min.css + katex: + copy_tex_js: + copy_tex_css: + + # Internal version: 0.2.8 + # Example: + # pjax: //cdn.jsdelivr.net/gh/theme-next/theme-next-pjax@0/pjax.min.js + pjax: + + # FancyBox + # Example: + # jquery: //cdn.jsdelivr.net/npm/jquery@3/dist/jquery.min.js + # fancybox: //cdn.jsdelivr.net/gh/fancyapps/fancybox@3/dist/jquery.fancybox.min.js + # fancybox_css: //cdn.jsdelivr.net/gh/fancyapps/fancybox@3/dist/jquery.fancybox.min.css + jquery: + fancybox: + fancybox_css: + + # Medium-zoom + # Example: + # mediumzoom: //cdn.jsdelivr.net/npm/medium-zoom@1/dist/medium-zoom.min.js + mediumzoom: + + # Lazyload + # Example: + # lazyload: //cdn.jsdelivr.net/npm/lozad@1/dist/lozad.min.js + # lazyload: //cdnjs.cloudflare.com/ajax/libs/lozad.js/1.9.0/lozad.min.js + lazyload: + + # Pangu + # Example: + # pangu: //cdn.jsdelivr.net/npm/pangu@4/dist/browser/pangu.min.js + # pangu: //cdnjs.cloudflare.com/ajax/libs/pangu/4.0.7/pangu.min.js + pangu: + + # Quicklink + # Example: + # quicklink: //cdn.jsdelivr.net/npm/quicklink@1/dist/quicklink.umd.js + quicklink: + + # DisqusJS + # Example: + # disqusjs_js: //cdn.jsdelivr.net/npm/disqusjs@1/dist/disqus.js + # disqusjs_css: //cdn.jsdelivr.net/npm/disqusjs@1/dist/disqusjs.css + disqusjs_js: + disqusjs_css: + + # Valine + # Example: + # valine: //cdn.jsdelivr.net/npm/valine@1/dist/Valine.min.js + # valine: //cdnjs.cloudflare.com/ajax/libs/valine/1.3.4/Valine.min.js + valine: + + # Gitalk + # Example: + # gitalk_js: //cdn.jsdelivr.net/npm/gitalk@1/dist/gitalk.min.js + # gitalk_css: //cdn.jsdelivr.net/npm/gitalk@1/dist/gitalk.css + gitalk_js: + gitalk_css: + + # Algolia Search + # Example: + # algolia_instant_js: //cdn.jsdelivr.net/npm/instantsearch.js@2/dist/instantsearch.min.js + # algolia_instant_css: //cdn.jsdelivr.net/npm/instantsearch.js@2/dist/instantsearch.min.css + algolia_instant_js: + algolia_instant_css: + + # PDF + # Example: + # pdfobject: //cdn.jsdelivr.net/npm/pdfobject@2/pdfobject.min.js + # pdfobject: //cdnjs.cloudflare.com/ajax/libs/pdfobject/2.1.1/pdfobject.min.js + pdfobject: + + # Mermaid + # Example: + # mermaid: //cdn.jsdelivr.net/npm/mermaid@8/dist/mermaid.min.js + # mermaid: //cdnjs.cloudflare.com/ajax/libs/mermaid/8.0.0/mermaid.min.js + mermaid: + + # Internal version: 1.2.1 + # Example: + # velocity: //cdn.jsdelivr.net/npm/velocity-animate@1/velocity.min.js + # velocity: //cdnjs.cloudflare.com/ajax/libs/velocity/1.2.1/velocity.min.js + # velocity_ui: //cdn.jsdelivr.net/npm/velocity-animate@1/velocity.ui.min.js + # velocity_ui: //cdnjs.cloudflare.com/ajax/libs/velocity/1.2.1/velocity.ui.min.js + velocity: + velocity_ui: + + # Internal version: 1.0.2 + # Example: + # pace: //cdn.jsdelivr.net/npm/pace-js@1/pace.min.js + # pace: //cdnjs.cloudflare.com/ajax/libs/pace/1.0.2/pace.min.js + # pace_css: //cdn.jsdelivr.net/npm/pace-js@1/themes/blue/pace-theme-minimal.css + # pace_css: //cdnjs.cloudflare.com/ajax/libs/pace/1.0.2/themes/blue/pace-theme-minimal.min.css + pace: + pace_css: + + # Internal version: 1.0.0 + # Example: + # three: //cdn.jsdelivr.net/gh/theme-next/theme-next-three@1/three.min.js + # three_waves: //cdn.jsdelivr.net/gh/theme-next/theme-next-three@1/three-waves.min.js + # canvas_lines: //cdn.jsdelivr.net/gh/theme-next/theme-next-three@1/canvas_lines.min.js + # canvas_sphere: //cdn.jsdelivr.net/gh/theme-next/theme-next-three@1/canvas_sphere.min.js + three: + three_waves: + canvas_lines: + canvas_sphere: + + # Internal version: 1.0.0 + # Example: + # canvas_nest: //cdn.jsdelivr.net/gh/theme-next/theme-next-canvas-nest@1/canvas-nest.min.js + # canvas_nest_nomobile: //cdn.jsdelivr.net/gh/theme-next/theme-next-canvas-nest@1/canvas-nest-nomobile.min.js + canvas_nest: + canvas_nest_nomobile: + + # Internal version: 1.0.0 + # Example: + # canvas_ribbon: //cdn.jsdelivr.net/gh/theme-next/theme-next-canvas-ribbon@1/canvas-ribbon.js + canvas_ribbon: + +# Assets +css: css +js: js +images: images diff --git a/crowdin.yml b/themes/next/crowdin.yml similarity index 100% rename from crowdin.yml rename to themes/next/crowdin.yml diff --git a/docs/AGPL3.md b/themes/next/docs/AGPL3.md similarity index 100% rename from docs/AGPL3.md rename to themes/next/docs/AGPL3.md diff --git a/docs/ALGOLIA-SEARCH.md b/themes/next/docs/ALGOLIA-SEARCH.md similarity index 100% rename from docs/ALGOLIA-SEARCH.md rename to themes/next/docs/ALGOLIA-SEARCH.md diff --git a/docs/AUTHORS.md b/themes/next/docs/AUTHORS.md similarity index 100% rename from docs/AUTHORS.md rename to themes/next/docs/AUTHORS.md diff --git a/docs/DATA-FILES.md b/themes/next/docs/DATA-FILES.md similarity index 100% rename from docs/DATA-FILES.md rename to themes/next/docs/DATA-FILES.md diff --git a/docs/INSTALLATION.md b/themes/next/docs/INSTALLATION.md similarity index 100% rename from docs/INSTALLATION.md rename to themes/next/docs/INSTALLATION.md diff --git a/docs/LEANCLOUD-COUNTER-SECURITY.md b/themes/next/docs/LEANCLOUD-COUNTER-SECURITY.md similarity index 100% rename from docs/LEANCLOUD-COUNTER-SECURITY.md rename to themes/next/docs/LEANCLOUD-COUNTER-SECURITY.md diff --git a/docs/LICENSE.txt b/themes/next/docs/LICENSE.txt similarity index 100% rename from docs/LICENSE.txt rename to themes/next/docs/LICENSE.txt diff --git a/docs/MATH.md b/themes/next/docs/MATH.md similarity index 100% rename from docs/MATH.md rename to themes/next/docs/MATH.md diff --git a/docs/UPDATE-FROM-5.1.X.md b/themes/next/docs/UPDATE-FROM-5.1.X.md similarity index 100% rename from docs/UPDATE-FROM-5.1.X.md rename to themes/next/docs/UPDATE-FROM-5.1.X.md diff --git a/docs/ru/DATA-FILES.md b/themes/next/docs/ru/DATA-FILES.md similarity index 100% rename from docs/ru/DATA-FILES.md rename to themes/next/docs/ru/DATA-FILES.md diff --git a/docs/ru/INSTALLATION.md b/themes/next/docs/ru/INSTALLATION.md similarity index 100% rename from docs/ru/INSTALLATION.md rename to themes/next/docs/ru/INSTALLATION.md diff --git a/docs/ru/README.md b/themes/next/docs/ru/README.md similarity index 100% rename from docs/ru/README.md rename to themes/next/docs/ru/README.md diff --git a/docs/ru/UPDATE-FROM-5.1.X.md b/themes/next/docs/ru/UPDATE-FROM-5.1.X.md similarity index 100% rename from docs/ru/UPDATE-FROM-5.1.X.md rename to themes/next/docs/ru/UPDATE-FROM-5.1.X.md diff --git a/docs/zh-CN/ALGOLIA-SEARCH.md b/themes/next/docs/zh-CN/ALGOLIA-SEARCH.md similarity index 100% rename from docs/zh-CN/ALGOLIA-SEARCH.md rename to themes/next/docs/zh-CN/ALGOLIA-SEARCH.md diff --git a/docs/zh-CN/CODE_OF_CONDUCT.md b/themes/next/docs/zh-CN/CODE_OF_CONDUCT.md similarity index 100% rename from docs/zh-CN/CODE_OF_CONDUCT.md rename to themes/next/docs/zh-CN/CODE_OF_CONDUCT.md diff --git a/docs/zh-CN/CONTRIBUTING.md b/themes/next/docs/zh-CN/CONTRIBUTING.md similarity index 100% rename from docs/zh-CN/CONTRIBUTING.md rename to themes/next/docs/zh-CN/CONTRIBUTING.md diff --git a/docs/zh-CN/DATA-FILES.md b/themes/next/docs/zh-CN/DATA-FILES.md similarity index 100% rename from docs/zh-CN/DATA-FILES.md rename to themes/next/docs/zh-CN/DATA-FILES.md diff --git a/docs/zh-CN/INSTALLATION.md b/themes/next/docs/zh-CN/INSTALLATION.md similarity index 100% rename from docs/zh-CN/INSTALLATION.md rename to themes/next/docs/zh-CN/INSTALLATION.md diff --git a/docs/zh-CN/LEANCLOUD-COUNTER-SECURITY.md b/themes/next/docs/zh-CN/LEANCLOUD-COUNTER-SECURITY.md similarity index 100% rename from docs/zh-CN/LEANCLOUD-COUNTER-SECURITY.md rename to themes/next/docs/zh-CN/LEANCLOUD-COUNTER-SECURITY.md diff --git a/docs/zh-CN/MATH.md b/themes/next/docs/zh-CN/MATH.md similarity index 100% rename from docs/zh-CN/MATH.md rename to themes/next/docs/zh-CN/MATH.md diff --git a/docs/zh-CN/README.md b/themes/next/docs/zh-CN/README.md similarity index 100% rename from docs/zh-CN/README.md rename to themes/next/docs/zh-CN/README.md diff --git a/docs/zh-CN/UPDATE-FROM-5.1.X.md b/themes/next/docs/zh-CN/UPDATE-FROM-5.1.X.md similarity index 100% rename from docs/zh-CN/UPDATE-FROM-5.1.X.md rename to themes/next/docs/zh-CN/UPDATE-FROM-5.1.X.md diff --git a/gulpfile.js b/themes/next/gulpfile.js similarity index 100% rename from gulpfile.js rename to themes/next/gulpfile.js diff --git a/languages/de.yml b/themes/next/languages/de.yml similarity index 100% rename from languages/de.yml rename to themes/next/languages/de.yml diff --git a/languages/default.yml b/themes/next/languages/default.yml similarity index 100% rename from languages/default.yml rename to themes/next/languages/default.yml diff --git a/languages/en.yml b/themes/next/languages/en.yml similarity index 100% rename from languages/en.yml rename to themes/next/languages/en.yml diff --git a/languages/es.yml b/themes/next/languages/es.yml similarity index 100% rename from languages/es.yml rename to themes/next/languages/es.yml diff --git a/languages/fa.yml b/themes/next/languages/fa.yml similarity index 100% rename from languages/fa.yml rename to themes/next/languages/fa.yml diff --git a/languages/fr.yml b/themes/next/languages/fr.yml similarity index 100% rename from languages/fr.yml rename to themes/next/languages/fr.yml diff --git a/languages/hu.yml b/themes/next/languages/hu.yml similarity index 100% rename from languages/hu.yml rename to themes/next/languages/hu.yml diff --git a/languages/id.yml b/themes/next/languages/id.yml similarity index 100% rename from languages/id.yml rename to themes/next/languages/id.yml diff --git a/languages/it.yml b/themes/next/languages/it.yml similarity index 100% rename from languages/it.yml rename to themes/next/languages/it.yml diff --git a/languages/ja.yml b/themes/next/languages/ja.yml similarity index 100% rename from languages/ja.yml rename to themes/next/languages/ja.yml diff --git a/languages/ko.yml b/themes/next/languages/ko.yml similarity index 100% rename from languages/ko.yml rename to themes/next/languages/ko.yml diff --git a/languages/nl.yml b/themes/next/languages/nl.yml similarity index 100% rename from languages/nl.yml rename to themes/next/languages/nl.yml diff --git a/languages/pt-BR.yml b/themes/next/languages/pt-BR.yml similarity index 100% rename from languages/pt-BR.yml rename to themes/next/languages/pt-BR.yml diff --git a/languages/pt.yml b/themes/next/languages/pt.yml similarity index 100% rename from languages/pt.yml rename to themes/next/languages/pt.yml diff --git a/languages/ru.yml b/themes/next/languages/ru.yml similarity index 100% rename from languages/ru.yml rename to themes/next/languages/ru.yml diff --git a/languages/tr.yml b/themes/next/languages/tr.yml similarity index 100% rename from languages/tr.yml rename to themes/next/languages/tr.yml diff --git a/languages/uk.yml b/themes/next/languages/uk.yml similarity index 100% rename from languages/uk.yml rename to themes/next/languages/uk.yml diff --git a/languages/vi.yml b/themes/next/languages/vi.yml similarity index 100% rename from languages/vi.yml rename to themes/next/languages/vi.yml diff --git a/languages/zh-CN.yml b/themes/next/languages/zh-CN.yml similarity index 100% rename from languages/zh-CN.yml rename to themes/next/languages/zh-CN.yml diff --git a/languages/zh-HK.yml b/themes/next/languages/zh-HK.yml similarity index 100% rename from languages/zh-HK.yml rename to themes/next/languages/zh-HK.yml diff --git a/languages/zh-TW.yml b/themes/next/languages/zh-TW.yml similarity index 100% rename from languages/zh-TW.yml rename to themes/next/languages/zh-TW.yml diff --git a/layout/_layout.swig b/themes/next/layout/_layout.swig similarity index 100% rename from layout/_layout.swig rename to themes/next/layout/_layout.swig diff --git a/layout/_macro/post-collapse.swig b/themes/next/layout/_macro/post-collapse.swig similarity index 100% rename from layout/_macro/post-collapse.swig rename to themes/next/layout/_macro/post-collapse.swig diff --git a/layout/_macro/post.swig b/themes/next/layout/_macro/post.swig similarity index 100% rename from layout/_macro/post.swig rename to themes/next/layout/_macro/post.swig diff --git a/layout/_macro/sidebar.swig b/themes/next/layout/_macro/sidebar.swig similarity index 100% rename from layout/_macro/sidebar.swig rename to themes/next/layout/_macro/sidebar.swig diff --git a/layout/_partials/analytics/busuanzi-counter.swig b/themes/next/layout/_partials/analytics/busuanzi-counter.swig similarity index 100% rename from layout/_partials/analytics/busuanzi-counter.swig rename to themes/next/layout/_partials/analytics/busuanzi-counter.swig diff --git a/layout/_partials/analytics/cnzz-analytics.swig b/themes/next/layout/_partials/analytics/cnzz-analytics.swig similarity index 100% rename from layout/_partials/analytics/cnzz-analytics.swig rename to themes/next/layout/_partials/analytics/cnzz-analytics.swig diff --git a/layout/_partials/analytics/firestore.swig b/themes/next/layout/_partials/analytics/firestore.swig similarity index 100% rename from layout/_partials/analytics/firestore.swig rename to themes/next/layout/_partials/analytics/firestore.swig diff --git a/layout/_partials/analytics/index.swig b/themes/next/layout/_partials/analytics/index.swig similarity index 100% rename from layout/_partials/analytics/index.swig rename to themes/next/layout/_partials/analytics/index.swig diff --git a/layout/_partials/analytics/lean-analytics.swig b/themes/next/layout/_partials/analytics/lean-analytics.swig similarity index 100% rename from layout/_partials/analytics/lean-analytics.swig rename to themes/next/layout/_partials/analytics/lean-analytics.swig diff --git a/layout/_partials/analytics/tencent-analytics.swig b/themes/next/layout/_partials/analytics/tencent-analytics.swig similarity index 100% rename from layout/_partials/analytics/tencent-analytics.swig rename to themes/next/layout/_partials/analytics/tencent-analytics.swig diff --git a/layout/_partials/analytics/tencent-mta.swig b/themes/next/layout/_partials/analytics/tencent-mta.swig similarity index 100% rename from layout/_partials/analytics/tencent-mta.swig rename to themes/next/layout/_partials/analytics/tencent-mta.swig diff --git a/layout/_partials/comments.swig b/themes/next/layout/_partials/comments.swig similarity index 100% rename from layout/_partials/comments.swig rename to themes/next/layout/_partials/comments.swig diff --git a/layout/_partials/footer.swig b/themes/next/layout/_partials/footer.swig similarity index 100% rename from layout/_partials/footer.swig rename to themes/next/layout/_partials/footer.swig diff --git a/layout/_partials/head/head-unique.swig b/themes/next/layout/_partials/head/head-unique.swig similarity index 100% rename from layout/_partials/head/head-unique.swig rename to themes/next/layout/_partials/head/head-unique.swig diff --git a/layout/_partials/head/head.swig b/themes/next/layout/_partials/head/head.swig similarity index 100% rename from layout/_partials/head/head.swig rename to themes/next/layout/_partials/head/head.swig diff --git a/layout/_partials/header/brand.swig b/themes/next/layout/_partials/header/brand.swig similarity index 100% rename from layout/_partials/header/brand.swig rename to themes/next/layout/_partials/header/brand.swig diff --git a/layout/_partials/header/index.swig b/themes/next/layout/_partials/header/index.swig similarity index 100% rename from layout/_partials/header/index.swig rename to themes/next/layout/_partials/header/index.swig diff --git a/layout/_partials/header/menu-item.swig b/themes/next/layout/_partials/header/menu-item.swig similarity index 100% rename from layout/_partials/header/menu-item.swig rename to themes/next/layout/_partials/header/menu-item.swig diff --git a/layout/_partials/header/menu.swig b/themes/next/layout/_partials/header/menu.swig similarity index 100% rename from layout/_partials/header/menu.swig rename to themes/next/layout/_partials/header/menu.swig diff --git a/layout/_partials/header/sub-menu.swig b/themes/next/layout/_partials/header/sub-menu.swig similarity index 100% rename from layout/_partials/header/sub-menu.swig rename to themes/next/layout/_partials/header/sub-menu.swig diff --git a/layout/_partials/page/breadcrumb.swig b/themes/next/layout/_partials/page/breadcrumb.swig similarity index 100% rename from layout/_partials/page/breadcrumb.swig rename to themes/next/layout/_partials/page/breadcrumb.swig diff --git a/layout/_partials/page/page-header.swig b/themes/next/layout/_partials/page/page-header.swig similarity index 100% rename from layout/_partials/page/page-header.swig rename to themes/next/layout/_partials/page/page-header.swig diff --git a/layout/_partials/pagination.swig b/themes/next/layout/_partials/pagination.swig similarity index 100% rename from layout/_partials/pagination.swig rename to themes/next/layout/_partials/pagination.swig diff --git a/layout/_partials/post-edit.swig b/themes/next/layout/_partials/post-edit.swig similarity index 100% rename from layout/_partials/post-edit.swig rename to themes/next/layout/_partials/post-edit.swig diff --git a/layout/_partials/post/post-copyright.swig b/themes/next/layout/_partials/post/post-copyright.swig similarity index 100% rename from layout/_partials/post/post-copyright.swig rename to themes/next/layout/_partials/post/post-copyright.swig diff --git a/layout/_partials/post/post-footer.swig b/themes/next/layout/_partials/post/post-footer.swig similarity index 100% rename from layout/_partials/post/post-footer.swig rename to themes/next/layout/_partials/post/post-footer.swig diff --git a/layout/_partials/post/post-related.swig b/themes/next/layout/_partials/post/post-related.swig similarity index 100% rename from layout/_partials/post/post-related.swig rename to themes/next/layout/_partials/post/post-related.swig diff --git a/layout/_partials/post/post-reward.swig b/themes/next/layout/_partials/post/post-reward.swig similarity index 100% rename from layout/_partials/post/post-reward.swig rename to themes/next/layout/_partials/post/post-reward.swig diff --git a/layout/_partials/post/wechat-subscriber.swig b/themes/next/layout/_partials/post/wechat-subscriber.swig similarity index 100% rename from layout/_partials/post/wechat-subscriber.swig rename to themes/next/layout/_partials/post/wechat-subscriber.swig diff --git a/layout/_partials/search/algolia-search.swig b/themes/next/layout/_partials/search/algolia-search.swig similarity index 100% rename from layout/_partials/search/algolia-search.swig rename to themes/next/layout/_partials/search/algolia-search.swig diff --git a/layout/_partials/search/index.swig b/themes/next/layout/_partials/search/index.swig similarity index 100% rename from layout/_partials/search/index.swig rename to themes/next/layout/_partials/search/index.swig diff --git a/layout/_partials/search/localsearch.swig b/themes/next/layout/_partials/search/localsearch.swig similarity index 100% rename from layout/_partials/search/localsearch.swig rename to themes/next/layout/_partials/search/localsearch.swig diff --git a/layout/_partials/sidebar/site-overview.swig b/themes/next/layout/_partials/sidebar/site-overview.swig similarity index 100% rename from layout/_partials/sidebar/site-overview.swig rename to themes/next/layout/_partials/sidebar/site-overview.swig diff --git a/layout/_partials/widgets.swig b/themes/next/layout/_partials/widgets.swig similarity index 100% rename from layout/_partials/widgets.swig rename to themes/next/layout/_partials/widgets.swig diff --git a/layout/_scripts/index.swig b/themes/next/layout/_scripts/index.swig similarity index 100% rename from layout/_scripts/index.swig rename to themes/next/layout/_scripts/index.swig diff --git a/layout/_scripts/noscript.swig b/themes/next/layout/_scripts/noscript.swig similarity index 100% rename from layout/_scripts/noscript.swig rename to themes/next/layout/_scripts/noscript.swig diff --git a/layout/_scripts/pages/schedule.swig b/themes/next/layout/_scripts/pages/schedule.swig similarity index 100% rename from layout/_scripts/pages/schedule.swig rename to themes/next/layout/_scripts/pages/schedule.swig diff --git a/layout/_scripts/pjax.swig b/themes/next/layout/_scripts/pjax.swig similarity index 100% rename from layout/_scripts/pjax.swig rename to themes/next/layout/_scripts/pjax.swig diff --git a/layout/_scripts/schemes/gemini.swig b/themes/next/layout/_scripts/schemes/gemini.swig similarity index 100% rename from layout/_scripts/schemes/gemini.swig rename to themes/next/layout/_scripts/schemes/gemini.swig diff --git a/layout/_scripts/schemes/mist.swig b/themes/next/layout/_scripts/schemes/mist.swig similarity index 100% rename from layout/_scripts/schemes/mist.swig rename to themes/next/layout/_scripts/schemes/mist.swig diff --git a/layout/_scripts/schemes/muse.swig b/themes/next/layout/_scripts/schemes/muse.swig similarity index 100% rename from layout/_scripts/schemes/muse.swig rename to themes/next/layout/_scripts/schemes/muse.swig diff --git a/layout/_scripts/schemes/pisces.swig b/themes/next/layout/_scripts/schemes/pisces.swig similarity index 100% rename from layout/_scripts/schemes/pisces.swig rename to themes/next/layout/_scripts/schemes/pisces.swig diff --git a/layout/_scripts/three.swig b/themes/next/layout/_scripts/three.swig similarity index 100% rename from layout/_scripts/three.swig rename to themes/next/layout/_scripts/three.swig diff --git a/layout/_scripts/vendors.swig b/themes/next/layout/_scripts/vendors.swig similarity index 100% rename from layout/_scripts/vendors.swig rename to themes/next/layout/_scripts/vendors.swig diff --git a/layout/_third-party/analytics/application-insights.swig b/themes/next/layout/_third-party/analytics/application-insights.swig similarity index 100% rename from layout/_third-party/analytics/application-insights.swig rename to themes/next/layout/_third-party/analytics/application-insights.swig diff --git a/layout/_third-party/analytics/baidu-analytics.swig b/themes/next/layout/_third-party/analytics/baidu-analytics.swig similarity index 100% rename from layout/_third-party/analytics/baidu-analytics.swig rename to themes/next/layout/_third-party/analytics/baidu-analytics.swig diff --git a/layout/_third-party/analytics/google-analytics.swig b/themes/next/layout/_third-party/analytics/google-analytics.swig similarity index 100% rename from layout/_third-party/analytics/google-analytics.swig rename to themes/next/layout/_third-party/analytics/google-analytics.swig diff --git a/layout/_third-party/analytics/growingio.swig b/themes/next/layout/_third-party/analytics/growingio.swig similarity index 100% rename from layout/_third-party/analytics/growingio.swig rename to themes/next/layout/_third-party/analytics/growingio.swig diff --git a/layout/_third-party/analytics/index.swig b/themes/next/layout/_third-party/analytics/index.swig similarity index 100% rename from layout/_third-party/analytics/index.swig rename to themes/next/layout/_third-party/analytics/index.swig diff --git a/layout/_third-party/baidu-push.swig b/themes/next/layout/_third-party/baidu-push.swig similarity index 100% rename from layout/_third-party/baidu-push.swig rename to themes/next/layout/_third-party/baidu-push.swig diff --git a/layout/_third-party/chat/chatra.swig b/themes/next/layout/_third-party/chat/chatra.swig similarity index 100% rename from layout/_third-party/chat/chatra.swig rename to themes/next/layout/_third-party/chat/chatra.swig diff --git a/layout/_third-party/chat/index.swig b/themes/next/layout/_third-party/chat/index.swig similarity index 100% rename from layout/_third-party/chat/index.swig rename to themes/next/layout/_third-party/chat/index.swig diff --git a/layout/_third-party/chat/tidio.swig b/themes/next/layout/_third-party/chat/tidio.swig similarity index 100% rename from layout/_third-party/chat/tidio.swig rename to themes/next/layout/_third-party/chat/tidio.swig diff --git a/layout/_third-party/comments/changyan.swig b/themes/next/layout/_third-party/comments/changyan.swig similarity index 100% rename from layout/_third-party/comments/changyan.swig rename to themes/next/layout/_third-party/comments/changyan.swig diff --git a/layout/_third-party/comments/disqus.swig b/themes/next/layout/_third-party/comments/disqus.swig similarity index 100% rename from layout/_third-party/comments/disqus.swig rename to themes/next/layout/_third-party/comments/disqus.swig diff --git a/layout/_third-party/comments/disqusjs.swig b/themes/next/layout/_third-party/comments/disqusjs.swig similarity index 100% rename from layout/_third-party/comments/disqusjs.swig rename to themes/next/layout/_third-party/comments/disqusjs.swig diff --git a/layout/_third-party/comments/gitalk.swig b/themes/next/layout/_third-party/comments/gitalk.swig similarity index 100% rename from layout/_third-party/comments/gitalk.swig rename to themes/next/layout/_third-party/comments/gitalk.swig diff --git a/layout/_third-party/comments/livere.swig b/themes/next/layout/_third-party/comments/livere.swig similarity index 100% rename from layout/_third-party/comments/livere.swig rename to themes/next/layout/_third-party/comments/livere.swig diff --git a/layout/_third-party/comments/valine.swig b/themes/next/layout/_third-party/comments/valine.swig similarity index 100% rename from layout/_third-party/comments/valine.swig rename to themes/next/layout/_third-party/comments/valine.swig diff --git a/layout/_third-party/facebook-sdk.swig b/themes/next/layout/_third-party/facebook-sdk.swig similarity index 100% rename from layout/_third-party/facebook-sdk.swig rename to themes/next/layout/_third-party/facebook-sdk.swig diff --git a/layout/_third-party/index.swig b/themes/next/layout/_third-party/index.swig similarity index 100% rename from layout/_third-party/index.swig rename to themes/next/layout/_third-party/index.swig diff --git a/layout/_third-party/math/index.swig b/themes/next/layout/_third-party/math/index.swig similarity index 100% rename from layout/_third-party/math/index.swig rename to themes/next/layout/_third-party/math/index.swig diff --git a/layout/_third-party/math/katex.swig b/themes/next/layout/_third-party/math/katex.swig similarity index 100% rename from layout/_third-party/math/katex.swig rename to themes/next/layout/_third-party/math/katex.swig diff --git a/layout/_third-party/math/mathjax.swig b/themes/next/layout/_third-party/math/mathjax.swig similarity index 100% rename from layout/_third-party/math/mathjax.swig rename to themes/next/layout/_third-party/math/mathjax.swig diff --git a/layout/_third-party/quicklink.swig b/themes/next/layout/_third-party/quicklink.swig similarity index 100% rename from layout/_third-party/quicklink.swig rename to themes/next/layout/_third-party/quicklink.swig diff --git a/layout/_third-party/rating.swig b/themes/next/layout/_third-party/rating.swig similarity index 100% rename from layout/_third-party/rating.swig rename to themes/next/layout/_third-party/rating.swig diff --git a/layout/_third-party/search/algolia-search.swig b/themes/next/layout/_third-party/search/algolia-search.swig similarity index 100% rename from layout/_third-party/search/algolia-search.swig rename to themes/next/layout/_third-party/search/algolia-search.swig diff --git a/layout/_third-party/search/index.swig b/themes/next/layout/_third-party/search/index.swig similarity index 100% rename from layout/_third-party/search/index.swig rename to themes/next/layout/_third-party/search/index.swig diff --git a/layout/_third-party/search/localsearch.swig b/themes/next/layout/_third-party/search/localsearch.swig similarity index 100% rename from layout/_third-party/search/localsearch.swig rename to themes/next/layout/_third-party/search/localsearch.swig diff --git a/layout/_third-party/search/swiftype.swig b/themes/next/layout/_third-party/search/swiftype.swig similarity index 100% rename from layout/_third-party/search/swiftype.swig rename to themes/next/layout/_third-party/search/swiftype.swig diff --git a/layout/_third-party/tags/index.swig b/themes/next/layout/_third-party/tags/index.swig similarity index 100% rename from layout/_third-party/tags/index.swig rename to themes/next/layout/_third-party/tags/index.swig diff --git a/layout/_third-party/tags/mermaid.swig b/themes/next/layout/_third-party/tags/mermaid.swig similarity index 100% rename from layout/_third-party/tags/mermaid.swig rename to themes/next/layout/_third-party/tags/mermaid.swig diff --git a/layout/_third-party/tags/pdf.swig b/themes/next/layout/_third-party/tags/pdf.swig similarity index 100% rename from layout/_third-party/tags/pdf.swig rename to themes/next/layout/_third-party/tags/pdf.swig diff --git a/layout/_third-party/vkontakte-api.swig b/themes/next/layout/_third-party/vkontakte-api.swig similarity index 100% rename from layout/_third-party/vkontakte-api.swig rename to themes/next/layout/_third-party/vkontakte-api.swig diff --git a/layout/archive.swig b/themes/next/layout/archive.swig similarity index 100% rename from layout/archive.swig rename to themes/next/layout/archive.swig diff --git a/layout/category.swig b/themes/next/layout/category.swig similarity index 100% rename from layout/category.swig rename to themes/next/layout/category.swig diff --git a/layout/index.swig b/themes/next/layout/index.swig similarity index 100% rename from layout/index.swig rename to themes/next/layout/index.swig diff --git a/layout/page.swig b/themes/next/layout/page.swig similarity index 100% rename from layout/page.swig rename to themes/next/layout/page.swig diff --git a/layout/post.swig b/themes/next/layout/post.swig similarity index 100% rename from layout/post.swig rename to themes/next/layout/post.swig diff --git a/layout/tag.swig b/themes/next/layout/tag.swig similarity index 100% rename from layout/tag.swig rename to themes/next/layout/tag.swig diff --git a/themes/next/package.json b/themes/next/package.json new file mode 100644 index 000000000..3716f964a --- /dev/null +++ b/themes/next/package.json @@ -0,0 +1,39 @@ +{ + "name": "hexo-theme-next", + "version": "7.4.1", + "description": "Elegant and powerful theme for Hexo", + "main": "gulpfile.js", + "scripts": { + "test": "gulp", + "contributors:add": "all-contributors add", + "contributors:generate": "all-contributors generate" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/theme-next/hexo-theme-next.git" + }, + "keywords": [ + "hexo", + "theme", + "next" + ], + "author": "NexT (https://theme-next.org)", + "license": "AGPL", + "bugs": { + "url": "https://github.com/theme-next/hexo-theme-next/issues" + }, + "homepage": "https://theme-next.org", + "devDependencies": { + "all-contributors-cli": "^6.9.1", + "eslint": "^6.5.1", + "eslint-config-theme-next": "^1.1.3", + "gulp": "^4.0.2", + "gulp-eslint": "^6.0.0", + "gulp-shell": "^0.7.1", + "js-yaml": "^3.13.1", + "stylint": "^2.0.0" + }, + "engines": { + "node": ">=8.6.0" + } +} diff --git a/scripts/events/index.js b/themes/next/scripts/events/index.js similarity index 100% rename from scripts/events/index.js rename to themes/next/scripts/events/index.js diff --git a/scripts/events/lib/config.js b/themes/next/scripts/events/lib/config.js similarity index 100% rename from scripts/events/lib/config.js rename to themes/next/scripts/events/lib/config.js diff --git a/scripts/events/lib/injects-point.js b/themes/next/scripts/events/lib/injects-point.js similarity index 100% rename from scripts/events/lib/injects-point.js rename to themes/next/scripts/events/lib/injects-point.js diff --git a/scripts/events/lib/injects.js b/themes/next/scripts/events/lib/injects.js similarity index 100% rename from scripts/events/lib/injects.js rename to themes/next/scripts/events/lib/injects.js diff --git a/scripts/filters/comment/changyan.js b/themes/next/scripts/filters/comment/changyan.js similarity index 100% rename from scripts/filters/comment/changyan.js rename to themes/next/scripts/filters/comment/changyan.js diff --git a/scripts/filters/comment/common.js b/themes/next/scripts/filters/comment/common.js similarity index 100% rename from scripts/filters/comment/common.js rename to themes/next/scripts/filters/comment/common.js diff --git a/scripts/filters/comment/default-config.js b/themes/next/scripts/filters/comment/default-config.js similarity index 100% rename from scripts/filters/comment/default-config.js rename to themes/next/scripts/filters/comment/default-config.js diff --git a/scripts/filters/comment/disqus.js b/themes/next/scripts/filters/comment/disqus.js similarity index 100% rename from scripts/filters/comment/disqus.js rename to themes/next/scripts/filters/comment/disqus.js diff --git a/scripts/filters/comment/disqusjs.js b/themes/next/scripts/filters/comment/disqusjs.js similarity index 100% rename from scripts/filters/comment/disqusjs.js rename to themes/next/scripts/filters/comment/disqusjs.js diff --git a/scripts/filters/comment/facebook-comments-plugin.js b/themes/next/scripts/filters/comment/facebook-comments-plugin.js similarity index 100% rename from scripts/filters/comment/facebook-comments-plugin.js rename to themes/next/scripts/filters/comment/facebook-comments-plugin.js diff --git a/scripts/filters/comment/gitalk.js b/themes/next/scripts/filters/comment/gitalk.js similarity index 100% rename from scripts/filters/comment/gitalk.js rename to themes/next/scripts/filters/comment/gitalk.js diff --git a/scripts/filters/comment/livere.js b/themes/next/scripts/filters/comment/livere.js similarity index 100% rename from scripts/filters/comment/livere.js rename to themes/next/scripts/filters/comment/livere.js diff --git a/scripts/filters/comment/valine.js b/themes/next/scripts/filters/comment/valine.js similarity index 100% rename from scripts/filters/comment/valine.js rename to themes/next/scripts/filters/comment/valine.js diff --git a/scripts/filters/comment/vkontakte.js b/themes/next/scripts/filters/comment/vkontakte.js similarity index 100% rename from scripts/filters/comment/vkontakte.js rename to themes/next/scripts/filters/comment/vkontakte.js diff --git a/scripts/filters/default-injects.js b/themes/next/scripts/filters/default-injects.js similarity index 100% rename from scripts/filters/default-injects.js rename to themes/next/scripts/filters/default-injects.js diff --git a/scripts/filters/excerpt.js b/themes/next/scripts/filters/excerpt.js similarity index 100% rename from scripts/filters/excerpt.js rename to themes/next/scripts/filters/excerpt.js diff --git a/scripts/filters/exturl.js b/themes/next/scripts/filters/exturl.js similarity index 100% rename from scripts/filters/exturl.js rename to themes/next/scripts/filters/exturl.js diff --git a/scripts/filters/lazyload.js b/themes/next/scripts/filters/lazyload.js similarity index 100% rename from scripts/filters/lazyload.js rename to themes/next/scripts/filters/lazyload.js diff --git a/scripts/filters/minify.js b/themes/next/scripts/filters/minify.js similarity index 100% rename from scripts/filters/minify.js rename to themes/next/scripts/filters/minify.js diff --git a/scripts/helpers/engine.js b/themes/next/scripts/helpers/engine.js similarity index 100% rename from scripts/helpers/engine.js rename to themes/next/scripts/helpers/engine.js diff --git a/scripts/helpers/font.js b/themes/next/scripts/helpers/font.js similarity index 100% rename from scripts/helpers/font.js rename to themes/next/scripts/helpers/font.js diff --git a/scripts/helpers/next-inject.js b/themes/next/scripts/helpers/next-inject.js similarity index 100% rename from scripts/helpers/next-inject.js rename to themes/next/scripts/helpers/next-inject.js diff --git a/scripts/helpers/next-js.js b/themes/next/scripts/helpers/next-js.js similarity index 100% rename from scripts/helpers/next-js.js rename to themes/next/scripts/helpers/next-js.js diff --git a/scripts/helpers/next-url.js b/themes/next/scripts/helpers/next-url.js similarity index 100% rename from scripts/helpers/next-url.js rename to themes/next/scripts/helpers/next-url.js diff --git a/scripts/helpers/next-vendors.js b/themes/next/scripts/helpers/next-vendors.js similarity index 100% rename from scripts/helpers/next-vendors.js rename to themes/next/scripts/helpers/next-vendors.js diff --git a/scripts/tags/button.js b/themes/next/scripts/tags/button.js similarity index 100% rename from scripts/tags/button.js rename to themes/next/scripts/tags/button.js diff --git a/scripts/tags/caniuse.js b/themes/next/scripts/tags/caniuse.js similarity index 100% rename from scripts/tags/caniuse.js rename to themes/next/scripts/tags/caniuse.js diff --git a/scripts/tags/center-quote.js b/themes/next/scripts/tags/center-quote.js similarity index 100% rename from scripts/tags/center-quote.js rename to themes/next/scripts/tags/center-quote.js diff --git a/scripts/tags/group-pictures.js b/themes/next/scripts/tags/group-pictures.js similarity index 100% rename from scripts/tags/group-pictures.js rename to themes/next/scripts/tags/group-pictures.js diff --git a/scripts/tags/include-raw.js b/themes/next/scripts/tags/include-raw.js similarity index 100% rename from scripts/tags/include-raw.js rename to themes/next/scripts/tags/include-raw.js diff --git a/scripts/tags/label.js b/themes/next/scripts/tags/label.js similarity index 100% rename from scripts/tags/label.js rename to themes/next/scripts/tags/label.js diff --git a/scripts/tags/mermaid.js b/themes/next/scripts/tags/mermaid.js similarity index 100% rename from scripts/tags/mermaid.js rename to themes/next/scripts/tags/mermaid.js diff --git a/scripts/tags/note.js b/themes/next/scripts/tags/note.js similarity index 100% rename from scripts/tags/note.js rename to themes/next/scripts/tags/note.js diff --git a/scripts/tags/pdf.js b/themes/next/scripts/tags/pdf.js similarity index 100% rename from scripts/tags/pdf.js rename to themes/next/scripts/tags/pdf.js diff --git a/scripts/tags/tabs.js b/themes/next/scripts/tags/tabs.js similarity index 100% rename from scripts/tags/tabs.js rename to themes/next/scripts/tags/tabs.js diff --git a/scripts/tags/video.js b/themes/next/scripts/tags/video.js similarity index 100% rename from scripts/tags/video.js rename to themes/next/scripts/tags/video.js diff --git a/source/css/_common/components/back-to-top-sidebar.styl b/themes/next/source/css/_common/components/back-to-top-sidebar.styl similarity index 100% rename from source/css/_common/components/back-to-top-sidebar.styl rename to themes/next/source/css/_common/components/back-to-top-sidebar.styl diff --git a/source/css/_common/components/back-to-top.styl b/themes/next/source/css/_common/components/back-to-top.styl similarity index 100% rename from source/css/_common/components/back-to-top.styl rename to themes/next/source/css/_common/components/back-to-top.styl diff --git a/source/css/_common/components/components.styl b/themes/next/source/css/_common/components/components.styl similarity index 100% rename from source/css/_common/components/components.styl rename to themes/next/source/css/_common/components/components.styl diff --git a/source/css/_common/components/pages/breadcrumb.styl b/themes/next/source/css/_common/components/pages/breadcrumb.styl similarity index 100% rename from source/css/_common/components/pages/breadcrumb.styl rename to themes/next/source/css/_common/components/pages/breadcrumb.styl diff --git a/source/css/_common/components/pages/categories.styl b/themes/next/source/css/_common/components/pages/categories.styl similarity index 100% rename from source/css/_common/components/pages/categories.styl rename to themes/next/source/css/_common/components/pages/categories.styl diff --git a/source/css/_common/components/pages/pages.styl b/themes/next/source/css/_common/components/pages/pages.styl similarity index 100% rename from source/css/_common/components/pages/pages.styl rename to themes/next/source/css/_common/components/pages/pages.styl diff --git a/source/css/_common/components/pages/schedule.styl b/themes/next/source/css/_common/components/pages/schedule.styl similarity index 100% rename from source/css/_common/components/pages/schedule.styl rename to themes/next/source/css/_common/components/pages/schedule.styl diff --git a/source/css/_common/components/pages/tag-cloud.styl b/themes/next/source/css/_common/components/pages/tag-cloud.styl similarity index 100% rename from source/css/_common/components/pages/tag-cloud.styl rename to themes/next/source/css/_common/components/pages/tag-cloud.styl diff --git a/source/css/_common/components/post/post-collapse.styl b/themes/next/source/css/_common/components/post/post-collapse.styl similarity index 100% rename from source/css/_common/components/post/post-collapse.styl rename to themes/next/source/css/_common/components/post/post-collapse.styl diff --git a/source/css/_common/components/post/post-copyright.styl b/themes/next/source/css/_common/components/post/post-copyright.styl similarity index 100% rename from source/css/_common/components/post/post-copyright.styl rename to themes/next/source/css/_common/components/post/post-copyright.styl diff --git a/source/css/_common/components/post/post-eof.styl b/themes/next/source/css/_common/components/post/post-eof.styl similarity index 100% rename from source/css/_common/components/post/post-eof.styl rename to themes/next/source/css/_common/components/post/post-eof.styl diff --git a/source/css/_common/components/post/post-expand.styl b/themes/next/source/css/_common/components/post/post-expand.styl similarity index 100% rename from source/css/_common/components/post/post-expand.styl rename to themes/next/source/css/_common/components/post/post-expand.styl diff --git a/source/css/_common/components/post/post-gallery.styl b/themes/next/source/css/_common/components/post/post-gallery.styl similarity index 100% rename from source/css/_common/components/post/post-gallery.styl rename to themes/next/source/css/_common/components/post/post-gallery.styl diff --git a/source/css/_common/components/post/post-header.styl b/themes/next/source/css/_common/components/post/post-header.styl similarity index 100% rename from source/css/_common/components/post/post-header.styl rename to themes/next/source/css/_common/components/post/post-header.styl diff --git a/source/css/_common/components/post/post-nav.styl b/themes/next/source/css/_common/components/post/post-nav.styl similarity index 100% rename from source/css/_common/components/post/post-nav.styl rename to themes/next/source/css/_common/components/post/post-nav.styl diff --git a/source/css/_common/components/post/post-reward.styl b/themes/next/source/css/_common/components/post/post-reward.styl similarity index 100% rename from source/css/_common/components/post/post-reward.styl rename to themes/next/source/css/_common/components/post/post-reward.styl diff --git a/source/css/_common/components/post/post-rtl.styl b/themes/next/source/css/_common/components/post/post-rtl.styl similarity index 100% rename from source/css/_common/components/post/post-rtl.styl rename to themes/next/source/css/_common/components/post/post-rtl.styl diff --git a/source/css/_common/components/post/post-tags.styl b/themes/next/source/css/_common/components/post/post-tags.styl similarity index 100% rename from source/css/_common/components/post/post-tags.styl rename to themes/next/source/css/_common/components/post/post-tags.styl diff --git a/source/css/_common/components/post/post-widgets.styl b/themes/next/source/css/_common/components/post/post-widgets.styl similarity index 100% rename from source/css/_common/components/post/post-widgets.styl rename to themes/next/source/css/_common/components/post/post-widgets.styl diff --git a/source/css/_common/components/post/post.styl b/themes/next/source/css/_common/components/post/post.styl similarity index 100% rename from source/css/_common/components/post/post.styl rename to themes/next/source/css/_common/components/post/post.styl diff --git a/source/css/_common/components/rainbow.styl b/themes/next/source/css/_common/components/rainbow.styl similarity index 100% rename from source/css/_common/components/rainbow.styl rename to themes/next/source/css/_common/components/rainbow.styl diff --git a/source/css/_common/components/reading-progress.styl b/themes/next/source/css/_common/components/reading-progress.styl similarity index 100% rename from source/css/_common/components/reading-progress.styl rename to themes/next/source/css/_common/components/reading-progress.styl diff --git a/source/css/_common/components/scrollbar.styl b/themes/next/source/css/_common/components/scrollbar.styl similarity index 100% rename from source/css/_common/components/scrollbar.styl rename to themes/next/source/css/_common/components/scrollbar.styl diff --git a/source/css/_common/components/third-party/gitalk.styl b/themes/next/source/css/_common/components/third-party/gitalk.styl similarity index 100% rename from source/css/_common/components/third-party/gitalk.styl rename to themes/next/source/css/_common/components/third-party/gitalk.styl diff --git a/source/css/_common/components/third-party/math.styl b/themes/next/source/css/_common/components/third-party/math.styl similarity index 100% rename from source/css/_common/components/third-party/math.styl rename to themes/next/source/css/_common/components/third-party/math.styl diff --git a/source/css/_common/components/third-party/related-posts.styl b/themes/next/source/css/_common/components/third-party/related-posts.styl similarity index 100% rename from source/css/_common/components/third-party/related-posts.styl rename to themes/next/source/css/_common/components/third-party/related-posts.styl diff --git a/source/css/_common/components/third-party/search.styl b/themes/next/source/css/_common/components/third-party/search.styl similarity index 100% rename from source/css/_common/components/third-party/search.styl rename to themes/next/source/css/_common/components/third-party/search.styl diff --git a/source/css/_common/components/third-party/third-party.styl b/themes/next/source/css/_common/components/third-party/third-party.styl similarity index 100% rename from source/css/_common/components/third-party/third-party.styl rename to themes/next/source/css/_common/components/third-party/third-party.styl diff --git a/source/css/_common/outline/footer/footer.styl b/themes/next/source/css/_common/outline/footer/footer.styl similarity index 100% rename from source/css/_common/outline/footer/footer.styl rename to themes/next/source/css/_common/outline/footer/footer.styl diff --git a/source/css/_common/outline/header/bookmark.styl b/themes/next/source/css/_common/outline/header/bookmark.styl similarity index 100% rename from source/css/_common/outline/header/bookmark.styl rename to themes/next/source/css/_common/outline/header/bookmark.styl diff --git a/source/css/_common/outline/header/github-banner.styl b/themes/next/source/css/_common/outline/header/github-banner.styl similarity index 100% rename from source/css/_common/outline/header/github-banner.styl rename to themes/next/source/css/_common/outline/header/github-banner.styl diff --git a/source/css/_common/outline/header/header.styl b/themes/next/source/css/_common/outline/header/header.styl similarity index 100% rename from source/css/_common/outline/header/header.styl rename to themes/next/source/css/_common/outline/header/header.styl diff --git a/source/css/_common/outline/header/headerband.styl b/themes/next/source/css/_common/outline/header/headerband.styl similarity index 100% rename from source/css/_common/outline/header/headerband.styl rename to themes/next/source/css/_common/outline/header/headerband.styl diff --git a/source/css/_common/outline/header/menu.styl b/themes/next/source/css/_common/outline/header/menu.styl similarity index 100% rename from source/css/_common/outline/header/menu.styl rename to themes/next/source/css/_common/outline/header/menu.styl diff --git a/source/css/_common/outline/header/site-meta.styl b/themes/next/source/css/_common/outline/header/site-meta.styl similarity index 100% rename from source/css/_common/outline/header/site-meta.styl rename to themes/next/source/css/_common/outline/header/site-meta.styl diff --git a/source/css/_common/outline/header/site-nav.styl b/themes/next/source/css/_common/outline/header/site-nav.styl similarity index 100% rename from source/css/_common/outline/header/site-nav.styl rename to themes/next/source/css/_common/outline/header/site-nav.styl diff --git a/source/css/_common/outline/mobile.styl b/themes/next/source/css/_common/outline/mobile.styl similarity index 100% rename from source/css/_common/outline/mobile.styl rename to themes/next/source/css/_common/outline/mobile.styl diff --git a/source/css/_common/outline/outline.styl b/themes/next/source/css/_common/outline/outline.styl similarity index 100% rename from source/css/_common/outline/outline.styl rename to themes/next/source/css/_common/outline/outline.styl diff --git a/source/css/_common/outline/sidebar/sidebar-author-links.styl b/themes/next/source/css/_common/outline/sidebar/sidebar-author-links.styl similarity index 100% rename from source/css/_common/outline/sidebar/sidebar-author-links.styl rename to themes/next/source/css/_common/outline/sidebar/sidebar-author-links.styl diff --git a/source/css/_common/outline/sidebar/sidebar-author.styl b/themes/next/source/css/_common/outline/sidebar/sidebar-author.styl similarity index 100% rename from source/css/_common/outline/sidebar/sidebar-author.styl rename to themes/next/source/css/_common/outline/sidebar/sidebar-author.styl diff --git a/source/css/_common/outline/sidebar/sidebar-blogroll.styl b/themes/next/source/css/_common/outline/sidebar/sidebar-blogroll.styl similarity index 100% rename from source/css/_common/outline/sidebar/sidebar-blogroll.styl rename to themes/next/source/css/_common/outline/sidebar/sidebar-blogroll.styl diff --git a/source/css/_common/outline/sidebar/sidebar-button.styl b/themes/next/source/css/_common/outline/sidebar/sidebar-button.styl similarity index 100% rename from source/css/_common/outline/sidebar/sidebar-button.styl rename to themes/next/source/css/_common/outline/sidebar/sidebar-button.styl diff --git a/source/css/_common/outline/sidebar/sidebar-dimmer.styl b/themes/next/source/css/_common/outline/sidebar/sidebar-dimmer.styl similarity index 100% rename from source/css/_common/outline/sidebar/sidebar-dimmer.styl rename to themes/next/source/css/_common/outline/sidebar/sidebar-dimmer.styl diff --git a/source/css/_common/outline/sidebar/sidebar-nav.styl b/themes/next/source/css/_common/outline/sidebar/sidebar-nav.styl similarity index 100% rename from source/css/_common/outline/sidebar/sidebar-nav.styl rename to themes/next/source/css/_common/outline/sidebar/sidebar-nav.styl diff --git a/source/css/_common/outline/sidebar/sidebar-toc.styl b/themes/next/source/css/_common/outline/sidebar/sidebar-toc.styl similarity index 100% rename from source/css/_common/outline/sidebar/sidebar-toc.styl rename to themes/next/source/css/_common/outline/sidebar/sidebar-toc.styl diff --git a/source/css/_common/outline/sidebar/sidebar-toggle.styl b/themes/next/source/css/_common/outline/sidebar/sidebar-toggle.styl similarity index 100% rename from source/css/_common/outline/sidebar/sidebar-toggle.styl rename to themes/next/source/css/_common/outline/sidebar/sidebar-toggle.styl diff --git a/source/css/_common/outline/sidebar/sidebar.styl b/themes/next/source/css/_common/outline/sidebar/sidebar.styl similarity index 100% rename from source/css/_common/outline/sidebar/sidebar.styl rename to themes/next/source/css/_common/outline/sidebar/sidebar.styl diff --git a/source/css/_common/outline/sidebar/site-state.styl b/themes/next/source/css/_common/outline/sidebar/site-state.styl similarity index 100% rename from source/css/_common/outline/sidebar/site-state.styl rename to themes/next/source/css/_common/outline/sidebar/site-state.styl diff --git a/source/css/_common/scaffolding/base.styl b/themes/next/source/css/_common/scaffolding/base.styl similarity index 100% rename from source/css/_common/scaffolding/base.styl rename to themes/next/source/css/_common/scaffolding/base.styl diff --git a/source/css/_common/scaffolding/buttons.styl b/themes/next/source/css/_common/scaffolding/buttons.styl similarity index 100% rename from source/css/_common/scaffolding/buttons.styl rename to themes/next/source/css/_common/scaffolding/buttons.styl diff --git a/source/css/_common/scaffolding/comments.styl b/themes/next/source/css/_common/scaffolding/comments.styl similarity index 100% rename from source/css/_common/scaffolding/comments.styl rename to themes/next/source/css/_common/scaffolding/comments.styl diff --git a/source/css/_common/scaffolding/highlight/copy-code.styl b/themes/next/source/css/_common/scaffolding/highlight/copy-code.styl similarity index 100% rename from source/css/_common/scaffolding/highlight/copy-code.styl rename to themes/next/source/css/_common/scaffolding/highlight/copy-code.styl diff --git a/source/css/_common/scaffolding/highlight/diff.styl b/themes/next/source/css/_common/scaffolding/highlight/diff.styl similarity index 100% rename from source/css/_common/scaffolding/highlight/diff.styl rename to themes/next/source/css/_common/scaffolding/highlight/diff.styl diff --git a/source/css/_common/scaffolding/highlight/highlight.styl b/themes/next/source/css/_common/scaffolding/highlight/highlight.styl similarity index 100% rename from source/css/_common/scaffolding/highlight/highlight.styl rename to themes/next/source/css/_common/scaffolding/highlight/highlight.styl diff --git a/source/css/_common/scaffolding/highlight/theme.styl b/themes/next/source/css/_common/scaffolding/highlight/theme.styl similarity index 100% rename from source/css/_common/scaffolding/highlight/theme.styl rename to themes/next/source/css/_common/scaffolding/highlight/theme.styl diff --git a/source/css/_common/scaffolding/normalize.styl b/themes/next/source/css/_common/scaffolding/normalize.styl similarity index 100% rename from source/css/_common/scaffolding/normalize.styl rename to themes/next/source/css/_common/scaffolding/normalize.styl diff --git a/source/css/_common/scaffolding/pagination.styl b/themes/next/source/css/_common/scaffolding/pagination.styl similarity index 100% rename from source/css/_common/scaffolding/pagination.styl rename to themes/next/source/css/_common/scaffolding/pagination.styl diff --git a/source/css/_common/scaffolding/scaffolding.styl b/themes/next/source/css/_common/scaffolding/scaffolding.styl similarity index 100% rename from source/css/_common/scaffolding/scaffolding.styl rename to themes/next/source/css/_common/scaffolding/scaffolding.styl diff --git a/source/css/_common/scaffolding/tables.styl b/themes/next/source/css/_common/scaffolding/tables.styl similarity index 100% rename from source/css/_common/scaffolding/tables.styl rename to themes/next/source/css/_common/scaffolding/tables.styl diff --git a/source/css/_common/scaffolding/tags/blockquote-center.styl b/themes/next/source/css/_common/scaffolding/tags/blockquote-center.styl similarity index 100% rename from source/css/_common/scaffolding/tags/blockquote-center.styl rename to themes/next/source/css/_common/scaffolding/tags/blockquote-center.styl diff --git a/source/css/_common/scaffolding/tags/group-pictures.styl b/themes/next/source/css/_common/scaffolding/tags/group-pictures.styl similarity index 100% rename from source/css/_common/scaffolding/tags/group-pictures.styl rename to themes/next/source/css/_common/scaffolding/tags/group-pictures.styl diff --git a/source/css/_common/scaffolding/tags/label.styl b/themes/next/source/css/_common/scaffolding/tags/label.styl similarity index 100% rename from source/css/_common/scaffolding/tags/label.styl rename to themes/next/source/css/_common/scaffolding/tags/label.styl diff --git a/source/css/_common/scaffolding/tags/note.styl b/themes/next/source/css/_common/scaffolding/tags/note.styl similarity index 100% rename from source/css/_common/scaffolding/tags/note.styl rename to themes/next/source/css/_common/scaffolding/tags/note.styl diff --git a/source/css/_common/scaffolding/tags/pdf.styl b/themes/next/source/css/_common/scaffolding/tags/pdf.styl similarity index 100% rename from source/css/_common/scaffolding/tags/pdf.styl rename to themes/next/source/css/_common/scaffolding/tags/pdf.styl diff --git a/source/css/_common/scaffolding/tags/tabs.styl b/themes/next/source/css/_common/scaffolding/tags/tabs.styl similarity index 100% rename from source/css/_common/scaffolding/tags/tabs.styl rename to themes/next/source/css/_common/scaffolding/tags/tabs.styl diff --git a/source/css/_common/scaffolding/tags/tags.styl b/themes/next/source/css/_common/scaffolding/tags/tags.styl similarity index 100% rename from source/css/_common/scaffolding/tags/tags.styl rename to themes/next/source/css/_common/scaffolding/tags/tags.styl diff --git a/source/css/_common/scaffolding/toggles.styl b/themes/next/source/css/_common/scaffolding/toggles.styl similarity index 100% rename from source/css/_common/scaffolding/toggles.styl rename to themes/next/source/css/_common/scaffolding/toggles.styl diff --git a/source/css/_mixins/Gemini.styl b/themes/next/source/css/_mixins/Gemini.styl similarity index 100% rename from source/css/_mixins/Gemini.styl rename to themes/next/source/css/_mixins/Gemini.styl diff --git a/source/css/_mixins/Mist.styl b/themes/next/source/css/_mixins/Mist.styl similarity index 100% rename from source/css/_mixins/Mist.styl rename to themes/next/source/css/_mixins/Mist.styl diff --git a/source/css/_mixins/Muse.styl b/themes/next/source/css/_mixins/Muse.styl similarity index 100% rename from source/css/_mixins/Muse.styl rename to themes/next/source/css/_mixins/Muse.styl diff --git a/source/css/_mixins/Pisces.styl b/themes/next/source/css/_mixins/Pisces.styl similarity index 100% rename from source/css/_mixins/Pisces.styl rename to themes/next/source/css/_mixins/Pisces.styl diff --git a/source/css/_mixins/base.styl b/themes/next/source/css/_mixins/base.styl similarity index 100% rename from source/css/_mixins/base.styl rename to themes/next/source/css/_mixins/base.styl diff --git a/source/css/_schemes/Gemini/index.styl b/themes/next/source/css/_schemes/Gemini/index.styl similarity index 100% rename from source/css/_schemes/Gemini/index.styl rename to themes/next/source/css/_schemes/Gemini/index.styl diff --git a/source/css/_schemes/Mist/_base.styl b/themes/next/source/css/_schemes/Mist/_base.styl similarity index 100% rename from source/css/_schemes/Mist/_base.styl rename to themes/next/source/css/_schemes/Mist/_base.styl diff --git a/source/css/_schemes/Mist/_header.styl b/themes/next/source/css/_schemes/Mist/_header.styl similarity index 100% rename from source/css/_schemes/Mist/_header.styl rename to themes/next/source/css/_schemes/Mist/_header.styl diff --git a/source/css/_schemes/Mist/_logo.styl b/themes/next/source/css/_schemes/Mist/_logo.styl similarity index 100% rename from source/css/_schemes/Mist/_logo.styl rename to themes/next/source/css/_schemes/Mist/_logo.styl diff --git a/source/css/_schemes/Mist/_menu.styl b/themes/next/source/css/_schemes/Mist/_menu.styl similarity index 100% rename from source/css/_schemes/Mist/_menu.styl rename to themes/next/source/css/_schemes/Mist/_menu.styl diff --git a/source/css/_schemes/Mist/_posts-expand.styl b/themes/next/source/css/_schemes/Mist/_posts-expand.styl similarity index 100% rename from source/css/_schemes/Mist/_posts-expand.styl rename to themes/next/source/css/_schemes/Mist/_posts-expand.styl diff --git a/source/css/_schemes/Mist/index.styl b/themes/next/source/css/_schemes/Mist/index.styl similarity index 100% rename from source/css/_schemes/Mist/index.styl rename to themes/next/source/css/_schemes/Mist/index.styl diff --git a/source/css/_schemes/Muse/_layout.styl b/themes/next/source/css/_schemes/Muse/_layout.styl similarity index 100% rename from source/css/_schemes/Muse/_layout.styl rename to themes/next/source/css/_schemes/Muse/_layout.styl diff --git a/source/css/_schemes/Muse/_logo.styl b/themes/next/source/css/_schemes/Muse/_logo.styl similarity index 100% rename from source/css/_schemes/Muse/_logo.styl rename to themes/next/source/css/_schemes/Muse/_logo.styl diff --git a/source/css/_schemes/Muse/_menu.styl b/themes/next/source/css/_schemes/Muse/_menu.styl similarity index 100% rename from source/css/_schemes/Muse/_menu.styl rename to themes/next/source/css/_schemes/Muse/_menu.styl diff --git a/source/css/_schemes/Muse/_sidebar.styl b/themes/next/source/css/_schemes/Muse/_sidebar.styl similarity index 100% rename from source/css/_schemes/Muse/_sidebar.styl rename to themes/next/source/css/_schemes/Muse/_sidebar.styl diff --git a/source/css/_schemes/Muse/index.styl b/themes/next/source/css/_schemes/Muse/index.styl similarity index 100% rename from source/css/_schemes/Muse/index.styl rename to themes/next/source/css/_schemes/Muse/index.styl diff --git a/source/css/_schemes/Pisces/_brand.styl b/themes/next/source/css/_schemes/Pisces/_brand.styl similarity index 100% rename from source/css/_schemes/Pisces/_brand.styl rename to themes/next/source/css/_schemes/Pisces/_brand.styl diff --git a/source/css/_schemes/Pisces/_layout.styl b/themes/next/source/css/_schemes/Pisces/_layout.styl similarity index 100% rename from source/css/_schemes/Pisces/_layout.styl rename to themes/next/source/css/_schemes/Pisces/_layout.styl diff --git a/source/css/_schemes/Pisces/_menu.styl b/themes/next/source/css/_schemes/Pisces/_menu.styl similarity index 100% rename from source/css/_schemes/Pisces/_menu.styl rename to themes/next/source/css/_schemes/Pisces/_menu.styl diff --git a/source/css/_schemes/Pisces/_sidebar.styl b/themes/next/source/css/_schemes/Pisces/_sidebar.styl similarity index 100% rename from source/css/_schemes/Pisces/_sidebar.styl rename to themes/next/source/css/_schemes/Pisces/_sidebar.styl diff --git a/source/css/_schemes/Pisces/_sub-menu.styl b/themes/next/source/css/_schemes/Pisces/_sub-menu.styl similarity index 100% rename from source/css/_schemes/Pisces/_sub-menu.styl rename to themes/next/source/css/_schemes/Pisces/_sub-menu.styl diff --git a/source/css/_schemes/Pisces/index.styl b/themes/next/source/css/_schemes/Pisces/index.styl similarity index 100% rename from source/css/_schemes/Pisces/index.styl rename to themes/next/source/css/_schemes/Pisces/index.styl diff --git a/source/css/_variables/Gemini.styl b/themes/next/source/css/_variables/Gemini.styl similarity index 100% rename from source/css/_variables/Gemini.styl rename to themes/next/source/css/_variables/Gemini.styl diff --git a/source/css/_variables/Mist.styl b/themes/next/source/css/_variables/Mist.styl similarity index 100% rename from source/css/_variables/Mist.styl rename to themes/next/source/css/_variables/Mist.styl diff --git a/source/css/_variables/Muse.styl b/themes/next/source/css/_variables/Muse.styl similarity index 100% rename from source/css/_variables/Muse.styl rename to themes/next/source/css/_variables/Muse.styl diff --git a/source/css/_variables/Pisces.styl b/themes/next/source/css/_variables/Pisces.styl similarity index 100% rename from source/css/_variables/Pisces.styl rename to themes/next/source/css/_variables/Pisces.styl diff --git a/source/css/_variables/base.styl b/themes/next/source/css/_variables/base.styl similarity index 100% rename from source/css/_variables/base.styl rename to themes/next/source/css/_variables/base.styl diff --git a/source/css/main.styl b/themes/next/source/css/main.styl similarity index 100% rename from source/css/main.styl rename to themes/next/source/css/main.styl diff --git a/source/images/algolia_logo.svg b/themes/next/source/images/algolia_logo.svg similarity index 100% rename from source/images/algolia_logo.svg rename to themes/next/source/images/algolia_logo.svg diff --git a/source/images/apple-touch-icon-next.png b/themes/next/source/images/apple-touch-icon-next.png similarity index 100% rename from source/images/apple-touch-icon-next.png rename to themes/next/source/images/apple-touch-icon-next.png diff --git a/source/images/avatar.gif b/themes/next/source/images/avatar.gif similarity index 100% rename from source/images/avatar.gif rename to themes/next/source/images/avatar.gif diff --git a/source/images/cc-by-nc-nd.svg b/themes/next/source/images/cc-by-nc-nd.svg similarity index 100% rename from source/images/cc-by-nc-nd.svg rename to themes/next/source/images/cc-by-nc-nd.svg diff --git a/source/images/cc-by-nc-sa.svg b/themes/next/source/images/cc-by-nc-sa.svg similarity index 100% rename from source/images/cc-by-nc-sa.svg rename to themes/next/source/images/cc-by-nc-sa.svg diff --git a/source/images/cc-by-nc.svg b/themes/next/source/images/cc-by-nc.svg similarity index 100% rename from source/images/cc-by-nc.svg rename to themes/next/source/images/cc-by-nc.svg diff --git a/source/images/cc-by-nd.svg b/themes/next/source/images/cc-by-nd.svg similarity index 100% rename from source/images/cc-by-nd.svg rename to themes/next/source/images/cc-by-nd.svg diff --git a/source/images/cc-by-sa.svg b/themes/next/source/images/cc-by-sa.svg similarity index 100% rename from source/images/cc-by-sa.svg rename to themes/next/source/images/cc-by-sa.svg diff --git a/source/images/cc-by.svg b/themes/next/source/images/cc-by.svg similarity index 100% rename from source/images/cc-by.svg rename to themes/next/source/images/cc-by.svg diff --git a/source/images/cc-zero.svg b/themes/next/source/images/cc-zero.svg similarity index 100% rename from source/images/cc-zero.svg rename to themes/next/source/images/cc-zero.svg diff --git a/source/images/favicon-16x16-next.png b/themes/next/source/images/favicon-16x16-next.png similarity index 100% rename from source/images/favicon-16x16-next.png rename to themes/next/source/images/favicon-16x16-next.png diff --git a/source/images/favicon-32x32-next.png b/themes/next/source/images/favicon-32x32-next.png similarity index 100% rename from source/images/favicon-32x32-next.png rename to themes/next/source/images/favicon-32x32-next.png diff --git a/source/images/logo.svg b/themes/next/source/images/logo.svg similarity index 100% rename from source/images/logo.svg rename to themes/next/source/images/logo.svg diff --git a/source/images/quote-l.svg b/themes/next/source/images/quote-l.svg similarity index 100% rename from source/images/quote-l.svg rename to themes/next/source/images/quote-l.svg diff --git a/source/images/quote-r.svg b/themes/next/source/images/quote-r.svg similarity index 100% rename from source/images/quote-r.svg rename to themes/next/source/images/quote-r.svg diff --git a/source/js/algolia-search.js b/themes/next/source/js/algolia-search.js similarity index 100% rename from source/js/algolia-search.js rename to themes/next/source/js/algolia-search.js diff --git a/source/js/bookmark.js b/themes/next/source/js/bookmark.js similarity index 100% rename from source/js/bookmark.js rename to themes/next/source/js/bookmark.js diff --git a/source/js/local-search.js b/themes/next/source/js/local-search.js similarity index 100% rename from source/js/local-search.js rename to themes/next/source/js/local-search.js diff --git a/source/js/motion.js b/themes/next/source/js/motion.js similarity index 100% rename from source/js/motion.js rename to themes/next/source/js/motion.js diff --git a/source/js/next-boot.js b/themes/next/source/js/next-boot.js similarity index 100% rename from source/js/next-boot.js rename to themes/next/source/js/next-boot.js diff --git a/source/js/schemes/muse.js b/themes/next/source/js/schemes/muse.js similarity index 100% rename from source/js/schemes/muse.js rename to themes/next/source/js/schemes/muse.js diff --git a/source/js/schemes/pisces.js b/themes/next/source/js/schemes/pisces.js similarity index 100% rename from source/js/schemes/pisces.js rename to themes/next/source/js/schemes/pisces.js diff --git a/source/js/utils.js b/themes/next/source/js/utils.js similarity index 100% rename from source/js/utils.js rename to themes/next/source/js/utils.js diff --git a/source/lib/anime.min.js b/themes/next/source/lib/anime.min.js similarity index 100% rename from source/lib/anime.min.js rename to themes/next/source/lib/anime.min.js diff --git a/source/lib/font-awesome/.bower.json b/themes/next/source/lib/font-awesome/.bower.json similarity index 100% rename from source/lib/font-awesome/.bower.json rename to themes/next/source/lib/font-awesome/.bower.json diff --git a/source/lib/font-awesome/.gitignore b/themes/next/source/lib/font-awesome/.gitignore similarity index 100% rename from source/lib/font-awesome/.gitignore rename to themes/next/source/lib/font-awesome/.gitignore diff --git a/source/lib/font-awesome/.npmignore b/themes/next/source/lib/font-awesome/.npmignore similarity index 100% rename from source/lib/font-awesome/.npmignore rename to themes/next/source/lib/font-awesome/.npmignore diff --git a/source/lib/font-awesome/HELP-US-OUT.txt b/themes/next/source/lib/font-awesome/HELP-US-OUT.txt similarity index 100% rename from source/lib/font-awesome/HELP-US-OUT.txt rename to themes/next/source/lib/font-awesome/HELP-US-OUT.txt diff --git a/source/lib/font-awesome/bower.json b/themes/next/source/lib/font-awesome/bower.json similarity index 100% rename from source/lib/font-awesome/bower.json rename to themes/next/source/lib/font-awesome/bower.json diff --git a/source/lib/font-awesome/css/font-awesome.css b/themes/next/source/lib/font-awesome/css/font-awesome.css similarity index 100% rename from source/lib/font-awesome/css/font-awesome.css rename to themes/next/source/lib/font-awesome/css/font-awesome.css diff --git a/source/lib/font-awesome/css/font-awesome.css.map b/themes/next/source/lib/font-awesome/css/font-awesome.css.map similarity index 100% rename from source/lib/font-awesome/css/font-awesome.css.map rename to themes/next/source/lib/font-awesome/css/font-awesome.css.map diff --git a/source/lib/font-awesome/css/font-awesome.min.css b/themes/next/source/lib/font-awesome/css/font-awesome.min.css similarity index 100% rename from source/lib/font-awesome/css/font-awesome.min.css rename to themes/next/source/lib/font-awesome/css/font-awesome.min.css diff --git a/source/lib/font-awesome/fonts/fontawesome-webfont.eot b/themes/next/source/lib/font-awesome/fonts/fontawesome-webfont.eot similarity index 100% rename from source/lib/font-awesome/fonts/fontawesome-webfont.eot rename to themes/next/source/lib/font-awesome/fonts/fontawesome-webfont.eot diff --git a/source/lib/font-awesome/fonts/fontawesome-webfont.woff b/themes/next/source/lib/font-awesome/fonts/fontawesome-webfont.woff similarity index 100% rename from source/lib/font-awesome/fonts/fontawesome-webfont.woff rename to themes/next/source/lib/font-awesome/fonts/fontawesome-webfont.woff diff --git a/source/lib/font-awesome/fonts/fontawesome-webfont.woff2 b/themes/next/source/lib/font-awesome/fonts/fontawesome-webfont.woff2 similarity index 100% rename from source/lib/font-awesome/fonts/fontawesome-webfont.woff2 rename to themes/next/source/lib/font-awesome/fonts/fontawesome-webfont.woff2 diff --git a/source/lib/pdf/LICENSE b/themes/next/source/lib/pdf/LICENSE similarity index 100% rename from source/lib/pdf/LICENSE rename to themes/next/source/lib/pdf/LICENSE diff --git a/source/lib/pdf/README.md b/themes/next/source/lib/pdf/README.md similarity index 100% rename from source/lib/pdf/README.md rename to themes/next/source/lib/pdf/README.md diff --git a/source/lib/pdf/build/pdf.js b/themes/next/source/lib/pdf/build/pdf.js similarity index 100% rename from source/lib/pdf/build/pdf.js rename to themes/next/source/lib/pdf/build/pdf.js diff --git a/source/lib/pdf/build/pdf.js.map b/themes/next/source/lib/pdf/build/pdf.js.map similarity index 100% rename from source/lib/pdf/build/pdf.js.map rename to themes/next/source/lib/pdf/build/pdf.js.map diff --git a/source/lib/pdf/build/pdf.worker.js b/themes/next/source/lib/pdf/build/pdf.worker.js similarity index 100% rename from source/lib/pdf/build/pdf.worker.js rename to themes/next/source/lib/pdf/build/pdf.worker.js diff --git a/source/lib/pdf/build/pdf.worker.js.map b/themes/next/source/lib/pdf/build/pdf.worker.js.map similarity index 100% rename from source/lib/pdf/build/pdf.worker.js.map rename to themes/next/source/lib/pdf/build/pdf.worker.js.map diff --git a/source/lib/pdf/web/cmaps/78-EUC-H.bcmap b/themes/next/source/lib/pdf/web/cmaps/78-EUC-H.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/78-EUC-H.bcmap rename to themes/next/source/lib/pdf/web/cmaps/78-EUC-H.bcmap diff --git a/source/lib/pdf/web/cmaps/78-EUC-V.bcmap b/themes/next/source/lib/pdf/web/cmaps/78-EUC-V.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/78-EUC-V.bcmap rename to themes/next/source/lib/pdf/web/cmaps/78-EUC-V.bcmap diff --git a/source/lib/pdf/web/cmaps/78-H.bcmap b/themes/next/source/lib/pdf/web/cmaps/78-H.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/78-H.bcmap rename to themes/next/source/lib/pdf/web/cmaps/78-H.bcmap diff --git a/source/lib/pdf/web/cmaps/78-RKSJ-H.bcmap b/themes/next/source/lib/pdf/web/cmaps/78-RKSJ-H.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/78-RKSJ-H.bcmap rename to themes/next/source/lib/pdf/web/cmaps/78-RKSJ-H.bcmap diff --git a/source/lib/pdf/web/cmaps/78-RKSJ-V.bcmap b/themes/next/source/lib/pdf/web/cmaps/78-RKSJ-V.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/78-RKSJ-V.bcmap rename to themes/next/source/lib/pdf/web/cmaps/78-RKSJ-V.bcmap diff --git a/source/lib/pdf/web/cmaps/78-V.bcmap b/themes/next/source/lib/pdf/web/cmaps/78-V.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/78-V.bcmap rename to themes/next/source/lib/pdf/web/cmaps/78-V.bcmap diff --git a/source/lib/pdf/web/cmaps/78ms-RKSJ-H.bcmap b/themes/next/source/lib/pdf/web/cmaps/78ms-RKSJ-H.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/78ms-RKSJ-H.bcmap rename to themes/next/source/lib/pdf/web/cmaps/78ms-RKSJ-H.bcmap diff --git a/source/lib/pdf/web/cmaps/78ms-RKSJ-V.bcmap b/themes/next/source/lib/pdf/web/cmaps/78ms-RKSJ-V.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/78ms-RKSJ-V.bcmap rename to themes/next/source/lib/pdf/web/cmaps/78ms-RKSJ-V.bcmap diff --git a/source/lib/pdf/web/cmaps/83pv-RKSJ-H.bcmap b/themes/next/source/lib/pdf/web/cmaps/83pv-RKSJ-H.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/83pv-RKSJ-H.bcmap rename to themes/next/source/lib/pdf/web/cmaps/83pv-RKSJ-H.bcmap diff --git a/source/lib/pdf/web/cmaps/90ms-RKSJ-H.bcmap b/themes/next/source/lib/pdf/web/cmaps/90ms-RKSJ-H.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/90ms-RKSJ-H.bcmap rename to themes/next/source/lib/pdf/web/cmaps/90ms-RKSJ-H.bcmap diff --git a/source/lib/pdf/web/cmaps/90ms-RKSJ-V.bcmap b/themes/next/source/lib/pdf/web/cmaps/90ms-RKSJ-V.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/90ms-RKSJ-V.bcmap rename to themes/next/source/lib/pdf/web/cmaps/90ms-RKSJ-V.bcmap diff --git a/source/lib/pdf/web/cmaps/90msp-RKSJ-H.bcmap b/themes/next/source/lib/pdf/web/cmaps/90msp-RKSJ-H.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/90msp-RKSJ-H.bcmap rename to themes/next/source/lib/pdf/web/cmaps/90msp-RKSJ-H.bcmap diff --git a/source/lib/pdf/web/cmaps/90msp-RKSJ-V.bcmap b/themes/next/source/lib/pdf/web/cmaps/90msp-RKSJ-V.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/90msp-RKSJ-V.bcmap rename to themes/next/source/lib/pdf/web/cmaps/90msp-RKSJ-V.bcmap diff --git a/source/lib/pdf/web/cmaps/90pv-RKSJ-H.bcmap b/themes/next/source/lib/pdf/web/cmaps/90pv-RKSJ-H.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/90pv-RKSJ-H.bcmap rename to themes/next/source/lib/pdf/web/cmaps/90pv-RKSJ-H.bcmap diff --git a/source/lib/pdf/web/cmaps/90pv-RKSJ-V.bcmap b/themes/next/source/lib/pdf/web/cmaps/90pv-RKSJ-V.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/90pv-RKSJ-V.bcmap rename to themes/next/source/lib/pdf/web/cmaps/90pv-RKSJ-V.bcmap diff --git a/source/lib/pdf/web/cmaps/Add-H.bcmap b/themes/next/source/lib/pdf/web/cmaps/Add-H.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/Add-H.bcmap rename to themes/next/source/lib/pdf/web/cmaps/Add-H.bcmap diff --git a/source/lib/pdf/web/cmaps/Add-RKSJ-H.bcmap b/themes/next/source/lib/pdf/web/cmaps/Add-RKSJ-H.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/Add-RKSJ-H.bcmap rename to themes/next/source/lib/pdf/web/cmaps/Add-RKSJ-H.bcmap diff --git a/source/lib/pdf/web/cmaps/Add-RKSJ-V.bcmap b/themes/next/source/lib/pdf/web/cmaps/Add-RKSJ-V.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/Add-RKSJ-V.bcmap rename to themes/next/source/lib/pdf/web/cmaps/Add-RKSJ-V.bcmap diff --git a/source/lib/pdf/web/cmaps/Add-V.bcmap b/themes/next/source/lib/pdf/web/cmaps/Add-V.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/Add-V.bcmap rename to themes/next/source/lib/pdf/web/cmaps/Add-V.bcmap diff --git a/source/lib/pdf/web/cmaps/Adobe-CNS1-0.bcmap b/themes/next/source/lib/pdf/web/cmaps/Adobe-CNS1-0.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/Adobe-CNS1-0.bcmap rename to themes/next/source/lib/pdf/web/cmaps/Adobe-CNS1-0.bcmap diff --git a/source/lib/pdf/web/cmaps/Adobe-CNS1-1.bcmap b/themes/next/source/lib/pdf/web/cmaps/Adobe-CNS1-1.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/Adobe-CNS1-1.bcmap rename to themes/next/source/lib/pdf/web/cmaps/Adobe-CNS1-1.bcmap diff --git a/source/lib/pdf/web/cmaps/Adobe-CNS1-2.bcmap b/themes/next/source/lib/pdf/web/cmaps/Adobe-CNS1-2.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/Adobe-CNS1-2.bcmap rename to themes/next/source/lib/pdf/web/cmaps/Adobe-CNS1-2.bcmap diff --git a/source/lib/pdf/web/cmaps/Adobe-CNS1-3.bcmap b/themes/next/source/lib/pdf/web/cmaps/Adobe-CNS1-3.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/Adobe-CNS1-3.bcmap rename to themes/next/source/lib/pdf/web/cmaps/Adobe-CNS1-3.bcmap diff --git a/source/lib/pdf/web/cmaps/Adobe-CNS1-4.bcmap b/themes/next/source/lib/pdf/web/cmaps/Adobe-CNS1-4.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/Adobe-CNS1-4.bcmap rename to themes/next/source/lib/pdf/web/cmaps/Adobe-CNS1-4.bcmap diff --git a/source/lib/pdf/web/cmaps/Adobe-CNS1-5.bcmap b/themes/next/source/lib/pdf/web/cmaps/Adobe-CNS1-5.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/Adobe-CNS1-5.bcmap rename to themes/next/source/lib/pdf/web/cmaps/Adobe-CNS1-5.bcmap diff --git a/source/lib/pdf/web/cmaps/Adobe-CNS1-6.bcmap b/themes/next/source/lib/pdf/web/cmaps/Adobe-CNS1-6.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/Adobe-CNS1-6.bcmap rename to themes/next/source/lib/pdf/web/cmaps/Adobe-CNS1-6.bcmap diff --git a/source/lib/pdf/web/cmaps/Adobe-CNS1-UCS2.bcmap b/themes/next/source/lib/pdf/web/cmaps/Adobe-CNS1-UCS2.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/Adobe-CNS1-UCS2.bcmap rename to themes/next/source/lib/pdf/web/cmaps/Adobe-CNS1-UCS2.bcmap diff --git a/source/lib/pdf/web/cmaps/Adobe-GB1-0.bcmap b/themes/next/source/lib/pdf/web/cmaps/Adobe-GB1-0.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/Adobe-GB1-0.bcmap rename to themes/next/source/lib/pdf/web/cmaps/Adobe-GB1-0.bcmap diff --git a/source/lib/pdf/web/cmaps/Adobe-GB1-1.bcmap b/themes/next/source/lib/pdf/web/cmaps/Adobe-GB1-1.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/Adobe-GB1-1.bcmap rename to themes/next/source/lib/pdf/web/cmaps/Adobe-GB1-1.bcmap diff --git a/source/lib/pdf/web/cmaps/Adobe-GB1-2.bcmap b/themes/next/source/lib/pdf/web/cmaps/Adobe-GB1-2.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/Adobe-GB1-2.bcmap rename to themes/next/source/lib/pdf/web/cmaps/Adobe-GB1-2.bcmap diff --git a/source/lib/pdf/web/cmaps/Adobe-GB1-3.bcmap b/themes/next/source/lib/pdf/web/cmaps/Adobe-GB1-3.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/Adobe-GB1-3.bcmap rename to themes/next/source/lib/pdf/web/cmaps/Adobe-GB1-3.bcmap diff --git a/source/lib/pdf/web/cmaps/Adobe-GB1-4.bcmap b/themes/next/source/lib/pdf/web/cmaps/Adobe-GB1-4.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/Adobe-GB1-4.bcmap rename to themes/next/source/lib/pdf/web/cmaps/Adobe-GB1-4.bcmap diff --git a/source/lib/pdf/web/cmaps/Adobe-GB1-5.bcmap b/themes/next/source/lib/pdf/web/cmaps/Adobe-GB1-5.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/Adobe-GB1-5.bcmap rename to themes/next/source/lib/pdf/web/cmaps/Adobe-GB1-5.bcmap diff --git a/source/lib/pdf/web/cmaps/Adobe-GB1-UCS2.bcmap b/themes/next/source/lib/pdf/web/cmaps/Adobe-GB1-UCS2.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/Adobe-GB1-UCS2.bcmap rename to themes/next/source/lib/pdf/web/cmaps/Adobe-GB1-UCS2.bcmap diff --git a/source/lib/pdf/web/cmaps/Adobe-Japan1-0.bcmap b/themes/next/source/lib/pdf/web/cmaps/Adobe-Japan1-0.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/Adobe-Japan1-0.bcmap rename to themes/next/source/lib/pdf/web/cmaps/Adobe-Japan1-0.bcmap diff --git a/source/lib/pdf/web/cmaps/Adobe-Japan1-1.bcmap b/themes/next/source/lib/pdf/web/cmaps/Adobe-Japan1-1.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/Adobe-Japan1-1.bcmap rename to themes/next/source/lib/pdf/web/cmaps/Adobe-Japan1-1.bcmap diff --git a/source/lib/pdf/web/cmaps/Adobe-Japan1-2.bcmap b/themes/next/source/lib/pdf/web/cmaps/Adobe-Japan1-2.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/Adobe-Japan1-2.bcmap rename to themes/next/source/lib/pdf/web/cmaps/Adobe-Japan1-2.bcmap diff --git a/source/lib/pdf/web/cmaps/Adobe-Japan1-3.bcmap b/themes/next/source/lib/pdf/web/cmaps/Adobe-Japan1-3.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/Adobe-Japan1-3.bcmap rename to themes/next/source/lib/pdf/web/cmaps/Adobe-Japan1-3.bcmap diff --git a/source/lib/pdf/web/cmaps/Adobe-Japan1-4.bcmap b/themes/next/source/lib/pdf/web/cmaps/Adobe-Japan1-4.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/Adobe-Japan1-4.bcmap rename to themes/next/source/lib/pdf/web/cmaps/Adobe-Japan1-4.bcmap diff --git a/source/lib/pdf/web/cmaps/Adobe-Japan1-5.bcmap b/themes/next/source/lib/pdf/web/cmaps/Adobe-Japan1-5.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/Adobe-Japan1-5.bcmap rename to themes/next/source/lib/pdf/web/cmaps/Adobe-Japan1-5.bcmap diff --git a/source/lib/pdf/web/cmaps/Adobe-Japan1-6.bcmap b/themes/next/source/lib/pdf/web/cmaps/Adobe-Japan1-6.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/Adobe-Japan1-6.bcmap rename to themes/next/source/lib/pdf/web/cmaps/Adobe-Japan1-6.bcmap diff --git a/source/lib/pdf/web/cmaps/Adobe-Japan1-UCS2.bcmap b/themes/next/source/lib/pdf/web/cmaps/Adobe-Japan1-UCS2.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/Adobe-Japan1-UCS2.bcmap rename to themes/next/source/lib/pdf/web/cmaps/Adobe-Japan1-UCS2.bcmap diff --git a/source/lib/pdf/web/cmaps/Adobe-Korea1-0.bcmap b/themes/next/source/lib/pdf/web/cmaps/Adobe-Korea1-0.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/Adobe-Korea1-0.bcmap rename to themes/next/source/lib/pdf/web/cmaps/Adobe-Korea1-0.bcmap diff --git a/source/lib/pdf/web/cmaps/Adobe-Korea1-1.bcmap b/themes/next/source/lib/pdf/web/cmaps/Adobe-Korea1-1.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/Adobe-Korea1-1.bcmap rename to themes/next/source/lib/pdf/web/cmaps/Adobe-Korea1-1.bcmap diff --git a/source/lib/pdf/web/cmaps/Adobe-Korea1-2.bcmap b/themes/next/source/lib/pdf/web/cmaps/Adobe-Korea1-2.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/Adobe-Korea1-2.bcmap rename to themes/next/source/lib/pdf/web/cmaps/Adobe-Korea1-2.bcmap diff --git a/source/lib/pdf/web/cmaps/Adobe-Korea1-UCS2.bcmap b/themes/next/source/lib/pdf/web/cmaps/Adobe-Korea1-UCS2.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/Adobe-Korea1-UCS2.bcmap rename to themes/next/source/lib/pdf/web/cmaps/Adobe-Korea1-UCS2.bcmap diff --git a/source/lib/pdf/web/cmaps/B5-H.bcmap b/themes/next/source/lib/pdf/web/cmaps/B5-H.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/B5-H.bcmap rename to themes/next/source/lib/pdf/web/cmaps/B5-H.bcmap diff --git a/source/lib/pdf/web/cmaps/B5-V.bcmap b/themes/next/source/lib/pdf/web/cmaps/B5-V.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/B5-V.bcmap rename to themes/next/source/lib/pdf/web/cmaps/B5-V.bcmap diff --git a/source/lib/pdf/web/cmaps/B5pc-H.bcmap b/themes/next/source/lib/pdf/web/cmaps/B5pc-H.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/B5pc-H.bcmap rename to themes/next/source/lib/pdf/web/cmaps/B5pc-H.bcmap diff --git a/source/lib/pdf/web/cmaps/B5pc-V.bcmap b/themes/next/source/lib/pdf/web/cmaps/B5pc-V.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/B5pc-V.bcmap rename to themes/next/source/lib/pdf/web/cmaps/B5pc-V.bcmap diff --git a/source/lib/pdf/web/cmaps/CNS-EUC-H.bcmap b/themes/next/source/lib/pdf/web/cmaps/CNS-EUC-H.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/CNS-EUC-H.bcmap rename to themes/next/source/lib/pdf/web/cmaps/CNS-EUC-H.bcmap diff --git a/source/lib/pdf/web/cmaps/CNS-EUC-V.bcmap b/themes/next/source/lib/pdf/web/cmaps/CNS-EUC-V.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/CNS-EUC-V.bcmap rename to themes/next/source/lib/pdf/web/cmaps/CNS-EUC-V.bcmap diff --git a/source/lib/pdf/web/cmaps/CNS1-H.bcmap b/themes/next/source/lib/pdf/web/cmaps/CNS1-H.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/CNS1-H.bcmap rename to themes/next/source/lib/pdf/web/cmaps/CNS1-H.bcmap diff --git a/source/lib/pdf/web/cmaps/CNS1-V.bcmap b/themes/next/source/lib/pdf/web/cmaps/CNS1-V.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/CNS1-V.bcmap rename to themes/next/source/lib/pdf/web/cmaps/CNS1-V.bcmap diff --git a/source/lib/pdf/web/cmaps/CNS2-H.bcmap b/themes/next/source/lib/pdf/web/cmaps/CNS2-H.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/CNS2-H.bcmap rename to themes/next/source/lib/pdf/web/cmaps/CNS2-H.bcmap diff --git a/source/lib/pdf/web/cmaps/CNS2-V.bcmap b/themes/next/source/lib/pdf/web/cmaps/CNS2-V.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/CNS2-V.bcmap rename to themes/next/source/lib/pdf/web/cmaps/CNS2-V.bcmap diff --git a/source/lib/pdf/web/cmaps/ETHK-B5-H.bcmap b/themes/next/source/lib/pdf/web/cmaps/ETHK-B5-H.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/ETHK-B5-H.bcmap rename to themes/next/source/lib/pdf/web/cmaps/ETHK-B5-H.bcmap diff --git a/source/lib/pdf/web/cmaps/ETHK-B5-V.bcmap b/themes/next/source/lib/pdf/web/cmaps/ETHK-B5-V.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/ETHK-B5-V.bcmap rename to themes/next/source/lib/pdf/web/cmaps/ETHK-B5-V.bcmap diff --git a/source/lib/pdf/web/cmaps/ETen-B5-H.bcmap b/themes/next/source/lib/pdf/web/cmaps/ETen-B5-H.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/ETen-B5-H.bcmap rename to themes/next/source/lib/pdf/web/cmaps/ETen-B5-H.bcmap diff --git a/source/lib/pdf/web/cmaps/ETen-B5-V.bcmap b/themes/next/source/lib/pdf/web/cmaps/ETen-B5-V.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/ETen-B5-V.bcmap rename to themes/next/source/lib/pdf/web/cmaps/ETen-B5-V.bcmap diff --git a/source/lib/pdf/web/cmaps/ETenms-B5-H.bcmap b/themes/next/source/lib/pdf/web/cmaps/ETenms-B5-H.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/ETenms-B5-H.bcmap rename to themes/next/source/lib/pdf/web/cmaps/ETenms-B5-H.bcmap diff --git a/source/lib/pdf/web/cmaps/ETenms-B5-V.bcmap b/themes/next/source/lib/pdf/web/cmaps/ETenms-B5-V.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/ETenms-B5-V.bcmap rename to themes/next/source/lib/pdf/web/cmaps/ETenms-B5-V.bcmap diff --git a/source/lib/pdf/web/cmaps/EUC-H.bcmap b/themes/next/source/lib/pdf/web/cmaps/EUC-H.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/EUC-H.bcmap rename to themes/next/source/lib/pdf/web/cmaps/EUC-H.bcmap diff --git a/source/lib/pdf/web/cmaps/EUC-V.bcmap b/themes/next/source/lib/pdf/web/cmaps/EUC-V.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/EUC-V.bcmap rename to themes/next/source/lib/pdf/web/cmaps/EUC-V.bcmap diff --git a/source/lib/pdf/web/cmaps/Ext-H.bcmap b/themes/next/source/lib/pdf/web/cmaps/Ext-H.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/Ext-H.bcmap rename to themes/next/source/lib/pdf/web/cmaps/Ext-H.bcmap diff --git a/source/lib/pdf/web/cmaps/Ext-RKSJ-H.bcmap b/themes/next/source/lib/pdf/web/cmaps/Ext-RKSJ-H.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/Ext-RKSJ-H.bcmap rename to themes/next/source/lib/pdf/web/cmaps/Ext-RKSJ-H.bcmap diff --git a/source/lib/pdf/web/cmaps/Ext-RKSJ-V.bcmap b/themes/next/source/lib/pdf/web/cmaps/Ext-RKSJ-V.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/Ext-RKSJ-V.bcmap rename to themes/next/source/lib/pdf/web/cmaps/Ext-RKSJ-V.bcmap diff --git a/source/lib/pdf/web/cmaps/Ext-V.bcmap b/themes/next/source/lib/pdf/web/cmaps/Ext-V.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/Ext-V.bcmap rename to themes/next/source/lib/pdf/web/cmaps/Ext-V.bcmap diff --git a/source/lib/pdf/web/cmaps/GB-EUC-H.bcmap b/themes/next/source/lib/pdf/web/cmaps/GB-EUC-H.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/GB-EUC-H.bcmap rename to themes/next/source/lib/pdf/web/cmaps/GB-EUC-H.bcmap diff --git a/source/lib/pdf/web/cmaps/GB-EUC-V.bcmap b/themes/next/source/lib/pdf/web/cmaps/GB-EUC-V.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/GB-EUC-V.bcmap rename to themes/next/source/lib/pdf/web/cmaps/GB-EUC-V.bcmap diff --git a/source/lib/pdf/web/cmaps/GB-H.bcmap b/themes/next/source/lib/pdf/web/cmaps/GB-H.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/GB-H.bcmap rename to themes/next/source/lib/pdf/web/cmaps/GB-H.bcmap diff --git a/source/lib/pdf/web/cmaps/GB-V.bcmap b/themes/next/source/lib/pdf/web/cmaps/GB-V.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/GB-V.bcmap rename to themes/next/source/lib/pdf/web/cmaps/GB-V.bcmap diff --git a/source/lib/pdf/web/cmaps/GBK-EUC-H.bcmap b/themes/next/source/lib/pdf/web/cmaps/GBK-EUC-H.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/GBK-EUC-H.bcmap rename to themes/next/source/lib/pdf/web/cmaps/GBK-EUC-H.bcmap diff --git a/source/lib/pdf/web/cmaps/GBK-EUC-V.bcmap b/themes/next/source/lib/pdf/web/cmaps/GBK-EUC-V.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/GBK-EUC-V.bcmap rename to themes/next/source/lib/pdf/web/cmaps/GBK-EUC-V.bcmap diff --git a/source/lib/pdf/web/cmaps/GBK2K-H.bcmap b/themes/next/source/lib/pdf/web/cmaps/GBK2K-H.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/GBK2K-H.bcmap rename to themes/next/source/lib/pdf/web/cmaps/GBK2K-H.bcmap diff --git a/source/lib/pdf/web/cmaps/GBK2K-V.bcmap b/themes/next/source/lib/pdf/web/cmaps/GBK2K-V.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/GBK2K-V.bcmap rename to themes/next/source/lib/pdf/web/cmaps/GBK2K-V.bcmap diff --git a/source/lib/pdf/web/cmaps/GBKp-EUC-H.bcmap b/themes/next/source/lib/pdf/web/cmaps/GBKp-EUC-H.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/GBKp-EUC-H.bcmap rename to themes/next/source/lib/pdf/web/cmaps/GBKp-EUC-H.bcmap diff --git a/source/lib/pdf/web/cmaps/GBKp-EUC-V.bcmap b/themes/next/source/lib/pdf/web/cmaps/GBKp-EUC-V.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/GBKp-EUC-V.bcmap rename to themes/next/source/lib/pdf/web/cmaps/GBKp-EUC-V.bcmap diff --git a/source/lib/pdf/web/cmaps/GBT-EUC-H.bcmap b/themes/next/source/lib/pdf/web/cmaps/GBT-EUC-H.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/GBT-EUC-H.bcmap rename to themes/next/source/lib/pdf/web/cmaps/GBT-EUC-H.bcmap diff --git a/source/lib/pdf/web/cmaps/GBT-EUC-V.bcmap b/themes/next/source/lib/pdf/web/cmaps/GBT-EUC-V.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/GBT-EUC-V.bcmap rename to themes/next/source/lib/pdf/web/cmaps/GBT-EUC-V.bcmap diff --git a/source/lib/pdf/web/cmaps/GBT-H.bcmap b/themes/next/source/lib/pdf/web/cmaps/GBT-H.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/GBT-H.bcmap rename to themes/next/source/lib/pdf/web/cmaps/GBT-H.bcmap diff --git a/source/lib/pdf/web/cmaps/GBT-V.bcmap b/themes/next/source/lib/pdf/web/cmaps/GBT-V.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/GBT-V.bcmap rename to themes/next/source/lib/pdf/web/cmaps/GBT-V.bcmap diff --git a/source/lib/pdf/web/cmaps/GBTpc-EUC-H.bcmap b/themes/next/source/lib/pdf/web/cmaps/GBTpc-EUC-H.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/GBTpc-EUC-H.bcmap rename to themes/next/source/lib/pdf/web/cmaps/GBTpc-EUC-H.bcmap diff --git a/source/lib/pdf/web/cmaps/GBTpc-EUC-V.bcmap b/themes/next/source/lib/pdf/web/cmaps/GBTpc-EUC-V.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/GBTpc-EUC-V.bcmap rename to themes/next/source/lib/pdf/web/cmaps/GBTpc-EUC-V.bcmap diff --git a/source/lib/pdf/web/cmaps/GBpc-EUC-H.bcmap b/themes/next/source/lib/pdf/web/cmaps/GBpc-EUC-H.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/GBpc-EUC-H.bcmap rename to themes/next/source/lib/pdf/web/cmaps/GBpc-EUC-H.bcmap diff --git a/source/lib/pdf/web/cmaps/GBpc-EUC-V.bcmap b/themes/next/source/lib/pdf/web/cmaps/GBpc-EUC-V.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/GBpc-EUC-V.bcmap rename to themes/next/source/lib/pdf/web/cmaps/GBpc-EUC-V.bcmap diff --git a/source/lib/pdf/web/cmaps/H.bcmap b/themes/next/source/lib/pdf/web/cmaps/H.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/H.bcmap rename to themes/next/source/lib/pdf/web/cmaps/H.bcmap diff --git a/source/lib/pdf/web/cmaps/HKdla-B5-H.bcmap b/themes/next/source/lib/pdf/web/cmaps/HKdla-B5-H.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/HKdla-B5-H.bcmap rename to themes/next/source/lib/pdf/web/cmaps/HKdla-B5-H.bcmap diff --git a/source/lib/pdf/web/cmaps/HKdla-B5-V.bcmap b/themes/next/source/lib/pdf/web/cmaps/HKdla-B5-V.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/HKdla-B5-V.bcmap rename to themes/next/source/lib/pdf/web/cmaps/HKdla-B5-V.bcmap diff --git a/source/lib/pdf/web/cmaps/HKdlb-B5-H.bcmap b/themes/next/source/lib/pdf/web/cmaps/HKdlb-B5-H.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/HKdlb-B5-H.bcmap rename to themes/next/source/lib/pdf/web/cmaps/HKdlb-B5-H.bcmap diff --git a/source/lib/pdf/web/cmaps/HKdlb-B5-V.bcmap b/themes/next/source/lib/pdf/web/cmaps/HKdlb-B5-V.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/HKdlb-B5-V.bcmap rename to themes/next/source/lib/pdf/web/cmaps/HKdlb-B5-V.bcmap diff --git a/source/lib/pdf/web/cmaps/HKgccs-B5-H.bcmap b/themes/next/source/lib/pdf/web/cmaps/HKgccs-B5-H.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/HKgccs-B5-H.bcmap rename to themes/next/source/lib/pdf/web/cmaps/HKgccs-B5-H.bcmap diff --git a/source/lib/pdf/web/cmaps/HKgccs-B5-V.bcmap b/themes/next/source/lib/pdf/web/cmaps/HKgccs-B5-V.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/HKgccs-B5-V.bcmap rename to themes/next/source/lib/pdf/web/cmaps/HKgccs-B5-V.bcmap diff --git a/source/lib/pdf/web/cmaps/HKm314-B5-H.bcmap b/themes/next/source/lib/pdf/web/cmaps/HKm314-B5-H.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/HKm314-B5-H.bcmap rename to themes/next/source/lib/pdf/web/cmaps/HKm314-B5-H.bcmap diff --git a/source/lib/pdf/web/cmaps/HKm314-B5-V.bcmap b/themes/next/source/lib/pdf/web/cmaps/HKm314-B5-V.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/HKm314-B5-V.bcmap rename to themes/next/source/lib/pdf/web/cmaps/HKm314-B5-V.bcmap diff --git a/source/lib/pdf/web/cmaps/HKm471-B5-H.bcmap b/themes/next/source/lib/pdf/web/cmaps/HKm471-B5-H.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/HKm471-B5-H.bcmap rename to themes/next/source/lib/pdf/web/cmaps/HKm471-B5-H.bcmap diff --git a/source/lib/pdf/web/cmaps/HKm471-B5-V.bcmap b/themes/next/source/lib/pdf/web/cmaps/HKm471-B5-V.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/HKm471-B5-V.bcmap rename to themes/next/source/lib/pdf/web/cmaps/HKm471-B5-V.bcmap diff --git a/source/lib/pdf/web/cmaps/HKscs-B5-H.bcmap b/themes/next/source/lib/pdf/web/cmaps/HKscs-B5-H.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/HKscs-B5-H.bcmap rename to themes/next/source/lib/pdf/web/cmaps/HKscs-B5-H.bcmap diff --git a/source/lib/pdf/web/cmaps/HKscs-B5-V.bcmap b/themes/next/source/lib/pdf/web/cmaps/HKscs-B5-V.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/HKscs-B5-V.bcmap rename to themes/next/source/lib/pdf/web/cmaps/HKscs-B5-V.bcmap diff --git a/source/lib/pdf/web/cmaps/Hankaku.bcmap b/themes/next/source/lib/pdf/web/cmaps/Hankaku.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/Hankaku.bcmap rename to themes/next/source/lib/pdf/web/cmaps/Hankaku.bcmap diff --git a/source/lib/pdf/web/cmaps/Hiragana.bcmap b/themes/next/source/lib/pdf/web/cmaps/Hiragana.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/Hiragana.bcmap rename to themes/next/source/lib/pdf/web/cmaps/Hiragana.bcmap diff --git a/source/lib/pdf/web/cmaps/KSC-EUC-H.bcmap b/themes/next/source/lib/pdf/web/cmaps/KSC-EUC-H.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/KSC-EUC-H.bcmap rename to themes/next/source/lib/pdf/web/cmaps/KSC-EUC-H.bcmap diff --git a/source/lib/pdf/web/cmaps/KSC-EUC-V.bcmap b/themes/next/source/lib/pdf/web/cmaps/KSC-EUC-V.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/KSC-EUC-V.bcmap rename to themes/next/source/lib/pdf/web/cmaps/KSC-EUC-V.bcmap diff --git a/source/lib/pdf/web/cmaps/KSC-H.bcmap b/themes/next/source/lib/pdf/web/cmaps/KSC-H.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/KSC-H.bcmap rename to themes/next/source/lib/pdf/web/cmaps/KSC-H.bcmap diff --git a/source/lib/pdf/web/cmaps/KSC-Johab-H.bcmap b/themes/next/source/lib/pdf/web/cmaps/KSC-Johab-H.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/KSC-Johab-H.bcmap rename to themes/next/source/lib/pdf/web/cmaps/KSC-Johab-H.bcmap diff --git a/source/lib/pdf/web/cmaps/KSC-Johab-V.bcmap b/themes/next/source/lib/pdf/web/cmaps/KSC-Johab-V.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/KSC-Johab-V.bcmap rename to themes/next/source/lib/pdf/web/cmaps/KSC-Johab-V.bcmap diff --git a/source/lib/pdf/web/cmaps/KSC-V.bcmap b/themes/next/source/lib/pdf/web/cmaps/KSC-V.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/KSC-V.bcmap rename to themes/next/source/lib/pdf/web/cmaps/KSC-V.bcmap diff --git a/source/lib/pdf/web/cmaps/KSCms-UHC-H.bcmap b/themes/next/source/lib/pdf/web/cmaps/KSCms-UHC-H.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/KSCms-UHC-H.bcmap rename to themes/next/source/lib/pdf/web/cmaps/KSCms-UHC-H.bcmap diff --git a/source/lib/pdf/web/cmaps/KSCms-UHC-HW-H.bcmap b/themes/next/source/lib/pdf/web/cmaps/KSCms-UHC-HW-H.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/KSCms-UHC-HW-H.bcmap rename to themes/next/source/lib/pdf/web/cmaps/KSCms-UHC-HW-H.bcmap diff --git a/source/lib/pdf/web/cmaps/KSCms-UHC-HW-V.bcmap b/themes/next/source/lib/pdf/web/cmaps/KSCms-UHC-HW-V.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/KSCms-UHC-HW-V.bcmap rename to themes/next/source/lib/pdf/web/cmaps/KSCms-UHC-HW-V.bcmap diff --git a/source/lib/pdf/web/cmaps/KSCms-UHC-V.bcmap b/themes/next/source/lib/pdf/web/cmaps/KSCms-UHC-V.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/KSCms-UHC-V.bcmap rename to themes/next/source/lib/pdf/web/cmaps/KSCms-UHC-V.bcmap diff --git a/source/lib/pdf/web/cmaps/KSCpc-EUC-H.bcmap b/themes/next/source/lib/pdf/web/cmaps/KSCpc-EUC-H.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/KSCpc-EUC-H.bcmap rename to themes/next/source/lib/pdf/web/cmaps/KSCpc-EUC-H.bcmap diff --git a/source/lib/pdf/web/cmaps/KSCpc-EUC-V.bcmap b/themes/next/source/lib/pdf/web/cmaps/KSCpc-EUC-V.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/KSCpc-EUC-V.bcmap rename to themes/next/source/lib/pdf/web/cmaps/KSCpc-EUC-V.bcmap diff --git a/source/lib/pdf/web/cmaps/Katakana.bcmap b/themes/next/source/lib/pdf/web/cmaps/Katakana.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/Katakana.bcmap rename to themes/next/source/lib/pdf/web/cmaps/Katakana.bcmap diff --git a/source/lib/pdf/web/cmaps/LICENSE b/themes/next/source/lib/pdf/web/cmaps/LICENSE similarity index 100% rename from source/lib/pdf/web/cmaps/LICENSE rename to themes/next/source/lib/pdf/web/cmaps/LICENSE diff --git a/source/lib/pdf/web/cmaps/NWP-H.bcmap b/themes/next/source/lib/pdf/web/cmaps/NWP-H.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/NWP-H.bcmap rename to themes/next/source/lib/pdf/web/cmaps/NWP-H.bcmap diff --git a/source/lib/pdf/web/cmaps/NWP-V.bcmap b/themes/next/source/lib/pdf/web/cmaps/NWP-V.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/NWP-V.bcmap rename to themes/next/source/lib/pdf/web/cmaps/NWP-V.bcmap diff --git a/source/lib/pdf/web/cmaps/RKSJ-H.bcmap b/themes/next/source/lib/pdf/web/cmaps/RKSJ-H.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/RKSJ-H.bcmap rename to themes/next/source/lib/pdf/web/cmaps/RKSJ-H.bcmap diff --git a/source/lib/pdf/web/cmaps/RKSJ-V.bcmap b/themes/next/source/lib/pdf/web/cmaps/RKSJ-V.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/RKSJ-V.bcmap rename to themes/next/source/lib/pdf/web/cmaps/RKSJ-V.bcmap diff --git a/source/lib/pdf/web/cmaps/Roman.bcmap b/themes/next/source/lib/pdf/web/cmaps/Roman.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/Roman.bcmap rename to themes/next/source/lib/pdf/web/cmaps/Roman.bcmap diff --git a/source/lib/pdf/web/cmaps/UniCNS-UCS2-H.bcmap b/themes/next/source/lib/pdf/web/cmaps/UniCNS-UCS2-H.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/UniCNS-UCS2-H.bcmap rename to themes/next/source/lib/pdf/web/cmaps/UniCNS-UCS2-H.bcmap diff --git a/source/lib/pdf/web/cmaps/UniCNS-UCS2-V.bcmap b/themes/next/source/lib/pdf/web/cmaps/UniCNS-UCS2-V.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/UniCNS-UCS2-V.bcmap rename to themes/next/source/lib/pdf/web/cmaps/UniCNS-UCS2-V.bcmap diff --git a/source/lib/pdf/web/cmaps/UniCNS-UTF16-H.bcmap b/themes/next/source/lib/pdf/web/cmaps/UniCNS-UTF16-H.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/UniCNS-UTF16-H.bcmap rename to themes/next/source/lib/pdf/web/cmaps/UniCNS-UTF16-H.bcmap diff --git a/source/lib/pdf/web/cmaps/UniCNS-UTF16-V.bcmap b/themes/next/source/lib/pdf/web/cmaps/UniCNS-UTF16-V.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/UniCNS-UTF16-V.bcmap rename to themes/next/source/lib/pdf/web/cmaps/UniCNS-UTF16-V.bcmap diff --git a/source/lib/pdf/web/cmaps/UniCNS-UTF32-H.bcmap b/themes/next/source/lib/pdf/web/cmaps/UniCNS-UTF32-H.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/UniCNS-UTF32-H.bcmap rename to themes/next/source/lib/pdf/web/cmaps/UniCNS-UTF32-H.bcmap diff --git a/source/lib/pdf/web/cmaps/UniCNS-UTF32-V.bcmap b/themes/next/source/lib/pdf/web/cmaps/UniCNS-UTF32-V.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/UniCNS-UTF32-V.bcmap rename to themes/next/source/lib/pdf/web/cmaps/UniCNS-UTF32-V.bcmap diff --git a/source/lib/pdf/web/cmaps/UniCNS-UTF8-H.bcmap b/themes/next/source/lib/pdf/web/cmaps/UniCNS-UTF8-H.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/UniCNS-UTF8-H.bcmap rename to themes/next/source/lib/pdf/web/cmaps/UniCNS-UTF8-H.bcmap diff --git a/source/lib/pdf/web/cmaps/UniCNS-UTF8-V.bcmap b/themes/next/source/lib/pdf/web/cmaps/UniCNS-UTF8-V.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/UniCNS-UTF8-V.bcmap rename to themes/next/source/lib/pdf/web/cmaps/UniCNS-UTF8-V.bcmap diff --git a/source/lib/pdf/web/cmaps/UniGB-UCS2-H.bcmap b/themes/next/source/lib/pdf/web/cmaps/UniGB-UCS2-H.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/UniGB-UCS2-H.bcmap rename to themes/next/source/lib/pdf/web/cmaps/UniGB-UCS2-H.bcmap diff --git a/source/lib/pdf/web/cmaps/UniGB-UCS2-V.bcmap b/themes/next/source/lib/pdf/web/cmaps/UniGB-UCS2-V.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/UniGB-UCS2-V.bcmap rename to themes/next/source/lib/pdf/web/cmaps/UniGB-UCS2-V.bcmap diff --git a/source/lib/pdf/web/cmaps/UniGB-UTF16-H.bcmap b/themes/next/source/lib/pdf/web/cmaps/UniGB-UTF16-H.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/UniGB-UTF16-H.bcmap rename to themes/next/source/lib/pdf/web/cmaps/UniGB-UTF16-H.bcmap diff --git a/source/lib/pdf/web/cmaps/UniGB-UTF16-V.bcmap b/themes/next/source/lib/pdf/web/cmaps/UniGB-UTF16-V.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/UniGB-UTF16-V.bcmap rename to themes/next/source/lib/pdf/web/cmaps/UniGB-UTF16-V.bcmap diff --git a/source/lib/pdf/web/cmaps/UniGB-UTF32-H.bcmap b/themes/next/source/lib/pdf/web/cmaps/UniGB-UTF32-H.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/UniGB-UTF32-H.bcmap rename to themes/next/source/lib/pdf/web/cmaps/UniGB-UTF32-H.bcmap diff --git a/source/lib/pdf/web/cmaps/UniGB-UTF32-V.bcmap b/themes/next/source/lib/pdf/web/cmaps/UniGB-UTF32-V.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/UniGB-UTF32-V.bcmap rename to themes/next/source/lib/pdf/web/cmaps/UniGB-UTF32-V.bcmap diff --git a/source/lib/pdf/web/cmaps/UniGB-UTF8-H.bcmap b/themes/next/source/lib/pdf/web/cmaps/UniGB-UTF8-H.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/UniGB-UTF8-H.bcmap rename to themes/next/source/lib/pdf/web/cmaps/UniGB-UTF8-H.bcmap diff --git a/source/lib/pdf/web/cmaps/UniGB-UTF8-V.bcmap b/themes/next/source/lib/pdf/web/cmaps/UniGB-UTF8-V.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/UniGB-UTF8-V.bcmap rename to themes/next/source/lib/pdf/web/cmaps/UniGB-UTF8-V.bcmap diff --git a/source/lib/pdf/web/cmaps/UniJIS-UCS2-H.bcmap b/themes/next/source/lib/pdf/web/cmaps/UniJIS-UCS2-H.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/UniJIS-UCS2-H.bcmap rename to themes/next/source/lib/pdf/web/cmaps/UniJIS-UCS2-H.bcmap diff --git a/source/lib/pdf/web/cmaps/UniJIS-UCS2-HW-H.bcmap b/themes/next/source/lib/pdf/web/cmaps/UniJIS-UCS2-HW-H.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/UniJIS-UCS2-HW-H.bcmap rename to themes/next/source/lib/pdf/web/cmaps/UniJIS-UCS2-HW-H.bcmap diff --git a/source/lib/pdf/web/cmaps/UniJIS-UCS2-HW-V.bcmap b/themes/next/source/lib/pdf/web/cmaps/UniJIS-UCS2-HW-V.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/UniJIS-UCS2-HW-V.bcmap rename to themes/next/source/lib/pdf/web/cmaps/UniJIS-UCS2-HW-V.bcmap diff --git a/source/lib/pdf/web/cmaps/UniJIS-UCS2-V.bcmap b/themes/next/source/lib/pdf/web/cmaps/UniJIS-UCS2-V.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/UniJIS-UCS2-V.bcmap rename to themes/next/source/lib/pdf/web/cmaps/UniJIS-UCS2-V.bcmap diff --git a/source/lib/pdf/web/cmaps/UniJIS-UTF16-H.bcmap b/themes/next/source/lib/pdf/web/cmaps/UniJIS-UTF16-H.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/UniJIS-UTF16-H.bcmap rename to themes/next/source/lib/pdf/web/cmaps/UniJIS-UTF16-H.bcmap diff --git a/source/lib/pdf/web/cmaps/UniJIS-UTF16-V.bcmap b/themes/next/source/lib/pdf/web/cmaps/UniJIS-UTF16-V.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/UniJIS-UTF16-V.bcmap rename to themes/next/source/lib/pdf/web/cmaps/UniJIS-UTF16-V.bcmap diff --git a/source/lib/pdf/web/cmaps/UniJIS-UTF32-H.bcmap b/themes/next/source/lib/pdf/web/cmaps/UniJIS-UTF32-H.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/UniJIS-UTF32-H.bcmap rename to themes/next/source/lib/pdf/web/cmaps/UniJIS-UTF32-H.bcmap diff --git a/source/lib/pdf/web/cmaps/UniJIS-UTF32-V.bcmap b/themes/next/source/lib/pdf/web/cmaps/UniJIS-UTF32-V.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/UniJIS-UTF32-V.bcmap rename to themes/next/source/lib/pdf/web/cmaps/UniJIS-UTF32-V.bcmap diff --git a/source/lib/pdf/web/cmaps/UniJIS-UTF8-H.bcmap b/themes/next/source/lib/pdf/web/cmaps/UniJIS-UTF8-H.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/UniJIS-UTF8-H.bcmap rename to themes/next/source/lib/pdf/web/cmaps/UniJIS-UTF8-H.bcmap diff --git a/source/lib/pdf/web/cmaps/UniJIS-UTF8-V.bcmap b/themes/next/source/lib/pdf/web/cmaps/UniJIS-UTF8-V.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/UniJIS-UTF8-V.bcmap rename to themes/next/source/lib/pdf/web/cmaps/UniJIS-UTF8-V.bcmap diff --git a/source/lib/pdf/web/cmaps/UniJIS2004-UTF16-H.bcmap b/themes/next/source/lib/pdf/web/cmaps/UniJIS2004-UTF16-H.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/UniJIS2004-UTF16-H.bcmap rename to themes/next/source/lib/pdf/web/cmaps/UniJIS2004-UTF16-H.bcmap diff --git a/source/lib/pdf/web/cmaps/UniJIS2004-UTF16-V.bcmap b/themes/next/source/lib/pdf/web/cmaps/UniJIS2004-UTF16-V.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/UniJIS2004-UTF16-V.bcmap rename to themes/next/source/lib/pdf/web/cmaps/UniJIS2004-UTF16-V.bcmap diff --git a/source/lib/pdf/web/cmaps/UniJIS2004-UTF32-H.bcmap b/themes/next/source/lib/pdf/web/cmaps/UniJIS2004-UTF32-H.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/UniJIS2004-UTF32-H.bcmap rename to themes/next/source/lib/pdf/web/cmaps/UniJIS2004-UTF32-H.bcmap diff --git a/source/lib/pdf/web/cmaps/UniJIS2004-UTF32-V.bcmap b/themes/next/source/lib/pdf/web/cmaps/UniJIS2004-UTF32-V.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/UniJIS2004-UTF32-V.bcmap rename to themes/next/source/lib/pdf/web/cmaps/UniJIS2004-UTF32-V.bcmap diff --git a/source/lib/pdf/web/cmaps/UniJIS2004-UTF8-H.bcmap b/themes/next/source/lib/pdf/web/cmaps/UniJIS2004-UTF8-H.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/UniJIS2004-UTF8-H.bcmap rename to themes/next/source/lib/pdf/web/cmaps/UniJIS2004-UTF8-H.bcmap diff --git a/source/lib/pdf/web/cmaps/UniJIS2004-UTF8-V.bcmap b/themes/next/source/lib/pdf/web/cmaps/UniJIS2004-UTF8-V.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/UniJIS2004-UTF8-V.bcmap rename to themes/next/source/lib/pdf/web/cmaps/UniJIS2004-UTF8-V.bcmap diff --git a/source/lib/pdf/web/cmaps/UniJISPro-UCS2-HW-V.bcmap b/themes/next/source/lib/pdf/web/cmaps/UniJISPro-UCS2-HW-V.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/UniJISPro-UCS2-HW-V.bcmap rename to themes/next/source/lib/pdf/web/cmaps/UniJISPro-UCS2-HW-V.bcmap diff --git a/source/lib/pdf/web/cmaps/UniJISPro-UCS2-V.bcmap b/themes/next/source/lib/pdf/web/cmaps/UniJISPro-UCS2-V.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/UniJISPro-UCS2-V.bcmap rename to themes/next/source/lib/pdf/web/cmaps/UniJISPro-UCS2-V.bcmap diff --git a/source/lib/pdf/web/cmaps/UniJISPro-UTF8-V.bcmap b/themes/next/source/lib/pdf/web/cmaps/UniJISPro-UTF8-V.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/UniJISPro-UTF8-V.bcmap rename to themes/next/source/lib/pdf/web/cmaps/UniJISPro-UTF8-V.bcmap diff --git a/source/lib/pdf/web/cmaps/UniJISX0213-UTF32-H.bcmap b/themes/next/source/lib/pdf/web/cmaps/UniJISX0213-UTF32-H.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/UniJISX0213-UTF32-H.bcmap rename to themes/next/source/lib/pdf/web/cmaps/UniJISX0213-UTF32-H.bcmap diff --git a/source/lib/pdf/web/cmaps/UniJISX0213-UTF32-V.bcmap b/themes/next/source/lib/pdf/web/cmaps/UniJISX0213-UTF32-V.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/UniJISX0213-UTF32-V.bcmap rename to themes/next/source/lib/pdf/web/cmaps/UniJISX0213-UTF32-V.bcmap diff --git a/source/lib/pdf/web/cmaps/UniJISX02132004-UTF32-H.bcmap b/themes/next/source/lib/pdf/web/cmaps/UniJISX02132004-UTF32-H.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/UniJISX02132004-UTF32-H.bcmap rename to themes/next/source/lib/pdf/web/cmaps/UniJISX02132004-UTF32-H.bcmap diff --git a/source/lib/pdf/web/cmaps/UniJISX02132004-UTF32-V.bcmap b/themes/next/source/lib/pdf/web/cmaps/UniJISX02132004-UTF32-V.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/UniJISX02132004-UTF32-V.bcmap rename to themes/next/source/lib/pdf/web/cmaps/UniJISX02132004-UTF32-V.bcmap diff --git a/source/lib/pdf/web/cmaps/UniKS-UCS2-H.bcmap b/themes/next/source/lib/pdf/web/cmaps/UniKS-UCS2-H.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/UniKS-UCS2-H.bcmap rename to themes/next/source/lib/pdf/web/cmaps/UniKS-UCS2-H.bcmap diff --git a/source/lib/pdf/web/cmaps/UniKS-UCS2-V.bcmap b/themes/next/source/lib/pdf/web/cmaps/UniKS-UCS2-V.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/UniKS-UCS2-V.bcmap rename to themes/next/source/lib/pdf/web/cmaps/UniKS-UCS2-V.bcmap diff --git a/source/lib/pdf/web/cmaps/UniKS-UTF16-H.bcmap b/themes/next/source/lib/pdf/web/cmaps/UniKS-UTF16-H.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/UniKS-UTF16-H.bcmap rename to themes/next/source/lib/pdf/web/cmaps/UniKS-UTF16-H.bcmap diff --git a/source/lib/pdf/web/cmaps/UniKS-UTF16-V.bcmap b/themes/next/source/lib/pdf/web/cmaps/UniKS-UTF16-V.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/UniKS-UTF16-V.bcmap rename to themes/next/source/lib/pdf/web/cmaps/UniKS-UTF16-V.bcmap diff --git a/source/lib/pdf/web/cmaps/UniKS-UTF32-H.bcmap b/themes/next/source/lib/pdf/web/cmaps/UniKS-UTF32-H.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/UniKS-UTF32-H.bcmap rename to themes/next/source/lib/pdf/web/cmaps/UniKS-UTF32-H.bcmap diff --git a/source/lib/pdf/web/cmaps/UniKS-UTF32-V.bcmap b/themes/next/source/lib/pdf/web/cmaps/UniKS-UTF32-V.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/UniKS-UTF32-V.bcmap rename to themes/next/source/lib/pdf/web/cmaps/UniKS-UTF32-V.bcmap diff --git a/source/lib/pdf/web/cmaps/UniKS-UTF8-H.bcmap b/themes/next/source/lib/pdf/web/cmaps/UniKS-UTF8-H.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/UniKS-UTF8-H.bcmap rename to themes/next/source/lib/pdf/web/cmaps/UniKS-UTF8-H.bcmap diff --git a/source/lib/pdf/web/cmaps/UniKS-UTF8-V.bcmap b/themes/next/source/lib/pdf/web/cmaps/UniKS-UTF8-V.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/UniKS-UTF8-V.bcmap rename to themes/next/source/lib/pdf/web/cmaps/UniKS-UTF8-V.bcmap diff --git a/source/lib/pdf/web/cmaps/V.bcmap b/themes/next/source/lib/pdf/web/cmaps/V.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/V.bcmap rename to themes/next/source/lib/pdf/web/cmaps/V.bcmap diff --git a/source/lib/pdf/web/cmaps/WP-Symbol.bcmap b/themes/next/source/lib/pdf/web/cmaps/WP-Symbol.bcmap similarity index 100% rename from source/lib/pdf/web/cmaps/WP-Symbol.bcmap rename to themes/next/source/lib/pdf/web/cmaps/WP-Symbol.bcmap diff --git a/source/lib/pdf/web/compressed.tracemonkey-pldi-09.pdf b/themes/next/source/lib/pdf/web/compressed.tracemonkey-pldi-09.pdf similarity index 100% rename from source/lib/pdf/web/compressed.tracemonkey-pldi-09.pdf rename to themes/next/source/lib/pdf/web/compressed.tracemonkey-pldi-09.pdf diff --git a/source/lib/pdf/web/debugger.js b/themes/next/source/lib/pdf/web/debugger.js similarity index 100% rename from source/lib/pdf/web/debugger.js rename to themes/next/source/lib/pdf/web/debugger.js diff --git a/source/lib/pdf/web/images/annotation-check.svg b/themes/next/source/lib/pdf/web/images/annotation-check.svg similarity index 100% rename from source/lib/pdf/web/images/annotation-check.svg rename to themes/next/source/lib/pdf/web/images/annotation-check.svg diff --git a/source/lib/pdf/web/images/annotation-comment.svg b/themes/next/source/lib/pdf/web/images/annotation-comment.svg similarity index 100% rename from source/lib/pdf/web/images/annotation-comment.svg rename to themes/next/source/lib/pdf/web/images/annotation-comment.svg diff --git a/source/lib/pdf/web/images/annotation-help.svg b/themes/next/source/lib/pdf/web/images/annotation-help.svg similarity index 100% rename from source/lib/pdf/web/images/annotation-help.svg rename to themes/next/source/lib/pdf/web/images/annotation-help.svg diff --git a/source/lib/pdf/web/images/annotation-insert.svg b/themes/next/source/lib/pdf/web/images/annotation-insert.svg similarity index 100% rename from source/lib/pdf/web/images/annotation-insert.svg rename to themes/next/source/lib/pdf/web/images/annotation-insert.svg diff --git a/source/lib/pdf/web/images/annotation-key.svg b/themes/next/source/lib/pdf/web/images/annotation-key.svg similarity index 100% rename from source/lib/pdf/web/images/annotation-key.svg rename to themes/next/source/lib/pdf/web/images/annotation-key.svg diff --git a/source/lib/pdf/web/images/annotation-newparagraph.svg b/themes/next/source/lib/pdf/web/images/annotation-newparagraph.svg similarity index 100% rename from source/lib/pdf/web/images/annotation-newparagraph.svg rename to themes/next/source/lib/pdf/web/images/annotation-newparagraph.svg diff --git a/source/lib/pdf/web/images/annotation-noicon.svg b/themes/next/source/lib/pdf/web/images/annotation-noicon.svg similarity index 100% rename from source/lib/pdf/web/images/annotation-noicon.svg rename to themes/next/source/lib/pdf/web/images/annotation-noicon.svg diff --git a/source/lib/pdf/web/images/annotation-note.svg b/themes/next/source/lib/pdf/web/images/annotation-note.svg similarity index 100% rename from source/lib/pdf/web/images/annotation-note.svg rename to themes/next/source/lib/pdf/web/images/annotation-note.svg diff --git a/source/lib/pdf/web/images/annotation-paragraph.svg b/themes/next/source/lib/pdf/web/images/annotation-paragraph.svg similarity index 100% rename from source/lib/pdf/web/images/annotation-paragraph.svg rename to themes/next/source/lib/pdf/web/images/annotation-paragraph.svg diff --git a/source/lib/pdf/web/images/findbarButton-next-rtl.png b/themes/next/source/lib/pdf/web/images/findbarButton-next-rtl.png similarity index 100% rename from source/lib/pdf/web/images/findbarButton-next-rtl.png rename to themes/next/source/lib/pdf/web/images/findbarButton-next-rtl.png diff --git a/source/lib/pdf/web/images/findbarButton-next-rtl@2x.png b/themes/next/source/lib/pdf/web/images/findbarButton-next-rtl@2x.png similarity index 100% rename from source/lib/pdf/web/images/findbarButton-next-rtl@2x.png rename to themes/next/source/lib/pdf/web/images/findbarButton-next-rtl@2x.png diff --git a/source/lib/pdf/web/images/findbarButton-next.png b/themes/next/source/lib/pdf/web/images/findbarButton-next.png similarity index 100% rename from source/lib/pdf/web/images/findbarButton-next.png rename to themes/next/source/lib/pdf/web/images/findbarButton-next.png diff --git a/source/lib/pdf/web/images/findbarButton-next@2x.png b/themes/next/source/lib/pdf/web/images/findbarButton-next@2x.png similarity index 100% rename from source/lib/pdf/web/images/findbarButton-next@2x.png rename to themes/next/source/lib/pdf/web/images/findbarButton-next@2x.png diff --git a/source/lib/pdf/web/images/findbarButton-previous-rtl.png b/themes/next/source/lib/pdf/web/images/findbarButton-previous-rtl.png similarity index 100% rename from source/lib/pdf/web/images/findbarButton-previous-rtl.png rename to themes/next/source/lib/pdf/web/images/findbarButton-previous-rtl.png diff --git a/source/lib/pdf/web/images/findbarButton-previous-rtl@2x.png b/themes/next/source/lib/pdf/web/images/findbarButton-previous-rtl@2x.png similarity index 100% rename from source/lib/pdf/web/images/findbarButton-previous-rtl@2x.png rename to themes/next/source/lib/pdf/web/images/findbarButton-previous-rtl@2x.png diff --git a/source/lib/pdf/web/images/findbarButton-previous.png b/themes/next/source/lib/pdf/web/images/findbarButton-previous.png similarity index 100% rename from source/lib/pdf/web/images/findbarButton-previous.png rename to themes/next/source/lib/pdf/web/images/findbarButton-previous.png diff --git a/source/lib/pdf/web/images/findbarButton-previous@2x.png b/themes/next/source/lib/pdf/web/images/findbarButton-previous@2x.png similarity index 100% rename from source/lib/pdf/web/images/findbarButton-previous@2x.png rename to themes/next/source/lib/pdf/web/images/findbarButton-previous@2x.png diff --git a/source/lib/pdf/web/images/grab.cur b/themes/next/source/lib/pdf/web/images/grab.cur similarity index 100% rename from source/lib/pdf/web/images/grab.cur rename to themes/next/source/lib/pdf/web/images/grab.cur diff --git a/source/lib/pdf/web/images/grabbing.cur b/themes/next/source/lib/pdf/web/images/grabbing.cur similarity index 100% rename from source/lib/pdf/web/images/grabbing.cur rename to themes/next/source/lib/pdf/web/images/grabbing.cur diff --git a/source/lib/pdf/web/images/loading-icon.gif b/themes/next/source/lib/pdf/web/images/loading-icon.gif similarity index 100% rename from source/lib/pdf/web/images/loading-icon.gif rename to themes/next/source/lib/pdf/web/images/loading-icon.gif diff --git a/source/lib/pdf/web/images/loading-small.png b/themes/next/source/lib/pdf/web/images/loading-small.png similarity index 100% rename from source/lib/pdf/web/images/loading-small.png rename to themes/next/source/lib/pdf/web/images/loading-small.png diff --git a/source/lib/pdf/web/images/loading-small@2x.png b/themes/next/source/lib/pdf/web/images/loading-small@2x.png similarity index 100% rename from source/lib/pdf/web/images/loading-small@2x.png rename to themes/next/source/lib/pdf/web/images/loading-small@2x.png diff --git a/source/lib/pdf/web/images/secondaryToolbarButton-documentProperties.png b/themes/next/source/lib/pdf/web/images/secondaryToolbarButton-documentProperties.png similarity index 100% rename from source/lib/pdf/web/images/secondaryToolbarButton-documentProperties.png rename to themes/next/source/lib/pdf/web/images/secondaryToolbarButton-documentProperties.png diff --git a/source/lib/pdf/web/images/secondaryToolbarButton-documentProperties@2x.png b/themes/next/source/lib/pdf/web/images/secondaryToolbarButton-documentProperties@2x.png similarity index 100% rename from source/lib/pdf/web/images/secondaryToolbarButton-documentProperties@2x.png rename to themes/next/source/lib/pdf/web/images/secondaryToolbarButton-documentProperties@2x.png diff --git a/source/lib/pdf/web/images/secondaryToolbarButton-firstPage.png b/themes/next/source/lib/pdf/web/images/secondaryToolbarButton-firstPage.png similarity index 100% rename from source/lib/pdf/web/images/secondaryToolbarButton-firstPage.png rename to themes/next/source/lib/pdf/web/images/secondaryToolbarButton-firstPage.png diff --git a/source/lib/pdf/web/images/secondaryToolbarButton-firstPage@2x.png b/themes/next/source/lib/pdf/web/images/secondaryToolbarButton-firstPage@2x.png similarity index 100% rename from source/lib/pdf/web/images/secondaryToolbarButton-firstPage@2x.png rename to themes/next/source/lib/pdf/web/images/secondaryToolbarButton-firstPage@2x.png diff --git a/source/lib/pdf/web/images/secondaryToolbarButton-handTool.png b/themes/next/source/lib/pdf/web/images/secondaryToolbarButton-handTool.png similarity index 100% rename from source/lib/pdf/web/images/secondaryToolbarButton-handTool.png rename to themes/next/source/lib/pdf/web/images/secondaryToolbarButton-handTool.png diff --git a/source/lib/pdf/web/images/secondaryToolbarButton-handTool@2x.png b/themes/next/source/lib/pdf/web/images/secondaryToolbarButton-handTool@2x.png similarity index 100% rename from source/lib/pdf/web/images/secondaryToolbarButton-handTool@2x.png rename to themes/next/source/lib/pdf/web/images/secondaryToolbarButton-handTool@2x.png diff --git a/source/lib/pdf/web/images/secondaryToolbarButton-lastPage.png b/themes/next/source/lib/pdf/web/images/secondaryToolbarButton-lastPage.png similarity index 100% rename from source/lib/pdf/web/images/secondaryToolbarButton-lastPage.png rename to themes/next/source/lib/pdf/web/images/secondaryToolbarButton-lastPage.png diff --git a/source/lib/pdf/web/images/secondaryToolbarButton-lastPage@2x.png b/themes/next/source/lib/pdf/web/images/secondaryToolbarButton-lastPage@2x.png similarity index 100% rename from source/lib/pdf/web/images/secondaryToolbarButton-lastPage@2x.png rename to themes/next/source/lib/pdf/web/images/secondaryToolbarButton-lastPage@2x.png diff --git a/source/lib/pdf/web/images/secondaryToolbarButton-rotateCcw.png b/themes/next/source/lib/pdf/web/images/secondaryToolbarButton-rotateCcw.png similarity index 100% rename from source/lib/pdf/web/images/secondaryToolbarButton-rotateCcw.png rename to themes/next/source/lib/pdf/web/images/secondaryToolbarButton-rotateCcw.png diff --git a/source/lib/pdf/web/images/secondaryToolbarButton-rotateCcw@2x.png b/themes/next/source/lib/pdf/web/images/secondaryToolbarButton-rotateCcw@2x.png similarity index 100% rename from source/lib/pdf/web/images/secondaryToolbarButton-rotateCcw@2x.png rename to themes/next/source/lib/pdf/web/images/secondaryToolbarButton-rotateCcw@2x.png diff --git a/source/lib/pdf/web/images/secondaryToolbarButton-rotateCw.png b/themes/next/source/lib/pdf/web/images/secondaryToolbarButton-rotateCw.png similarity index 100% rename from source/lib/pdf/web/images/secondaryToolbarButton-rotateCw.png rename to themes/next/source/lib/pdf/web/images/secondaryToolbarButton-rotateCw.png diff --git a/source/lib/pdf/web/images/secondaryToolbarButton-rotateCw@2x.png b/themes/next/source/lib/pdf/web/images/secondaryToolbarButton-rotateCw@2x.png similarity index 100% rename from source/lib/pdf/web/images/secondaryToolbarButton-rotateCw@2x.png rename to themes/next/source/lib/pdf/web/images/secondaryToolbarButton-rotateCw@2x.png diff --git a/source/lib/pdf/web/images/secondaryToolbarButton-scrollHorizontal.png b/themes/next/source/lib/pdf/web/images/secondaryToolbarButton-scrollHorizontal.png similarity index 100% rename from source/lib/pdf/web/images/secondaryToolbarButton-scrollHorizontal.png rename to themes/next/source/lib/pdf/web/images/secondaryToolbarButton-scrollHorizontal.png diff --git a/source/lib/pdf/web/images/secondaryToolbarButton-scrollHorizontal@2x.png b/themes/next/source/lib/pdf/web/images/secondaryToolbarButton-scrollHorizontal@2x.png similarity index 100% rename from source/lib/pdf/web/images/secondaryToolbarButton-scrollHorizontal@2x.png rename to themes/next/source/lib/pdf/web/images/secondaryToolbarButton-scrollHorizontal@2x.png diff --git a/source/lib/pdf/web/images/secondaryToolbarButton-scrollVertical.png b/themes/next/source/lib/pdf/web/images/secondaryToolbarButton-scrollVertical.png similarity index 100% rename from source/lib/pdf/web/images/secondaryToolbarButton-scrollVertical.png rename to themes/next/source/lib/pdf/web/images/secondaryToolbarButton-scrollVertical.png diff --git a/source/lib/pdf/web/images/secondaryToolbarButton-scrollVertical@2x.png b/themes/next/source/lib/pdf/web/images/secondaryToolbarButton-scrollVertical@2x.png similarity index 100% rename from source/lib/pdf/web/images/secondaryToolbarButton-scrollVertical@2x.png rename to themes/next/source/lib/pdf/web/images/secondaryToolbarButton-scrollVertical@2x.png diff --git a/source/lib/pdf/web/images/secondaryToolbarButton-scrollWrapped.png b/themes/next/source/lib/pdf/web/images/secondaryToolbarButton-scrollWrapped.png similarity index 100% rename from source/lib/pdf/web/images/secondaryToolbarButton-scrollWrapped.png rename to themes/next/source/lib/pdf/web/images/secondaryToolbarButton-scrollWrapped.png diff --git a/source/lib/pdf/web/images/secondaryToolbarButton-scrollWrapped@2x.png b/themes/next/source/lib/pdf/web/images/secondaryToolbarButton-scrollWrapped@2x.png similarity index 100% rename from source/lib/pdf/web/images/secondaryToolbarButton-scrollWrapped@2x.png rename to themes/next/source/lib/pdf/web/images/secondaryToolbarButton-scrollWrapped@2x.png diff --git a/source/lib/pdf/web/images/secondaryToolbarButton-selectTool.png b/themes/next/source/lib/pdf/web/images/secondaryToolbarButton-selectTool.png similarity index 100% rename from source/lib/pdf/web/images/secondaryToolbarButton-selectTool.png rename to themes/next/source/lib/pdf/web/images/secondaryToolbarButton-selectTool.png diff --git a/source/lib/pdf/web/images/secondaryToolbarButton-selectTool@2x.png b/themes/next/source/lib/pdf/web/images/secondaryToolbarButton-selectTool@2x.png similarity index 100% rename from source/lib/pdf/web/images/secondaryToolbarButton-selectTool@2x.png rename to themes/next/source/lib/pdf/web/images/secondaryToolbarButton-selectTool@2x.png diff --git a/source/lib/pdf/web/images/secondaryToolbarButton-spreadEven.png b/themes/next/source/lib/pdf/web/images/secondaryToolbarButton-spreadEven.png similarity index 100% rename from source/lib/pdf/web/images/secondaryToolbarButton-spreadEven.png rename to themes/next/source/lib/pdf/web/images/secondaryToolbarButton-spreadEven.png diff --git a/source/lib/pdf/web/images/secondaryToolbarButton-spreadEven@2x.png b/themes/next/source/lib/pdf/web/images/secondaryToolbarButton-spreadEven@2x.png similarity index 100% rename from source/lib/pdf/web/images/secondaryToolbarButton-spreadEven@2x.png rename to themes/next/source/lib/pdf/web/images/secondaryToolbarButton-spreadEven@2x.png diff --git a/source/lib/pdf/web/images/secondaryToolbarButton-spreadNone.png b/themes/next/source/lib/pdf/web/images/secondaryToolbarButton-spreadNone.png similarity index 100% rename from source/lib/pdf/web/images/secondaryToolbarButton-spreadNone.png rename to themes/next/source/lib/pdf/web/images/secondaryToolbarButton-spreadNone.png diff --git a/source/lib/pdf/web/images/secondaryToolbarButton-spreadNone@2x.png b/themes/next/source/lib/pdf/web/images/secondaryToolbarButton-spreadNone@2x.png similarity index 100% rename from source/lib/pdf/web/images/secondaryToolbarButton-spreadNone@2x.png rename to themes/next/source/lib/pdf/web/images/secondaryToolbarButton-spreadNone@2x.png diff --git a/source/lib/pdf/web/images/secondaryToolbarButton-spreadOdd.png b/themes/next/source/lib/pdf/web/images/secondaryToolbarButton-spreadOdd.png similarity index 100% rename from source/lib/pdf/web/images/secondaryToolbarButton-spreadOdd.png rename to themes/next/source/lib/pdf/web/images/secondaryToolbarButton-spreadOdd.png diff --git a/source/lib/pdf/web/images/secondaryToolbarButton-spreadOdd@2x.png b/themes/next/source/lib/pdf/web/images/secondaryToolbarButton-spreadOdd@2x.png similarity index 100% rename from source/lib/pdf/web/images/secondaryToolbarButton-spreadOdd@2x.png rename to themes/next/source/lib/pdf/web/images/secondaryToolbarButton-spreadOdd@2x.png diff --git a/source/lib/pdf/web/images/shadow.png b/themes/next/source/lib/pdf/web/images/shadow.png similarity index 100% rename from source/lib/pdf/web/images/shadow.png rename to themes/next/source/lib/pdf/web/images/shadow.png diff --git a/source/lib/pdf/web/images/texture.png b/themes/next/source/lib/pdf/web/images/texture.png similarity index 100% rename from source/lib/pdf/web/images/texture.png rename to themes/next/source/lib/pdf/web/images/texture.png diff --git a/source/lib/pdf/web/images/toolbarButton-bookmark.png b/themes/next/source/lib/pdf/web/images/toolbarButton-bookmark.png similarity index 100% rename from source/lib/pdf/web/images/toolbarButton-bookmark.png rename to themes/next/source/lib/pdf/web/images/toolbarButton-bookmark.png diff --git a/source/lib/pdf/web/images/toolbarButton-bookmark@2x.png b/themes/next/source/lib/pdf/web/images/toolbarButton-bookmark@2x.png similarity index 100% rename from source/lib/pdf/web/images/toolbarButton-bookmark@2x.png rename to themes/next/source/lib/pdf/web/images/toolbarButton-bookmark@2x.png diff --git a/source/lib/pdf/web/images/toolbarButton-download.png b/themes/next/source/lib/pdf/web/images/toolbarButton-download.png similarity index 100% rename from source/lib/pdf/web/images/toolbarButton-download.png rename to themes/next/source/lib/pdf/web/images/toolbarButton-download.png diff --git a/source/lib/pdf/web/images/toolbarButton-download@2x.png b/themes/next/source/lib/pdf/web/images/toolbarButton-download@2x.png similarity index 100% rename from source/lib/pdf/web/images/toolbarButton-download@2x.png rename to themes/next/source/lib/pdf/web/images/toolbarButton-download@2x.png diff --git a/source/lib/pdf/web/images/toolbarButton-menuArrows.png b/themes/next/source/lib/pdf/web/images/toolbarButton-menuArrows.png similarity index 100% rename from source/lib/pdf/web/images/toolbarButton-menuArrows.png rename to themes/next/source/lib/pdf/web/images/toolbarButton-menuArrows.png diff --git a/source/lib/pdf/web/images/toolbarButton-menuArrows@2x.png b/themes/next/source/lib/pdf/web/images/toolbarButton-menuArrows@2x.png similarity index 100% rename from source/lib/pdf/web/images/toolbarButton-menuArrows@2x.png rename to themes/next/source/lib/pdf/web/images/toolbarButton-menuArrows@2x.png diff --git a/source/lib/pdf/web/images/toolbarButton-openFile.png b/themes/next/source/lib/pdf/web/images/toolbarButton-openFile.png similarity index 100% rename from source/lib/pdf/web/images/toolbarButton-openFile.png rename to themes/next/source/lib/pdf/web/images/toolbarButton-openFile.png diff --git a/source/lib/pdf/web/images/toolbarButton-openFile@2x.png b/themes/next/source/lib/pdf/web/images/toolbarButton-openFile@2x.png similarity index 100% rename from source/lib/pdf/web/images/toolbarButton-openFile@2x.png rename to themes/next/source/lib/pdf/web/images/toolbarButton-openFile@2x.png diff --git a/source/lib/pdf/web/images/toolbarButton-pageDown-rtl.png b/themes/next/source/lib/pdf/web/images/toolbarButton-pageDown-rtl.png similarity index 100% rename from source/lib/pdf/web/images/toolbarButton-pageDown-rtl.png rename to themes/next/source/lib/pdf/web/images/toolbarButton-pageDown-rtl.png diff --git a/source/lib/pdf/web/images/toolbarButton-pageDown-rtl@2x.png b/themes/next/source/lib/pdf/web/images/toolbarButton-pageDown-rtl@2x.png similarity index 100% rename from source/lib/pdf/web/images/toolbarButton-pageDown-rtl@2x.png rename to themes/next/source/lib/pdf/web/images/toolbarButton-pageDown-rtl@2x.png diff --git a/source/lib/pdf/web/images/toolbarButton-pageDown.png b/themes/next/source/lib/pdf/web/images/toolbarButton-pageDown.png similarity index 100% rename from source/lib/pdf/web/images/toolbarButton-pageDown.png rename to themes/next/source/lib/pdf/web/images/toolbarButton-pageDown.png diff --git a/source/lib/pdf/web/images/toolbarButton-pageDown@2x.png b/themes/next/source/lib/pdf/web/images/toolbarButton-pageDown@2x.png similarity index 100% rename from source/lib/pdf/web/images/toolbarButton-pageDown@2x.png rename to themes/next/source/lib/pdf/web/images/toolbarButton-pageDown@2x.png diff --git a/source/lib/pdf/web/images/toolbarButton-pageUp-rtl.png b/themes/next/source/lib/pdf/web/images/toolbarButton-pageUp-rtl.png similarity index 100% rename from source/lib/pdf/web/images/toolbarButton-pageUp-rtl.png rename to themes/next/source/lib/pdf/web/images/toolbarButton-pageUp-rtl.png diff --git a/source/lib/pdf/web/images/toolbarButton-pageUp-rtl@2x.png b/themes/next/source/lib/pdf/web/images/toolbarButton-pageUp-rtl@2x.png similarity index 100% rename from source/lib/pdf/web/images/toolbarButton-pageUp-rtl@2x.png rename to themes/next/source/lib/pdf/web/images/toolbarButton-pageUp-rtl@2x.png diff --git a/source/lib/pdf/web/images/toolbarButton-pageUp.png b/themes/next/source/lib/pdf/web/images/toolbarButton-pageUp.png similarity index 100% rename from source/lib/pdf/web/images/toolbarButton-pageUp.png rename to themes/next/source/lib/pdf/web/images/toolbarButton-pageUp.png diff --git a/source/lib/pdf/web/images/toolbarButton-pageUp@2x.png b/themes/next/source/lib/pdf/web/images/toolbarButton-pageUp@2x.png similarity index 100% rename from source/lib/pdf/web/images/toolbarButton-pageUp@2x.png rename to themes/next/source/lib/pdf/web/images/toolbarButton-pageUp@2x.png diff --git a/source/lib/pdf/web/images/toolbarButton-presentationMode.png b/themes/next/source/lib/pdf/web/images/toolbarButton-presentationMode.png similarity index 100% rename from source/lib/pdf/web/images/toolbarButton-presentationMode.png rename to themes/next/source/lib/pdf/web/images/toolbarButton-presentationMode.png diff --git a/source/lib/pdf/web/images/toolbarButton-presentationMode@2x.png b/themes/next/source/lib/pdf/web/images/toolbarButton-presentationMode@2x.png similarity index 100% rename from source/lib/pdf/web/images/toolbarButton-presentationMode@2x.png rename to themes/next/source/lib/pdf/web/images/toolbarButton-presentationMode@2x.png diff --git a/source/lib/pdf/web/images/toolbarButton-print.png b/themes/next/source/lib/pdf/web/images/toolbarButton-print.png similarity index 100% rename from source/lib/pdf/web/images/toolbarButton-print.png rename to themes/next/source/lib/pdf/web/images/toolbarButton-print.png diff --git a/source/lib/pdf/web/images/toolbarButton-print@2x.png b/themes/next/source/lib/pdf/web/images/toolbarButton-print@2x.png similarity index 100% rename from source/lib/pdf/web/images/toolbarButton-print@2x.png rename to themes/next/source/lib/pdf/web/images/toolbarButton-print@2x.png diff --git a/source/lib/pdf/web/images/toolbarButton-search.png b/themes/next/source/lib/pdf/web/images/toolbarButton-search.png similarity index 100% rename from source/lib/pdf/web/images/toolbarButton-search.png rename to themes/next/source/lib/pdf/web/images/toolbarButton-search.png diff --git a/source/lib/pdf/web/images/toolbarButton-search@2x.png b/themes/next/source/lib/pdf/web/images/toolbarButton-search@2x.png similarity index 100% rename from source/lib/pdf/web/images/toolbarButton-search@2x.png rename to themes/next/source/lib/pdf/web/images/toolbarButton-search@2x.png diff --git a/source/lib/pdf/web/images/toolbarButton-secondaryToolbarToggle-rtl.png b/themes/next/source/lib/pdf/web/images/toolbarButton-secondaryToolbarToggle-rtl.png similarity index 100% rename from source/lib/pdf/web/images/toolbarButton-secondaryToolbarToggle-rtl.png rename to themes/next/source/lib/pdf/web/images/toolbarButton-secondaryToolbarToggle-rtl.png diff --git a/source/lib/pdf/web/images/toolbarButton-secondaryToolbarToggle-rtl@2x.png b/themes/next/source/lib/pdf/web/images/toolbarButton-secondaryToolbarToggle-rtl@2x.png similarity index 100% rename from source/lib/pdf/web/images/toolbarButton-secondaryToolbarToggle-rtl@2x.png rename to themes/next/source/lib/pdf/web/images/toolbarButton-secondaryToolbarToggle-rtl@2x.png diff --git a/source/lib/pdf/web/images/toolbarButton-secondaryToolbarToggle.png b/themes/next/source/lib/pdf/web/images/toolbarButton-secondaryToolbarToggle.png similarity index 100% rename from source/lib/pdf/web/images/toolbarButton-secondaryToolbarToggle.png rename to themes/next/source/lib/pdf/web/images/toolbarButton-secondaryToolbarToggle.png diff --git a/source/lib/pdf/web/images/toolbarButton-secondaryToolbarToggle@2x.png b/themes/next/source/lib/pdf/web/images/toolbarButton-secondaryToolbarToggle@2x.png similarity index 100% rename from source/lib/pdf/web/images/toolbarButton-secondaryToolbarToggle@2x.png rename to themes/next/source/lib/pdf/web/images/toolbarButton-secondaryToolbarToggle@2x.png diff --git a/source/lib/pdf/web/images/toolbarButton-sidebarToggle-rtl.png b/themes/next/source/lib/pdf/web/images/toolbarButton-sidebarToggle-rtl.png similarity index 100% rename from source/lib/pdf/web/images/toolbarButton-sidebarToggle-rtl.png rename to themes/next/source/lib/pdf/web/images/toolbarButton-sidebarToggle-rtl.png diff --git a/source/lib/pdf/web/images/toolbarButton-sidebarToggle-rtl@2x.png b/themes/next/source/lib/pdf/web/images/toolbarButton-sidebarToggle-rtl@2x.png similarity index 100% rename from source/lib/pdf/web/images/toolbarButton-sidebarToggle-rtl@2x.png rename to themes/next/source/lib/pdf/web/images/toolbarButton-sidebarToggle-rtl@2x.png diff --git a/source/lib/pdf/web/images/toolbarButton-sidebarToggle.png b/themes/next/source/lib/pdf/web/images/toolbarButton-sidebarToggle.png similarity index 100% rename from source/lib/pdf/web/images/toolbarButton-sidebarToggle.png rename to themes/next/source/lib/pdf/web/images/toolbarButton-sidebarToggle.png diff --git a/source/lib/pdf/web/images/toolbarButton-sidebarToggle@2x.png b/themes/next/source/lib/pdf/web/images/toolbarButton-sidebarToggle@2x.png similarity index 100% rename from source/lib/pdf/web/images/toolbarButton-sidebarToggle@2x.png rename to themes/next/source/lib/pdf/web/images/toolbarButton-sidebarToggle@2x.png diff --git a/source/lib/pdf/web/images/toolbarButton-viewAttachments.png b/themes/next/source/lib/pdf/web/images/toolbarButton-viewAttachments.png similarity index 100% rename from source/lib/pdf/web/images/toolbarButton-viewAttachments.png rename to themes/next/source/lib/pdf/web/images/toolbarButton-viewAttachments.png diff --git a/source/lib/pdf/web/images/toolbarButton-viewAttachments@2x.png b/themes/next/source/lib/pdf/web/images/toolbarButton-viewAttachments@2x.png similarity index 100% rename from source/lib/pdf/web/images/toolbarButton-viewAttachments@2x.png rename to themes/next/source/lib/pdf/web/images/toolbarButton-viewAttachments@2x.png diff --git a/source/lib/pdf/web/images/toolbarButton-viewOutline-rtl.png b/themes/next/source/lib/pdf/web/images/toolbarButton-viewOutline-rtl.png similarity index 100% rename from source/lib/pdf/web/images/toolbarButton-viewOutline-rtl.png rename to themes/next/source/lib/pdf/web/images/toolbarButton-viewOutline-rtl.png diff --git a/source/lib/pdf/web/images/toolbarButton-viewOutline-rtl@2x.png b/themes/next/source/lib/pdf/web/images/toolbarButton-viewOutline-rtl@2x.png similarity index 100% rename from source/lib/pdf/web/images/toolbarButton-viewOutline-rtl@2x.png rename to themes/next/source/lib/pdf/web/images/toolbarButton-viewOutline-rtl@2x.png diff --git a/source/lib/pdf/web/images/toolbarButton-viewOutline.png b/themes/next/source/lib/pdf/web/images/toolbarButton-viewOutline.png similarity index 100% rename from source/lib/pdf/web/images/toolbarButton-viewOutline.png rename to themes/next/source/lib/pdf/web/images/toolbarButton-viewOutline.png diff --git a/source/lib/pdf/web/images/toolbarButton-viewOutline@2x.png b/themes/next/source/lib/pdf/web/images/toolbarButton-viewOutline@2x.png similarity index 100% rename from source/lib/pdf/web/images/toolbarButton-viewOutline@2x.png rename to themes/next/source/lib/pdf/web/images/toolbarButton-viewOutline@2x.png diff --git a/source/lib/pdf/web/images/toolbarButton-viewThumbnail.png b/themes/next/source/lib/pdf/web/images/toolbarButton-viewThumbnail.png similarity index 100% rename from source/lib/pdf/web/images/toolbarButton-viewThumbnail.png rename to themes/next/source/lib/pdf/web/images/toolbarButton-viewThumbnail.png diff --git a/source/lib/pdf/web/images/toolbarButton-viewThumbnail@2x.png b/themes/next/source/lib/pdf/web/images/toolbarButton-viewThumbnail@2x.png similarity index 100% rename from source/lib/pdf/web/images/toolbarButton-viewThumbnail@2x.png rename to themes/next/source/lib/pdf/web/images/toolbarButton-viewThumbnail@2x.png diff --git a/source/lib/pdf/web/images/toolbarButton-zoomIn.png b/themes/next/source/lib/pdf/web/images/toolbarButton-zoomIn.png similarity index 100% rename from source/lib/pdf/web/images/toolbarButton-zoomIn.png rename to themes/next/source/lib/pdf/web/images/toolbarButton-zoomIn.png diff --git a/source/lib/pdf/web/images/toolbarButton-zoomIn@2x.png b/themes/next/source/lib/pdf/web/images/toolbarButton-zoomIn@2x.png similarity index 100% rename from source/lib/pdf/web/images/toolbarButton-zoomIn@2x.png rename to themes/next/source/lib/pdf/web/images/toolbarButton-zoomIn@2x.png diff --git a/source/lib/pdf/web/images/toolbarButton-zoomOut.png b/themes/next/source/lib/pdf/web/images/toolbarButton-zoomOut.png similarity index 100% rename from source/lib/pdf/web/images/toolbarButton-zoomOut.png rename to themes/next/source/lib/pdf/web/images/toolbarButton-zoomOut.png diff --git a/source/lib/pdf/web/images/toolbarButton-zoomOut@2x.png b/themes/next/source/lib/pdf/web/images/toolbarButton-zoomOut@2x.png similarity index 100% rename from source/lib/pdf/web/images/toolbarButton-zoomOut@2x.png rename to themes/next/source/lib/pdf/web/images/toolbarButton-zoomOut@2x.png diff --git a/source/lib/pdf/web/images/treeitem-collapsed-rtl.png b/themes/next/source/lib/pdf/web/images/treeitem-collapsed-rtl.png similarity index 100% rename from source/lib/pdf/web/images/treeitem-collapsed-rtl.png rename to themes/next/source/lib/pdf/web/images/treeitem-collapsed-rtl.png diff --git a/source/lib/pdf/web/images/treeitem-collapsed-rtl@2x.png b/themes/next/source/lib/pdf/web/images/treeitem-collapsed-rtl@2x.png similarity index 100% rename from source/lib/pdf/web/images/treeitem-collapsed-rtl@2x.png rename to themes/next/source/lib/pdf/web/images/treeitem-collapsed-rtl@2x.png diff --git a/source/lib/pdf/web/images/treeitem-collapsed.png b/themes/next/source/lib/pdf/web/images/treeitem-collapsed.png similarity index 100% rename from source/lib/pdf/web/images/treeitem-collapsed.png rename to themes/next/source/lib/pdf/web/images/treeitem-collapsed.png diff --git a/source/lib/pdf/web/images/treeitem-collapsed@2x.png b/themes/next/source/lib/pdf/web/images/treeitem-collapsed@2x.png similarity index 100% rename from source/lib/pdf/web/images/treeitem-collapsed@2x.png rename to themes/next/source/lib/pdf/web/images/treeitem-collapsed@2x.png diff --git a/source/lib/pdf/web/images/treeitem-expanded.png b/themes/next/source/lib/pdf/web/images/treeitem-expanded.png similarity index 100% rename from source/lib/pdf/web/images/treeitem-expanded.png rename to themes/next/source/lib/pdf/web/images/treeitem-expanded.png diff --git a/source/lib/pdf/web/images/treeitem-expanded@2x.png b/themes/next/source/lib/pdf/web/images/treeitem-expanded@2x.png similarity index 100% rename from source/lib/pdf/web/images/treeitem-expanded@2x.png rename to themes/next/source/lib/pdf/web/images/treeitem-expanded@2x.png diff --git a/source/lib/pdf/web/locale/ach/viewer.properties b/themes/next/source/lib/pdf/web/locale/ach/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/ach/viewer.properties rename to themes/next/source/lib/pdf/web/locale/ach/viewer.properties diff --git a/source/lib/pdf/web/locale/af/viewer.properties b/themes/next/source/lib/pdf/web/locale/af/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/af/viewer.properties rename to themes/next/source/lib/pdf/web/locale/af/viewer.properties diff --git a/source/lib/pdf/web/locale/ak/viewer.properties b/themes/next/source/lib/pdf/web/locale/ak/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/ak/viewer.properties rename to themes/next/source/lib/pdf/web/locale/ak/viewer.properties diff --git a/source/lib/pdf/web/locale/an/viewer.properties b/themes/next/source/lib/pdf/web/locale/an/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/an/viewer.properties rename to themes/next/source/lib/pdf/web/locale/an/viewer.properties diff --git a/source/lib/pdf/web/locale/ar/viewer.properties b/themes/next/source/lib/pdf/web/locale/ar/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/ar/viewer.properties rename to themes/next/source/lib/pdf/web/locale/ar/viewer.properties diff --git a/source/lib/pdf/web/locale/as/viewer.properties b/themes/next/source/lib/pdf/web/locale/as/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/as/viewer.properties rename to themes/next/source/lib/pdf/web/locale/as/viewer.properties diff --git a/source/lib/pdf/web/locale/ast/viewer.properties b/themes/next/source/lib/pdf/web/locale/ast/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/ast/viewer.properties rename to themes/next/source/lib/pdf/web/locale/ast/viewer.properties diff --git a/source/lib/pdf/web/locale/az/viewer.properties b/themes/next/source/lib/pdf/web/locale/az/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/az/viewer.properties rename to themes/next/source/lib/pdf/web/locale/az/viewer.properties diff --git a/source/lib/pdf/web/locale/be/viewer.properties b/themes/next/source/lib/pdf/web/locale/be/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/be/viewer.properties rename to themes/next/source/lib/pdf/web/locale/be/viewer.properties diff --git a/source/lib/pdf/web/locale/bg/viewer.properties b/themes/next/source/lib/pdf/web/locale/bg/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/bg/viewer.properties rename to themes/next/source/lib/pdf/web/locale/bg/viewer.properties diff --git a/source/lib/pdf/web/locale/bn-BD/viewer.properties b/themes/next/source/lib/pdf/web/locale/bn-BD/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/bn-BD/viewer.properties rename to themes/next/source/lib/pdf/web/locale/bn-BD/viewer.properties diff --git a/source/lib/pdf/web/locale/bn-IN/viewer.properties b/themes/next/source/lib/pdf/web/locale/bn-IN/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/bn-IN/viewer.properties rename to themes/next/source/lib/pdf/web/locale/bn-IN/viewer.properties diff --git a/source/lib/pdf/web/locale/br/viewer.properties b/themes/next/source/lib/pdf/web/locale/br/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/br/viewer.properties rename to themes/next/source/lib/pdf/web/locale/br/viewer.properties diff --git a/source/lib/pdf/web/locale/brx/viewer.properties b/themes/next/source/lib/pdf/web/locale/brx/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/brx/viewer.properties rename to themes/next/source/lib/pdf/web/locale/brx/viewer.properties diff --git a/source/lib/pdf/web/locale/bs/viewer.properties b/themes/next/source/lib/pdf/web/locale/bs/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/bs/viewer.properties rename to themes/next/source/lib/pdf/web/locale/bs/viewer.properties diff --git a/source/lib/pdf/web/locale/ca/viewer.properties b/themes/next/source/lib/pdf/web/locale/ca/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/ca/viewer.properties rename to themes/next/source/lib/pdf/web/locale/ca/viewer.properties diff --git a/source/lib/pdf/web/locale/cak/viewer.properties b/themes/next/source/lib/pdf/web/locale/cak/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/cak/viewer.properties rename to themes/next/source/lib/pdf/web/locale/cak/viewer.properties diff --git a/source/lib/pdf/web/locale/crh/viewer.properties b/themes/next/source/lib/pdf/web/locale/crh/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/crh/viewer.properties rename to themes/next/source/lib/pdf/web/locale/crh/viewer.properties diff --git a/source/lib/pdf/web/locale/cs/viewer.properties b/themes/next/source/lib/pdf/web/locale/cs/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/cs/viewer.properties rename to themes/next/source/lib/pdf/web/locale/cs/viewer.properties diff --git a/source/lib/pdf/web/locale/csb/viewer.properties b/themes/next/source/lib/pdf/web/locale/csb/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/csb/viewer.properties rename to themes/next/source/lib/pdf/web/locale/csb/viewer.properties diff --git a/source/lib/pdf/web/locale/cy/viewer.properties b/themes/next/source/lib/pdf/web/locale/cy/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/cy/viewer.properties rename to themes/next/source/lib/pdf/web/locale/cy/viewer.properties diff --git a/source/lib/pdf/web/locale/da/viewer.properties b/themes/next/source/lib/pdf/web/locale/da/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/da/viewer.properties rename to themes/next/source/lib/pdf/web/locale/da/viewer.properties diff --git a/source/lib/pdf/web/locale/de/viewer.properties b/themes/next/source/lib/pdf/web/locale/de/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/de/viewer.properties rename to themes/next/source/lib/pdf/web/locale/de/viewer.properties diff --git a/source/lib/pdf/web/locale/el/viewer.properties b/themes/next/source/lib/pdf/web/locale/el/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/el/viewer.properties rename to themes/next/source/lib/pdf/web/locale/el/viewer.properties diff --git a/source/lib/pdf/web/locale/en-CA/viewer.properties b/themes/next/source/lib/pdf/web/locale/en-CA/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/en-CA/viewer.properties rename to themes/next/source/lib/pdf/web/locale/en-CA/viewer.properties diff --git a/source/lib/pdf/web/locale/en-GB/viewer.properties b/themes/next/source/lib/pdf/web/locale/en-GB/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/en-GB/viewer.properties rename to themes/next/source/lib/pdf/web/locale/en-GB/viewer.properties diff --git a/source/lib/pdf/web/locale/en-US/viewer.properties b/themes/next/source/lib/pdf/web/locale/en-US/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/en-US/viewer.properties rename to themes/next/source/lib/pdf/web/locale/en-US/viewer.properties diff --git a/source/lib/pdf/web/locale/en-ZA/viewer.properties b/themes/next/source/lib/pdf/web/locale/en-ZA/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/en-ZA/viewer.properties rename to themes/next/source/lib/pdf/web/locale/en-ZA/viewer.properties diff --git a/source/lib/pdf/web/locale/eo/viewer.properties b/themes/next/source/lib/pdf/web/locale/eo/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/eo/viewer.properties rename to themes/next/source/lib/pdf/web/locale/eo/viewer.properties diff --git a/source/lib/pdf/web/locale/es-AR/viewer.properties b/themes/next/source/lib/pdf/web/locale/es-AR/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/es-AR/viewer.properties rename to themes/next/source/lib/pdf/web/locale/es-AR/viewer.properties diff --git a/source/lib/pdf/web/locale/es-CL/viewer.properties b/themes/next/source/lib/pdf/web/locale/es-CL/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/es-CL/viewer.properties rename to themes/next/source/lib/pdf/web/locale/es-CL/viewer.properties diff --git a/source/lib/pdf/web/locale/es-ES/viewer.properties b/themes/next/source/lib/pdf/web/locale/es-ES/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/es-ES/viewer.properties rename to themes/next/source/lib/pdf/web/locale/es-ES/viewer.properties diff --git a/source/lib/pdf/web/locale/es-MX/viewer.properties b/themes/next/source/lib/pdf/web/locale/es-MX/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/es-MX/viewer.properties rename to themes/next/source/lib/pdf/web/locale/es-MX/viewer.properties diff --git a/source/lib/pdf/web/locale/et/viewer.properties b/themes/next/source/lib/pdf/web/locale/et/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/et/viewer.properties rename to themes/next/source/lib/pdf/web/locale/et/viewer.properties diff --git a/source/lib/pdf/web/locale/eu/viewer.properties b/themes/next/source/lib/pdf/web/locale/eu/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/eu/viewer.properties rename to themes/next/source/lib/pdf/web/locale/eu/viewer.properties diff --git a/source/lib/pdf/web/locale/fa/viewer.properties b/themes/next/source/lib/pdf/web/locale/fa/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/fa/viewer.properties rename to themes/next/source/lib/pdf/web/locale/fa/viewer.properties diff --git a/source/lib/pdf/web/locale/ff/viewer.properties b/themes/next/source/lib/pdf/web/locale/ff/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/ff/viewer.properties rename to themes/next/source/lib/pdf/web/locale/ff/viewer.properties diff --git a/source/lib/pdf/web/locale/fi/viewer.properties b/themes/next/source/lib/pdf/web/locale/fi/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/fi/viewer.properties rename to themes/next/source/lib/pdf/web/locale/fi/viewer.properties diff --git a/source/lib/pdf/web/locale/fr/viewer.properties b/themes/next/source/lib/pdf/web/locale/fr/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/fr/viewer.properties rename to themes/next/source/lib/pdf/web/locale/fr/viewer.properties diff --git a/source/lib/pdf/web/locale/fy-NL/viewer.properties b/themes/next/source/lib/pdf/web/locale/fy-NL/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/fy-NL/viewer.properties rename to themes/next/source/lib/pdf/web/locale/fy-NL/viewer.properties diff --git a/source/lib/pdf/web/locale/ga-IE/viewer.properties b/themes/next/source/lib/pdf/web/locale/ga-IE/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/ga-IE/viewer.properties rename to themes/next/source/lib/pdf/web/locale/ga-IE/viewer.properties diff --git a/source/lib/pdf/web/locale/gd/viewer.properties b/themes/next/source/lib/pdf/web/locale/gd/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/gd/viewer.properties rename to themes/next/source/lib/pdf/web/locale/gd/viewer.properties diff --git a/source/lib/pdf/web/locale/gl/viewer.properties b/themes/next/source/lib/pdf/web/locale/gl/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/gl/viewer.properties rename to themes/next/source/lib/pdf/web/locale/gl/viewer.properties diff --git a/source/lib/pdf/web/locale/gn/viewer.properties b/themes/next/source/lib/pdf/web/locale/gn/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/gn/viewer.properties rename to themes/next/source/lib/pdf/web/locale/gn/viewer.properties diff --git a/source/lib/pdf/web/locale/gu-IN/viewer.properties b/themes/next/source/lib/pdf/web/locale/gu-IN/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/gu-IN/viewer.properties rename to themes/next/source/lib/pdf/web/locale/gu-IN/viewer.properties diff --git a/source/lib/pdf/web/locale/he/viewer.properties b/themes/next/source/lib/pdf/web/locale/he/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/he/viewer.properties rename to themes/next/source/lib/pdf/web/locale/he/viewer.properties diff --git a/source/lib/pdf/web/locale/hi-IN/viewer.properties b/themes/next/source/lib/pdf/web/locale/hi-IN/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/hi-IN/viewer.properties rename to themes/next/source/lib/pdf/web/locale/hi-IN/viewer.properties diff --git a/source/lib/pdf/web/locale/hr/viewer.properties b/themes/next/source/lib/pdf/web/locale/hr/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/hr/viewer.properties rename to themes/next/source/lib/pdf/web/locale/hr/viewer.properties diff --git a/source/lib/pdf/web/locale/hsb/viewer.properties b/themes/next/source/lib/pdf/web/locale/hsb/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/hsb/viewer.properties rename to themes/next/source/lib/pdf/web/locale/hsb/viewer.properties diff --git a/source/lib/pdf/web/locale/hto/viewer.properties b/themes/next/source/lib/pdf/web/locale/hto/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/hto/viewer.properties rename to themes/next/source/lib/pdf/web/locale/hto/viewer.properties diff --git a/source/lib/pdf/web/locale/hu/viewer.properties b/themes/next/source/lib/pdf/web/locale/hu/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/hu/viewer.properties rename to themes/next/source/lib/pdf/web/locale/hu/viewer.properties diff --git a/source/lib/pdf/web/locale/hy-AM/viewer.properties b/themes/next/source/lib/pdf/web/locale/hy-AM/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/hy-AM/viewer.properties rename to themes/next/source/lib/pdf/web/locale/hy-AM/viewer.properties diff --git a/source/lib/pdf/web/locale/ia/viewer.properties b/themes/next/source/lib/pdf/web/locale/ia/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/ia/viewer.properties rename to themes/next/source/lib/pdf/web/locale/ia/viewer.properties diff --git a/source/lib/pdf/web/locale/id/viewer.properties b/themes/next/source/lib/pdf/web/locale/id/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/id/viewer.properties rename to themes/next/source/lib/pdf/web/locale/id/viewer.properties diff --git a/source/lib/pdf/web/locale/is/viewer.properties b/themes/next/source/lib/pdf/web/locale/is/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/is/viewer.properties rename to themes/next/source/lib/pdf/web/locale/is/viewer.properties diff --git a/source/lib/pdf/web/locale/it/viewer.properties b/themes/next/source/lib/pdf/web/locale/it/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/it/viewer.properties rename to themes/next/source/lib/pdf/web/locale/it/viewer.properties diff --git a/source/lib/pdf/web/locale/ja/viewer.properties b/themes/next/source/lib/pdf/web/locale/ja/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/ja/viewer.properties rename to themes/next/source/lib/pdf/web/locale/ja/viewer.properties diff --git a/source/lib/pdf/web/locale/ka/viewer.properties b/themes/next/source/lib/pdf/web/locale/ka/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/ka/viewer.properties rename to themes/next/source/lib/pdf/web/locale/ka/viewer.properties diff --git a/source/lib/pdf/web/locale/kab/viewer.properties b/themes/next/source/lib/pdf/web/locale/kab/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/kab/viewer.properties rename to themes/next/source/lib/pdf/web/locale/kab/viewer.properties diff --git a/source/lib/pdf/web/locale/kk/viewer.properties b/themes/next/source/lib/pdf/web/locale/kk/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/kk/viewer.properties rename to themes/next/source/lib/pdf/web/locale/kk/viewer.properties diff --git a/source/lib/pdf/web/locale/km/viewer.properties b/themes/next/source/lib/pdf/web/locale/km/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/km/viewer.properties rename to themes/next/source/lib/pdf/web/locale/km/viewer.properties diff --git a/source/lib/pdf/web/locale/kn/viewer.properties b/themes/next/source/lib/pdf/web/locale/kn/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/kn/viewer.properties rename to themes/next/source/lib/pdf/web/locale/kn/viewer.properties diff --git a/source/lib/pdf/web/locale/ko/viewer.properties b/themes/next/source/lib/pdf/web/locale/ko/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/ko/viewer.properties rename to themes/next/source/lib/pdf/web/locale/ko/viewer.properties diff --git a/source/lib/pdf/web/locale/kok/viewer.properties b/themes/next/source/lib/pdf/web/locale/kok/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/kok/viewer.properties rename to themes/next/source/lib/pdf/web/locale/kok/viewer.properties diff --git a/source/lib/pdf/web/locale/ks/viewer.properties b/themes/next/source/lib/pdf/web/locale/ks/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/ks/viewer.properties rename to themes/next/source/lib/pdf/web/locale/ks/viewer.properties diff --git a/source/lib/pdf/web/locale/ku/viewer.properties b/themes/next/source/lib/pdf/web/locale/ku/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/ku/viewer.properties rename to themes/next/source/lib/pdf/web/locale/ku/viewer.properties diff --git a/source/lib/pdf/web/locale/lg/viewer.properties b/themes/next/source/lib/pdf/web/locale/lg/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/lg/viewer.properties rename to themes/next/source/lib/pdf/web/locale/lg/viewer.properties diff --git a/source/lib/pdf/web/locale/lij/viewer.properties b/themes/next/source/lib/pdf/web/locale/lij/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/lij/viewer.properties rename to themes/next/source/lib/pdf/web/locale/lij/viewer.properties diff --git a/source/lib/pdf/web/locale/lo/viewer.properties b/themes/next/source/lib/pdf/web/locale/lo/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/lo/viewer.properties rename to themes/next/source/lib/pdf/web/locale/lo/viewer.properties diff --git a/source/lib/pdf/web/locale/locale.properties b/themes/next/source/lib/pdf/web/locale/locale.properties similarity index 100% rename from source/lib/pdf/web/locale/locale.properties rename to themes/next/source/lib/pdf/web/locale/locale.properties diff --git a/source/lib/pdf/web/locale/lt/viewer.properties b/themes/next/source/lib/pdf/web/locale/lt/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/lt/viewer.properties rename to themes/next/source/lib/pdf/web/locale/lt/viewer.properties diff --git a/source/lib/pdf/web/locale/ltg/viewer.properties b/themes/next/source/lib/pdf/web/locale/ltg/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/ltg/viewer.properties rename to themes/next/source/lib/pdf/web/locale/ltg/viewer.properties diff --git a/source/lib/pdf/web/locale/lv/viewer.properties b/themes/next/source/lib/pdf/web/locale/lv/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/lv/viewer.properties rename to themes/next/source/lib/pdf/web/locale/lv/viewer.properties diff --git a/source/lib/pdf/web/locale/mai/viewer.properties b/themes/next/source/lib/pdf/web/locale/mai/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/mai/viewer.properties rename to themes/next/source/lib/pdf/web/locale/mai/viewer.properties diff --git a/source/lib/pdf/web/locale/meh/viewer.properties b/themes/next/source/lib/pdf/web/locale/meh/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/meh/viewer.properties rename to themes/next/source/lib/pdf/web/locale/meh/viewer.properties diff --git a/source/lib/pdf/web/locale/mk/viewer.properties b/themes/next/source/lib/pdf/web/locale/mk/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/mk/viewer.properties rename to themes/next/source/lib/pdf/web/locale/mk/viewer.properties diff --git a/source/lib/pdf/web/locale/ml/viewer.properties b/themes/next/source/lib/pdf/web/locale/ml/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/ml/viewer.properties rename to themes/next/source/lib/pdf/web/locale/ml/viewer.properties diff --git a/source/lib/pdf/web/locale/mn/viewer.properties b/themes/next/source/lib/pdf/web/locale/mn/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/mn/viewer.properties rename to themes/next/source/lib/pdf/web/locale/mn/viewer.properties diff --git a/source/lib/pdf/web/locale/mr/viewer.properties b/themes/next/source/lib/pdf/web/locale/mr/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/mr/viewer.properties rename to themes/next/source/lib/pdf/web/locale/mr/viewer.properties diff --git a/source/lib/pdf/web/locale/ms/viewer.properties b/themes/next/source/lib/pdf/web/locale/ms/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/ms/viewer.properties rename to themes/next/source/lib/pdf/web/locale/ms/viewer.properties diff --git a/source/lib/pdf/web/locale/my/viewer.properties b/themes/next/source/lib/pdf/web/locale/my/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/my/viewer.properties rename to themes/next/source/lib/pdf/web/locale/my/viewer.properties diff --git a/source/lib/pdf/web/locale/nb-NO/viewer.properties b/themes/next/source/lib/pdf/web/locale/nb-NO/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/nb-NO/viewer.properties rename to themes/next/source/lib/pdf/web/locale/nb-NO/viewer.properties diff --git a/source/lib/pdf/web/locale/ne-NP/viewer.properties b/themes/next/source/lib/pdf/web/locale/ne-NP/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/ne-NP/viewer.properties rename to themes/next/source/lib/pdf/web/locale/ne-NP/viewer.properties diff --git a/source/lib/pdf/web/locale/nl/viewer.properties b/themes/next/source/lib/pdf/web/locale/nl/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/nl/viewer.properties rename to themes/next/source/lib/pdf/web/locale/nl/viewer.properties diff --git a/source/lib/pdf/web/locale/nn-NO/viewer.properties b/themes/next/source/lib/pdf/web/locale/nn-NO/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/nn-NO/viewer.properties rename to themes/next/source/lib/pdf/web/locale/nn-NO/viewer.properties diff --git a/source/lib/pdf/web/locale/nso/viewer.properties b/themes/next/source/lib/pdf/web/locale/nso/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/nso/viewer.properties rename to themes/next/source/lib/pdf/web/locale/nso/viewer.properties diff --git a/source/lib/pdf/web/locale/oc/viewer.properties b/themes/next/source/lib/pdf/web/locale/oc/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/oc/viewer.properties rename to themes/next/source/lib/pdf/web/locale/oc/viewer.properties diff --git a/source/lib/pdf/web/locale/or/viewer.properties b/themes/next/source/lib/pdf/web/locale/or/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/or/viewer.properties rename to themes/next/source/lib/pdf/web/locale/or/viewer.properties diff --git a/source/lib/pdf/web/locale/pa-IN/viewer.properties b/themes/next/source/lib/pdf/web/locale/pa-IN/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/pa-IN/viewer.properties rename to themes/next/source/lib/pdf/web/locale/pa-IN/viewer.properties diff --git a/source/lib/pdf/web/locale/pl/viewer.properties b/themes/next/source/lib/pdf/web/locale/pl/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/pl/viewer.properties rename to themes/next/source/lib/pdf/web/locale/pl/viewer.properties diff --git a/source/lib/pdf/web/locale/pt-BR/viewer.properties b/themes/next/source/lib/pdf/web/locale/pt-BR/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/pt-BR/viewer.properties rename to themes/next/source/lib/pdf/web/locale/pt-BR/viewer.properties diff --git a/source/lib/pdf/web/locale/pt-PT/viewer.properties b/themes/next/source/lib/pdf/web/locale/pt-PT/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/pt-PT/viewer.properties rename to themes/next/source/lib/pdf/web/locale/pt-PT/viewer.properties diff --git a/source/lib/pdf/web/locale/rm/viewer.properties b/themes/next/source/lib/pdf/web/locale/rm/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/rm/viewer.properties rename to themes/next/source/lib/pdf/web/locale/rm/viewer.properties diff --git a/source/lib/pdf/web/locale/ro/viewer.properties b/themes/next/source/lib/pdf/web/locale/ro/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/ro/viewer.properties rename to themes/next/source/lib/pdf/web/locale/ro/viewer.properties diff --git a/source/lib/pdf/web/locale/ru/viewer.properties b/themes/next/source/lib/pdf/web/locale/ru/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/ru/viewer.properties rename to themes/next/source/lib/pdf/web/locale/ru/viewer.properties diff --git a/source/lib/pdf/web/locale/rw/viewer.properties b/themes/next/source/lib/pdf/web/locale/rw/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/rw/viewer.properties rename to themes/next/source/lib/pdf/web/locale/rw/viewer.properties diff --git a/source/lib/pdf/web/locale/sah/viewer.properties b/themes/next/source/lib/pdf/web/locale/sah/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/sah/viewer.properties rename to themes/next/source/lib/pdf/web/locale/sah/viewer.properties diff --git a/source/lib/pdf/web/locale/sat/viewer.properties b/themes/next/source/lib/pdf/web/locale/sat/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/sat/viewer.properties rename to themes/next/source/lib/pdf/web/locale/sat/viewer.properties diff --git a/source/lib/pdf/web/locale/si/viewer.properties b/themes/next/source/lib/pdf/web/locale/si/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/si/viewer.properties rename to themes/next/source/lib/pdf/web/locale/si/viewer.properties diff --git a/source/lib/pdf/web/locale/sk/viewer.properties b/themes/next/source/lib/pdf/web/locale/sk/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/sk/viewer.properties rename to themes/next/source/lib/pdf/web/locale/sk/viewer.properties diff --git a/source/lib/pdf/web/locale/sl/viewer.properties b/themes/next/source/lib/pdf/web/locale/sl/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/sl/viewer.properties rename to themes/next/source/lib/pdf/web/locale/sl/viewer.properties diff --git a/source/lib/pdf/web/locale/son/viewer.properties b/themes/next/source/lib/pdf/web/locale/son/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/son/viewer.properties rename to themes/next/source/lib/pdf/web/locale/son/viewer.properties diff --git a/source/lib/pdf/web/locale/sq/viewer.properties b/themes/next/source/lib/pdf/web/locale/sq/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/sq/viewer.properties rename to themes/next/source/lib/pdf/web/locale/sq/viewer.properties diff --git a/source/lib/pdf/web/locale/sr/viewer.properties b/themes/next/source/lib/pdf/web/locale/sr/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/sr/viewer.properties rename to themes/next/source/lib/pdf/web/locale/sr/viewer.properties diff --git a/source/lib/pdf/web/locale/sv-SE/viewer.properties b/themes/next/source/lib/pdf/web/locale/sv-SE/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/sv-SE/viewer.properties rename to themes/next/source/lib/pdf/web/locale/sv-SE/viewer.properties diff --git a/source/lib/pdf/web/locale/sw/viewer.properties b/themes/next/source/lib/pdf/web/locale/sw/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/sw/viewer.properties rename to themes/next/source/lib/pdf/web/locale/sw/viewer.properties diff --git a/source/lib/pdf/web/locale/ta-LK/viewer.properties b/themes/next/source/lib/pdf/web/locale/ta-LK/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/ta-LK/viewer.properties rename to themes/next/source/lib/pdf/web/locale/ta-LK/viewer.properties diff --git a/source/lib/pdf/web/locale/ta/viewer.properties b/themes/next/source/lib/pdf/web/locale/ta/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/ta/viewer.properties rename to themes/next/source/lib/pdf/web/locale/ta/viewer.properties diff --git a/source/lib/pdf/web/locale/te/viewer.properties b/themes/next/source/lib/pdf/web/locale/te/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/te/viewer.properties rename to themes/next/source/lib/pdf/web/locale/te/viewer.properties diff --git a/source/lib/pdf/web/locale/th/viewer.properties b/themes/next/source/lib/pdf/web/locale/th/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/th/viewer.properties rename to themes/next/source/lib/pdf/web/locale/th/viewer.properties diff --git a/source/lib/pdf/web/locale/tl/viewer.properties b/themes/next/source/lib/pdf/web/locale/tl/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/tl/viewer.properties rename to themes/next/source/lib/pdf/web/locale/tl/viewer.properties diff --git a/source/lib/pdf/web/locale/tn/viewer.properties b/themes/next/source/lib/pdf/web/locale/tn/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/tn/viewer.properties rename to themes/next/source/lib/pdf/web/locale/tn/viewer.properties diff --git a/source/lib/pdf/web/locale/tr/viewer.properties b/themes/next/source/lib/pdf/web/locale/tr/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/tr/viewer.properties rename to themes/next/source/lib/pdf/web/locale/tr/viewer.properties diff --git a/source/lib/pdf/web/locale/tsz/viewer.properties b/themes/next/source/lib/pdf/web/locale/tsz/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/tsz/viewer.properties rename to themes/next/source/lib/pdf/web/locale/tsz/viewer.properties diff --git a/source/lib/pdf/web/locale/uk/viewer.properties b/themes/next/source/lib/pdf/web/locale/uk/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/uk/viewer.properties rename to themes/next/source/lib/pdf/web/locale/uk/viewer.properties diff --git a/source/lib/pdf/web/locale/ur/viewer.properties b/themes/next/source/lib/pdf/web/locale/ur/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/ur/viewer.properties rename to themes/next/source/lib/pdf/web/locale/ur/viewer.properties diff --git a/source/lib/pdf/web/locale/uz/viewer.properties b/themes/next/source/lib/pdf/web/locale/uz/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/uz/viewer.properties rename to themes/next/source/lib/pdf/web/locale/uz/viewer.properties diff --git a/source/lib/pdf/web/locale/vi/viewer.properties b/themes/next/source/lib/pdf/web/locale/vi/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/vi/viewer.properties rename to themes/next/source/lib/pdf/web/locale/vi/viewer.properties diff --git a/source/lib/pdf/web/locale/wo/viewer.properties b/themes/next/source/lib/pdf/web/locale/wo/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/wo/viewer.properties rename to themes/next/source/lib/pdf/web/locale/wo/viewer.properties diff --git a/source/lib/pdf/web/locale/xh/viewer.properties b/themes/next/source/lib/pdf/web/locale/xh/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/xh/viewer.properties rename to themes/next/source/lib/pdf/web/locale/xh/viewer.properties diff --git a/source/lib/pdf/web/locale/zam/viewer.properties b/themes/next/source/lib/pdf/web/locale/zam/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/zam/viewer.properties rename to themes/next/source/lib/pdf/web/locale/zam/viewer.properties diff --git a/source/lib/pdf/web/locale/zh-CN/viewer.properties b/themes/next/source/lib/pdf/web/locale/zh-CN/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/zh-CN/viewer.properties rename to themes/next/source/lib/pdf/web/locale/zh-CN/viewer.properties diff --git a/source/lib/pdf/web/locale/zh-TW/viewer.properties b/themes/next/source/lib/pdf/web/locale/zh-TW/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/zh-TW/viewer.properties rename to themes/next/source/lib/pdf/web/locale/zh-TW/viewer.properties diff --git a/source/lib/pdf/web/locale/zu/viewer.properties b/themes/next/source/lib/pdf/web/locale/zu/viewer.properties similarity index 100% rename from source/lib/pdf/web/locale/zu/viewer.properties rename to themes/next/source/lib/pdf/web/locale/zu/viewer.properties diff --git a/source/lib/pdf/web/viewer.css b/themes/next/source/lib/pdf/web/viewer.css similarity index 100% rename from source/lib/pdf/web/viewer.css rename to themes/next/source/lib/pdf/web/viewer.css diff --git a/source/lib/pdf/web/viewer.html b/themes/next/source/lib/pdf/web/viewer.html similarity index 100% rename from source/lib/pdf/web/viewer.html rename to themes/next/source/lib/pdf/web/viewer.html diff --git a/source/lib/pdf/web/viewer.js b/themes/next/source/lib/pdf/web/viewer.js similarity index 100% rename from source/lib/pdf/web/viewer.js rename to themes/next/source/lib/pdf/web/viewer.js diff --git a/source/lib/pdf/web/viewer.js.map b/themes/next/source/lib/pdf/web/viewer.js.map similarity index 100% rename from source/lib/pdf/web/viewer.js.map rename to themes/next/source/lib/pdf/web/viewer.js.map diff --git a/source/lib/velocity/velocity.min.js b/themes/next/source/lib/velocity/velocity.min.js similarity index 100% rename from source/lib/velocity/velocity.min.js rename to themes/next/source/lib/velocity/velocity.min.js diff --git a/source/lib/velocity/velocity.ui.min.js b/themes/next/source/lib/velocity/velocity.ui.min.js similarity index 100% rename from source/lib/velocity/velocity.ui.min.js rename to themes/next/source/lib/velocity/velocity.ui.min.js