From 16c9d78ae518aebb65c3bca5871b2550bbabca16 Mon Sep 17 00:00:00 2001 From: Alexander Dunkel <13646666+Sieboldianus@users.noreply.github.com> Date: Sun, 18 Aug 2019 16:27:31 +0200 Subject: [PATCH] Add code copy button to all code fields in the blog (#81) --- README.md | 2 + assets/js/code-copy.js | 56 +++++++++++++++++++ assets/scss/style.scss | 31 ++++++++++ exampleSite/config.toml | 2 + layouts/_default/baseof.html | 13 ++++- ..._d11fe7b62c27961c87ecd0f2490357b9.content} | 6 +- ...e.js_d11fe7b62c27961c87ecd0f2490357b9.json | 1 + ...n.js_d11fe7b62c27961c87ecd0f2490357b9.json | 1 - ...s_c16d144eee185fbddd582cd5e25a4fae.content | 2 +- ...scss_c16d144eee185fbddd582cd5e25a4fae.json | 2 +- 10 files changed, 110 insertions(+), 6 deletions(-) create mode 100644 assets/js/code-copy.js rename resources/_gen/assets/js/js/{main.js_d11fe7b62c27961c87ecd0f2490357b9.content => bundle.js_d11fe7b62c27961c87ecd0f2490357b9.content} (63%) create mode 100755 resources/_gen/assets/js/js/bundle.js_d11fe7b62c27961c87ecd0f2490357b9.json delete mode 100644 resources/_gen/assets/js/js/main.js_d11fe7b62c27961c87ecd0f2490357b9.json mode change 100644 => 100755 resources/_gen/assets/scss/scss/style.scss_c16d144eee185fbddd582cd5e25a4fae.content mode change 100644 => 100755 resources/_gen/assets/scss/scss/style.scss_c16d144eee185fbddd582cd5e25a4fae.json diff --git a/README.md b/README.md index e1cf944..ba6c3d2 100755 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ Hermit is a minimal and fast theme for Hugo. It's built for bloggers who want a * Featured image is supported. It will be displayed as a dimmed background of the page. * Displays all of your posts on a single page, with one section per year, simple and compact. * Extremely lightweight and load fast. No third party framework, no unnecessary code. +* All code fields feature syntax highlighting and a code-copy function * Responsive & Retina Ready. Scales gracefully from a big screen all the way down to the smallest mobile phone. Assets in vector format ensures that it looks sharp on high-resolution screens. **[Theme Demo](https://hugo-theme-hermit.netlify.com/)** (uses contents and config from the `exampleSite` folder) @@ -111,5 +112,6 @@ You can inject any html code to every page's document head or right above the cl * [normalize.css](https://necolas.github.io/normalize.css/) - [MIT](https://github.com/necolas/normalize.css/blob/master/LICENSE.md) * [animate.css](https://daneden.github.io/animate.css/) - [MIT](https://github.com/daneden/animate.css/blob/master/LICENSE) * [feather](https://feathericons.com/) - [MIT](https://github.com/feathericons/feather/blob/master/LICENSE) +* [code-copy.js](assets/js/code-copy.js) - [Tom Spencer](https://www.fiznool.com/blog/2018/09/14/adding-click-to-copy-buttons-to-a-hugo-powered-blog/) Thanks! diff --git a/assets/js/code-copy.js b/assets/js/code-copy.js new file mode 100644 index 0000000..68036c8 --- /dev/null +++ b/assets/js/code-copy.js @@ -0,0 +1,56 @@ +/** + * Utils + */ + +// Add code-copy buttons using progressive enhancement +// © 2019. Tom Spencer +// https://www.fiznool.com/blog/2018/09/14/adding-click-to-copy-buttons-to-a-hugo-powered-blog/ +(function() { + 'use strict'; + + if(!document.queryCommandSupported('copy')) { + return; + } + + function flashCopyMessage(el, msg) { + el.textContent = msg; + setTimeout(function() { + el.textContent = "Copy"; + }, 1000); + } + + function selectText(node) { + var selection = window.getSelection(); + var range = document.createRange(); + range.selectNodeContents(node); + selection.removeAllRanges(); + selection.addRange(range); + return selection; + } + + function addCopyButton(containerEl) { + var copyBtn = document.createElement("button"); + copyBtn.className = "highlight-copy-btn"; + copyBtn.textContent = "Copy"; + + var codeEl = containerEl.firstElementChild; + copyBtn.addEventListener('click', function() { + try { + var selection = selectText(codeEl); + document.execCommand('copy'); + selection.removeAllRanges(); + + flashCopyMessage(copyBtn, 'Copied!') + } catch(e) { + console && console.log(e); + flashCopyMessage(copyBtn, 'Failed :\'(') + } + }); + + containerEl.appendChild(copyBtn); + } + + // Add copy button to code blocks + var highlightBlocks = document.getElementsByClassName('highlight'); + Array.prototype.forEach.call(highlightBlocks, addCopyButton); +})(); diff --git a/assets/scss/style.scss b/assets/scss/style.scss index 4476504..51143d4 100644 --- a/assets/scss/style.scss +++ b/assets/scss/style.scss @@ -153,6 +153,37 @@ table { display: none; } +// Code copy buttons +// + +.highlight { + position: relative; +} + +.highlight pre { + padding-right: 75px; +} + +.highlight-copy-btn { + position: absolute; + bottom: 7px; + right: 7px; + border: 0; + border-radius: 4px; + padding: 1px; + font-size: 0.7em; + line-height: 1.8; + color: #fff; + background-color: #777; + opacity: 0.6; + min-width: 55px; + text-align: center; +} + +.highlight-copy-btn:hover { + background-color: #666; +} + // Accessibility // .screen-reader-text { diff --git a/exampleSite/config.toml b/exampleSite/config.toml index 3c94862..4e60475 100644 --- a/exampleSite/config.toml +++ b/exampleSite/config.toml @@ -48,6 +48,8 @@ enableEmoji = true # Shorthand emojis in content files - https://gohugo.io/func relatedPosts = false # Add a related content section to all single posts page + code_copy_button = true # Turn on/off the code-copy-button for code-fields + # Add custom css # customCSS = ["css/foo.css", "css/bar.css"] diff --git a/layouts/_default/baseof.html b/layouts/_default/baseof.html index cdb9a1f..6d312b6 100644 --- a/layouts/_default/baseof.html +++ b/layouts/_default/baseof.html @@ -30,8 +30,17 @@ {{ block "header" . -}}{{ end -}} {{ block "main" . -}}{{ end -}} {{ block "footer" . -}}{{ end }} - {{ $script := resources.Get "js/main.js" | minify | fingerprint -}} - + + {{ $main := resources.Get "js/main.js" -}} + {{ if .Site.Params.code_copy_button | default true -}} + {{ $codeCopy := resources.Get "js/code-copy.js" -}} + {{ $script := slice $main $codeCopy | resources.Concat "js/bundle.js" | minify | fingerprint -}} + + {{ else -}} + {{ $script := $main | minify | fingerprint -}} + + {{ end }} + {{- partial "analytics.html" . }} {{- if templates.Exists "partials/extra-foot.html" -}} {{ partial "extra-foot.html" . }} diff --git a/resources/_gen/assets/js/js/main.js_d11fe7b62c27961c87ecd0f2490357b9.content b/resources/_gen/assets/js/js/bundle.js_d11fe7b62c27961c87ecd0f2490357b9.content similarity index 63% rename from resources/_gen/assets/js/js/main.js_d11fe7b62c27961c87ecd0f2490357b9.content rename to resources/_gen/assets/js/js/bundle.js_d11fe7b62c27961c87ecd0f2490357b9.content index cd989df..7137f68 100644 --- a/resources/_gen/assets/js/js/main.js_d11fe7b62c27961c87ecd0f2490357b9.content +++ b/resources/_gen/assets/js/js/bundle.js_d11fe7b62c27961c87ecd0f2490357b9.content @@ -6,4 +6,8 @@ mobileMenuVisible=false;}} const showImg=()=>{document.querySelector('.bg-img').classList.add('show-bg-img');} const hideImg=()=>{document.querySelector('.bg-img').classList.remove('show-bg-img');} const toggleToc=()=>{document.getElementById('toc').classList.toggle('show-toc');} -if(header!==null){listen('#menu-btn',"click",toggleMobileMenu);listen('#toc-btn',"click",toggleToc);listen('#img-btn',"click",showImg);listen('.bg-img',"click",hideImg);document.querySelectorAll('.post-year').forEach((ele)=>{ele.addEventListener('click',()=>{window.location.hash='#'+ele.id;});});window.addEventListener('scroll',throttle(()=>{autoHideHeader();if(mobileMenuVisible==true){toggleMobileMenu();}},250));} \ No newline at end of file +if(header!==null){listen('#menu-btn',"click",toggleMobileMenu);listen('#toc-btn',"click",toggleToc);listen('#img-btn',"click",showImg);listen('.bg-img',"click",hideImg);document.querySelectorAll('.post-year').forEach((ele)=>{ele.addEventListener('click',()=>{window.location.hash='#'+ele.id;});});window.addEventListener('scroll',throttle(()=>{autoHideHeader();if(mobileMenuVisible==true){toggleMobileMenu();}},250));};(function(){'use strict';if(!document.queryCommandSupported('copy')){return;} +function flashCopyMessage(el,msg){el.textContent=msg;setTimeout(function(){el.textContent="Copy";},1000);} +function selectText(node){var selection=window.getSelection();var range=document.createRange();range.selectNodeContents(node);selection.removeAllRanges();selection.addRange(range);return selection;} +function addCopyButton(containerEl){var copyBtn=document.createElement("button");copyBtn.className="highlight-copy-btn";copyBtn.textContent="Copy";var codeEl=containerEl.firstElementChild;copyBtn.addEventListener('click',function(){try{var selection=selectText(codeEl);document.execCommand('copy');selection.removeAllRanges();flashCopyMessage(copyBtn,'Copied!')}catch(e){console&&console.log(e);flashCopyMessage(copyBtn,'Failed :\'(')}});containerEl.appendChild(copyBtn);} +var highlightBlocks=document.getElementsByClassName('highlight');Array.prototype.forEach.call(highlightBlocks,addCopyButton);})(); \ No newline at end of file diff --git a/resources/_gen/assets/js/js/bundle.js_d11fe7b62c27961c87ecd0f2490357b9.json b/resources/_gen/assets/js/js/bundle.js_d11fe7b62c27961c87ecd0f2490357b9.json new file mode 100755 index 0000000..523e6ac --- /dev/null +++ b/resources/_gen/assets/js/js/bundle.js_d11fe7b62c27961c87ecd0f2490357b9.json @@ -0,0 +1 @@ +{"Target":"js/bundle.min.4a9a0ac3d2217822c7865b4161e6c2a71de1d70492264337755427898dd718f6.js","MediaType":"application/javascript","Data":{"Integrity":"sha256-SpoKw9IheCLHhltBYebCpx3h1wSSJkM3dVQniY3XGPY="}} \ No newline at end of file diff --git a/resources/_gen/assets/js/js/main.js_d11fe7b62c27961c87ecd0f2490357b9.json b/resources/_gen/assets/js/js/main.js_d11fe7b62c27961c87ecd0f2490357b9.json deleted file mode 100644 index ece2781..0000000 --- a/resources/_gen/assets/js/js/main.js_d11fe7b62c27961c87ecd0f2490357b9.json +++ /dev/null @@ -1 +0,0 @@ -{"Target":"js/main.min.35ccbf1cdceb91e4c64c06b5d009d6e2977fafe56beda7762febd4e67528d2ac.js","MediaType":"application/javascript","Data":{"Integrity":"sha256-Ncy/HNzrkeTGTAa10AnW4pd/r+Vr7ad2L+vU5nUo0qw="}} \ No newline at end of file diff --git a/resources/_gen/assets/scss/scss/style.scss_c16d144eee185fbddd582cd5e25a4fae.content b/resources/_gen/assets/scss/scss/style.scss_c16d144eee185fbddd582cd5e25a4fae.content old mode 100644 new mode 100755 index 4ad7f30..475f72e --- a/resources/_gen/assets/scss/scss/style.scss_c16d144eee185fbddd582cd5e25a4fae.content +++ b/resources/_gen/assets/scss/scss/style.scss_c16d144eee185fbddd582cd5e25a4fae.content @@ -2,4 +2,4 @@ * Version - 3.7.0 * Licensed under the MIT license - http://opensource.org/licenses/MIT * -* Copyright (c) 2019 Daniel Eden*/@-webkit-keyframes flash{0%,50%,to{opacity:1}25%,75%{opacity:0}}@keyframes flash{0%,50%,to{opacity:1}25%,75%{opacity:0}}.flash{-webkit-animation-name:flash;animation-name:flash}@-webkit-keyframes bounceInRight{0%,60%,75%,90%,to{-webkit-animation-timing-function:cubic-bezier(0.215,0.61,0.355,1);animation-timing-function:cubic-bezier(0.215,0.61,0.355,1)}0%{opacity:0;-webkit-transform:translate3d(3000px,0,0);transform:translate3d(3000px,0,0)}60%{opacity:1;-webkit-transform:translate3d(-25px,0,0);transform:translate3d(-25px,0,0)}75%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}90%{-webkit-transform:translate3d(-5px,0,0);transform:translate3d(-5px,0,0)}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes bounceInRight{0%,60%,75%,90%,to{-webkit-animation-timing-function:cubic-bezier(0.215,0.61,0.355,1);animation-timing-function:cubic-bezier(0.215,0.61,0.355,1)}0%{opacity:0;-webkit-transform:translate3d(3000px,0,0);transform:translate3d(3000px,0,0)}60%{opacity:1;-webkit-transform:translate3d(-25px,0,0);transform:translate3d(-25px,0,0)}75%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}90%{-webkit-transform:translate3d(-5px,0,0);transform:translate3d(-5px,0,0)}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}.bounceInRight{-webkit-animation-name:bounceInRight;animation-name:bounceInRight}@-webkit-keyframes bounceOutRight{20%{opacity:1;-webkit-transform:translate3d(-20px,0,0);transform:translate3d(-20px,0,0)}to{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}@keyframes bounceOutRight{20%{opacity:1;-webkit-transform:translate3d(-20px,0,0);transform:translate3d(-20px,0,0)}to{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}.bounceOutRight{-webkit-animation-name:bounceOutRight;animation-name:bounceOutRight}@-webkit-keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}.fadeIn{-webkit-animation-name:fadeIn;animation-name:fadeIn}@-webkit-keyframes slideInUp{0%{-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0);visibility:visible}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes slideInUp{0%{-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0);visibility:visible}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}.slideInUp{-webkit-animation-name:slideInUp;animation-name:slideInUp}@-webkit-keyframes slideOutDown{0%{-webkit-transform:translateZ(0);transform:translateZ(0)}to{visibility:hidden;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}@keyframes slideOutDown{0%{-webkit-transform:translateZ(0);transform:translateZ(0)}to{visibility:hidden;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}.slideOutDown{-webkit-animation-name:slideOutDown;animation-name:slideOutDown}.animated{-webkit-animation-duration:1s;animation-duration:1s;-webkit-animation-fill-mode:both;animation-fill-mode:both}.animated.infinite{-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite}.animated.delay-1s{-webkit-animation-delay:1s;animation-delay:1s}.animated.delay-2s{-webkit-animation-delay:2s;animation-delay:2s}.animated.delay-3s{-webkit-animation-delay:3s;animation-delay:3s}.animated.delay-4s{-webkit-animation-delay:4s;animation-delay:4s}.animated.delay-5s{-webkit-animation-delay:5s;animation-delay:5s}.animated.fast{-webkit-animation-duration:.8s;animation-duration:.8s}.animated.faster{-webkit-animation-duration:.5s;animation-duration:.5s}.animated.slow{-webkit-animation-duration:2s;animation-duration:2s}.animated.slower{-webkit-animation-duration:3s;animation-duration:3s}@media(prefers-reduced-motion),(print){.animated{-webkit-animation:unset!important;animation:unset!important;-webkit-transition:none!important;transition:none!important}}::-webkit-scrollbar{width:8px;height:8px;background:#2c3e50}::-webkit-scrollbar-thumb{background:#888}::-webkit-scrollbar-thumb:hover{background:#e8eef2}html{background:#494f5c;line-height:1.6;letter-spacing:.06em;scroll-behavior:smooth}body,button,input,select,textarea{color:#e8eef2;font-family:trebuchet ms,Verdana,verdana ref,segoe ui,Candara,lucida grande,lucida sans unicode,lucida sans,Tahoma,sans-serif}pre,code,pre tt{font-family:Consolas,andale mono wt,andale mono,Menlo,Monaco,lucida console,lucida sans typewriter,dejavu sans mono,bitstream vera sans mono,liberation mono,nimbus mono l,courier new,Courier,yahei consolas hybrid,monospace,segoe ui emoji,pingfang sc,microsoft yahei}pre{padding:.7em 1.1em;overflow:auto;font-size:.9em;line-height:1.5;letter-spacing:normal;white-space:pre;color:#eee;background:#2c3e50;border-radius:4px}pre code{padding:0;margin:0;background:#2c3e50}code{color:#eee;background:#7d828a;border-radius:3px;padding:0 3px;margin:0 4px;word-wrap:break-word;letter-spacing:normal}blockquote{border-left:.25em solid;margin:1em;padding:0 1em;font-style:italic}blockquote cite{font-weight:700;font-style:normal}blockquote cite::before{content:"—— "}a{color:#e8eef2;text-decoration:none;border:none;transition-property:color;transition-duration:.4s;transition-timing-function:ease-out}a:hover{color:#fff;text-shadow:0 0 1px #fff}hr{opacity:.2;border-width:0 0 5px;border-style:dashed;background:transparent;width:50%;margin:1.8em auto}table{border-collapse:collapse;border-spacing:0;empty-cells:show;width:100%;max-width:100%}table th,table td{padding:1.5%;border:1px solid}table th{font-weight:700;vertical-align:bottom}.section-inner{margin:0 auto;max-width:1200px;width:93%}.thin{max-width:720px;margin:auto}.feather{display:inline-block;vertical-align:-.125em;width:1em;height:1em}.sub-menu{font-size:.7em}.desktop-only,.desktop-only-ib{display:none}.screen-reader-text{border:0;clip:rect(1px,1px,1px,1px);clip-path:inset(50%);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute!important;width:1px;word-wrap:normal!important}.screen-reader-text:focus{background-color:#f1f1f1;border-radius:3px;box-shadow:0 0 2px 2px rgba(0,0,0,.6);clip:auto!important;clip-path:none;color:#21759b;display:block;font-size:14px;font-size:.875rem;font-weight:700;height:auto;left:5px;line-height:normal;padding:15px 23px 14px;text-decoration:none;top:5px;width:auto;z-index:100000}#site-header{position:fixed;z-index:1;bottom:0;width:100%;box-sizing:border-box;box-shadow:-1px -2px 3px rgba(0,0,0,.45);background-color:#3b3e48}.hdr-wrapper{display:flex;justify-content:space-between;align-items:center;padding:.5em 0;font-size:1.2rem}.hdr-wrapper .site-branding{display:inline-block;margin-right:.8em;font-size:1.2em}.hdr-wrapper .site-nav{display:inline-block;font-size:1.1em;opacity:.8}.hdr-wrapper .site-nav .has-children{padding-right:.5em;border-right:2px solid #7d828a}.hdr-wrapper .site-nav .sub-menu>a{margin-left:.3em}.hdr-wrapper .site-nav a{margin-left:.8em}.hdr-icons{font-size:1.2em}.hdr-social{display:inline-block;margin-left:.6em}.hdr-social>a{margin-left:.4em}.hdr-btn{border:none;background:0 0;padding:0;margin-left:.4em;cursor:pointer}#menu-btn{display:none;margin-left:.6em;cursor:pointer}#mobile-menu{position:fixed;bottom:4.8em;right:1.5em;display:none;padding:.6em 1.8em;z-index:1;box-sizing:border-box;box-shadow:-1px -2px 3px 0 rgba(0,0,0,.45);background-color:#3b3e48}#mobile-menu ul{list-style:none;margin:0;padding:0;line-height:2;font-size:1.2em}#site-footer{text-align:center;font-size:.9em;margin-bottom:96px;margin-top:64px}#site-footer p{margin:0}#spotlight{display:flex;height:100vh;flex-direction:column;align-items:center;justify-content:center;max-width:93%;margin:auto;font-size:1.5rem}#spotlight.error-404{flex-direction:row;line-height:normal}p.img-404{margin:0}p.img-404 svg{width:180px;max-width:100%;height:auto}.banner-404{margin-left:2em}.banner-404 h1{font-size:3em;margin:.5rem 0}.banner-404 p{margin-top:0}.banner-404 .btn-404{font-size:.8em}.banner-404 .btn-404 a{display:inline-block;border:2px solid #e8eef2;border-radius:5px;padding:5px;transition-property:color,border-color}.banner-404 .btn-404 a:first-child{margin-right:1em}.banner-404 .btn-404 a:hover{border-color:#fff}.banner-404 .btn-404 a svg{margin-right:.5em}#home-center{display:flex;flex-grow:1;flex-direction:column;justify-content:center}#home-title{margin:0;text-align:center}#home-subtitle{margin-top:0;margin-bottom:1.5em;text-align:center;line-height:normal;font-size:.7em;font-style:italic;opacity:.9}#home-social{font-size:1.4em;text-align:center;opacity:.8}#home-social a{margin:0 .2em}#home-nav{opacity:.8}#home-nav a{display:block;text-align:center;margin-top:.5em}#home-footer{text-align:center;font-size:.6em;line-height:normal;opacity:.6}#home-footer p{margin-top:0}.posts-group{display:flex;margin-bottom:1.9em;line-height:normal}.posts-group .post-year{padding-top:6px;margin-right:1.8em;font-size:1.6em;opacity:.6}.posts-group .post-year:hover{text-decoration:underline;cursor:pointer}.posts-group .posts-list{flex-grow:1;margin:0;padding:0;list-style:none}.posts-group .post-item{border-bottom:1px #7d828a dashed}.posts-group .post-item a{display:flex;justify-content:space-between;align-items:baseline;padding:12px 0}.posts-group .post-day{flex-shrink:0;margin-left:1em;opacity:.6}.bg-img{width:100vw;height:100vh;opacity:.03;z-index:-1;position:fixed;top:0;background-attachment:fixed;background-repeat:no-repeat;background-size:cover;background-position:50%;transition:opacity .5s}.show-bg-img{z-index:100;opacity:1;cursor:pointer}.post-header{margin-top:1.2em;line-height:normal}.post-header .post-meta{font-size:.9em;letter-spacing:normal;opacity:.6}.post-header h1{margin-top:.1em}hr.post-end{width:50%;margin-top:1.6em;margin-bottom:.8em;margin-left:0;border-style:solid;border-bottom-width:4px}.content a{word-wrap:break-word;border:none;box-shadow:inset 0 -4px 0 #018574;transition-property:box-shadow;transition-duration:.1s}.content a:hover{box-shadow:inset 0 -1em 0 #018574}.content figure{max-width:100%;height:auto;margin:0;text-align:center}.content figure p{font-size:.8em;font-style:italic;opacity:.6}.content figure.left{float:left;margin-right:1.5em;max-width:50%}.content figure.right{float:right;margin-left:1.5em;max-width:50%}.content figure.big{max-width:100vw}.content img{display:block;max-width:100%;height:auto;margin:auto;border-radius:4px}.content ul,.content ol{padding:0;margin-left:1.8em}.content a.anchor{float:left;margin-left:-20px;padding-right:6px;box-shadow:none;opacity:.8}.content a.anchor:hover{background:0 0;color:#018574;opacity:1}.content a.anchor svg{display:inline-block;width:14px;height:14px;vertical-align:baseline;visibility:hidden}.content a.anchor:focus svg{visibility:visible}.content h1:hover a.anchor svg,.content h2:hover a.anchor svg,.content h3:hover a.anchor svg,.content h4:hover a.anchor svg,.content h5:hover a.anchor svg,.content h6:hover a.anchor svg{visibility:visible}.footnotes{font-size:.85em}.footnotes a{box-shadow:none;text-decoration:underline;transition-property:color}.footnotes a:hover{background:transparent}.footnotes a.footnote-return{text-decoration:none}.footnotes ol{line-height:1.8}.footnote-ref a{box-shadow:none;text-decoration:none;padding:2px;border-radius:2px;background-color:#2c3e50}.post-info{font-size:.8rem;line-height:normal;opacity:.6}.post-info p{margin:.8em 0}.post-info a:hover{border-bottom:1px solid #018574}.post-info svg{margin-right:.8em}.post-info .tag{margin-right:.5em}.post-info .tag::before{content:"#"}#toc{position:fixed;left:50%;top:0;display:none}.toc-title{margin-left:1em;margin-bottom:.5em;font-size:.8em;font-weight:700}#TableOfContents{font-size:.8em;opacity:.6}#TableOfContents ul{padding-left:1em;margin:0}#TableOfContents>ul{list-style-type:none}#TableOfContents>ul ul ul{font-size:.9em}#TableOfContents a:hover{border-bottom:#018574 1px solid}.post-nav{display:flex;justify-content:space-between;margin-top:1.5em;margin-bottom:2.5em;font-size:1.2em}.post-nav a{flex-basis:50%;flex-grow:1}.post-nav .next-post{text-align:left;padding-right:5px}.post-nav .prev-post{text-align:right;padding-left:5px}.post-nav .post-nav-label{font-size:.8em;opacity:.8;text-transform:uppercase}.related-posts{padding:.8em;margin-top:1.5em;font-size:.8rem;border:3px dashed rgba(255,255,255,.2);border-radius:5px}.related-posts h2{margin:0;line-height:normal}.related-posts ul{margin-top:.5em;margin-bottom:0}@media(min-width:800px){.site-main{margin-top:3em}hr.post-end{width:40%}}@media(min-width:960px){.site-main{margin-top:6em}}@media(min-width:1300px){.site-main{margin-top:8em}.desktop-only,#toc.show-toc{display:block}.desktop-only-ib{display:inline-block}figure.left{margin-left:-240px}figure.left p{text-align:left}figure.right{margin-right:-240px}figure.right p{text-align:right}figure.big{width:1200px;margin-left:-240px}hr.post-end{width:30%}#toc{top:13em;margin-left:370px;max-width:220px}}@media(min-width:1800px){.site-main{margin-top:10em}.section-inner{max-width:1600px}.thin{max-width:960px}figure.left{max-width:75%;margin-left:-320px}figure.right{max-width:75%;margin-right:-320px}figure.big{width:1600px;margin-left:-320px}hr.post-end{width:30%}#toc{top:15em;margin-left:490px;max-width:300px}}@media(max-width:760px){.hide-in-mobile,.site-nav.hide-in-mobile{display:none}#menu-btn{display:inline-block}.posts-group{display:block}.posts-group .post-year{margin:-6px 0 4px}#spotlight.error-404{flex-direction:column;text-align:center}#spotlight.error-404 .banner-404{margin:0}}@media(max-width:520px){.content figure.left,.content figure.right{float:unset;max-width:100%;margin:0}hr.post-end{width:60%}#mobile-menu{right:1.2em}} \ No newline at end of file +* Copyright (c) 2019 Daniel Eden*/@-webkit-keyframes flash{0%,50%,to{opacity:1}25%,75%{opacity:0}}@keyframes flash{0%,50%,to{opacity:1}25%,75%{opacity:0}}.flash{-webkit-animation-name:flash;animation-name:flash}@-webkit-keyframes bounceInRight{0%,60%,75%,90%,to{-webkit-animation-timing-function:cubic-bezier(0.215,0.61,0.355,1);animation-timing-function:cubic-bezier(0.215,0.61,0.355,1)}0%{opacity:0;-webkit-transform:translate3d(3000px,0,0);transform:translate3d(3000px,0,0)}60%{opacity:1;-webkit-transform:translate3d(-25px,0,0);transform:translate3d(-25px,0,0)}75%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}90%{-webkit-transform:translate3d(-5px,0,0);transform:translate3d(-5px,0,0)}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes bounceInRight{0%,60%,75%,90%,to{-webkit-animation-timing-function:cubic-bezier(0.215,0.61,0.355,1);animation-timing-function:cubic-bezier(0.215,0.61,0.355,1)}0%{opacity:0;-webkit-transform:translate3d(3000px,0,0);transform:translate3d(3000px,0,0)}60%{opacity:1;-webkit-transform:translate3d(-25px,0,0);transform:translate3d(-25px,0,0)}75%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}90%{-webkit-transform:translate3d(-5px,0,0);transform:translate3d(-5px,0,0)}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}.bounceInRight{-webkit-animation-name:bounceInRight;animation-name:bounceInRight}@-webkit-keyframes bounceOutRight{20%{opacity:1;-webkit-transform:translate3d(-20px,0,0);transform:translate3d(-20px,0,0)}to{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}@keyframes bounceOutRight{20%{opacity:1;-webkit-transform:translate3d(-20px,0,0);transform:translate3d(-20px,0,0)}to{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}.bounceOutRight{-webkit-animation-name:bounceOutRight;animation-name:bounceOutRight}@-webkit-keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}.fadeIn{-webkit-animation-name:fadeIn;animation-name:fadeIn}@-webkit-keyframes slideInUp{0%{-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0);visibility:visible}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes slideInUp{0%{-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0);visibility:visible}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}.slideInUp{-webkit-animation-name:slideInUp;animation-name:slideInUp}@-webkit-keyframes slideOutDown{0%{-webkit-transform:translateZ(0);transform:translateZ(0)}to{visibility:hidden;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}@keyframes slideOutDown{0%{-webkit-transform:translateZ(0);transform:translateZ(0)}to{visibility:hidden;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}.slideOutDown{-webkit-animation-name:slideOutDown;animation-name:slideOutDown}.animated{-webkit-animation-duration:1s;animation-duration:1s;-webkit-animation-fill-mode:both;animation-fill-mode:both}.animated.infinite{-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite}.animated.delay-1s{-webkit-animation-delay:1s;animation-delay:1s}.animated.delay-2s{-webkit-animation-delay:2s;animation-delay:2s}.animated.delay-3s{-webkit-animation-delay:3s;animation-delay:3s}.animated.delay-4s{-webkit-animation-delay:4s;animation-delay:4s}.animated.delay-5s{-webkit-animation-delay:5s;animation-delay:5s}.animated.fast{-webkit-animation-duration:.8s;animation-duration:.8s}.animated.faster{-webkit-animation-duration:.5s;animation-duration:.5s}.animated.slow{-webkit-animation-duration:2s;animation-duration:2s}.animated.slower{-webkit-animation-duration:3s;animation-duration:3s}@media(prefers-reduced-motion),(print){.animated{-webkit-animation:unset!important;animation:unset!important;-webkit-transition:none!important;transition:none!important}}::-webkit-scrollbar{width:8px;height:8px;background:#2c3e50}::-webkit-scrollbar-thumb{background:#888}::-webkit-scrollbar-thumb:hover{background:#e8eef2}html{background:#494f5c;line-height:1.6;letter-spacing:.06em;scroll-behavior:smooth}body,button,input,select,textarea{color:#e8eef2;font-family:trebuchet ms,Verdana,verdana ref,segoe ui,Candara,lucida grande,lucida sans unicode,lucida sans,Tahoma,sans-serif}pre,code,pre tt{font-family:Consolas,andale mono wt,andale mono,Menlo,Monaco,lucida console,lucida sans typewriter,dejavu sans mono,bitstream vera sans mono,liberation mono,nimbus mono l,courier new,Courier,yahei consolas hybrid,monospace,segoe ui emoji,pingfang sc,microsoft yahei}pre{padding:.7em 1.1em;overflow:auto;font-size:.9em;line-height:1.5;letter-spacing:normal;white-space:pre;color:#eee;background:#2c3e50;border-radius:4px}pre code{padding:0;margin:0;background:#2c3e50}code{color:#eee;background:#7d828a;border-radius:3px;padding:0 3px;margin:0 4px;word-wrap:break-word;letter-spacing:normal}blockquote{border-left:.25em solid;margin:1em;padding:0 1em;font-style:italic}blockquote cite{font-weight:700;font-style:normal}blockquote cite::before{content:"—— "}a{color:#e8eef2;text-decoration:none;border:none;transition-property:color;transition-duration:.4s;transition-timing-function:ease-out}a:hover{color:#fff;text-shadow:0 0 1px #fff}hr{opacity:.2;border-width:0 0 5px;border-style:dashed;background:transparent;width:50%;margin:1.8em auto}table{border-collapse:collapse;border-spacing:0;empty-cells:show;width:100%;max-width:100%}table th,table td{padding:1.5%;border:1px solid}table th{font-weight:700;vertical-align:bottom}.section-inner{margin:0 auto;max-width:1200px;width:93%}.thin{max-width:720px;margin:auto}.feather{display:inline-block;vertical-align:-.125em;width:1em;height:1em}.sub-menu{font-size:.7em}.desktop-only,.desktop-only-ib{display:none}.highlight{position:relative}.highlight pre{padding-right:75px}.highlight-copy-btn{position:absolute;bottom:7px;right:7px;border:0;border-radius:4px;padding:1px;font-size:.7em;line-height:1.8;color:#fff;background-color:#777;opacity:.6;min-width:55px;text-align:center}.highlight-copy-btn:hover{background-color:#666}.screen-reader-text{border:0;clip:rect(1px,1px,1px,1px);clip-path:inset(50%);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute!important;width:1px;word-wrap:normal!important}.screen-reader-text:focus{background-color:#f1f1f1;border-radius:3px;box-shadow:0 0 2px 2px rgba(0,0,0,.6);clip:auto!important;clip-path:none;color:#21759b;display:block;font-size:14px;font-size:.875rem;font-weight:700;height:auto;left:5px;line-height:normal;padding:15px 23px 14px;text-decoration:none;top:5px;width:auto;z-index:100000}#site-header{position:fixed;z-index:1;bottom:0;width:100%;box-sizing:border-box;box-shadow:-1px -2px 3px rgba(0,0,0,.45);background-color:#3b3e48}.hdr-wrapper{display:flex;justify-content:space-between;align-items:center;padding:.5em 0;font-size:1.2rem}.hdr-wrapper .site-branding{display:inline-block;margin-right:.8em;font-size:1.2em}.hdr-wrapper .site-nav{display:inline-block;font-size:1.1em;opacity:.8}.hdr-wrapper .site-nav .has-children{padding-right:.5em;border-right:2px solid #7d828a}.hdr-wrapper .site-nav .sub-menu>a{margin-left:.3em}.hdr-wrapper .site-nav a{margin-left:.8em}.hdr-icons{font-size:1.2em}.hdr-social{display:inline-block;margin-left:.6em}.hdr-social>a{margin-left:.4em}.hdr-btn{border:none;background:0 0;padding:0;margin-left:.4em;cursor:pointer}#menu-btn{display:none;margin-left:.6em;cursor:pointer}#mobile-menu{position:fixed;bottom:4.8em;right:1.5em;display:none;padding:.6em 1.8em;z-index:1;box-sizing:border-box;box-shadow:-1px -2px 3px 0 rgba(0,0,0,.45);background-color:#3b3e48}#mobile-menu ul{list-style:none;margin:0;padding:0;line-height:2;font-size:1.2em}#site-footer{text-align:center;font-size:.9em;margin-bottom:96px;margin-top:64px}#site-footer p{margin:0}#spotlight{display:flex;height:100vh;flex-direction:column;align-items:center;justify-content:center;max-width:93%;margin:auto;font-size:1.5rem}#spotlight.error-404{flex-direction:row;line-height:normal}p.img-404{margin:0}p.img-404 svg{width:180px;max-width:100%;height:auto}.banner-404{margin-left:2em}.banner-404 h1{font-size:3em;margin:.5rem 0}.banner-404 p{margin-top:0}.banner-404 .btn-404{font-size:.8em}.banner-404 .btn-404 a{display:inline-block;border:2px solid #e8eef2;border-radius:5px;padding:5px;transition-property:color,border-color}.banner-404 .btn-404 a:first-child{margin-right:1em}.banner-404 .btn-404 a:hover{border-color:#fff}.banner-404 .btn-404 a svg{margin-right:.5em}#home-center{display:flex;flex-grow:1;flex-direction:column;justify-content:center}#home-title{margin:0;text-align:center}#home-subtitle{margin-top:0;margin-bottom:1.5em;text-align:center;line-height:normal;font-size:.7em;font-style:italic;opacity:.9}#home-social{font-size:1.4em;text-align:center;opacity:.8}#home-social a{margin:0 .2em}#home-nav{opacity:.8}#home-nav a{display:block;text-align:center;margin-top:.5em}#home-footer{text-align:center;font-size:.6em;line-height:normal;opacity:.6}#home-footer p{margin-top:0}.posts-group{display:flex;margin-bottom:1.9em;line-height:normal}.posts-group .post-year{padding-top:6px;margin-right:1.8em;font-size:1.6em;opacity:.6}.posts-group .post-year:hover{text-decoration:underline;cursor:pointer}.posts-group .posts-list{flex-grow:1;margin:0;padding:0;list-style:none}.posts-group .post-item{border-bottom:1px #7d828a dashed}.posts-group .post-item a{display:flex;justify-content:space-between;align-items:baseline;padding:12px 0}.posts-group .post-day{flex-shrink:0;margin-left:1em;opacity:.6}.bg-img{width:100vw;height:100vh;opacity:.03;z-index:-1;position:fixed;top:0;background-attachment:fixed;background-repeat:no-repeat;background-size:cover;background-position:50%;transition:opacity .5s}.show-bg-img{z-index:100;opacity:1;cursor:pointer}.post-header{margin-top:1.2em;line-height:normal}.post-header .post-meta{font-size:.9em;letter-spacing:normal;opacity:.6}.post-header h1{margin-top:.1em}hr.post-end{width:50%;margin-top:1.6em;margin-bottom:.8em;margin-left:0;border-style:solid;border-bottom-width:4px}.content a{word-wrap:break-word;border:none;box-shadow:inset 0 -4px 0 #018574;transition-property:box-shadow;transition-duration:.1s}.content a:hover{box-shadow:inset 0 -1em 0 #018574}.content figure{max-width:100%;height:auto;margin:0;text-align:center}.content figure p{font-size:.8em;font-style:italic;opacity:.6}.content figure.left{float:left;margin-right:1.5em;max-width:50%}.content figure.right{float:right;margin-left:1.5em;max-width:50%}.content figure.big{max-width:100vw}.content img{display:block;max-width:100%;height:auto;margin:auto;border-radius:4px}.content ul,.content ol{padding:0;margin-left:1.8em}.content a.anchor{float:left;margin-left:-20px;padding-right:6px;box-shadow:none;opacity:.8}.content a.anchor:hover{background:0 0;color:#018574;opacity:1}.content a.anchor svg{display:inline-block;width:14px;height:14px;vertical-align:baseline;visibility:hidden}.content a.anchor:focus svg{visibility:visible}.content h1:hover a.anchor svg,.content h2:hover a.anchor svg,.content h3:hover a.anchor svg,.content h4:hover a.anchor svg,.content h5:hover a.anchor svg,.content h6:hover a.anchor svg{visibility:visible}.footnotes{font-size:.85em}.footnotes a{box-shadow:none;text-decoration:underline;transition-property:color}.footnotes a:hover{background:transparent}.footnotes a.footnote-return{text-decoration:none}.footnotes ol{line-height:1.8}.footnote-ref a{box-shadow:none;text-decoration:none;padding:2px;border-radius:2px;background-color:#2c3e50}.post-info{font-size:.8rem;line-height:normal;opacity:.6}.post-info p{margin:.8em 0}.post-info a:hover{border-bottom:1px solid #018574}.post-info svg{margin-right:.8em}.post-info .tag{margin-right:.5em}.post-info .tag::before{content:"#"}#toc{position:fixed;left:50%;top:0;display:none}.toc-title{margin-left:1em;margin-bottom:.5em;font-size:.8em;font-weight:700}#TableOfContents{font-size:.8em;opacity:.6}#TableOfContents ul{padding-left:1em;margin:0}#TableOfContents>ul{list-style-type:none}#TableOfContents>ul ul ul{font-size:.9em}#TableOfContents a:hover{border-bottom:#018574 1px solid}.post-nav{display:flex;justify-content:space-between;margin-top:1.5em;margin-bottom:2.5em;font-size:1.2em}.post-nav a{flex-basis:50%;flex-grow:1}.post-nav .next-post{text-align:left;padding-right:5px}.post-nav .prev-post{text-align:right;padding-left:5px}.post-nav .post-nav-label{font-size:.8em;opacity:.8;text-transform:uppercase}.related-posts{padding:.8em;margin-top:1.5em;font-size:.8rem;border:3px dashed rgba(255,255,255,.2);border-radius:5px}.related-posts h2{margin:0;line-height:normal}.related-posts ul{margin-top:.5em;margin-bottom:0}@media(min-width:800px){.site-main{margin-top:3em}hr.post-end{width:40%}}@media(min-width:960px){.site-main{margin-top:6em}}@media(min-width:1300px){.site-main{margin-top:8em}.desktop-only,#toc.show-toc{display:block}.desktop-only-ib{display:inline-block}figure.left{margin-left:-240px}figure.left p{text-align:left}figure.right{margin-right:-240px}figure.right p{text-align:right}figure.big{width:1200px;margin-left:-240px}hr.post-end{width:30%}#toc{top:13em;margin-left:370px;max-width:220px}}@media(min-width:1800px){.site-main{margin-top:10em}.section-inner{max-width:1600px}.thin{max-width:960px}figure.left{max-width:75%;margin-left:-320px}figure.right{max-width:75%;margin-right:-320px}figure.big{width:1600px;margin-left:-320px}hr.post-end{width:30%}#toc{top:15em;margin-left:490px;max-width:300px}}@media(max-width:760px){.hide-in-mobile,.site-nav.hide-in-mobile{display:none}#menu-btn{display:inline-block}.posts-group{display:block}.posts-group .post-year{margin:-6px 0 4px}#spotlight.error-404{flex-direction:column;text-align:center}#spotlight.error-404 .banner-404{margin:0}}@media(max-width:520px){.content figure.left,.content figure.right{float:unset;max-width:100%;margin:0}hr.post-end{width:60%}#mobile-menu{right:1.2em}} \ No newline at end of file diff --git a/resources/_gen/assets/scss/scss/style.scss_c16d144eee185fbddd582cd5e25a4fae.json b/resources/_gen/assets/scss/scss/style.scss_c16d144eee185fbddd582cd5e25a4fae.json old mode 100644 new mode 100755 index 982ade6..1b63b4f --- a/resources/_gen/assets/scss/scss/style.scss_c16d144eee185fbddd582cd5e25a4fae.json +++ b/resources/_gen/assets/scss/scss/style.scss_c16d144eee185fbddd582cd5e25a4fae.json @@ -1 +1 @@ -{"Target":"css/style.min.568c54a56780af2a70c45272522247710b69dbfc080b315211fb98381e3796f8.css","MediaType":"text/css","Data":{"Integrity":"sha256-VoxUpWeArypwxFJyUiJHcQtp2/wICzFSEfuYOB43lvg="}} \ No newline at end of file +{"Target":"css/style.min.5ee5e7976cd09872c64e40a582206543f6aa38c69a8c43898aadc70040344b92.css","MediaType":"text/css","Data":{"Integrity":"sha256-XuXnl2zQmHLGTkClgiBlQ/aqOMaajEOJiq3HAEA0S5I="}} \ No newline at end of file