Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/monkeyWzr/hugo-theme-cactus.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormonkeyWzr <monkeywzr@gmail.com>2021-07-05 10:08:31 +0300
committermonkeyWzr <monkeywzr@gmail.com>2021-07-05 10:08:31 +0300
commita6ec2491417315c1bfeed7578ca04abf13470509 (patch)
tree71333d3347e713344b5f84504b64e2a417b320bb
parent965c5ea600ff956fe8df56b7ee2f4e4562ece0c5 (diff)
add copy code button
-rw-r--r--assets/scss/style.scss59
-rw-r--r--exampleSite/config.toml2
-rw-r--r--exampleSite/content/posts/code-block-test.md41
-rw-r--r--exampleSite/resources/_gen/assets/scss/scss/style.scss_17a317b87063135b4df76ed814d78726.content2
-rw-r--r--exampleSite/resources/_gen/assets/scss/scss/style.scss_17a317b87063135b4df76ed814d78726.json2
-rw-r--r--layouts/posts/single.html1
-rw-r--r--static/js/code-copy.js36
7 files changed, 134 insertions, 9 deletions
diff --git a/assets/scss/style.scss b/assets/scss/style.scss
index ec93e8c..f9c0691 100644
--- a/assets/scss/style.scss
+++ b/assets/scss/style.scss
@@ -150,13 +150,38 @@ body {
pre {
overflow-x: auto;
- padding: 10px 15px;
+ padding: 15px 15px 10px 15px;
border: 1px dotted $color-border;
- border-radius: 4px;
+ border-radius: 2px;
+ -webkit-border-radius: 2px;
font-size: 13px;
font-family: $font-family-mono;
line-height: 22px;
- -webkit-border-radius: 4px;
+ position: relative;
+
+ .code-copy-btn {
+ position: absolute;
+ top: 0;
+ right: 0;
+ border: 0;
+ border-radius: 0 2px;
+ padding: 0;
+ font-family: "JetBrains Mono", monospace;
+ font-weight: 800;
+ font-size: 0.9em;
+ line-height: 1.7;
+ color: #fff;
+ background-color: #8c8c8c;
+ min-width: 60px;
+ text-align: center;
+ cursor: pointer;
+ letter-spacing: 0em;
+ }
+
+ .code-copy-btn:hover {
+ background-color: #666;
+ color: #2bbc8a;
+ }
code {
display: block;
@@ -164,15 +189,43 @@ pre {
border: none;
}
}
+
code {
+ font-family: $font-family-mono;
padding: 0 5px;
border: 1px dotted $color-border;
border-radius: 2px;
-webkit-border-radius: 2px;
}
+
.highlight {
+
+ & > div {
+ border-radius: 2px;
+ -webkit-border-radius: 2px;
+ }
+
pre {
border: none;
background: none;
}
+
+ table {
+
+ pre {
+ margin-top: 0;
+ }
+
+ td:first-child {
+ pre {
+ padding-right: 0;
+ }
+ }
+
+ td:last-child {
+ pre {
+ padding-left: 0;
+ }
+ }
+ }
} \ No newline at end of file
diff --git a/exampleSite/config.toml b/exampleSite/config.toml
index 0d54ff5..dd0e4ef 100644
--- a/exampleSite/config.toml
+++ b/exampleSite/config.toml
@@ -41,7 +41,7 @@ weight = 4
hl_Lines = ""
lineNoStart = 1
lineNos = true
- lineNumbersInTable = true
+ lineNumbersInTable = false
noClasses = true
style = "dracula"
tabWidth = 4
diff --git a/exampleSite/content/posts/code-block-test.md b/exampleSite/content/posts/code-block-test.md
index af384f2..a7ef079 100644
--- a/exampleSite/content/posts/code-block-test.md
+++ b/exampleSite/content/posts/code-block-test.md
@@ -28,10 +28,10 @@ text
<tag>
```
-Fenced code block with language:
+Fenced code block with language (lineNumbersInTable = false):
```Java
-// Java
+// JavaJavaJavaJavaJavaJavaJavaJavaJavaJavaJavaJavaJavaJavaJavaJavaJavaJavaJavaJavaJavaJavaJavaJavaJavaJavaJavaJavaJavaJava
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence
{
@@ -98,7 +98,7 @@ public final class String
}
```
-Using hugo's `highlight` [shortcode]([highlight](https://gohugo.io/content-management/syntax-highlighting/#highlight-shortcode)):
+Using hugo's `highlight` [shortcode]([highlight](https://gohugo.io/content-management/syntax-highlighting/#highlight-shortcode)) (lineNumbersInTable = true):
{{< highlight typescript "linenos=table, hl_lines=8 18-21" >}}
// TypeScript
@@ -123,3 +123,38 @@ type ModifiableUser = {
-readonly [K in keyof User]: User[K]
}
{{< /highlight >}}
+
+Without line number
+
+{{< highlight javascript "linenos=false" >}}
+(() => {
+
+ function createCopyButton(codeNode) {
+ const copyBtn = document.createElement('button')
+ copyBtn.className = 'code-copy-btn'
+ copyBtn.type = 'button'
+ copyBtn.innerText = 'copy'
+ copyBtn.parentElement = codeNode.parentElement
+
+ let resetTimer
+ copyBtn.addEventListener('click', () => {
+ navigator.clipboard.writeText(codeNode.innerText).then(() => {
+ copyBtn.innerText = 'copied!'
+ }).then(() => {
+ clearTimeout(resetTimer)
+ resetTimer = setTimeout(() => {
+ copyBtn.innerText = 'copy'
+ }, 1000)
+ })
+ })
+
+ return copyBtn
+ }
+
+ document.querySelectorAll('pre > code').forEach((codeNode) => {
+ const copyBtn = createCopyButton(codeNode);
+ codeNode.parentNode.insertBefore(copyBtn, codeNode)
+ })
+
+})()
+{{< / highlight >}}
diff --git a/exampleSite/resources/_gen/assets/scss/scss/style.scss_17a317b87063135b4df76ed814d78726.content b/exampleSite/resources/_gen/assets/scss/scss/style.scss_17a317b87063135b4df76ed814d78726.content
index bbb3388..2edcada 100644
--- a/exampleSite/resources/_gen/assets/scss/scss/style.scss_17a317b87063135b4df76ed814d78726.content
+++ b/exampleSite/resources/_gen/assets/scss/scss/style.scss_17a317b87063135b4df76ed814d78726.content
@@ -1,3 +1,3 @@
-.inline{display:inline}.block{display:block}.inline-block{display:inline-block}.table{display:table}.table-cell{display:table-cell}.overflow-hidden{overflow:hidden}.overflow-scroll{overflow:scroll}.overflow-auto{overflow:auto}.clearfix:before,.clearfix:after{display:table;content:" "}.clearfix:after{clear:both}.left{float:left}.right{float:right}.fit{max-width:100%}.truncate{display:inline-block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.max-width-1{max-width:24rem}.max-width-2{max-width:32rem}.max-width-3{max-width:48rem}.max-width-4{max-width:64rem}.border-box{box-sizing:border-box}.m0{margin:0}.mt0{margin-top:0}.mr0{margin-right:0}.mb0{margin-bottom:0}.ml0{margin-left:0}.mx0{margin-right:0;margin-left:0}.my0{margin-top:0;margin-bottom:0}.m1{margin:.5rem}.mt1{margin-top:.5rem}.mr1{margin-right:.5rem}.mb1{margin-bottom:.5rem}.ml1{margin-left:.5rem}.mx1{margin-right:.5rem;margin-left:.5rem}.my1{margin-top:.5rem;margin-bottom:.5rem}.m2{margin:1rem}.mt2{margin-top:1rem}.mr2{margin-right:1rem}.mb2{margin-bottom:1rem}.ml2{margin-left:1rem}.mx2{margin-right:1rem;margin-left:1rem}.my2{margin-top:1rem;margin-bottom:1rem}.m3{margin:2rem}.mt3{margin-top:2rem}.mr3{margin-right:2rem}.mb3{margin-bottom:2rem}.ml3{margin-left:2rem}.mx3{margin-right:2rem;margin-left:2rem}.my3{margin-top:2rem;margin-bottom:2rem}.m4{margin:4rem}.mt4{margin-top:4rem}.mr4{margin-right:4rem}.mb4{margin-bottom:4rem}.ml4{margin-left:4rem}.mx4{margin-right:4rem;margin-left:4rem}.my4{margin-top:4rem;margin-bottom:4rem}.mxn1{margin-right:-.5rem;margin-left:-.5rem}.mxn2{margin-right:-1rem;margin-left:-1rem}.mxn3{margin-right:-2rem;margin-left:-2rem}.mxn4{margin-right:-4rem;margin-left:-4rem}.ml-auto{margin-left:auto}.mr-auto{margin-right:auto}.mx-auto{margin-right:auto;margin-left:auto}.p0{padding:0}.pt0{padding-top:0}.pr0{padding-right:0}.pb0{padding-bottom:0}.pl0{padding-left:0}.px0{padding-right:0;padding-left:0}.py0{padding-top:0;padding-bottom:0}.p1{padding:.5rem}.pt1{padding-top:.5rem}.pr1{padding-right:.5rem}.pb1{padding-bottom:.5rem}.pl1{padding-left:.5rem}.py1{padding-top:.5rem;padding-bottom:.5rem}.px1{padding-right:.5rem;padding-left:.5rem}.p2{padding:1rem}.pt2{padding-top:1rem}.pr2{padding-right:1rem}.pb2{padding-bottom:1rem}.pl2{padding-left:1rem}.py2{padding-top:1rem;padding-bottom:1rem}.px2{padding-right:1rem;padding-left:1rem}.p3{padding:2rem}.pt3{padding-top:2rem}.pr3{padding-right:2rem}.pb3{padding-bottom:2rem}.pl3{padding-left:2rem}.py3{padding-top:2rem;padding-bottom:2rem}.px3{padding-right:2rem;padding-left:2rem}.p4{padding:4rem}.pt4{padding-top:4rem}.pr4{padding-right:4rem}.pb4{padding-bottom:4rem}.pl4{padding-left:4rem}.py4{padding-top:4rem;padding-bottom:4rem}.px4{padding-right:4rem;padding-left:4rem}h1,.h1{display:block;margin-top:3rem;margin-bottom:1rem;color:#2bbc8a;letter-spacing:.01em;font-weight:700;font-style:normal;font-size:1.5em;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased}h2,.h2{position:relative;display:block;margin-top:2rem;margin-bottom:.5rem;color:#383838;text-transform:none;letter-spacing:normal;font-weight:bold;font-size:1rem}h3{color:#383838;text-decoration:underline;font-weight:bold;font-size:.9rem}h4 h5 h6{display:inline;text-decoration:none;color:#8c8c8c;font-weight:bold;font-size:.9rem}h3 h4 h5 h6{margin-top:.9rem;margin-bottom:.5rem}hr{border:0.5px dashed #8c8c8c;opacity:.5;margin:0;margin-top:20px;margin-bottom:20px}strong{font-weight:bold}em cite{font-style:italic}sup sub{position:relative;vertical-align:baseline;font-size:.75em;line-height:0}sup{top:-.5em}sub{bottom:-.2em}small{font-size:.85em}acronym abbr{border-bottom:1px dotted}ul ol dl{line-height:1.725}ul ul,ol ul,ul ol,ol ol{margin-top:0;margin-bottom:0}ol{list-style:decimal}dt{font-weight:bold}table{width:100%;border-collapse:collapse;text-align:left;font-size:12px;overflow:auto;display:block}th{padding:8px;border-bottom:1px dashed #666;color:#383838;font-weight:bold;font-size:13px}td{padding:0 8px;border-bottom:none}@font-face{font-style:normal;font-family:"Meslo LG";src:local("Meslo LG S"),url("../lib/meslo-LG/MesloLGS-Regular.ttf") format("truetype")}@font-face{font-style:normal;font-family:"JetBrains Mono";src:local("JetBrains Mono"),url("../lib/JetBrainsMono/ttf/JetBrainsMono-Regular.ttf") format("truetype")}*,*:before,*:after{box-sizing:border-box}html{margin:0;padding:0;height:100%;border-top:2px solid #383838;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0;height:100%;background-color:#fff;color:#383838;font-display:swap;font-weight:400;font-size:14px;font-family:"JetBrains Mono",monospace;line-height:1.725;text-rendering:geometricPrecision;flex:1;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased}.content{position:relative;display:flex;flex-direction:column;min-height:100%;overflow-wrap:break-word}.content p{hyphens:auto;-moz-hyphens:auto;-ms-hyphens:auto;-webkit-hyphens:auto}.content code{hyphens:manual;-moz-hyphens:manual;-ms-hyphens:manual;-webkit-hyphens:manual}.content a{color:#383838;text-decoration:none;background-image:linear-gradient(transparent, transparent 5px, #383838 5px, #383838);background-position:bottom;background-size:100% 6px;background-repeat:repeat-x}.content a:hover{background-image:linear-gradient(transparent, transparent 4px, #d480aa 4px, #d480aa)}.content a.icon{background:none}.content a.icon:hover{color:#d480aa}.content h1 a,.content .h1 a,.content h2 a,.content h3 a,.content h4 a,.content h5 a,.content h6 a{background:none;color:inherit;text-decoration:none}.content h1 a:hover,.content .h1 a:hover,.content h2 a:hover,.content h3 a:hover,.content h4 a:hover,.content h5 a:hover,.content h6 a:hover{background-image:linear-gradient(transparent, transparent 6px, #d480aa 6px, #d480aa);background-position:bottom;background-size:100% 6px;background-repeat:repeat-x}.content h6 a{background:none;color:inherit;text-decoration:none}.content h6 a:hover{background-image:linear-gradient(transparent, transparent 6px, #d480aa 6px, #d480aa);background-position:bottom;background-size:100% 6px;background-repeat:repeat-x}@media (min-width: 540px){.image-wrap{flex-direction:row;margin-bottom:2rem}.image-wrap .image-block{flex:1 0 35%;margin-right:2rem}.image-wrap p{flex:1 0 65%}}.max-width{max-width:48rem}@media (max-width: 480px){.px3{padding-right:1rem;padding-left:1rem}.my4{margin-top:2rem;margin-bottom:2rem}}@media (min-width: 480px){p{text-align:justify}}#header{margin:0 auto 2rem;width:100%}#header h1,#header .h1{margin-top:0;margin-bottom:0;color:#383838;letter-spacing:.01em;font-weight:700;font-style:normal;font-size:1.5rem;line-height:2rem;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased}#header a{background:none;color:inherit;text-decoration:none}#header #logo{display:inline-block;float:left;margin-right:20px;width:50px;height:50px;border-radius:5px;background-size:50px 50px;background-repeat:no-repeat;filter:grayscale(100%);-webkit-filter:grayscale(100%)}#header #nav{color:#2bbc8a;letter-spacing:.01em;font-weight:200;font-style:normal;font-size:.8rem}#header #nav ul{margin:0;padding:0;list-style-type:none;line-height:15px}#header #nav ul a{margin-right:15px;color:#2bbc8a}#header #nav ul a:hover{background-image:linear-gradient(transparent, transparent 5px, #2bbc8a 5px, #2bbc8a);background-position:bottom;background-size:100% 6px;background-repeat:repeat-x}#header #nav ul li{display:inline-block;margin-right:15px;border-right:1px dotted;border-color:#2bbc8a;vertical-align:middle}#header #nav ul .icon{display:none}#header #nav ul li:last-child{margin-right:0;border-right:0}#header #nav ul li:last-child a{margin-right:0}#header:hover #logo{filter:none;-webkit-filter:none}@media screen and (max-width: 480px){#header #title{display:table;margin-right:5rem;min-height:50px}#header #title h1{display:table-cell;vertical-align:middle}#header #nav ul a:hover{background:none}#header #nav ul li{display:none;border-right:0}#header #nav ul li.icon{position:absolute;top:77px;right:1rem;display:inline-block}#header #nav ul.responsive li{display:block}#header #nav li:not(:first-child){padding-top:1rem;padding-left:70px;font-size:1rem}}#header-post{position:fixed;top:2rem;right:0;display:inline-block;float:right;z-index:100}#header-post a{background:none;color:inherit;text-decoration:none}#header-post a.icon{background:none}#header-post a.icon:hover{color:#d480aa}#header-post nav ul{display:block;list-style-image:none;list-style-position:outside;list-style-type:none;padding-inline-start:40px}#header-post nav ul li{display:list-item;margin-right:0px}#header-post nav>ul{margin-block-end:1em;margin-block-start:1em}#header-post ul{display:inline-block;margin:0;padding:0;list-style-type:none}#header-post ul li{display:inline-block;margin-right:15px;vertical-align:middle}#header-post ul li:last-child{margin-right:0}#header-post #menu-icon{float:right;margin-right:2rem;margin-left:15px}#header-post #menu-icon:hover{color:#2bbc8a}#header-post #menu-icon-tablet{float:right;margin-right:2rem;margin-left:15px}#header-post #menu-icon-tablet:hover{color:#2bbc8a}#header-post #top-icon-tablet{position:fixed;right:2rem;bottom:2rem;margin-right:2rem;margin-left:15px}#header-post #top-icon-tablet:hover{color:#2bbc8a}#header-post .active{color:#2bbc8a}#header-post #menu{visibility:hidden;margin-right:2rem}#header-post #nav{color:#2bbc8a;letter-spacing:.01em;font-weight:200;font-style:normal;font-size:.8rem}#header-post #nav ul{line-height:15px}#header-post #nav ul a{margin-right:15px;color:#2bbc8a}#header-post #nav ul a:hover{background-image:linear-gradient(transparent, transparent 5px, #2bbc8a 5px, #2bbc8a);background-position:bottom;background-size:100% 6px;background-repeat:repeat-x}#header-post #nav ul li{border-right:1px dotted #2bbc8a}#header-post #nav ul li:last-child{margin-right:0;border-right:0}#header-post #nav ul li:last-child a{margin-right:0}#header-post #actions{float:right;margin-top:2rem;margin-right:2rem;width:100%;text-align:right}#header-post #actions ul{display:block}#header-post #actions .info{display:block;font-style:italic}#header-post #share{clear:both;padding-top:1rem;padding-right:2rem;text-align:right}#header-post #share li{display:block;margin:0}#header-post #toc{float:right;clear:both;overflow:auto;margin-top:1rem;padding-right:2rem;max-width:20em;max-height:calc(95vh - 7rem);text-align:right}#header-post #toc a:hover{color:#d480aa}#header-post #toc nav>ul>li{color:#383838;font-size:.8rem}#header-post #toc nav>ul>li:before{color:#2bbc8a;content:"#";margin-right:8px}#header-post #toc nav>ul>li>ul>li{color:#666;font-size:.7rem}#header-post #toc nav>ul>li>ul>li:before{color:#2bbc8a;content:"·";font-weight:bold;margin-right:3px}#header-post #toc nav>ul>li>ul>li>ul>li{color:#333;font-size:.4rem}#header-post #toc .toc-level-5{display:none}#header-post #toc .toc-level-6{display:none}#header-post #toc .toc-number{display:none}@media screen and (max-width: 500px){#header-post{display:none}}@media screen and (max-width: 900px){#header-post #menu-icon{display:none}#header-post #actions{display:none}}@media screen and (max-width: 1199px){#header-post #toc{display:none}}@media screen and (min-width: 900px){#header-post #menu-icon-tablet{display:none !important}#header-post #top-icon-tablet{display:none !important}}@media screen and (min-width: 1199px){#header-post #actions{width:auto}#header-post #actions ul{display:inline-block;float:right}#header-post #actions .info{display:inline;float:left;margin-right:2rem;font-style:italic}}#footer-post{position:fixed;right:0;bottom:0;left:0;z-index:5000000;width:100%;border-top:1px solid #666;background:#fafafa;transition:opacity .2s}#footer-post a{background:none;color:inherit;text-decoration:none}#footer-post a.icon{background:none}#footer-post a.icon:hover{color:#d480aa}#footer-post #nav-footer{padding-right:1rem;padding-left:1rem;background:#e6e6e6;text-align:center}#footer-post #nav-footer a{color:#2bbc8a;font-size:1em}#footer-post #nav-footer a:hover{background-image:linear-gradient(transparent, transparent 5px, #2bbc8a 5px, #2bbc8a);background-position:bottom;background-size:100% 6px;background-repeat:repeat-x}#footer-post #nav-footer ul{display:table;margin:0;padding:0;width:100%;list-style-type:none}#footer-post #nav-footer ul li{display:inline-table;padding:10px;width:20%;vertical-align:middle}#footer-post #actions-footer{overflow:auto;margin-top:1rem;margin-bottom:1rem;padding-right:1rem;padding-left:1rem;width:100%;text-align:center;white-space:nowrap}#footer-post #actions-footer a{display:inline-block;padding-left:1rem;color:#2bbc8a}#footer-post #share-footer{padding-right:1rem;padding-left:1rem;background:#e6e6e6;text-align:center}#footer-post #share-footer ul{display:table;margin:0;padding:0;width:100%;list-style-type:none}#footer-post #share-footer ul li{display:inline-table;padding:10px;width:20%;vertical-align:middle}#footer-post #toc-footer{clear:both;padding-top:1rem;padding-bottom:1rem;background:#e6e6e6;text-align:left}#footer-post #toc-footer #TableOfContents ul{margin:0;padding-left:20px;list-style-type:none}#footer-post #toc-footer #TableOfContents ul li{line-height:30px}#footer-post #toc-footer a:hover{color:#d480aa}#footer-post #toc-footer #TableOfContents>ul>li{color:#383838;font-size:.8rem}#footer-post #toc-footer #TableOfContents>ul>li:before{color:#2bbc8a;content:"#";margin-right:8px}#footer-post #toc-footer #TableOfContents>ul>li>ul>li{color:#666;font-size:.7rem;line-height:15px}#footer-post #toc-footer #TableOfContents>ul>li>ul>li:before{color:#2bbc8a;content:"·";font-weight:bold;margin-right:3px}#footer-post #toc-footer #TableOfContents>ul>li>ul>li>ul>li{display:none}@media screen and (min-width: 500px){#footer-post-container{display:none}}.post-list{padding:0}.post-list .post-item{margin-bottom:1rem;margin-left:0;list-style-type:none}.post-list .post-item .meta{display:block;margin-right:16px;min-width:100px;color:#666;font-size:14px}@media (min-width: 480px){.post-list .post-item{display:flex;margin-bottom:5px}.post-list .post-item .meta{text-align:left}}.project-list{padding:0;list-style:none}.project-list .project-item{margin-bottom:5px}.project-list .project-item p{display:inline}article header .posttitle{margin-top:0;margin-bottom:0;text-transform:none;font-size:1.5em;line-height:1.25}article header .meta{margin-top:0;margin-bottom:1rem}article header .meta *{color:#8c8c8c;font-size:.85rem}article header .author{text-transform:uppercase;letter-spacing:.01em;font-weight:700}article header .postdate{display:inline}article .content h2:before{position:absolute;top:-4px;left:-1rem;color:#2bbc8a;content:"#";font-weight:bold;font-size:1.2rem}article .content img,article .content video{display:block;margin:auto;max-width:100%;height:auto}article .content img .video-container,article .content video .video-container{position:relative;overflow:hidden;padding-top:56.25% e;height:0}article .content img .video-container iframe,article .content img .video-container object,article .content img .video-container embed,article .content video .video-container iframe,article .content video .video-container object,article .content video .video-container embed{position:absolute;top:0;left:0;margin-top:0;width:100%;height:100%}article .content img blockquote,article .content video blockquote{margin:1rem 10px;padding:.5em 10px;background:inherit;color:#2bbc8a;quotes:"\201C" "\201D" "\2018" "\2019";font-weight:bold}article .content img blockquote p,article .content video blockquote p{margin:0}article .content img blockquote:before,article .content video blockquote:before{margin-right:.25em;color:#2bbc8a;content:"\201C";vertical-align:-.4em;font-size:2em;line-height:.1em}article .content img blockquote footer,article .content video blockquote footer{margin:line-height 0;color:#666;font-size:11px}article .content img blockquote footer a,article .content video blockquote footer a{background-image:linear-gradient(transparent, transparent 5px, #666 5px, #666);color:#666}article .content img blockquote footer a:hover,article .content video blockquote footer a:hover{background-image:linear-gradient(transparent, transparent 4px, #999 4px, #999);color:#999}article .content img blockquote footer cite:before,article .content video blockquote footer cite:before{padding:0 .5em;content:"—"}article .content img .pullquote,article .content video .pullquote{margin:0;width:45%;text-align:left}article .content img .pullquote.left,article .content video .pullquote.left{margin-right:1em;margin-left:.5em}article .content img .pullquote.right,article .content video .pullquote.right{margin-right:.5em;margin-left:1em}article .content img .caption,article .content video .caption{position:relative;display:block;margin-top:.5em;color:#666;text-align:center;font-size:.9em}.posttitle{text-transform:none;font-size:1.5em;line-height:1.25}.article-tag .tag-link:before{content:"#";background-image:linear-gradient(transparent, transparent 10px, #d480aa 10px, #d480aa);background-position:bottom;background-size:100% 6px;background-repeat:repeat-x}.article-category .category-link{background-image:linear-gradient(transparent, transparent 10px, #d480aa 10px, #d480aa);background-position:bottom;background-size:100% 6px;background-repeat:repeat-x}@media (min-width: 480px){.article-read-time,.article-tag,.article-category{display:inline}.article-read-time:before,.article-tag:before,.article-category:before{content:"|"}}#archive .post-list{padding:0}#archive .post-list .post-item{margin-bottom:1rem;margin-left:0;list-style-type:none}#archive .post-list .post-item .meta{display:block;margin-right:16px;min-width:100px;color:#666;font-size:14px}@media (min-width: 480px){#archive .post-list .post-item{display:flex;margin-bottom:5px;margin-left:1rem}#archive .post-list .post-item .meta{text-align:left}}.blog-post-comments{margin-top:4rem}#footer{position:absolute;bottom:0;margin-bottom:10px;width:100%;color:#666;vertical-align:top;text-align:center;font-size:11px}#footer ul{margin:0;padding:0;list-style:none}#footer li{display:inline-block;margin-right:15px;border-right:1px solid;border-color:#666;vertical-align:middle}#footer li a{margin-right:15px}#footer li:last-child{margin-right:0;border-right:0}#footer li:last-child a{margin-right:0}#footer a{color:#666;text-decoration:underline;background-image:none}#footer a:hover{color:#999}#footer .footer-left{height:20px;vertical-align:middle;line-height:20px}@media (min-width: 39rem){#footer{display:flex;flex-flow:row wrap;justify-content:space-between;align-items:center;align-content:center;margin-bottom:20px}#footer .footer-left{align-self:flex-start;margin-right:20px}#footer .footer-right{align-self:flex-end}}.pagination{display:inline-block;margin-top:2rem;width:100%;text-align:center}.pagination .page-number{color:#383838;font-size:.8rem}.pagination a{padding:4px 6px;border-radius:5px;background-image:none;color:#383838;text-decoration:none}.pagination a:hover{background-image:none}.pagination a:hover:not(.active){color:#383838}.search-input{padding:4px 7px;width:100%;outline:none;border:solid 1px #8c8c8c;border-radius:5px;background-color:#fff;color:#383838;font-size:1.2rem;-webkit-border-radius:5px;-moz-border-radius:5px}.search-input:focus{border:solid 1px #2bbc8a}#search-result ul.search-result-list{padding:0;list-style-type:none}#search-result li{margin:2em auto}#search-result a.search-result-title{background-image:none;color:#383838;text-transform:capitalize;font-weight:bold;line-height:1.2}#search-result p.search-result{overflow:hidden;margin:.4em auto;max-height:13em;text-align:justify;font-size:.8em}#search-result em.search-keyword{border-bottom:1px dashed #d480aa;color:#d480aa;font-weight:bold}.search-no-result{display:none;padding-bottom:.5em;color:#383838}#tag-cloud .tag-cloud-title{color:#666}#tag-cloud .tag-cloud-tags{clear:both;text-align:center}#tag-cloud .tag-cloud-tags a{display:inline-block;margin:10px}.tooltipped{position:relative}.tooltipped::after{position:absolute;z-index:1000000;display:none;padding:.2em .5em;-webkit-font-smoothing:subpixel-antialiased;color:#fff;font-display:swap;font-weight:400;font-size:11.2px;font-family:"JetBrains Mono",monospace;line-height:1.725;text-rendering:geometricPrecision;text-align:center;word-wrap:break-word;white-space:pre;content:attr(aria-label);background:#383838;border-radius:3px;opacity:0}.tooltipped::before{position:absolute;z-index:1000001;display:none;width:0;height:0;color:#383838;pointer-events:none;content:'';border:6px solid transparent;opacity:0}@keyframes tooltip-appear{from{opacity:0}to{opacity:1}}.tooltipped:hover::before,.tooltipped:hover::after,.tooltipped:active::before,.tooltipped:active::after,.tooltipped:focus::before,.tooltipped:focus::after{display:inline-block;text-decoration:none;animation-name:tooltip-appear;animation-duration:0.1s;animation-fill-mode:forwards;animation-timing-function:ease-in}.tooltipped-s::after,.tooltipped-sw::after{top:100%;right:50%;margin-top:6px}.tooltipped-s::before,.tooltipped-sw::before{top:auto;right:50%;bottom:-7px;margin-right:-6px;border-bottom-color:#383838}.tooltipped-sw::after{margin-right:-16px}.tooltipped-s::after{transform:translateX(50%)}#categories .category-list-title{color:#666}#categories .category-list .category-list-item .category-list-count{color:#666}#categories .category-list .category-list-item .category-list-count:before{content:" ("}#categories .category-list .category-list-item .category-list-count:after{content:")"}pre{overflow-x:auto;padding:10px 15px;border:1px dotted #666;border-radius:4px;font-size:13px;font-family:"JetBrains Mono",monospace;line-height:22px;-webkit-border-radius:4px;position:relative}pre .code-copy-btn{position:absolute;top:0;right:0;border:0;border-radius:4px;padding:1px;font-size:0.7em;line-height:1.8;color:#fff;background-color:#777;min-width:55px;text-align:center;cursor:pointer}pre .code-copy-btn:hover{background-color:#666}pre code{display:block;padding:0;border:none}code{padding:0 5px;border:1px dotted #666;border-radius:2px;-webkit-border-radius:2px}.highlight pre{border:none;background:none}.highlight table pre{margin-top:0}.highlight table td:first-child pre{padding-right:0}.highlight table td:last-child pre{padding-left:0}
+.inline{display:inline}.block{display:block}.inline-block{display:inline-block}.table{display:table}.table-cell{display:table-cell}.overflow-hidden{overflow:hidden}.overflow-scroll{overflow:scroll}.overflow-auto{overflow:auto}.clearfix:before,.clearfix:after{display:table;content:" "}.clearfix:after{clear:both}.left{float:left}.right{float:right}.fit{max-width:100%}.truncate{display:inline-block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.max-width-1{max-width:24rem}.max-width-2{max-width:32rem}.max-width-3{max-width:48rem}.max-width-4{max-width:64rem}.border-box{box-sizing:border-box}.m0{margin:0}.mt0{margin-top:0}.mr0{margin-right:0}.mb0{margin-bottom:0}.ml0{margin-left:0}.mx0{margin-right:0;margin-left:0}.my0{margin-top:0;margin-bottom:0}.m1{margin:.5rem}.mt1{margin-top:.5rem}.mr1{margin-right:.5rem}.mb1{margin-bottom:.5rem}.ml1{margin-left:.5rem}.mx1{margin-right:.5rem;margin-left:.5rem}.my1{margin-top:.5rem;margin-bottom:.5rem}.m2{margin:1rem}.mt2{margin-top:1rem}.mr2{margin-right:1rem}.mb2{margin-bottom:1rem}.ml2{margin-left:1rem}.mx2{margin-right:1rem;margin-left:1rem}.my2{margin-top:1rem;margin-bottom:1rem}.m3{margin:2rem}.mt3{margin-top:2rem}.mr3{margin-right:2rem}.mb3{margin-bottom:2rem}.ml3{margin-left:2rem}.mx3{margin-right:2rem;margin-left:2rem}.my3{margin-top:2rem;margin-bottom:2rem}.m4{margin:4rem}.mt4{margin-top:4rem}.mr4{margin-right:4rem}.mb4{margin-bottom:4rem}.ml4{margin-left:4rem}.mx4{margin-right:4rem;margin-left:4rem}.my4{margin-top:4rem;margin-bottom:4rem}.mxn1{margin-right:-.5rem;margin-left:-.5rem}.mxn2{margin-right:-1rem;margin-left:-1rem}.mxn3{margin-right:-2rem;margin-left:-2rem}.mxn4{margin-right:-4rem;margin-left:-4rem}.ml-auto{margin-left:auto}.mr-auto{margin-right:auto}.mx-auto{margin-right:auto;margin-left:auto}.p0{padding:0}.pt0{padding-top:0}.pr0{padding-right:0}.pb0{padding-bottom:0}.pl0{padding-left:0}.px0{padding-right:0;padding-left:0}.py0{padding-top:0;padding-bottom:0}.p1{padding:.5rem}.pt1{padding-top:.5rem}.pr1{padding-right:.5rem}.pb1{padding-bottom:.5rem}.pl1{padding-left:.5rem}.py1{padding-top:.5rem;padding-bottom:.5rem}.px1{padding-right:.5rem;padding-left:.5rem}.p2{padding:1rem}.pt2{padding-top:1rem}.pr2{padding-right:1rem}.pb2{padding-bottom:1rem}.pl2{padding-left:1rem}.py2{padding-top:1rem;padding-bottom:1rem}.px2{padding-right:1rem;padding-left:1rem}.p3{padding:2rem}.pt3{padding-top:2rem}.pr3{padding-right:2rem}.pb3{padding-bottom:2rem}.pl3{padding-left:2rem}.py3{padding-top:2rem;padding-bottom:2rem}.px3{padding-right:2rem;padding-left:2rem}.p4{padding:4rem}.pt4{padding-top:4rem}.pr4{padding-right:4rem}.pb4{padding-bottom:4rem}.pl4{padding-left:4rem}.py4{padding-top:4rem;padding-bottom:4rem}.px4{padding-right:4rem;padding-left:4rem}h1,.h1{display:block;margin-top:3rem;margin-bottom:1rem;color:#2bbc8a;letter-spacing:.01em;font-weight:700;font-style:normal;font-size:1.5em;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased}h2,.h2{position:relative;display:block;margin-top:2rem;margin-bottom:.5rem;color:#383838;text-transform:none;letter-spacing:normal;font-weight:bold;font-size:1rem}h3{color:#383838;text-decoration:underline;font-weight:bold;font-size:.9rem}h4 h5 h6{display:inline;text-decoration:none;color:#8c8c8c;font-weight:bold;font-size:.9rem}h3 h4 h5 h6{margin-top:.9rem;margin-bottom:.5rem}hr{border:0.5px dashed #8c8c8c;opacity:.5;margin:0;margin-top:20px;margin-bottom:20px}strong{font-weight:bold}em cite{font-style:italic}sup sub{position:relative;vertical-align:baseline;font-size:.75em;line-height:0}sup{top:-.5em}sub{bottom:-.2em}small{font-size:.85em}acronym abbr{border-bottom:1px dotted}ul ol dl{line-height:1.725}ul ul,ol ul,ul ol,ol ol{margin-top:0;margin-bottom:0}ol{list-style:decimal}dt{font-weight:bold}table{width:100%;border-collapse:collapse;text-align:left;font-size:12px;overflow:auto;display:block}th{padding:8px;border-bottom:1px dashed #666;color:#383838;font-weight:bold;font-size:13px}td{padding:0 8px;border-bottom:none}@font-face{font-style:normal;font-family:"Meslo LG";src:local("Meslo LG S"),url("../lib/meslo-LG/MesloLGS-Regular.ttf") format("truetype")}@font-face{font-style:normal;font-family:"JetBrains Mono";src:local("JetBrains Mono"),url("../lib/JetBrainsMono/ttf/JetBrainsMono-Regular.ttf") format("truetype")}*,*:before,*:after{box-sizing:border-box}html{margin:0;padding:0;height:100%;border-top:2px solid #383838;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0;height:100%;background-color:#fff;color:#383838;font-display:swap;font-weight:400;font-size:14px;font-family:"JetBrains Mono",monospace;line-height:1.725;text-rendering:geometricPrecision;flex:1;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased}.content{position:relative;display:flex;flex-direction:column;min-height:100%;overflow-wrap:break-word}.content p{hyphens:auto;-moz-hyphens:auto;-ms-hyphens:auto;-webkit-hyphens:auto}.content code{hyphens:manual;-moz-hyphens:manual;-ms-hyphens:manual;-webkit-hyphens:manual}.content a{color:#383838;text-decoration:none;background-image:linear-gradient(transparent, transparent 5px, #383838 5px, #383838);background-position:bottom;background-size:100% 6px;background-repeat:repeat-x}.content a:hover{background-image:linear-gradient(transparent, transparent 4px, #d480aa 4px, #d480aa)}.content a.icon{background:none}.content a.icon:hover{color:#d480aa}.content h1 a,.content .h1 a,.content h2 a,.content h3 a,.content h4 a,.content h5 a,.content h6 a{background:none;color:inherit;text-decoration:none}.content h1 a:hover,.content .h1 a:hover,.content h2 a:hover,.content h3 a:hover,.content h4 a:hover,.content h5 a:hover,.content h6 a:hover{background-image:linear-gradient(transparent, transparent 6px, #d480aa 6px, #d480aa);background-position:bottom;background-size:100% 6px;background-repeat:repeat-x}.content h6 a{background:none;color:inherit;text-decoration:none}.content h6 a:hover{background-image:linear-gradient(transparent, transparent 6px, #d480aa 6px, #d480aa);background-position:bottom;background-size:100% 6px;background-repeat:repeat-x}@media (min-width: 540px){.image-wrap{flex-direction:row;margin-bottom:2rem}.image-wrap .image-block{flex:1 0 35%;margin-right:2rem}.image-wrap p{flex:1 0 65%}}.max-width{max-width:48rem}@media (max-width: 480px){.px3{padding-right:1rem;padding-left:1rem}.my4{margin-top:2rem;margin-bottom:2rem}}@media (min-width: 480px){p{text-align:justify}}#header{margin:0 auto 2rem;width:100%}#header h1,#header .h1{margin-top:0;margin-bottom:0;color:#383838;letter-spacing:.01em;font-weight:700;font-style:normal;font-size:1.5rem;line-height:2rem;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased}#header a{background:none;color:inherit;text-decoration:none}#header #logo{display:inline-block;float:left;margin-right:20px;width:50px;height:50px;border-radius:5px;background-size:50px 50px;background-repeat:no-repeat;filter:grayscale(100%);-webkit-filter:grayscale(100%)}#header #nav{color:#2bbc8a;letter-spacing:.01em;font-weight:200;font-style:normal;font-size:.8rem}#header #nav ul{margin:0;padding:0;list-style-type:none;line-height:15px}#header #nav ul a{margin-right:15px;color:#2bbc8a}#header #nav ul a:hover{background-image:linear-gradient(transparent, transparent 5px, #2bbc8a 5px, #2bbc8a);background-position:bottom;background-size:100% 6px;background-repeat:repeat-x}#header #nav ul li{display:inline-block;margin-right:15px;border-right:1px dotted;border-color:#2bbc8a;vertical-align:middle}#header #nav ul .icon{display:none}#header #nav ul li:last-child{margin-right:0;border-right:0}#header #nav ul li:last-child a{margin-right:0}#header:hover #logo{filter:none;-webkit-filter:none}@media screen and (max-width: 480px){#header #title{display:table;margin-right:5rem;min-height:50px}#header #title h1{display:table-cell;vertical-align:middle}#header #nav ul a:hover{background:none}#header #nav ul li{display:none;border-right:0}#header #nav ul li.icon{position:absolute;top:77px;right:1rem;display:inline-block}#header #nav ul.responsive li{display:block}#header #nav li:not(:first-child){padding-top:1rem;padding-left:70px;font-size:1rem}}#header-post{position:fixed;top:2rem;right:0;display:inline-block;float:right;z-index:100}#header-post a{background:none;color:inherit;text-decoration:none}#header-post a.icon{background:none}#header-post a.icon:hover{color:#d480aa}#header-post nav ul{display:block;list-style-image:none;list-style-position:outside;list-style-type:none;padding-inline-start:40px}#header-post nav ul li{display:list-item;margin-right:0px}#header-post nav>ul{margin-block-end:1em;margin-block-start:1em}#header-post ul{display:inline-block;margin:0;padding:0;list-style-type:none}#header-post ul li{display:inline-block;margin-right:15px;vertical-align:middle}#header-post ul li:last-child{margin-right:0}#header-post #menu-icon{float:right;margin-right:2rem;margin-left:15px}#header-post #menu-icon:hover{color:#2bbc8a}#header-post #menu-icon-tablet{float:right;margin-right:2rem;margin-left:15px}#header-post #menu-icon-tablet:hover{color:#2bbc8a}#header-post #top-icon-tablet{position:fixed;right:2rem;bottom:2rem;margin-right:2rem;margin-left:15px}#header-post #top-icon-tablet:hover{color:#2bbc8a}#header-post .active{color:#2bbc8a}#header-post #menu{visibility:hidden;margin-right:2rem}#header-post #nav{color:#2bbc8a;letter-spacing:.01em;font-weight:200;font-style:normal;font-size:.8rem}#header-post #nav ul{line-height:15px}#header-post #nav ul a{margin-right:15px;color:#2bbc8a}#header-post #nav ul a:hover{background-image:linear-gradient(transparent, transparent 5px, #2bbc8a 5px, #2bbc8a);background-position:bottom;background-size:100% 6px;background-repeat:repeat-x}#header-post #nav ul li{border-right:1px dotted #2bbc8a}#header-post #nav ul li:last-child{margin-right:0;border-right:0}#header-post #nav ul li:last-child a{margin-right:0}#header-post #actions{float:right;margin-top:2rem;margin-right:2rem;width:100%;text-align:right}#header-post #actions ul{display:block}#header-post #actions .info{display:block;font-style:italic}#header-post #share{clear:both;padding-top:1rem;padding-right:2rem;text-align:right}#header-post #share li{display:block;margin:0}#header-post #toc{float:right;clear:both;overflow:auto;margin-top:1rem;padding-right:2rem;max-width:20em;max-height:calc(95vh - 7rem);text-align:right}#header-post #toc a:hover{color:#d480aa}#header-post #toc nav>ul>li{color:#383838;font-size:.8rem}#header-post #toc nav>ul>li:before{color:#2bbc8a;content:"#";margin-right:8px}#header-post #toc nav>ul>li>ul>li{color:#666;font-size:.7rem}#header-post #toc nav>ul>li>ul>li:before{color:#2bbc8a;content:"·";font-weight:bold;margin-right:3px}#header-post #toc nav>ul>li>ul>li>ul>li{color:#333;font-size:.4rem}#header-post #toc .toc-level-5{display:none}#header-post #toc .toc-level-6{display:none}#header-post #toc .toc-number{display:none}@media screen and (max-width: 500px){#header-post{display:none}}@media screen and (max-width: 900px){#header-post #menu-icon{display:none}#header-post #actions{display:none}}@media screen and (max-width: 1199px){#header-post #toc{display:none}}@media screen and (min-width: 900px){#header-post #menu-icon-tablet{display:none !important}#header-post #top-icon-tablet{display:none !important}}@media screen and (min-width: 1199px){#header-post #actions{width:auto}#header-post #actions ul{display:inline-block;float:right}#header-post #actions .info{display:inline;float:left;margin-right:2rem;font-style:italic}}#footer-post{position:fixed;right:0;bottom:0;left:0;z-index:5000000;width:100%;border-top:1px solid #666;background:#fafafa;transition:opacity .2s}#footer-post a{background:none;color:inherit;text-decoration:none}#footer-post a.icon{background:none}#footer-post a.icon:hover{color:#d480aa}#footer-post #nav-footer{padding-right:1rem;padding-left:1rem;background:#e6e6e6;text-align:center}#footer-post #nav-footer a{color:#2bbc8a;font-size:1em}#footer-post #nav-footer a:hover{background-image:linear-gradient(transparent, transparent 5px, #2bbc8a 5px, #2bbc8a);background-position:bottom;background-size:100% 6px;background-repeat:repeat-x}#footer-post #nav-footer ul{display:table;margin:0;padding:0;width:100%;list-style-type:none}#footer-post #nav-footer ul li{display:inline-table;padding:10px;width:20%;vertical-align:middle}#footer-post #actions-footer{overflow:auto;margin-top:1rem;margin-bottom:1rem;padding-right:1rem;padding-left:1rem;width:100%;text-align:center;white-space:nowrap}#footer-post #actions-footer a{display:inline-block;padding-left:1rem;color:#2bbc8a}#footer-post #share-footer{padding-right:1rem;padding-left:1rem;background:#e6e6e6;text-align:center}#footer-post #share-footer ul{display:table;margin:0;padding:0;width:100%;list-style-type:none}#footer-post #share-footer ul li{display:inline-table;padding:10px;width:20%;vertical-align:middle}#footer-post #toc-footer{clear:both;padding-top:1rem;padding-bottom:1rem;background:#e6e6e6;text-align:left}#footer-post #toc-footer #TableOfContents ul{margin:0;padding-left:20px;list-style-type:none}#footer-post #toc-footer #TableOfContents ul li{line-height:30px}#footer-post #toc-footer a:hover{color:#d480aa}#footer-post #toc-footer #TableOfContents>ul>li{color:#383838;font-size:.8rem}#footer-post #toc-footer #TableOfContents>ul>li:before{color:#2bbc8a;content:"#";margin-right:8px}#footer-post #toc-footer #TableOfContents>ul>li>ul>li{color:#666;font-size:.7rem;line-height:15px}#footer-post #toc-footer #TableOfContents>ul>li>ul>li:before{color:#2bbc8a;content:"·";font-weight:bold;margin-right:3px}#footer-post #toc-footer #TableOfContents>ul>li>ul>li>ul>li{display:none}@media screen and (min-width: 500px){#footer-post-container{display:none}}.post-list{padding:0}.post-list .post-item{margin-bottom:1rem;margin-left:0;list-style-type:none}.post-list .post-item .meta{display:block;margin-right:16px;min-width:100px;color:#666;font-size:14px}@media (min-width: 480px){.post-list .post-item{display:flex;margin-bottom:5px}.post-list .post-item .meta{text-align:left}}.project-list{padding:0;list-style:none}.project-list .project-item{margin-bottom:5px}.project-list .project-item p{display:inline}article header .posttitle{margin-top:0;margin-bottom:0;text-transform:none;font-size:1.5em;line-height:1.25}article header .meta{margin-top:0;margin-bottom:1rem}article header .meta *{color:#8c8c8c;font-size:.85rem}article header .author{text-transform:uppercase;letter-spacing:.01em;font-weight:700}article header .postdate{display:inline}article .content h2:before{position:absolute;top:-4px;left:-1rem;color:#2bbc8a;content:"#";font-weight:bold;font-size:1.2rem}article .content img,article .content video{display:block;margin:auto;max-width:100%;height:auto}article .content img .video-container,article .content video .video-container{position:relative;overflow:hidden;padding-top:56.25% e;height:0}article .content img .video-container iframe,article .content img .video-container object,article .content img .video-container embed,article .content video .video-container iframe,article .content video .video-container object,article .content video .video-container embed{position:absolute;top:0;left:0;margin-top:0;width:100%;height:100%}article .content img blockquote,article .content video blockquote{margin:1rem 10px;padding:.5em 10px;background:inherit;color:#2bbc8a;quotes:"\201C" "\201D" "\2018" "\2019";font-weight:bold}article .content img blockquote p,article .content video blockquote p{margin:0}article .content img blockquote:before,article .content video blockquote:before{margin-right:.25em;color:#2bbc8a;content:"\201C";vertical-align:-.4em;font-size:2em;line-height:.1em}article .content img blockquote footer,article .content video blockquote footer{margin:line-height 0;color:#666;font-size:11px}article .content img blockquote footer a,article .content video blockquote footer a{background-image:linear-gradient(transparent, transparent 5px, #666 5px, #666);color:#666}article .content img blockquote footer a:hover,article .content video blockquote footer a:hover{background-image:linear-gradient(transparent, transparent 4px, #999 4px, #999);color:#999}article .content img blockquote footer cite:before,article .content video blockquote footer cite:before{padding:0 .5em;content:"—"}article .content img .pullquote,article .content video .pullquote{margin:0;width:45%;text-align:left}article .content img .pullquote.left,article .content video .pullquote.left{margin-right:1em;margin-left:.5em}article .content img .pullquote.right,article .content video .pullquote.right{margin-right:.5em;margin-left:1em}article .content img .caption,article .content video .caption{position:relative;display:block;margin-top:.5em;color:#666;text-align:center;font-size:.9em}.posttitle{text-transform:none;font-size:1.5em;line-height:1.25}.article-tag .tag-link:before{content:"#";background-image:linear-gradient(transparent, transparent 10px, #d480aa 10px, #d480aa);background-position:bottom;background-size:100% 6px;background-repeat:repeat-x}.article-category .category-link{background-image:linear-gradient(transparent, transparent 10px, #d480aa 10px, #d480aa);background-position:bottom;background-size:100% 6px;background-repeat:repeat-x}@media (min-width: 480px){.article-read-time,.article-tag,.article-category{display:inline}.article-read-time:before,.article-tag:before,.article-category:before{content:"|"}}#archive .post-list{padding:0}#archive .post-list .post-item{margin-bottom:1rem;margin-left:0;list-style-type:none}#archive .post-list .post-item .meta{display:block;margin-right:16px;min-width:100px;color:#666;font-size:14px}@media (min-width: 480px){#archive .post-list .post-item{display:flex;margin-bottom:5px;margin-left:1rem}#archive .post-list .post-item .meta{text-align:left}}.blog-post-comments{margin-top:4rem}#footer{position:absolute;bottom:0;margin-bottom:10px;width:100%;color:#666;vertical-align:top;text-align:center;font-size:11px}#footer ul{margin:0;padding:0;list-style:none}#footer li{display:inline-block;margin-right:15px;border-right:1px solid;border-color:#666;vertical-align:middle}#footer li a{margin-right:15px}#footer li:last-child{margin-right:0;border-right:0}#footer li:last-child a{margin-right:0}#footer a{color:#666;text-decoration:underline;background-image:none}#footer a:hover{color:#999}#footer .footer-left{height:20px;vertical-align:middle;line-height:20px}@media (min-width: 39rem){#footer{display:flex;flex-flow:row wrap;justify-content:space-between;align-items:center;align-content:center;margin-bottom:20px}#footer .footer-left{align-self:flex-start;margin-right:20px}#footer .footer-right{align-self:flex-end}}.pagination{display:inline-block;margin-top:2rem;width:100%;text-align:center}.pagination .page-number{color:#383838;font-size:.8rem}.pagination a{padding:4px 6px;border-radius:5px;background-image:none;color:#383838;text-decoration:none}.pagination a:hover{background-image:none}.pagination a:hover:not(.active){color:#383838}.search-input{padding:4px 7px;width:100%;outline:none;border:solid 1px #8c8c8c;border-radius:5px;background-color:#fff;color:#383838;font-size:1.2rem;-webkit-border-radius:5px;-moz-border-radius:5px}.search-input:focus{border:solid 1px #2bbc8a}#search-result ul.search-result-list{padding:0;list-style-type:none}#search-result li{margin:2em auto}#search-result a.search-result-title{background-image:none;color:#383838;text-transform:capitalize;font-weight:bold;line-height:1.2}#search-result p.search-result{overflow:hidden;margin:.4em auto;max-height:13em;text-align:justify;font-size:.8em}#search-result em.search-keyword{border-bottom:1px dashed #d480aa;color:#d480aa;font-weight:bold}.search-no-result{display:none;padding-bottom:.5em;color:#383838}#tag-cloud .tag-cloud-title{color:#666}#tag-cloud .tag-cloud-tags{clear:both;text-align:center}#tag-cloud .tag-cloud-tags a{display:inline-block;margin:10px}.tooltipped{position:relative}.tooltipped::after{position:absolute;z-index:1000000;display:none;padding:.2em .5em;-webkit-font-smoothing:subpixel-antialiased;color:#fff;font-display:swap;font-weight:400;font-size:11.2px;font-family:"JetBrains Mono",monospace;line-height:1.725;text-rendering:geometricPrecision;text-align:center;word-wrap:break-word;white-space:pre;content:attr(aria-label);background:#383838;border-radius:3px;opacity:0}.tooltipped::before{position:absolute;z-index:1000001;display:none;width:0;height:0;color:#383838;pointer-events:none;content:'';border:6px solid transparent;opacity:0}@keyframes tooltip-appear{from{opacity:0}to{opacity:1}}.tooltipped:hover::before,.tooltipped:hover::after,.tooltipped:active::before,.tooltipped:active::after,.tooltipped:focus::before,.tooltipped:focus::after{display:inline-block;text-decoration:none;animation-name:tooltip-appear;animation-duration:0.1s;animation-fill-mode:forwards;animation-timing-function:ease-in}.tooltipped-s::after,.tooltipped-sw::after{top:100%;right:50%;margin-top:6px}.tooltipped-s::before,.tooltipped-sw::before{top:auto;right:50%;bottom:-7px;margin-right:-6px;border-bottom-color:#383838}.tooltipped-sw::after{margin-right:-16px}.tooltipped-s::after{transform:translateX(50%)}#categories .category-list-title{color:#666}#categories .category-list .category-list-item .category-list-count{color:#666}#categories .category-list .category-list-item .category-list-count:before{content:" ("}#categories .category-list .category-list-item .category-list-count:after{content:")"}pre{overflow-x:auto;padding:15px 15px 10px 15px;border:1px dotted #666;border-radius:2px;-webkit-border-radius:2px;font-size:13px;font-family:"JetBrains Mono",monospace;line-height:22px;position:relative}pre .code-copy-btn{position:absolute;top:0;right:0;border:0;border-radius:0 2px;padding:0;font-family:"JetBrains Mono", monospace;font-weight:800;font-size:0.9em;line-height:1.7;color:#fff;background-color:#8c8c8c;min-width:60px;text-align:center;cursor:pointer;letter-spacing:0em}pre .code-copy-btn:hover{background-color:#666;color:#2bbc8a}pre code{display:block;padding:0;border:none}code{font-family:"JetBrains Mono",monospace;padding:0 5px;border:1px dotted #666;border-radius:2px;-webkit-border-radius:2px}.highlight>div{border-radius:2px;-webkit-border-radius:2px}.highlight pre{border:none;background:none}.highlight table pre{margin-top:0}.highlight table td:first-child pre{padding-right:0}.highlight table td:last-child pre{padding-left:0}
/*# sourceMappingURL=styles.css.map */ \ No newline at end of file
diff --git a/exampleSite/resources/_gen/assets/scss/scss/style.scss_17a317b87063135b4df76ed814d78726.json b/exampleSite/resources/_gen/assets/scss/scss/style.scss_17a317b87063135b4df76ed814d78726.json
index eefeca3..bb64c4f 100644
--- a/exampleSite/resources/_gen/assets/scss/scss/style.scss_17a317b87063135b4df76ed814d78726.json
+++ b/exampleSite/resources/_gen/assets/scss/scss/style.scss_17a317b87063135b4df76ed814d78726.json
@@ -1 +1 @@
-{"Target":"css/styles.4704252c772b8b476694c4d903a90851367795c23ca2c2342f087653102167e53f161f8a5681694dfd29c10102705e6d54e8c68edb3b229cbf28b51fba4c8925.css","MediaType":"text/css","Data":{"Integrity":"sha512-RwQlLHcri0dmlMTZA6kIUTZ3lcI8osI0Lwh2UxAhZ+U/Fh+KVoFpTf0pwQECcF5tVOjGjts7Ipy/KLUfukyJJQ=="}} \ No newline at end of file
+{"Target":"css/styles.d23bd7196808bd99fe59825763bf82094481bfa34a9dae09a0d5533e47dd4d51fac9ec450dedb08f25a476777eb202998613128da8c2012ca09fd736de1aeec3.css","MediaType":"text/css","Data":{"Integrity":"sha512-0jvXGWgIvZn+WYJXY7+CCUSBv6NKna4JoNVTPkfdTVH6yexFDe2wjyWkdnd+sgKZhhMSjajCASygn9c23hruww=="}} \ No newline at end of file
diff --git a/layouts/posts/single.html b/layouts/posts/single.html
index bbf36e5..fb6a6b4 100644
--- a/layouts/posts/single.html
+++ b/layouts/posts/single.html
@@ -85,6 +85,7 @@
<link rel="stylesheet" href={{ "/lib/font-awesome/css/all.min.css" | relURL }}>
<script src={{ "/lib/jquery/jquery.min.js" | relURL }}></script>
<script src={{ "/js/main.js" | relURL }}></script>
+<script src={{ "js/code-copy.js" | relURL }}></script>
{{ $mathjax := false }}
{{ if isset .Params "mathjax" }}
{{ $mathjax = .Params.mathjax }}
diff --git a/static/js/code-copy.js b/static/js/code-copy.js
new file mode 100644
index 0000000..5a07bf8
--- /dev/null
+++ b/static/js/code-copy.js
@@ -0,0 +1,36 @@
+(() => {
+
+ function createCopyButton(codeNode) {
+ const copyBtn = document.createElement('button')
+ copyBtn.className = 'code-copy-btn'
+ copyBtn.type = 'button'
+ copyBtn.innerText = 'copy'
+
+ let resetTimer
+ copyBtn.addEventListener('click', () => {
+ navigator.clipboard.writeText(codeNode.innerText).then(() => {
+ copyBtn.innerText = 'copied!'
+ }).then(() => {
+ clearTimeout(resetTimer)
+ resetTimer = setTimeout(() => {
+ copyBtn.innerText = 'copy'
+ }, 1000)
+ })
+ })
+
+ return copyBtn
+ }
+
+ document.querySelectorAll('pre > code')
+ .forEach((codeNode) => {
+ const copyBtn = createCopyButton(codeNode);
+ const preNode = codeNode.parentNode
+ codeNode.parentNode.insertBefore(copyBtn, codeNode)
+ })
+
+ document.querySelectorAll('.highlight table > tbody > tr > td:first-child .code-copy-btn')
+ .forEach((btn) => {
+ btn.remove()
+ })
+
+})() \ No newline at end of file