jekyll-theme-satellite 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +21 -0
  3. data/_config.yml +82 -0
  4. data/_includes/loading.html +6 -0
  5. data/_includes/navigation.html +84 -0
  6. data/_includes/pagination.html +71 -0
  7. data/_includes/post.html +65 -0
  8. data/_includes/search.html +21 -0
  9. data/_includes/sidebar.html +83 -0
  10. data/_layouts/default.html +113 -0
  11. data/_sass/darkmode.scss +211 -0
  12. data/_sass/layout.scss +57 -0
  13. data/_sass/navigation.scss +178 -0
  14. data/_sass/pagination.scss +253 -0
  15. data/_sass/post.scss +640 -0
  16. data/_sass/search.scss +248 -0
  17. data/_sass/sidebar.scss +309 -0
  18. data/_sass/toc.scss +52 -0
  19. data/_sass/vars.scss +15 -0
  20. data/assets/css/highlight-dark.min.css +1 -0
  21. data/assets/css/highlight-default.min.css +1 -0
  22. data/assets/css/style.scss +89 -0
  23. data/assets/fonts/Lato-Regular.ttf +0 -0
  24. data/assets/fonts/NunitoSans-Regular.ttf +0 -0
  25. data/assets/fonts/Righteous-Regular.ttf +0 -0
  26. data/assets/img/La-Mancha.jpg +0 -0
  27. data/assets/img/example.jpg +0 -0
  28. data/assets/img/favicon.webp +0 -0
  29. data/assets/img/icon/book-solid.svg +1 -0
  30. data/assets/img/icon/calendar-days-regular.svg +1 -0
  31. data/assets/img/icon/clipboard-regular.svg +1 -0
  32. data/assets/img/icon/folder-open-regular.svg +1 -0
  33. data/assets/img/icon/tags-solid.svg +1 -0
  34. data/assets/img/loading.webp +0 -0
  35. data/assets/img/profile.jpg +0 -0
  36. data/assets/img/sorry.png +0 -0
  37. data/assets/img/thumbnail/book.jpg +0 -0
  38. data/assets/img/thumbnail/bricks.webp +0 -0
  39. data/assets/img/thumbnail/empty.jpg +0 -0
  40. data/assets/img/thumbnail/nightgardenflower.jpg +0 -0
  41. data/assets/img/thumbnail/sample.png +0 -0
  42. data/assets/img/tile.png +0 -0
  43. data/assets/js/404.js +22 -0
  44. data/assets/js/highlight.min.js +1213 -0
  45. data/assets/js/main.js +709 -0
  46. data/assets/js/stars.js +700 -0
  47. data/assets/js/sweet-scroll.min.js +2 -0
  48. data/assets/js/tocbot.min.js +1 -0
  49. metadata +104 -0
data/assets/js/main.js ADDED
@@ -0,0 +1,709 @@
1
+ document.addEventListener('DOMContentLoaded', function(){
2
+ // Loading page
3
+ window.addEventListener("load", () => {
4
+ var load_div = document.querySelector('#loading');
5
+
6
+ if(load_div != null){
7
+ setTimeout(function(){
8
+ load_div.style.transition = '.75s';
9
+ load_div.style.opacity = '0';
10
+ load_div.style.visibility = 'hidden';
11
+ }, 800);
12
+ }
13
+ });
14
+
15
+ // Lazy image loading
16
+ var content = document.querySelector('main');
17
+
18
+ if (content){
19
+ var images = content.querySelectorAll('img');
20
+
21
+ images.forEach((img) => {
22
+ img.setAttribute('loading', 'lazy');
23
+ });
24
+ }
25
+
26
+ function loadImage(image) {
27
+ var i = new Image();
28
+
29
+ i.onload = function() {
30
+ image.classList.add('lazy-loaded')
31
+ image.src = image.dataset.lazySrc
32
+ }
33
+
34
+ i.onerror = function() {image.classList.add('lazy-error')}
35
+ i.src = image.dataset.lazySrc
36
+ }
37
+
38
+ function onIntersection(entries) {
39
+ for (var e in entries) {
40
+ if(entries[e].intersectionRatio <= 0) continue
41
+ observer.unobserve(entries[e].target) // Stop watching
42
+ loadImage(entries[e].target)
43
+ }
44
+ }
45
+
46
+
47
+
48
+ // navigation (mobile)
49
+ var siteNav = document.querySelector('#navigation');
50
+ var siteContact = document.querySelector('#contact');
51
+ var menuButton = document.querySelector("#btn-nav");
52
+
53
+ menuButton.addEventListener('click', function() {
54
+ if (menuButton.classList.toggle('nav-open')) {
55
+ siteNav.classList.add('nav-open');
56
+ siteContact.classList.add('contact-open');
57
+ } else {
58
+ siteNav.classList.remove('nav-open');
59
+ siteContact.classList.remove('contact-open');
60
+ }
61
+ });
62
+
63
+ // kept nav opened
64
+ var firstNavs = document.querySelectorAll('#nav-first');
65
+ var page_path = window.location.pathname.replace(/%20/g, " ");
66
+ var page_tree = page_path.split('/');
67
+
68
+ Array.prototype.forEach.call(firstNavs, function (nav_first) {
69
+ if (page_tree[1] === nav_first.ariaLabel){
70
+ nav_first.classList.add('active');
71
+
72
+ var secondNavs = nav_first.querySelectorAll('#nav-second');
73
+
74
+ Array.prototype.forEach.call(secondNavs, function (nav_second) {
75
+ if (page_tree[2] === nav_second.ariaLabel){
76
+ nav_second.classList.toggle('active');
77
+
78
+ var thirdNavs = nav_second.querySelectorAll('#nav-third');
79
+
80
+ Array.prototype.forEach.call(thirdNavs, function (nav_third) {
81
+ if (page_tree[3] === nav_third.ariaLabel){
82
+ nav_third.classList.toggle('active');
83
+ }
84
+ });
85
+ }
86
+ });
87
+ }
88
+ });
89
+
90
+ // navigation (toogle sub-category)
91
+ document.addEventListener('click', function(e){
92
+ var target = e.target;
93
+
94
+ while (target && !(target.classList && target.classList.contains('nav-list-expander'))) {
95
+ target = target.parentNode;
96
+ }
97
+
98
+ if (target) {
99
+ e.preventDefault();
100
+ var nav_item = target.parentNode;
101
+ target.ariaPressed = nav_item.parentNode.classList.toggle('active');
102
+ }
103
+ });
104
+
105
+ document.querySelectorAll('.nav-item').forEach((nav_item) => {
106
+ if (nav_item.parentNode.classList.contains('active')){
107
+ nav_item.classList.add('selected');
108
+ }
109
+ else {
110
+ nav_item.classList.remove('selected');
111
+ }
112
+ });
113
+
114
+ // tocbot
115
+ //var content = document.querySelector('main');
116
+
117
+ if (content){
118
+ var headings = content.querySelectorAll('h1, h2');
119
+ var headingMap = {};
120
+
121
+ Array.prototype.forEach.call(headings, function (heading) {
122
+ var id = heading.id ? heading.id : heading.textContent.trim().toLowerCase()
123
+ .split(' ').join('-').replace(/[\!\@\#\$\%\^\&\*\(\):]/ig, '');
124
+
125
+ headingMap[id] = !isNaN(headingMap[id]) ? ++headingMap[id] : 0;
126
+
127
+ if (headingMap[id]) {
128
+ heading.id = id + '-' + headingMap[id];
129
+ } else {
130
+ heading.id = id;
131
+ }
132
+ })
133
+
134
+ tocbot.init({
135
+ tocSelector: '.toc-board',
136
+ contentSelector: '.inner-content',
137
+ headingSelector:'h1, h2',
138
+ hasInnerContainers: false
139
+ });
140
+ }
141
+
142
+ // link (for hover effect)
143
+ if (content){
144
+ var links = content.querySelectorAll('a');
145
+
146
+ links.forEach((link) => {
147
+ link.setAttribute('data-content', link.innerText);
148
+ });
149
+ }
150
+
151
+ // pagination
152
+ const paginationNumbers = document.querySelector("#pagination-numbers");
153
+ const paginatedList = document.querySelector(".paginated-list");
154
+
155
+ if (paginatedList) {
156
+ const listItems = paginatedList.querySelectorAll("li");
157
+ const nextButton = document.querySelector("#next-button");
158
+ const prevButton = document.querySelector("#prev-button");
159
+ const pageKey = "pageKey=" + document.URL;
160
+
161
+ const paginationLimit = 5;
162
+ const pageCount = Math.ceil(listItems.length / paginationLimit);
163
+ let currentPage = 1;
164
+
165
+ const disableButton = (button) => {
166
+ button.classList.add("disabled");
167
+ button.setAttribute("disabled", true);
168
+ };
169
+
170
+ const enableButton = (button) => {
171
+ button.classList.remove("disabled");
172
+ button.removeAttribute("disabled");
173
+ };
174
+
175
+ const handlePageButtonsStatus = () => {
176
+ if (currentPage === 1) {
177
+ disableButton(prevButton);
178
+ } else {
179
+ enableButton(prevButton);
180
+ }
181
+
182
+ if (pageCount === currentPage) {
183
+ disableButton(nextButton);
184
+ } else {
185
+ enableButton(nextButton);
186
+ }
187
+ };
188
+
189
+ const handleActivePageNumber = () => {
190
+ document.querySelectorAll(".pagination-number").forEach((button) => {
191
+ button.classList.remove("active");
192
+
193
+ const pageIndex = Number(button.getAttribute("page-index"));
194
+
195
+ if (pageIndex == currentPage) {
196
+ button.classList.add("active");
197
+ }
198
+ });
199
+ };
200
+
201
+ const appendPageNumber = (index) => {
202
+ const pageNumber = document.createElement("button");
203
+
204
+ pageNumber.className = "pagination-number";
205
+ pageNumber.innerHTML = index;
206
+ pageNumber.setAttribute("page-index", index);
207
+ pageNumber.setAttribute("aria-label", "Page " + index);
208
+
209
+ paginationNumbers.appendChild(pageNumber);
210
+ };
211
+
212
+ const getPaginationNumbers = () => {
213
+ for (let i = 1; i <= pageCount; i++) {
214
+ appendPageNumber(i);
215
+ }
216
+ };
217
+
218
+ const setCurrentPage = (pageNum) => {
219
+ currentPage = pageNum;
220
+
221
+ handleActivePageNumber();
222
+ handlePageButtonsStatus();
223
+
224
+ const prevRange = (pageNum - 1) * paginationLimit;
225
+ const currRange = pageNum * paginationLimit;
226
+
227
+ listItems.forEach((item, index) => {
228
+ item.classList.add("hidden");
229
+
230
+ if (index >= prevRange && index < currRange) {
231
+ item.classList.remove("hidden");
232
+ }
233
+ });
234
+
235
+ $('html, body').scrollTop(0);
236
+ localStorage.setItem(pageKey, currentPage);
237
+ };
238
+
239
+ window.addEventListener("load", (event) => {
240
+ // Load last visited page number
241
+ if (event.persisted
242
+ || (window.performance && window.performance.navigation.type == 2)) {
243
+ currentPage = localStorage.getItem(pageKey);
244
+ }
245
+
246
+ getPaginationNumbers();
247
+ setCurrentPage(currentPage);
248
+
249
+ prevButton.addEventListener("click", () => {
250
+ setCurrentPage(currentPage - 1);
251
+ });
252
+
253
+ nextButton.addEventListener("click", () => {
254
+ setCurrentPage(currentPage + 1);
255
+ });
256
+
257
+ document.querySelectorAll(".pagination-number").forEach((button) => {
258
+ const pageIndex = Number(button.getAttribute("page-index"));
259
+
260
+ if (pageIndex) {
261
+ button.addEventListener("click", () => {
262
+ setCurrentPage(pageIndex);
263
+ });
264
+ }
265
+ });
266
+ });
267
+ }
268
+
269
+ // code clipboard copy button
270
+ async function copyCode(block) {
271
+ let code = block.querySelector("code");
272
+ let text = code.innerText;
273
+
274
+ await navigator.clipboard.writeText(text);
275
+ }
276
+
277
+ let blocks = document.querySelectorAll("pre");
278
+
279
+ blocks.forEach((block) => {
280
+ // only add button if browser supports Clipboard API
281
+ if (navigator.clipboard) {
282
+ let clip_btn = document.createElement("button");
283
+ let clip_img = document.createElement("svg");
284
+
285
+ clip_btn.setAttribute('title', "Copy Code");
286
+ clip_img.ariaHidden = true;
287
+
288
+ block.appendChild(clip_btn);
289
+ clip_btn.appendChild(clip_img);
290
+
291
+ clip_btn.addEventListener("click", async () => {
292
+ await copyCode(block, clip_btn);
293
+ });
294
+ }
295
+ });
296
+
297
+ // dark mode
298
+ let currentTheme = localStorage.getItem('theme');
299
+ let isDarkMode = false;
300
+
301
+ if (currentTheme === 'dark'){
302
+ isDarkMode = true;
303
+ document.body.classList.add('dark-theme');
304
+
305
+ const moonIcons = document.querySelectorAll(".ico-dark");
306
+ const sunIcons = document.querySelectorAll(".ico-light");
307
+
308
+ moonIcons.forEach((ico) => {
309
+ ico.classList.add('active');
310
+ });
311
+
312
+ sunIcons.forEach((ico) => {
313
+ ico.classList.add('active');
314
+ });
315
+
316
+ // Disable highlighter default color theme
317
+ document.getElementById("highlight-default").disabled=true;
318
+ }
319
+ else {
320
+ isDarkMode = false;
321
+ // Disable highlighter dark color theme
322
+ document.getElementById("highlight-dark").disabled=true;
323
+ }
324
+
325
+ const themeButton = document.querySelectorAll("#btn-brightness");
326
+
327
+ themeButton.forEach((btn) => {
328
+ btn.addEventListener('click', function() {
329
+ const moonIcons = document.querySelectorAll(".btn-dark");
330
+ const sunIcons = document.querySelectorAll(".btn-light");
331
+
332
+ moonIcons.forEach((ico) => {
333
+ ico.classList.toggle('active');
334
+ });
335
+
336
+ sunIcons.forEach((ico) => {
337
+ ico.classList.toggle('active');
338
+ });
339
+
340
+ document.body.classList.toggle('dark-theme');
341
+
342
+ if (isDarkMode){
343
+ localStorage.setItem('theme', 'default');
344
+ // Disable highlighter dark color theme
345
+ document.getElementById("highlight-default").disabled=false;
346
+ document.getElementById("highlight-dark").disabled=true;
347
+ changeGiscusTheme('light');
348
+ isDarkMode = false;
349
+ }
350
+ else {
351
+ localStorage.setItem('theme', 'dark');
352
+ // Disable highlighter default color theme
353
+ document.getElementById("highlight-default").disabled=true;
354
+ document.getElementById("highlight-dark").disabled=false;
355
+ changeGiscusTheme('noborder_gray');
356
+ isDarkMode = true;
357
+ }
358
+ });
359
+ });
360
+
361
+ // Initialize/Change Giscus theme
362
+ const commentBox = document.getElementById('giscus');
363
+
364
+ if (commentBox) {
365
+ var giscusUserInfos = [];
366
+ var giscusTheme = "light";
367
+
368
+ $.getJSON('/giscus.json', function (data) {
369
+ giscusUserInfos = data[0];
370
+ })
371
+ .done(function() {
372
+ console.log('getJSON request succeeded! [giscus.json]');
373
+
374
+ if (giscusUserInfos.repo === '') return;
375
+
376
+ if (currentTheme === 'dark'){
377
+ giscusTheme = "noborder_gray";
378
+ }
379
+
380
+ let giscusAttributes = {
381
+ "src": "https://giscus.app/client.js",
382
+ "data-repo": giscusUserInfos.repo,
383
+ "data-repo-id": giscusUserInfos.repoId,
384
+ "data-category": giscusUserInfos.category,
385
+ "data-category-id": giscusUserInfos.categoryId,
386
+ "data-mapping": "pathname",
387
+ "data-reactions-enabled": "1",
388
+ "data-emit-metadata": "1",
389
+ "data-theme": giscusTheme,
390
+ "data-lang": "en",
391
+ "crossorigin": "anonymous",
392
+ "async": "",
393
+ };
394
+
395
+ let giscusScript = document.createElement("script");
396
+ Object.entries(giscusAttributes).forEach(([key, value]) => giscusScript.setAttribute(key, value));
397
+ document.body.appendChild(giscusScript);
398
+ })
399
+ .fail(function(jqXHR, textStatus, errorThrown) { console.log('getJSON request failed! [giscus.json] ' + textStatus); })
400
+ .always(function() { console.log('getJSON request ended! [giscus.json]'); });
401
+
402
+ // Giscus IMetadataMessage event handler
403
+ function handleMessage(event) {
404
+ if (event.origin !== 'https://giscus.app') return;
405
+ if (!(typeof event.data === 'object' && event.data.giscus)) return;
406
+
407
+ const giscusData = event.data.giscus;
408
+
409
+ if (giscusData && giscusData.hasOwnProperty('discussion')) {
410
+ $('#num-comments').text(giscusData.discussion.totalCommentCount);
411
+ }
412
+ else {
413
+ $('#num-comments').text('0');
414
+ }
415
+ }
416
+
417
+ window.addEventListener('message', handleMessage);
418
+ }
419
+
420
+ function changeGiscusTheme(theme) {
421
+ const iframe = document.querySelector('iframe.giscus-frame');
422
+ if (!iframe) return;
423
+
424
+ const message = {
425
+ setConfig: {
426
+ theme: theme
427
+ }
428
+ };
429
+
430
+ iframe.contentWindow.postMessage({ giscus: message }, 'https://giscus.app');
431
+ }
432
+
433
+ // search box
434
+ const searchButton = document.querySelectorAll("#btn-search");
435
+ const cancelButton = document.querySelector('#btn-clear');
436
+ const searchPage = document.querySelector("#search");
437
+
438
+ if (searchButton) {
439
+ searchButton.forEach((btn) => {
440
+ btn.addEventListener('click', function() {
441
+ searchPage.classList.add('active');
442
+ $('#search-input').focus();
443
+ });
444
+ });
445
+ }
446
+
447
+ if (searchPage) {
448
+ searchPage.addEventListener('click', function(event) {
449
+ const searchBar = document.querySelector(".search-box");
450
+ var target = event.target;
451
+
452
+ if (searchBar.contains(target))
453
+ return;
454
+
455
+ searchPage.classList.remove('active');
456
+ });
457
+ }
458
+
459
+ var posts = [];
460
+
461
+ $.getJSON('/search.json', function (data) {
462
+ posts = data;
463
+ })
464
+ .done(function() {
465
+ console.log('getJSON request succeeded! [search.json]');
466
+
467
+ // Related Posts
468
+ displayRelatedPosts(posts);
469
+ })
470
+ .fail(function(jqXHR, textStatus, errorThrown) { console.log('getJSON request failed! [search.json] ' + textStatus); })
471
+ .always(function() { console.log('getJSON request ended! [search.json]'); });
472
+
473
+ $('#search-input').on('keyup', function () {
474
+ var keyword = this.value.toLowerCase();
475
+ var searchResult = [];
476
+
477
+ if (keyword.length > 0) {
478
+ $('#search-result').show();
479
+ $('#btn-clear').show();
480
+ } else {
481
+ $('#search-result').hide();
482
+ $('#btn-clear').hide();
483
+ }
484
+
485
+ $('.result-item').remove();
486
+
487
+ for (var i = 0; i < posts.length; i++) {
488
+ var post = posts[i];
489
+
490
+ if (post.title === 'Home' && post.type == 'category') continue;
491
+
492
+ if (post.title.toLowerCase().indexOf(keyword) >= 0
493
+ || post.path.toLowerCase().indexOf(keyword) >= 0
494
+ || post.tags.toLowerCase().indexOf(keyword) >= 0){
495
+ searchResult.push(post);
496
+ }
497
+ }
498
+
499
+ if (searchResult.length === 0) {
500
+ $('#search-result').append(
501
+ '<li class="result-item"><span class="description">There is no search result.</span></li>'
502
+ );
503
+
504
+ return;
505
+ }
506
+
507
+ searchResult.sort(function (a, b) {
508
+ if (a.type == 'category') return 1;
509
+
510
+ return -1;
511
+ });
512
+
513
+ for (var i = 0; i < searchResult.length; i++) {
514
+ var highlighted_path = highlightKeyword(searchResult[i].path, keyword);
515
+
516
+ if (highlighted_path === '')
517
+ highlighted_path = "Home";
518
+
519
+ if (searchResult[i].type === 'post'){
520
+ var highlighted_title = highlightKeyword(searchResult[i].title, keyword);
521
+ var highlighted_tags = highlightKeyword(searchResult[i].tags, keyword);
522
+
523
+ if (highlighted_tags === '')
524
+ highlighted_tags = "none";
525
+
526
+ $('#search-result').append(
527
+ '<li class="result-item"><a href="' +
528
+ searchResult[i].url +
529
+ '"><table><thead><tr><th><svg class="ico-book"></svg></th><th>' + highlighted_title +
530
+ '</th></tr></thead><tbody><tr><td><svg class="ico-folder"></svg></td><td>' + highlighted_path +
531
+ '</td></tr><tr><td><svg class="ico-tags"></svg></td><td>' + highlighted_tags +
532
+ '</td></tr><tr><td><svg class="ico-calendar"></svg></td><td>' + searchResult[i].date +
533
+ '</td></tr></tbody></table></a></li>'
534
+ );
535
+ }
536
+ else {
537
+ $('#search-result').append(
538
+ '<li class="result-item"><a href="' +
539
+ searchResult[i].url +
540
+ '"><table><thead><tr><th><svg class="ico-folder"></svg></th><th>' + highlighted_path +
541
+ '</th></tr></thead></table></a></li>'
542
+ );
543
+ }
544
+ }
545
+ });
546
+
547
+ if (cancelButton) {
548
+ cancelButton.addEventListener('click', function() {
549
+ $('.result-item').remove();
550
+ $('#search-input').val("");
551
+ $('#btn-clear').hide();
552
+ });
553
+ }
554
+
555
+ function highlightKeyword(txt, keyword) {
556
+ var index = txt.toLowerCase().lastIndexOf(keyword);
557
+
558
+ if (index >= 0) {
559
+ out = txt.substring(0, index) +
560
+ "<span class='highlight'>" +
561
+ txt.substring(index, index+keyword.length) +
562
+ "</span>" +
563
+ txt.substring(index + keyword.length);
564
+ return out;
565
+ }
566
+
567
+ return txt;
568
+ }
569
+
570
+ // Tag EventListener
571
+ document.querySelectorAll('.tag-box').forEach(function(tagButton){
572
+ tagButton.addEventListener('click', function() {
573
+ const contentID = tagButton.getAttribute('contentID');
574
+ searchPage.classList.add('active');
575
+
576
+ $('#search-input').val(contentID);
577
+ $('#search-input').trigger('keyup');
578
+ });
579
+ });
580
+
581
+ // Related Posts
582
+ function displayRelatedPosts(pages){
583
+ const refBox = document.getElementById('related-box');
584
+
585
+ if (!refBox) return;
586
+
587
+ var relatedPosts = [];
588
+ var currPost = pages.find(obj => {return obj.url === location.pathname});
589
+
590
+ let currTags = currPost.tags.split(', ');
591
+ let currCategory = currPost.path.split(' > ').pop();
592
+
593
+ for (var i = 0; i < pages.length; i++) {
594
+ let page = pages[i];
595
+
596
+ if (page.type === 'category') continue;
597
+
598
+ if (page.title === currPost.title) continue;
599
+
600
+ let tags = page.tags.split(', ');
601
+ let category = page.path.split(' > ').pop();
602
+ let correlationScore = 0;
603
+
604
+ for (var j = 0; j < currTags.length; j++){
605
+ if (tags.indexOf(currTags[j]) != -1) correlationScore += 1;
606
+ }
607
+
608
+ if (category === currCategory) correlationScore += 1;
609
+
610
+ if (correlationScore == 0) continue;
611
+
612
+ relatedPosts.push({
613
+ 'title': page.title,
614
+ 'date': page.date,
615
+ 'category': category,
616
+ 'url': page.url,
617
+ 'thumbnail': page.image,
618
+ 'score': correlationScore
619
+ });
620
+ }
621
+
622
+ relatedPosts.sort(function (a, b) {
623
+ if(a.hasOwnProperty('score')){
624
+ return b.score - a.score;
625
+ }
626
+ });
627
+
628
+ if (relatedPosts.length == 0){
629
+ $('#related-box').hide();
630
+ return;
631
+ }
632
+
633
+ for (var i = 0; i < Math.min(relatedPosts.length, 6); i++){
634
+ let post = relatedPosts[i];
635
+ let date = '-';
636
+ let category = 'No category';
637
+
638
+ if (post.date !== '1900-01-01'){
639
+ date = new Date(post.date);
640
+ date = date.toLocaleString('en-US', {day: 'numeric', month:'long', year:'numeric'});
641
+ }
642
+
643
+ if (post.category !== '') category = post.category;
644
+
645
+ if (post.thumbnail === ''){
646
+ post.thumbnail = "/assets/img/thumbnail/empty.jpg";
647
+ }
648
+
649
+ $('#related-posts').append(
650
+ '<li class="related-item"><a href="' + post.url +
651
+ '"><img src="' + post.thumbnail +
652
+ '"/><p class="category">' + category +
653
+ '</p><p class="title">' + post.title +
654
+ '</p><p class="date">' + date +
655
+ '</p></a></li>'
656
+ );
657
+ }
658
+ }
659
+
660
+ // Page Hits
661
+ const pageHits = document.getElementById('page-hits');
662
+
663
+ if (pageHits) {
664
+ const goatcounterCode = pageHits.getAttribute('usercode');
665
+ const requestURL = 'https://'
666
+ + goatcounterCode
667
+ + '.goatcounter.com/counter/'
668
+ + encodeURIComponent(location.pathname)
669
+ + '.json';
670
+
671
+ var resp = new XMLHttpRequest();
672
+ resp.open('GET', requestURL);
673
+ resp.onerror = function() { pageHits.innerText = "0"; };
674
+ resp.onload = function() { pageHits.innerText = JSON.parse(this.responseText).count; };
675
+ resp.send();
676
+ }
677
+
678
+ // Sweat Scroll
679
+ const scroller = new SweetScroll({
680
+ /* some options */
681
+ });
682
+
683
+ // Move to Top
684
+ if (document.querySelector('.thumbnail')){
685
+ const arrowButton = document.querySelector('.top-arrow');
686
+
687
+ setInterval(function(){
688
+ var scrollPos = document.documentElement.scrollTop;
689
+ console.log(scrollPos);
690
+
691
+ if (scrollPos < 512){
692
+ arrowButton.classList.remove('arrow-open');
693
+ }
694
+ else {
695
+ arrowButton.classList.add('arrow-open');
696
+ }
697
+ }, 1000);
698
+ }
699
+
700
+ // Code highlighter
701
+ hljs.highlightAll();
702
+
703
+ // Disable code highlights to the plaintext codeblocks
704
+ document.querySelectorAll('.language-text, .language-plaintext').forEach(function(codeblock){
705
+ codeblock.querySelectorAll('.hljs-keyword, .hljs-meta, .hljs-selector-tag').forEach(function($){
706
+ $.outerHTML = $.innerHTML;
707
+ });
708
+ });
709
+ });