├── images ├── avatar.gif ├── favicon-16x16-next.png ├── favicon-32x32-next.png ├── apple-touch-icon-next.png ├── quote-r.svg ├── quote-l.svg ├── logo.svg ├── algolia_logo.svg ├── cc-zero.svg ├── cc-by.svg ├── cc-by-nd.svg ├── cc-by-nc.svg ├── cc-by-sa.svg ├── cc-by-nc-nd.svg └── cc-by-nc-sa.svg ├── lib ├── font-awesome │ ├── fonts │ │ ├── fontawesome-webfont.eot │ │ ├── fontawesome-webfont.woff │ │ └── fontawesome-webfont.woff2 │ ├── bower.json │ └── HELP-US-OUT.txt └── velocity │ └── velocity.ui.min.js ├── js ├── bookmark.js ├── schemes │ ├── pisces.js │ └── muse.js ├── next-boot.js ├── algolia-search.js ├── motion.js └── local-search.js ├── atom.xml ├── tags ├── Rust │ └── index.html ├── index.html ├── 嵌入式 │ └── index.html └── Note │ └── index.html ├── categories ├── Rust嵌入式 │ └── index.html └── index.html └── recommend └── index.html /images/avatar.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThinkCodeStudio/ThinkCodeStudio.github.io/main/images/avatar.gif -------------------------------------------------------------------------------- /images/favicon-16x16-next.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThinkCodeStudio/ThinkCodeStudio.github.io/main/images/favicon-16x16-next.png -------------------------------------------------------------------------------- /images/favicon-32x32-next.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThinkCodeStudio/ThinkCodeStudio.github.io/main/images/favicon-32x32-next.png -------------------------------------------------------------------------------- /images/apple-touch-icon-next.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThinkCodeStudio/ThinkCodeStudio.github.io/main/images/apple-touch-icon-next.png -------------------------------------------------------------------------------- /lib/font-awesome/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThinkCodeStudio/ThinkCodeStudio.github.io/main/lib/font-awesome/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /lib/font-awesome/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThinkCodeStudio/ThinkCodeStudio.github.io/main/lib/font-awesome/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /lib/font-awesome/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ThinkCodeStudio/ThinkCodeStudio.github.io/main/lib/font-awesome/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /lib/font-awesome/bower.json: -------------------------------------------------------------------------------- 1 | {"name":"font-awesome","description":"Font Awesome","keywords":[],"homepage":"http://fontawesome.io","dependencies":{},"devDependencies":{},"license":["OFL-1.1","MIT","CC-BY-3.0"],"main":["less/font-awesome.less","scss/font-awesome.scss"],"ignore":["*/.*","*.json","src","*.yml","Gemfile","Gemfile.lock","*.md"]} -------------------------------------------------------------------------------- /lib/font-awesome/HELP-US-OUT.txt: -------------------------------------------------------------------------------- 1 | I hope you love Font Awesome. If you've found it useful, please do me a favor and check out my latest project, 2 | Fort Awesome (https://fortawesome.com). It makes it easy to put the perfect icons on your website. Choose from our awesome, 3 | comprehensive icon sets or copy and paste your own. 4 | 5 | Please. Check it out. 6 | 7 | -Dave Gandy 8 | -------------------------------------------------------------------------------- /images/quote-r.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 12 | 13 | -------------------------------------------------------------------------------- /images/quote-l.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 13 | 14 | -------------------------------------------------------------------------------- /images/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | image/svg+xml 24 | -------------------------------------------------------------------------------- /js/bookmark.js: -------------------------------------------------------------------------------- 1 | /* global CONFIG */ 2 | 3 | window.addEventListener('DOMContentLoaded', () => { 4 | 'use strict'; 5 | 6 | var doSaveScroll = () => { 7 | localStorage.setItem('bookmark' + location.pathname, window.scrollY); 8 | }; 9 | 10 | var scrollToMark = () => { 11 | var top = localStorage.getItem('bookmark' + location.pathname); 12 | top = parseInt(top, 10); 13 | // If the page opens with a specific hash, just jump out 14 | if (!isNaN(top) && location.hash === '') { 15 | // Auto scroll to the position 16 | window.anime({ 17 | targets : document.scrollingElement, 18 | duration : 200, 19 | easing : 'linear', 20 | scrollTop: top 21 | }); 22 | } 23 | }; 24 | // Register everything 25 | var init = function(trigger) { 26 | // Create a link element 27 | var link = document.querySelector('.book-mark-link'); 28 | // Scroll event 29 | window.addEventListener('scroll', () => link.classList.toggle('book-mark-link-fixed', window.scrollY === 0)); 30 | // Register beforeunload event when the trigger is auto 31 | if (trigger === 'auto') { 32 | // Register beforeunload event 33 | window.addEventListener('beforeunload', doSaveScroll); 34 | window.addEventListener('pjax:send', doSaveScroll); 35 | } 36 | // Save the position by clicking the icon 37 | link.addEventListener('click', () => { 38 | doSaveScroll(); 39 | window.anime({ 40 | targets : link, 41 | duration: 200, 42 | easing : 'linear', 43 | top : -30, 44 | complete: () => { 45 | setTimeout(() => { 46 | link.style.top = ''; 47 | }, 400); 48 | } 49 | }); 50 | }); 51 | scrollToMark(); 52 | window.addEventListener('pjax:success', scrollToMark); 53 | }; 54 | 55 | init(CONFIG.bookmark.save); 56 | }); 57 | -------------------------------------------------------------------------------- /js/schemes/pisces.js: -------------------------------------------------------------------------------- 1 | /* global NexT, CONFIG */ 2 | 3 | var Affix = { 4 | init: function(element, options) { 5 | this.element = element; 6 | this.offset = options || 0; 7 | this.affixed = null; 8 | this.unpin = null; 9 | this.pinnedOffset = null; 10 | this.checkPosition(); 11 | window.addEventListener('scroll', this.checkPosition.bind(this)); 12 | window.addEventListener('click', this.checkPositionWithEventLoop.bind(this)); 13 | window.matchMedia('(min-width: 992px)').addListener(event => { 14 | if (event.matches) { 15 | this.offset = NexT.utils.getAffixParam(); 16 | this.checkPosition(); 17 | } 18 | }); 19 | }, 20 | getState: function(scrollHeight, height, offsetTop, offsetBottom) { 21 | let scrollTop = window.scrollY; 22 | let targetHeight = window.innerHeight; 23 | if (offsetTop != null && this.affixed === 'top') { 24 | if (document.querySelector('.content-wrap').offsetHeight < offsetTop) return 'top'; 25 | return scrollTop < offsetTop ? 'top' : false; 26 | } 27 | if (this.affixed === 'bottom') { 28 | if (offsetTop != null) return this.unpin <= this.element.getBoundingClientRect().top ? false : 'bottom'; 29 | return scrollTop + targetHeight <= scrollHeight - offsetBottom ? false : 'bottom'; 30 | } 31 | let initializing = this.affixed === null; 32 | let colliderTop = initializing ? scrollTop : this.element.getBoundingClientRect().top + scrollTop; 33 | let colliderHeight = initializing ? targetHeight : height; 34 | if (offsetTop != null && scrollTop <= offsetTop) return 'top'; 35 | if (offsetBottom != null && (colliderTop + colliderHeight >= scrollHeight - offsetBottom)) return 'bottom'; 36 | return false; 37 | }, 38 | getPinnedOffset: function() { 39 | if (this.pinnedOffset) return this.pinnedOffset; 40 | this.element.classList.remove('affix-top', 'affix-bottom'); 41 | this.element.classList.add('affix'); 42 | return (this.pinnedOffset = this.element.getBoundingClientRect().top); 43 | }, 44 | checkPositionWithEventLoop() { 45 | setTimeout(this.checkPosition.bind(this), 1); 46 | }, 47 | checkPosition: function() { 48 | if (window.getComputedStyle(this.element).display === 'none') return; 49 | let height = this.element.offsetHeight; 50 | let { offset } = this; 51 | let offsetTop = offset.top; 52 | let offsetBottom = offset.bottom; 53 | let { scrollHeight } = document.body; 54 | let affix = this.getState(scrollHeight, height, offsetTop, offsetBottom); 55 | if (this.affixed !== affix) { 56 | if (this.unpin != null) this.element.style.top = ''; 57 | let affixType = 'affix' + (affix ? '-' + affix : ''); 58 | this.affixed = affix; 59 | this.unpin = affix === 'bottom' ? this.getPinnedOffset() : null; 60 | this.element.classList.remove('affix', 'affix-top', 'affix-bottom'); 61 | this.element.classList.add(affixType); 62 | } 63 | if (affix === 'bottom') { 64 | this.element.style.top = scrollHeight - height - offsetBottom + 'px'; 65 | } 66 | } 67 | }; 68 | 69 | NexT.utils.getAffixParam = function() { 70 | const sidebarOffset = CONFIG.sidebar.offset || 12; 71 | 72 | let headerOffset = document.querySelector('.header-inner').offsetHeight; 73 | let footerOffset = document.querySelector('.footer').offsetHeight; 74 | 75 | document.querySelector('.sidebar').style.marginTop = headerOffset + sidebarOffset + 'px'; 76 | 77 | return { 78 | top : headerOffset, 79 | bottom: footerOffset 80 | }; 81 | }; 82 | 83 | window.addEventListener('DOMContentLoaded', () => { 84 | 85 | Affix.init(document.querySelector('.sidebar-inner'), NexT.utils.getAffixParam()); 86 | }); 87 | -------------------------------------------------------------------------------- /js/next-boot.js: -------------------------------------------------------------------------------- 1 | /* global NexT, CONFIG, Velocity */ 2 | 3 | NexT.boot = {}; 4 | 5 | NexT.boot.registerEvents = function() { 6 | 7 | NexT.utils.registerScrollPercent(); 8 | NexT.utils.registerCanIUseTag(); 9 | 10 | // Mobile top menu bar. 11 | document.querySelector('.site-nav-toggle .toggle').addEventListener('click', () => { 12 | event.currentTarget.classList.toggle('toggle-close'); 13 | var siteNav = document.querySelector('.site-nav'); 14 | var animateAction = siteNav.classList.contains('site-nav-on') ? 'slideUp' : 'slideDown'; 15 | 16 | if (typeof Velocity === 'function') { 17 | Velocity(siteNav, animateAction, { 18 | duration: 200, 19 | complete: function() { 20 | siteNav.classList.toggle('site-nav-on'); 21 | } 22 | }); 23 | } else { 24 | siteNav.classList.toggle('site-nav-on'); 25 | } 26 | }); 27 | 28 | var TAB_ANIMATE_DURATION = 200; 29 | document.querySelectorAll('.sidebar-nav li').forEach((element, index) => { 30 | element.addEventListener('click', event => { 31 | var item = event.currentTarget; 32 | var activeTabClassName = 'sidebar-nav-active'; 33 | var activePanelClassName = 'sidebar-panel-active'; 34 | if (item.classList.contains(activeTabClassName)) return; 35 | 36 | var targets = document.querySelectorAll('.sidebar-panel'); 37 | var target = targets[index]; 38 | var currentTarget = targets[1 - index]; 39 | window.anime({ 40 | targets : currentTarget, 41 | duration: TAB_ANIMATE_DURATION, 42 | easing : 'linear', 43 | opacity : 0, 44 | complete: () => { 45 | // Prevent adding TOC to Overview if Overview was selected when close & open sidebar. 46 | currentTarget.classList.remove(activePanelClassName); 47 | target.style.opacity = 0; 48 | target.classList.add(activePanelClassName); 49 | window.anime({ 50 | targets : target, 51 | duration: TAB_ANIMATE_DURATION, 52 | easing : 'linear', 53 | opacity : 1 54 | }); 55 | } 56 | }); 57 | 58 | [...item.parentNode.children].forEach(element => { 59 | element.classList.remove(activeTabClassName); 60 | }); 61 | item.classList.add(activeTabClassName); 62 | }); 63 | }); 64 | 65 | window.addEventListener('resize', NexT.utils.initSidebarDimension); 66 | 67 | window.addEventListener('hashchange', () => { 68 | var tHash = location.hash; 69 | if (tHash !== '' && !tHash.match(/%\S{2}/)) { 70 | var target = document.querySelector(`.tabs ul.nav-tabs li a[href="${tHash}"]`); 71 | target && target.click(); 72 | } 73 | }); 74 | }; 75 | 76 | NexT.boot.refresh = function() { 77 | 78 | /** 79 | * Register JS handlers by condition option. 80 | * Need to add config option in Front-End at 'layout/_partials/head.swig' file. 81 | */ 82 | CONFIG.fancybox && NexT.utils.wrapImageWithFancyBox(); 83 | CONFIG.mediumzoom && window.mediumZoom('.post-body :not(a) > img, .post-body > img'); 84 | CONFIG.lazyload && window.lozad('.post-body img').observe(); 85 | CONFIG.pangu && window.pangu.spacingPage(); 86 | 87 | CONFIG.exturl && NexT.utils.registerExtURL(); 88 | CONFIG.copycode.enable && NexT.utils.registerCopyCode(); 89 | NexT.utils.registerTabsTag(); 90 | NexT.utils.registerActiveMenuItem(); 91 | NexT.utils.registerLangSelect(); 92 | NexT.utils.registerSidebarTOC(); 93 | NexT.utils.wrapTableWithBox(); 94 | NexT.utils.registerVideoIframe(); 95 | }; 96 | 97 | NexT.boot.motion = function() { 98 | // Define Motion Sequence & Bootstrap Motion. 99 | if (CONFIG.motion.enable) { 100 | NexT.motion.integrator 101 | .add(NexT.motion.middleWares.logo) 102 | .add(NexT.motion.middleWares.menu) 103 | .add(NexT.motion.middleWares.postList) 104 | .add(NexT.motion.middleWares.sidebar) 105 | .bootstrap(); 106 | } 107 | NexT.utils.updateSidebarPosition(); 108 | }; 109 | 110 | window.addEventListener('DOMContentLoaded', () => { 111 | NexT.boot.registerEvents(); 112 | NexT.boot.refresh(); 113 | NexT.boot.motion(); 114 | }); 115 | -------------------------------------------------------------------------------- /images/algolia_logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /js/algolia-search.js: -------------------------------------------------------------------------------- 1 | /* global instantsearch, algoliasearch, CONFIG */ 2 | 3 | window.addEventListener('DOMContentLoaded', () => { 4 | const algoliaSettings = CONFIG.algolia; 5 | const { indexName, appID, apiKey } = algoliaSettings; 6 | 7 | let search = instantsearch({ 8 | indexName, 9 | searchClient : algoliasearch(appID, apiKey), 10 | searchFunction: helper => { 11 | let searchInput = document.querySelector('.search-input'); 12 | if (searchInput.value) { 13 | helper.search(); 14 | } 15 | } 16 | }); 17 | 18 | window.pjax && search.on('render', () => { 19 | window.pjax.refresh(document.getElementById('algolia-hits')); 20 | }); 21 | 22 | // Registering Widgets 23 | search.addWidgets([ 24 | instantsearch.widgets.configure({ 25 | hitsPerPage: algoliaSettings.hits.per_page || 10 26 | }), 27 | 28 | instantsearch.widgets.searchBox({ 29 | container : '.search-input-container', 30 | placeholder : algoliaSettings.labels.input_placeholder, 31 | // Hide default icons of algolia search 32 | showReset : false, 33 | showSubmit : false, 34 | showLoadingIndicator: false, 35 | cssClasses : { 36 | input: 'search-input' 37 | } 38 | }), 39 | 40 | instantsearch.widgets.stats({ 41 | container: '#algolia-stats', 42 | templates: { 43 | text: data => { 44 | let stats = algoliaSettings.labels.hits_stats 45 | .replace(/\$\{hits}/, data.nbHits) 46 | .replace(/\$\{time}/, data.processingTimeMS); 47 | return `${stats} 48 | 49 | Algolia 50 | 51 |
`; 52 | } 53 | } 54 | }), 55 | 56 | instantsearch.widgets.hits({ 57 | container: '#algolia-hits', 58 | templates: { 59 | item: data => { 60 | let link = data.permalink ? data.permalink : CONFIG.root + data.path; 61 | return `${data._highlightResult.title.value}`; 62 | }, 63 | empty: data => { 64 | return `
65 | ${algoliaSettings.labels.hits_empty.replace(/\$\{query}/, data.query)} 66 |
`; 67 | } 68 | }, 69 | cssClasses: { 70 | item: 'algolia-hit-item' 71 | } 72 | }), 73 | 74 | instantsearch.widgets.pagination({ 75 | container: '#algolia-pagination', 76 | scrollTo : false, 77 | showFirst: false, 78 | showLast : false, 79 | templates: { 80 | first : '', 81 | last : '', 82 | previous: '', 83 | next : '' 84 | }, 85 | cssClasses: { 86 | root : 'pagination', 87 | item : 'pagination-item', 88 | link : 'page-number', 89 | selectedItem: 'current', 90 | disabledItem: 'disabled-item' 91 | } 92 | }) 93 | ]); 94 | 95 | search.start(); 96 | 97 | // Handle and trigger popup window 98 | document.querySelectorAll('.popup-trigger').forEach(element => { 99 | element.addEventListener('click', () => { 100 | document.body.style.overflow = 'hidden'; 101 | document.querySelector('.search-pop-overlay').classList.add('search-active'); 102 | document.querySelector('.search-input').focus(); 103 | }); 104 | }); 105 | 106 | // Monitor main search box 107 | const onPopupClose = () => { 108 | document.body.style.overflow = ''; 109 | document.querySelector('.search-pop-overlay').classList.remove('search-active'); 110 | }; 111 | 112 | document.querySelector('.search-pop-overlay').addEventListener('click', event => { 113 | if (event.target === document.querySelector('.search-pop-overlay')) { 114 | onPopupClose(); 115 | } 116 | }); 117 | document.querySelector('.popup-btn-close').addEventListener('click', onPopupClose); 118 | window.addEventListener('pjax:success', onPopupClose); 119 | window.addEventListener('keyup', event => { 120 | if (event.key === 'Escape') { 121 | onPopupClose(); 122 | } 123 | }); 124 | }); 125 | -------------------------------------------------------------------------------- /atom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | ThinkCode's Blog 4 | https://thinkcodestudio.github.io/icon.png 5 | 6 | 7 | 8 | 9 | 2025-10-22T07:49:57.075Z 10 | https://thinkcodestudio.github.io/ 11 | 12 | 13 | ThinkCode 14 | 15 | 16 | 17 | Hexo 18 | 19 | 20 | linux终端显示git分支 21 | 22 | https://thinkcodestudio.github.io/2025/10/22/linux%E7%BB%88%E7%AB%AF%E6%98%BE%E7%A4%BAgit%E5%88%86%E6%94%AF/ 23 | 2025-10-22T06:39:20.000Z 24 | 2025-10-22T07:49:57.075Z 25 | 26 | 27 | <p>来源: <a href="https://gist.github.com/yisibl/8281454">在Mac、Linux 终端显示 Git 当前所在分支</a><br>本笔记记录配置脚本, 使Linux终端可以显示当前git分支信息</p> 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 源码编译Linux最小系统-HelloLinux 42 | 43 | https://thinkcodestudio.github.io/2025/10/21/%E6%BA%90%E7%A0%81%E7%BC%96%E8%AF%91Linux%E6%9C%80%E5%B0%8F%E7%B3%BB%E7%BB%9F-HelloLinux/ 44 | 2025-10-21T08:09:55.000Z 45 | 2025-10-22T00:38:30.621Z 46 | 47 | 48 | <p>一直想踏入Linux这个级别的嵌入式开发, 想使用性能更强的硬件设备, 以前也尝试过研究 rk3506 的SDK, 但是内容是在太多了, 也非常复杂, 而且瑞芯微和板商都做了非常多的工作导致非常完善无从下手, 所以我尝试编译Linux源码来起步学习. </p> 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | Rust-Knurling框架嵌入式开发 63 | 64 | https://thinkcodestudio.github.io/2025/10/11/Rust-Knurling%E6%A1%86%E6%9E%B6%E5%B5%8C%E5%85%A5%E5%BC%8F%E5%BC%80%E5%8F%91/ 65 | 2025-10-11T05:18:18.000Z 66 | 2025-10-22T00:42:03.409Z 67 | 68 | 69 | <p>本章使用 Knurling Rust 嵌入式框架完成环境部署, 快速使用, 实机运行等任务</p> 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | Hello World 84 | 85 | https://thinkcodestudio.github.io/2025/10/11/hello-world/ 86 | 2025-10-11T00:46:01.481Z 87 | 2025-10-22T00:43:41.728Z 88 | 89 | 90 | <p>Welcome to <a href="https://hexo.io/">Hexo</a>! This is your very first post. Check <a href="https://hexo.io/docs/">documentation</a> for more info. If you get any problems when using Hexo, you can find the answer in <a href="https://hexo.io/docs/troubleshooting.html">troubleshooting</a> or you can ask me on <a href="https://github.com/hexojs/hexo/issues">GitHub</a>.</p> 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | -------------------------------------------------------------------------------- /js/schemes/muse.js: -------------------------------------------------------------------------------- 1 | /* global NexT, CONFIG, Velocity */ 2 | 3 | window.addEventListener('DOMContentLoaded', () => { 4 | 5 | var isRight = CONFIG.sidebar.position === 'right'; 6 | var SIDEBAR_WIDTH = CONFIG.sidebar.width || 320; 7 | var SIDEBAR_DISPLAY_DURATION = 200; 8 | var mousePos = {}; 9 | 10 | var sidebarToggleLines = { 11 | lines: document.querySelector('.sidebar-toggle'), 12 | init : function() { 13 | this.lines.classList.remove('toggle-arrow', 'toggle-close'); 14 | }, 15 | arrow: function() { 16 | this.lines.classList.remove('toggle-close'); 17 | this.lines.classList.add('toggle-arrow'); 18 | }, 19 | close: function() { 20 | this.lines.classList.remove('toggle-arrow'); 21 | this.lines.classList.add('toggle-close'); 22 | } 23 | }; 24 | 25 | var sidebarToggleMotion = { 26 | sidebarEl : document.querySelector('.sidebar'), 27 | isSidebarVisible: false, 28 | init : function() { 29 | sidebarToggleLines.init(); 30 | 31 | window.addEventListener('mousedown', this.mousedownHandler.bind(this)); 32 | window.addEventListener('mouseup', this.mouseupHandler.bind(this)); 33 | document.querySelector('#sidebar-dimmer').addEventListener('click', this.clickHandler.bind(this)); 34 | document.querySelector('.sidebar-toggle').addEventListener('click', this.clickHandler.bind(this)); 35 | document.querySelector('.sidebar-toggle').addEventListener('mouseenter', this.mouseEnterHandler.bind(this)); 36 | document.querySelector('.sidebar-toggle').addEventListener('mouseleave', this.mouseLeaveHandler.bind(this)); 37 | window.addEventListener('sidebar:show', this.showSidebar.bind(this)); 38 | window.addEventListener('sidebar:hide', this.hideSidebar.bind(this)); 39 | }, 40 | mousedownHandler: function(event) { 41 | mousePos.X = event.pageX; 42 | mousePos.Y = event.pageY; 43 | }, 44 | mouseupHandler: function(event) { 45 | var deltaX = event.pageX - mousePos.X; 46 | var deltaY = event.pageY - mousePos.Y; 47 | var clickingBlankPart = Math.sqrt((deltaX * deltaX) + (deltaY * deltaY)) < 20 && event.target.matches('.main'); 48 | if (this.isSidebarVisible && (clickingBlankPart || event.target.matches('img.medium-zoom-image, .fancybox img'))) { 49 | this.hideSidebar(); 50 | } 51 | }, 52 | clickHandler: function() { 53 | this.isSidebarVisible ? this.hideSidebar() : this.showSidebar(); 54 | }, 55 | mouseEnterHandler: function() { 56 | if (!this.isSidebarVisible) { 57 | sidebarToggleLines.arrow(); 58 | } 59 | }, 60 | mouseLeaveHandler: function() { 61 | if (!this.isSidebarVisible) { 62 | sidebarToggleLines.init(); 63 | } 64 | }, 65 | showSidebar: function() { 66 | this.isSidebarVisible = true; 67 | this.sidebarEl.classList.add('sidebar-active'); 68 | if (typeof Velocity === 'function') { 69 | Velocity(document.querySelectorAll('.sidebar .motion-element'), isRight ? 'transition.slideRightIn' : 'transition.slideLeftIn', { 70 | stagger: 50, 71 | drag : true 72 | }); 73 | } 74 | 75 | sidebarToggleLines.close(); 76 | NexT.utils.isDesktop() && window.anime(Object.assign({ 77 | targets : document.body, 78 | duration: SIDEBAR_DISPLAY_DURATION, 79 | easing : 'linear' 80 | }, isRight ? { 81 | 'padding-right': SIDEBAR_WIDTH 82 | } : { 83 | 'padding-left': SIDEBAR_WIDTH 84 | })); 85 | }, 86 | hideSidebar: function() { 87 | this.isSidebarVisible = false; 88 | this.sidebarEl.classList.remove('sidebar-active'); 89 | 90 | sidebarToggleLines.init(); 91 | NexT.utils.isDesktop() && window.anime(Object.assign({ 92 | targets : document.body, 93 | duration: SIDEBAR_DISPLAY_DURATION, 94 | easing : 'linear' 95 | }, isRight ? { 96 | 'padding-right': 0 97 | } : { 98 | 'padding-left': 0 99 | })); 100 | } 101 | }; 102 | sidebarToggleMotion.init(); 103 | 104 | function updateFooterPosition() { 105 | var footer = document.querySelector('.footer'); 106 | var containerHeight = document.querySelector('.header').offsetHeight + document.querySelector('.main').offsetHeight + footer.offsetHeight; 107 | footer.classList.toggle('footer-fixed', containerHeight <= window.innerHeight); 108 | } 109 | 110 | updateFooterPosition(); 111 | window.addEventListener('resize', updateFooterPosition); 112 | window.addEventListener('scroll', updateFooterPosition); 113 | }); 114 | -------------------------------------------------------------------------------- /js/motion.js: -------------------------------------------------------------------------------- 1 | /* global NexT, CONFIG, Velocity */ 2 | 3 | if (window.$ && window.$.Velocity) window.Velocity = window.$.Velocity; 4 | 5 | NexT.motion = {}; 6 | 7 | NexT.motion.integrator = { 8 | queue : [], 9 | cursor: -1, 10 | init : function() { 11 | this.queue = []; 12 | this.cursor = -1; 13 | return this; 14 | }, 15 | add: function(fn) { 16 | this.queue.push(fn); 17 | return this; 18 | }, 19 | next: function() { 20 | this.cursor++; 21 | var fn = this.queue[this.cursor]; 22 | typeof fn === 'function' && fn(NexT.motion.integrator); 23 | }, 24 | bootstrap: function() { 25 | this.next(); 26 | } 27 | }; 28 | 29 | NexT.motion.middleWares = { 30 | logo: function(integrator) { 31 | var sequence = []; 32 | var brand = document.querySelector('.brand'); 33 | var image = document.querySelector('.custom-logo-image'); 34 | var title = document.querySelector('.site-title'); 35 | var subtitle = document.querySelector('.site-subtitle'); 36 | var logoLineTop = document.querySelector('.logo-line-before i'); 37 | var logoLineBottom = document.querySelector('.logo-line-after i'); 38 | 39 | brand && sequence.push({ 40 | e: brand, 41 | p: {opacity: 1}, 42 | o: {duration: 200} 43 | }); 44 | 45 | function getMistLineSettings(element, translateX) { 46 | return { 47 | e: element, 48 | p: {translateX}, 49 | o: { 50 | duration : 500, 51 | sequenceQueue: false 52 | } 53 | }; 54 | } 55 | 56 | function pushImageToSequence() { 57 | sequence.push({ 58 | e: image, 59 | p: {opacity: 1, top: 0}, 60 | o: {duration: 200} 61 | }); 62 | } 63 | 64 | CONFIG.scheme === 'Mist' && logoLineTop && logoLineBottom 65 | && sequence.push( 66 | getMistLineSettings(logoLineTop, '100%'), 67 | getMistLineSettings(logoLineBottom, '-100%') 68 | ); 69 | 70 | CONFIG.scheme === 'Muse' && image && pushImageToSequence(); 71 | 72 | title && sequence.push({ 73 | e: title, 74 | p: {opacity: 1, top: 0}, 75 | o: {duration: 200} 76 | }); 77 | 78 | subtitle && sequence.push({ 79 | e: subtitle, 80 | p: {opacity: 1, top: 0}, 81 | o: {duration: 200} 82 | }); 83 | 84 | (CONFIG.scheme === 'Pisces' || CONFIG.scheme === 'Gemini') && image && pushImageToSequence(); 85 | 86 | if (sequence.length > 0) { 87 | sequence[sequence.length - 1].o.complete = function() { 88 | integrator.next(); 89 | }; 90 | Velocity.RunSequence(sequence); 91 | } else { 92 | integrator.next(); 93 | } 94 | 95 | if (CONFIG.motion.async) { 96 | integrator.next(); 97 | } 98 | }, 99 | 100 | menu: function(integrator) { 101 | Velocity(document.querySelectorAll('.menu-item'), 'transition.slideDownIn', { 102 | display : null, 103 | duration: 200, 104 | complete: function() { 105 | integrator.next(); 106 | } 107 | }); 108 | 109 | if (CONFIG.motion.async) { 110 | integrator.next(); 111 | } 112 | }, 113 | 114 | subMenu: function(integrator) { 115 | var subMenuItem = document.querySelectorAll('.sub-menu .menu-item'); 116 | if (subMenuItem.length > 0) { 117 | subMenuItem.forEach(element => { 118 | element.style.opacity = 1; 119 | }); 120 | } 121 | integrator.next(); 122 | }, 123 | 124 | postList: function(integrator) { 125 | var postBlock = document.querySelectorAll('.post-block, .pagination, .comments'); 126 | var postBlockTransition = CONFIG.motion.transition.post_block; 127 | var postHeader = document.querySelectorAll('.post-header'); 128 | var postHeaderTransition = CONFIG.motion.transition.post_header; 129 | var postBody = document.querySelectorAll('.post-body'); 130 | var postBodyTransition = CONFIG.motion.transition.post_body; 131 | var collHeader = document.querySelectorAll('.collection-header'); 132 | var collHeaderTransition = CONFIG.motion.transition.coll_header; 133 | 134 | if (postBlock.length > 0) { 135 | var postMotionOptions = window.postMotionOptions || { 136 | stagger : 100, 137 | drag : true, 138 | complete: function() { 139 | integrator.next(); 140 | } 141 | }; 142 | 143 | if (CONFIG.motion.transition.post_block) { 144 | Velocity(postBlock, 'transition.' + postBlockTransition, postMotionOptions); 145 | } 146 | if (CONFIG.motion.transition.post_header) { 147 | Velocity(postHeader, 'transition.' + postHeaderTransition, postMotionOptions); 148 | } 149 | if (CONFIG.motion.transition.post_body) { 150 | Velocity(postBody, 'transition.' + postBodyTransition, postMotionOptions); 151 | } 152 | if (CONFIG.motion.transition.coll_header) { 153 | Velocity(collHeader, 'transition.' + collHeaderTransition, postMotionOptions); 154 | } 155 | } 156 | if (CONFIG.scheme === 'Pisces' || CONFIG.scheme === 'Gemini') { 157 | integrator.next(); 158 | } 159 | }, 160 | 161 | sidebar: function(integrator) { 162 | var sidebarAffix = document.querySelector('.sidebar-inner'); 163 | var sidebarAffixTransition = CONFIG.motion.transition.sidebar; 164 | // Only for Pisces | Gemini. 165 | if (sidebarAffixTransition && (CONFIG.scheme === 'Pisces' || CONFIG.scheme === 'Gemini')) { 166 | Velocity(sidebarAffix, 'transition.' + sidebarAffixTransition, { 167 | display : null, 168 | duration: 200, 169 | complete: function() { 170 | // After motion complete need to remove transform from sidebar to let affix work on Pisces | Gemini. 171 | sidebarAffix.style.transform = 'initial'; 172 | } 173 | }); 174 | } 175 | integrator.next(); 176 | } 177 | }; 178 | -------------------------------------------------------------------------------- /images/cc-zero.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 17 | 26 | 27 | 28 | 29 | 30 | 31 | 35 | 38 | 45 | 46 | 47 | 53 | 57 | 63 | 66 | 68 | 69 | 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /images/cc-by.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 19 | 21 | 24 | 31 | 32 | 33 | 56 | 58 | 59 | 61 | image/svg+xml 62 | 64 | 65 | 66 | 67 | 71 | 74 | 77 | 84 | 91 | 96 | 100 | 109 | 113 | 114 | 115 | 119 | 120 | 121 | 122 | -------------------------------------------------------------------------------- /images/cc-by-nd.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 19 | 21 | 24 | 31 | 32 | 33 | 56 | 58 | 59 | 61 | image/svg+xml 62 | 64 | 65 | 66 | 67 | 71 | 74 | 81 | 88 | 93 | 97 | 106 | 110 | 111 | 115 | 116 | 117 | 118 | -------------------------------------------------------------------------------- /images/cc-by-nc.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 19 | 21 | 24 | 31 | 32 | 33 | 56 | 58 | 59 | 61 | image/svg+xml 62 | 64 | 65 | 66 | 67 | 71 | 74 | 77 | 84 | 91 | 96 | 100 | 109 | 113 | 114 | 115 | 119 | 120 | 121 | 122 | -------------------------------------------------------------------------------- /images/cc-by-sa.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 19 | 21 | 24 | 31 | 32 | 33 | 56 | 58 | 59 | 61 | image/svg+xml 62 | 64 | 65 | 66 | 67 | 71 | 74 | 77 | 84 | 91 | 96 | 100 | 109 | 113 | 114 | 115 | 119 | 120 | 121 | 122 | -------------------------------------------------------------------------------- /js/local-search.js: -------------------------------------------------------------------------------- 1 | /* global CONFIG */ 2 | 3 | window.addEventListener('DOMContentLoaded', () => { 4 | // Popup Window 5 | let isfetched = false; 6 | let datas; 7 | let isXml = true; 8 | // Search DB path 9 | let searchPath = CONFIG.path; 10 | if (searchPath.length === 0) { 11 | searchPath = 'search.xml'; 12 | } else if (searchPath.endsWith('json')) { 13 | isXml = false; 14 | } 15 | const input = document.querySelector('.search-input'); 16 | const resultContent = document.getElementById('search-result'); 17 | 18 | const getIndexByWord = (word, text, caseSensitive) => { 19 | if (CONFIG.localsearch.unescape) { 20 | let div = document.createElement('div'); 21 | div.innerText = word; 22 | word = div.innerHTML; 23 | } 24 | let wordLen = word.length; 25 | if (wordLen === 0) return []; 26 | let startPosition = 0; 27 | let position = []; 28 | let index = []; 29 | if (!caseSensitive) { 30 | text = text.toLowerCase(); 31 | word = word.toLowerCase(); 32 | } 33 | while ((position = text.indexOf(word, startPosition)) > -1) { 34 | index.push({ position, word }); 35 | startPosition = position + wordLen; 36 | } 37 | return index; 38 | }; 39 | 40 | // Merge hits into slices 41 | const mergeIntoSlice = (start, end, index, searchText) => { 42 | let item = index[index.length - 1]; 43 | let { position, word } = item; 44 | let hits = []; 45 | let searchTextCountInSlice = 0; 46 | while (position + word.length <= end && index.length !== 0) { 47 | if (word === searchText) { 48 | searchTextCountInSlice++; 49 | } 50 | hits.push({ 51 | position, 52 | length: word.length 53 | }); 54 | let wordEnd = position + word.length; 55 | 56 | // Move to next position of hit 57 | index.pop(); 58 | while (index.length !== 0) { 59 | item = index[index.length - 1]; 60 | position = item.position; 61 | word = item.word; 62 | if (wordEnd > position) { 63 | index.pop(); 64 | } else { 65 | break; 66 | } 67 | } 68 | } 69 | return { 70 | hits, 71 | start, 72 | end, 73 | searchTextCount: searchTextCountInSlice 74 | }; 75 | }; 76 | 77 | // Highlight title and content 78 | const highlightKeyword = (text, slice) => { 79 | let result = ''; 80 | let prevEnd = slice.start; 81 | slice.hits.forEach(hit => { 82 | result += text.substring(prevEnd, hit.position); 83 | let end = hit.position + hit.length; 84 | result += `${text.substring(hit.position, end)}`; 85 | prevEnd = end; 86 | }); 87 | result += text.substring(prevEnd, slice.end); 88 | return result; 89 | }; 90 | 91 | const inputEventFunction = () => { 92 | if (!isfetched) return; 93 | let searchText = input.value.trim().toLowerCase(); 94 | let keywords = searchText.split(/[-\s]+/); 95 | if (keywords.length > 1) { 96 | keywords.push(searchText); 97 | } 98 | let resultItems = []; 99 | if (searchText.length > 0) { 100 | // Perform local searching 101 | datas.forEach(({ title, content, url }) => { 102 | let titleInLowerCase = title.toLowerCase(); 103 | let contentInLowerCase = content.toLowerCase(); 104 | let indexOfTitle = []; 105 | let indexOfContent = []; 106 | let searchTextCount = 0; 107 | keywords.forEach(keyword => { 108 | indexOfTitle = indexOfTitle.concat(getIndexByWord(keyword, titleInLowerCase, false)); 109 | indexOfContent = indexOfContent.concat(getIndexByWord(keyword, contentInLowerCase, false)); 110 | }); 111 | 112 | // Show search results 113 | if (indexOfTitle.length > 0 || indexOfContent.length > 0) { 114 | let hitCount = indexOfTitle.length + indexOfContent.length; 115 | // Sort index by position of keyword 116 | [indexOfTitle, indexOfContent].forEach(index => { 117 | index.sort((itemLeft, itemRight) => { 118 | if (itemRight.position !== itemLeft.position) { 119 | return itemRight.position - itemLeft.position; 120 | } 121 | return itemLeft.word.length - itemRight.word.length; 122 | }); 123 | }); 124 | 125 | let slicesOfTitle = []; 126 | if (indexOfTitle.length !== 0) { 127 | let tmp = mergeIntoSlice(0, title.length, indexOfTitle, searchText); 128 | searchTextCount += tmp.searchTextCountInSlice; 129 | slicesOfTitle.push(tmp); 130 | } 131 | 132 | let slicesOfContent = []; 133 | while (indexOfContent.length !== 0) { 134 | let item = indexOfContent[indexOfContent.length - 1]; 135 | let { position, word } = item; 136 | // Cut out 100 characters 137 | let start = position - 20; 138 | let end = position + 80; 139 | if (start < 0) { 140 | start = 0; 141 | } 142 | if (end < position + word.length) { 143 | end = position + word.length; 144 | } 145 | if (end > content.length) { 146 | end = content.length; 147 | } 148 | let tmp = mergeIntoSlice(start, end, indexOfContent, searchText); 149 | searchTextCount += tmp.searchTextCountInSlice; 150 | slicesOfContent.push(tmp); 151 | } 152 | 153 | // Sort slices in content by search text's count and hits' count 154 | slicesOfContent.sort((sliceLeft, sliceRight) => { 155 | if (sliceLeft.searchTextCount !== sliceRight.searchTextCount) { 156 | return sliceRight.searchTextCount - sliceLeft.searchTextCount; 157 | } else if (sliceLeft.hits.length !== sliceRight.hits.length) { 158 | return sliceRight.hits.length - sliceLeft.hits.length; 159 | } 160 | return sliceLeft.start - sliceRight.start; 161 | }); 162 | 163 | // Select top N slices in content 164 | let upperBound = parseInt(CONFIG.localsearch.top_n_per_article, 10); 165 | if (upperBound >= 0) { 166 | slicesOfContent = slicesOfContent.slice(0, upperBound); 167 | } 168 | 169 | let resultItem = ''; 170 | 171 | if (slicesOfTitle.length !== 0) { 172 | resultItem += `
  • ${highlightKeyword(title, slicesOfTitle[0])}`; 173 | } else { 174 | resultItem += `
  • ${title}`; 175 | } 176 | 177 | slicesOfContent.forEach(slice => { 178 | resultItem += `

    ${highlightKeyword(content, slice)}...

    `; 179 | }); 180 | 181 | resultItem += '
  • '; 182 | resultItems.push({ 183 | item: resultItem, 184 | id : resultItems.length, 185 | hitCount, 186 | searchTextCount 187 | }); 188 | } 189 | }); 190 | } 191 | if (keywords.length === 1 && keywords[0] === '') { 192 | resultContent.innerHTML = '
    '; 193 | } else if (resultItems.length === 0) { 194 | resultContent.innerHTML = '
    '; 195 | } else { 196 | resultItems.sort((resultLeft, resultRight) => { 197 | if (resultLeft.searchTextCount !== resultRight.searchTextCount) { 198 | return resultRight.searchTextCount - resultLeft.searchTextCount; 199 | } else if (resultLeft.hitCount !== resultRight.hitCount) { 200 | return resultRight.hitCount - resultLeft.hitCount; 201 | } 202 | return resultRight.id - resultLeft.id; 203 | }); 204 | resultContent.innerHTML = ``; 205 | window.pjax && window.pjax.refresh(resultContent); 206 | } 207 | }; 208 | 209 | const fetchData = () => { 210 | fetch(CONFIG.root + searchPath) 211 | .then(response => response.text()) 212 | .then(res => { 213 | // Get the contents from search data 214 | isfetched = true; 215 | datas = isXml ? [...new DOMParser().parseFromString(res, 'text/xml').querySelectorAll('entry')].map(element => { 216 | return { 217 | title : element.querySelector('title').textContent, 218 | content: element.querySelector('content').textContent, 219 | url : element.querySelector('url').textContent 220 | }; 221 | }) : JSON.parse(res); 222 | // Only match articles with not empty titles 223 | datas = datas.filter(data => data.title).map(data => { 224 | data.title = data.title.trim(); 225 | data.content = data.content ? data.content.trim().replace(/<[^>]+>/g, '') : ''; 226 | data.url = decodeURIComponent(data.url).replace(/\/{2,}/g, '/'); 227 | return data; 228 | }); 229 | // Remove loading animation 230 | document.getElementById('no-result').innerHTML = ''; 231 | inputEventFunction(); 232 | }); 233 | }; 234 | 235 | if (CONFIG.localsearch.preload) { 236 | fetchData(); 237 | } 238 | 239 | if (CONFIG.localsearch.trigger === 'auto') { 240 | input.addEventListener('input', inputEventFunction); 241 | } else { 242 | document.querySelector('.search-icon').addEventListener('click', inputEventFunction); 243 | input.addEventListener('keypress', event => { 244 | if (event.key === 'Enter') { 245 | inputEventFunction(); 246 | } 247 | }); 248 | } 249 | 250 | // Handle and trigger popup window 251 | document.querySelectorAll('.popup-trigger').forEach(element => { 252 | element.addEventListener('click', () => { 253 | document.body.style.overflow = 'hidden'; 254 | document.querySelector('.search-pop-overlay').classList.add('search-active'); 255 | input.focus(); 256 | if (!isfetched) fetchData(); 257 | }); 258 | }); 259 | 260 | // Monitor main search box 261 | const onPopupClose = () => { 262 | document.body.style.overflow = ''; 263 | document.querySelector('.search-pop-overlay').classList.remove('search-active'); 264 | }; 265 | 266 | document.querySelector('.search-pop-overlay').addEventListener('click', event => { 267 | if (event.target === document.querySelector('.search-pop-overlay')) { 268 | onPopupClose(); 269 | } 270 | }); 271 | document.querySelector('.popup-btn-close').addEventListener('click', onPopupClose); 272 | window.addEventListener('pjax:success', onPopupClose); 273 | window.addEventListener('keyup', event => { 274 | if (event.key === 'Escape') { 275 | onPopupClose(); 276 | } 277 | }); 278 | }); 279 | -------------------------------------------------------------------------------- /images/cc-by-nc-nd.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 19 | 21 | 24 | 31 | 32 | 33 | 56 | 58 | 59 | 61 | image/svg+xml 62 | 64 | 65 | 66 | 67 | 71 | 74 | 77 | 84 | 91 | 96 | 100 | 109 | 113 | 114 | 115 | 119 | 120 | 121 | 122 | -------------------------------------------------------------------------------- /images/cc-by-nc-sa.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 19 | 21 | 24 | 31 | 32 | 33 | 56 | 58 | 59 | 61 | image/svg+xml 62 | 64 | 65 | 66 | 67 | 71 | 74 | 77 | 84 | 91 | 96 | 100 | 109 | 113 | 114 | 115 | 119 | 120 | 121 | 122 | -------------------------------------------------------------------------------- /lib/velocity/velocity.ui.min.js: -------------------------------------------------------------------------------- 1 | /* VelocityJS.org UI Pack (5.0.4). (C) 2014 Julian Shapiro. MIT @license: en.wikipedia.org/wiki/MIT_License. Portions copyright Daniel Eden, Christian Pucci. */ 2 | !function(t){"function"==typeof require&&"object"==typeof exports?module.exports=t():"function"==typeof define&&define.amd?define(["velocity"],t):t()}(function(){return function(t,a,e,r){function n(t,a){var e=[];return t&&a?($.each([t,a],function(t,a){var r=[];$.each(a,function(t,a){for(;a.toString().length<5;)a="0"+a;r.push(a)}),e.push(r.join(""))}),parseFloat(e[0])>parseFloat(e[1])):!1}if(!t.Velocity||!t.Velocity.Utilities)return void(a.console&&console.log("Velocity UI Pack: Velocity must be loaded first. Aborting."));var i=t.Velocity,$=i.Utilities,s=i.version,o={major:1,minor:1,patch:0};if(n(o,s)){var l="Velocity UI Pack: You need to update Velocity (jquery.velocity.js) to a newer version. Visit http://github.com/julianshapiro/velocity.";throw alert(l),new Error(l)}i.RegisterEffect=i.RegisterUI=function(t,a){function e(t,a,e,r){var n=0,s;$.each(t.nodeType?[t]:t,function(t,a){r&&(e+=t*r),s=a.parentNode,$.each(["height","paddingTop","paddingBottom","marginTop","marginBottom"],function(t,e){n+=parseFloat(i.CSS.getPropertyValue(a,e))})}),i.animate(s,{height:("In"===a?"+":"-")+"="+n},{queue:!1,easing:"ease-in-out",duration:e*("In"===a?.6:1)})}return i.Redirects[t]=function(n,s,o,l,c,u){function f(){s.display!==r&&"none"!==s.display||!/Out$/.test(t)||$.each(c.nodeType?[c]:c,function(t,a){i.CSS.setPropertyValue(a,"display","none")}),s.complete&&s.complete.call(c,c),u&&u.resolver(c||n)}var p=o===l-1;a.defaultDuration="function"==typeof a.defaultDuration?a.defaultDuration.call(c,c):parseFloat(a.defaultDuration);for(var d=0;d1&&($.each(a.reverse(),function(t,e){var r=a[t+1];if(r){var n=e.o||e.options,s=r.o||r.options,o=n&&n.sequenceQueue===!1?"begin":"complete",l=s&&s[o],c={};c[o]=function(){var t=r.e||r.elements,a=t.nodeType?[t]:t;l&&l.call(a,a),i(e)},r.o?r.o=$.extend({},s,c):r.options=$.extend({},s,c)}}),a.reverse()),i(a[0])}}(window.jQuery||window.Zepto||window,window,document)}); -------------------------------------------------------------------------------- /tags/Rust/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 43 | 44 | 标签: Rust | ThinkCode's Blog 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 74 | 75 | 76 | 77 | 78 | 79 |
    80 |
    81 | 82 |
    83 |
    84 | 91 | 92 | 100 | 101 | 105 |
    106 | 107 | 108 | 109 | 110 | 144 | 145 | 146 | 147 | 148 |
    149 |
    150 | 151 | 152 |
    153 | 154 | 0% 155 |
    156 | 157 | 158 |
    159 |
    160 |
    161 | 162 | 163 |
    164 | 165 | 166 | 167 | 168 | 169 |
    170 |
    171 |
    172 |

    Rust 173 | 标签 174 |

    175 |
    176 | 177 | 178 |
    179 | 2025 180 |
    181 | 182 | 201 | 202 |
    203 |
    204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 |
    213 | 214 | 215 | 236 | 237 |
    238 | 239 | 240 | 245 | 246 | 312 | 313 | 314 | 315 |
    316 |
    317 | 318 |
    319 | 358 |
    359 |
    360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 |
    452 | 453 | 454 | 455 | 456 |
    457 | 458 | 459 | -------------------------------------------------------------------------------- /tags/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 45 | 46 | 标签 | ThinkCode's Blog 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 77 | 78 | 79 | 80 | 81 | 82 |
    83 |
    84 | 85 |
    86 |
    87 | 94 | 95 | 103 | 104 | 108 |
    109 | 110 | 111 | 112 | 113 | 147 | 148 | 149 | 150 | 151 |
    152 |
    153 | 154 | 155 |
    156 | 157 | 0% 158 |
    159 | 160 | 161 |
    162 |
    163 |
    164 | 165 | 166 | 167 | 168 |
    169 | 170 | 171 | 172 | 173 | 174 |
    175 |
    176 | 177 |

    标签 178 |

    179 | 180 | 184 | 185 |
    186 | 187 | 188 | 189 | 190 |
    191 |
    192 |
    193 | 目前共计 4 个标签 194 |
    195 |
    196 | Linux Note Rust 嵌入式 197 |
    198 |
    199 | 200 |
    201 | 202 | 203 | 204 |
    205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 |
    213 | 214 | 215 | 236 | 237 |
    238 | 239 | 240 | 245 | 246 | 312 | 313 | 314 | 315 |
    316 |
    317 | 318 |
    319 | 358 |
    359 |
    360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 |
    452 | 453 | 454 | 455 | 456 |
    457 | 458 | 459 | -------------------------------------------------------------------------------- /tags/嵌入式/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 43 | 44 | 标签: 嵌入式 | ThinkCode's Blog 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 74 | 75 | 76 | 77 | 78 | 79 |
    80 |
    81 | 82 |
    83 |
    84 | 91 | 92 | 100 | 101 | 105 |
    106 | 107 | 108 | 109 | 110 | 144 | 145 | 146 | 147 | 148 |
    149 |
    150 | 151 | 152 |
    153 | 154 | 0% 155 |
    156 | 157 | 158 |
    159 |
    160 |
    161 | 162 | 163 |
    164 | 165 | 166 | 167 | 168 | 169 |
    170 |
    171 |
    172 |

    嵌入式 173 | 标签 174 |

    175 |
    176 | 177 | 178 |
    179 | 2025 180 |
    181 | 182 | 201 | 202 |
    203 |
    204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 |
    213 | 214 | 215 | 236 | 237 |
    238 | 239 | 240 | 245 | 246 | 312 | 313 | 314 | 315 |
    316 |
    317 | 318 |
    319 | 358 |
    359 |
    360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 |
    452 | 453 | 454 | 455 | 456 |
    457 | 458 | 459 | -------------------------------------------------------------------------------- /categories/Rust嵌入式/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 43 | 44 | 分类: Rust嵌入式 | ThinkCode's Blog 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 74 | 75 | 76 | 77 | 78 | 79 |
    80 |
    81 | 82 |
    83 |
    84 | 91 | 92 | 100 | 101 | 105 |
    106 | 107 | 108 | 109 | 110 | 144 | 145 | 146 | 147 | 148 |
    149 |
    150 | 151 | 152 |
    153 | 154 | 0% 155 |
    156 | 157 | 158 |
    159 |
    160 |
    161 | 162 | 163 |
    164 | 165 | 166 | 167 | 168 | 169 |
    170 |
    171 |
    172 |

    Rust嵌入式 173 | 分类 174 |

    175 |
    176 | 177 | 178 |
    179 | 2025 180 |
    181 | 182 | 201 | 202 |
    203 |
    204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 |
    213 | 214 | 215 | 236 | 237 |
    238 | 239 | 240 | 245 | 246 | 312 | 313 | 314 | 315 |
    316 |
    317 | 318 |
    319 | 358 |
    359 |
    360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 |
    452 | 453 | 454 | 455 | 456 |
    457 | 458 | 459 | -------------------------------------------------------------------------------- /categories/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 45 | 46 | 分类 | ThinkCode's Blog 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 77 | 78 | 79 | 80 | 81 | 82 |
    83 |
    84 | 85 |
    86 |
    87 | 94 | 95 | 103 | 104 | 108 |
    109 | 110 | 111 | 112 | 113 | 147 | 148 | 149 | 150 | 151 |
    152 |
    153 | 154 | 155 |
    156 | 157 | 0% 158 |
    159 | 160 | 161 |
    162 |
    163 |
    164 | 165 | 166 | 167 | 168 |
    169 | 170 | 171 | 172 | 173 | 174 |
    175 |
    176 | 177 |

    分类 178 |

    179 | 180 | 184 | 185 |
    186 | 187 | 188 | 189 | 190 |
    191 |
    192 |
    193 | 目前共计 2 个分类 194 |
    195 |
    196 | 197 |
    198 |
    199 | 200 |
    201 | 202 | 203 | 204 |
    205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 |
    213 | 214 | 215 | 236 | 237 |
    238 | 239 | 240 | 245 | 246 | 312 | 313 | 314 | 315 |
    316 |
    317 | 318 |
    319 | 358 |
    359 |
    360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 |
    452 | 453 | 454 | 455 | 456 |
    457 | 458 | 459 | -------------------------------------------------------------------------------- /recommend/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 47 | 48 | 推荐 | ThinkCode's Blog 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 79 | 80 | 81 | 82 | 83 | 84 |
    85 |
    86 | 87 |
    88 |
    89 | 96 | 97 | 105 | 106 | 110 |
    111 | 112 | 113 | 114 | 115 | 149 | 150 | 151 | 152 | 153 |
    154 |
    155 | 156 | 157 |
    158 | 159 | 0% 160 |
    161 | 162 | 163 |
    164 |
    165 |
    166 | 167 | 168 | 169 | 170 |
    171 | 172 | 173 | 174 | 175 | 176 |
    177 |
    178 | 179 |

    推荐 180 |

    181 | 182 | 186 | 187 |
    188 | 189 | 190 | 191 | 192 |
    193 |

    技术文章

      194 |
    1. Hypervisor in 1,000 Lines
    2. 195 |
    3. 1000 行代码的操作系统
    4. 196 |
    5. bevy实战Demo开发
    6. 197 |
    198 | 199 |
    200 | 201 | 202 | 203 |
    204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 |
    212 | 213 | 214 | 235 | 236 |
    237 | 238 | 239 | 244 | 245 | 312 | 313 | 314 | 315 |
    316 |
    317 | 318 |
    319 | 358 |
    359 |
    360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 |
    452 | 453 | 454 | 455 | 456 |
    457 | 458 | 459 | -------------------------------------------------------------------------------- /tags/Note/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 43 | 44 | 标签: Note | ThinkCode's Blog 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 74 | 75 | 76 | 77 | 78 | 79 |
    80 |
    81 | 82 |
    83 |
    84 | 91 | 92 | 100 | 101 | 105 |
    106 | 107 | 108 | 109 | 110 | 144 | 145 | 146 | 147 | 148 |
    149 |
    150 | 151 | 152 |
    153 | 154 | 0% 155 |
    156 | 157 | 158 |
    159 |
    160 |
    161 | 162 | 163 |
    164 | 165 | 166 | 167 | 168 | 169 |
    170 |
    171 |
    172 |

    Note 173 | 标签 174 |

    175 |
    176 | 177 | 178 |
    179 | 2025 180 |
    181 | 182 | 201 | 202 | 221 | 222 |
    223 |
    224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 |
    233 | 234 | 235 | 256 | 257 |
    258 | 259 | 260 | 265 | 266 | 332 | 333 | 334 | 335 |
    336 |
    337 | 338 |
    339 | 378 |
    379 |
    380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 |
    472 | 473 | 474 | 475 | 476 |
    477 | 478 | 479 | --------------------------------------------------------------------------------