first commit
29
Jenkinsfile
vendored
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
pipeline {
|
||||||
|
agent any
|
||||||
|
environment {
|
||||||
|
DEPLOY_PATH = '/var/www/codejava.tech'
|
||||||
|
}
|
||||||
|
stages {
|
||||||
|
stage('Build') {
|
||||||
|
steps {
|
||||||
|
sh 'hugo --minify'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stage('Deploy') {
|
||||||
|
steps {
|
||||||
|
sh '''
|
||||||
|
rsync -az --delete -e "ssh -o StrictHostKeyChecking=no" \
|
||||||
|
public/ root@172.17.0.1:${DEPLOY_PATH}/
|
||||||
|
'''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
post {
|
||||||
|
success {
|
||||||
|
echo 'Deployment successful! Visit https://codejava.tech'
|
||||||
|
}
|
||||||
|
failure {
|
||||||
|
echo 'Deployment failed!'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
5
archetypes/default.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
+++
|
||||||
|
date = '{{ .Date }}'
|
||||||
|
draft = true
|
||||||
|
title = '{{ replace .File.ContentBaseName "-" " " | title }}'
|
||||||
|
+++
|
||||||
5
go.mod
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
module git.fymio.us/me/codejava.tech
|
||||||
|
|
||||||
|
go 1.25.7
|
||||||
|
|
||||||
|
require github.com/imfing/hextra v0.11.1 // indirect
|
||||||
2
go.sum
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
github.com/imfing/hextra v0.11.1 h1:8pTc4ReYbzGTHAnyiebmlT3ijFfIXiGu1r7tM/UGjFI=
|
||||||
|
github.com/imfing/hextra v0.11.1/go.mod h1:cEfel3lU/bSx7lTE/+uuR4GJaphyOyiwNR3PTqFTXpI=
|
||||||
17
hugo.toml
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
baseURL = 'https://codejava.tech/'
|
||||||
|
title = 'CodeJava'
|
||||||
|
theme = 'github.com/imfing/hextra'
|
||||||
|
|
||||||
|
[menu]
|
||||||
|
[[menu.main]]
|
||||||
|
name = 'Courses'
|
||||||
|
pageRef = '/courses'
|
||||||
|
weight = 1
|
||||||
|
[[menu.main]]
|
||||||
|
name = 'Search'
|
||||||
|
weight = 2
|
||||||
|
[menu.main.params]
|
||||||
|
type = 'search'
|
||||||
|
|
||||||
|
[params]
|
||||||
|
description = 'Learn Java programming'
|
||||||
40
public/404.html
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<script src="/livereload.js?mindelay=10&v=2&port=1313&path=livereload" data-no-instant defer></script><body
|
||||||
|
style='font-family:system-ui,"Segoe UI",Roboto,Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji"; height:100vh; text-align:center; display:flex; flex-direction:column; align-items:center; justify-content:center'
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
color: #000;
|
||||||
|
background: #fff;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hextra-error-h1 {
|
||||||
|
border-right: 1px solid rgba(0, 0, 0, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
body {
|
||||||
|
color: #fff;
|
||||||
|
background: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hextra-error-h1 {
|
||||||
|
border-right: 1px solid rgba(255, 255, 255, 0.3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<h1
|
||||||
|
class="hextra-error-h1"
|
||||||
|
style='display: inline-block; margin: 0 20px 0 0; padding-right: 23px; font-size: 24px; font-weight: 500; vertical-align: top; line-height: 49px; font-feature-settings: "rlig" 1,"calt" 1,"ss01" 1,"ss06" 1 !important;'
|
||||||
|
>
|
||||||
|
404
|
||||||
|
</h1>
|
||||||
|
<div style="display: inline-block; text-align: left">
|
||||||
|
<h2 style="font-size: 14px; font-weight: 400; line-height: 49px; margin: 0">This page could not be found.</h2>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
BIN
public/android-chrome-192x192.png
Normal file
|
After Width: | Height: | Size: 7.1 KiB |
BIN
public/android-chrome-512x512.png
Normal file
|
After Width: | Height: | Size: 27 KiB |
BIN
public/apple-touch-icon.png
Normal file
|
After Width: | Height: | Size: 6.4 KiB |
19
public/casts/demo.cast
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
{"version": 2, "width": 80, "height": 24, "timestamp": 1640995200, "env": {"TERM": "xterm-256color", "SHELL": "/bin/bash"}, "title": "Demo Terminal Session"}
|
||||||
|
[0.0, "o", "Welcome to the demo!\r\n"]
|
||||||
|
[1.0, "o", "$ "]
|
||||||
|
[2.0, "o", "ls -la\r\n"]
|
||||||
|
[2.5, "o", "total 8\r\n"]
|
||||||
|
[2.6, "o", "drwxr-xr-x 2 user user 4096 Jan 1 12:00 .\r\n"]
|
||||||
|
[2.7, "o", "drwxr-xr-x 20 user user 4096 Jan 1 12:00 ..\r\n"]
|
||||||
|
[2.8, "o", "-rw-r--r-- 1 user user 0 Jan 1 12:00 demo.txt\r\n"]
|
||||||
|
[3.0, "o", "$ "]
|
||||||
|
[4.0, "o", "cat demo.txt\r\n"]
|
||||||
|
[4.5, "o", "Hello, this is a demo file!\r\n"]
|
||||||
|
[5.0, "o", "$ "]
|
||||||
|
[6.0, "o", "echo 'This is a test command'\r\n"]
|
||||||
|
[6.5, "o", "This is a test command\r\n"]
|
||||||
|
[7.0, "o", "$ "]
|
||||||
|
[8.0, "o", "pwd\r\n"]
|
||||||
|
[8.5, "o", "/home/user/demo\r\n"]
|
||||||
|
[9.0, "o", "$ "]
|
||||||
|
[10.0, "o", "exit\r\n"]
|
||||||
280
public/categories/index.html
Normal file
@@ -0,0 +1,280 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en" dir="ltr"><head><script src="/livereload.js?mindelay=10&v=2&port=1313&path=livereload" data-no-instant defer></script>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="robots" content="noindex, nofollow" />
|
||||||
|
<link rel="icon shortcut" href="/favicon.ico" sizes="32x32" />
|
||||||
|
<link rel="icon" href="/favicon.svg" type="image/svg+xml" id="favicon-svg" />
|
||||||
|
<link rel="icon" href="/favicon-16x16.png" type="image/png" sizes="16x16" />
|
||||||
|
<link rel="icon" href="/favicon-32x32.png" type="image/png" sizes="32x32" />
|
||||||
|
<link rel="apple-touch-icon" href="/apple-touch-icon.png" sizes="180x180" />
|
||||||
|
<link fetchpriority="low" href="/site.webmanifest" rel="manifest" />
|
||||||
|
<title>Categories – CodeJava</title>
|
||||||
|
<meta name="description" content="" /><link rel="canonical" href="http://localhost:1313/categories/" itemprop="url" />
|
||||||
|
|
||||||
|
<meta property="og:title" content="Categories">
|
||||||
|
<meta
|
||||||
|
property="og:description"
|
||||||
|
content="
|
||||||
|
|
||||||
|
Learn Java programming
|
||||||
|
|
||||||
|
">
|
||||||
|
<meta
|
||||||
|
property="og:type"
|
||||||
|
content="
|
||||||
|
website
|
||||||
|
">
|
||||||
|
<meta property="og:url" content="http://localhost:1313/categories/">
|
||||||
|
|
||||||
|
|
||||||
|
<meta itemprop="name" content="Categories">
|
||||||
|
<meta itemprop="description" content="Learn Java programming">
|
||||||
|
<meta name="twitter:card" content="summary">
|
||||||
|
<meta name="twitter:title" content="Categories">
|
||||||
|
<meta name="twitter:description" content="Learn Java programming">
|
||||||
|
<link href="/css/compiled/main.css" rel="stylesheet" />
|
||||||
|
<link href="/css/variables.css" rel="stylesheet" />
|
||||||
|
<link href="/css/custom.css" rel="stylesheet" />
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
|
||||||
|
function setTheme(theme) {
|
||||||
|
document.documentElement.classList.remove("light", "dark");
|
||||||
|
|
||||||
|
if (theme !== "light" && theme !== "dark") {
|
||||||
|
theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
|
||||||
|
}
|
||||||
|
|
||||||
|
document.documentElement.classList.add(theme);
|
||||||
|
document.documentElement.style.colorScheme = theme;
|
||||||
|
}
|
||||||
|
|
||||||
|
setTheme("color-theme" in localStorage ? localStorage.getItem("color-theme") : 'system')
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
|
||||||
|
if (localStorage.getItem('banner-closed')) {
|
||||||
|
document.documentElement.style.setProperty("--hextra-banner-height", "0px");
|
||||||
|
document.documentElement.classList.add("hextra-banner-hidden");
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</head>
|
||||||
|
<body><div class="hextra-nav-container hx:sticky hx:top-0 hx:z-20 hx:w-full hx:bg-transparent hx:print:hidden">
|
||||||
|
<div
|
||||||
|
class="hextra-nav-container-blur hx:pointer-events-none hx:absolute hx:z-[-1] hx:h-full hx:w-full hx:bg-white hx:dark:bg-dark hx:shadow-[0_2px_4px_rgba(0,0,0,.02),0_1px_0_rgba(0,0,0,.06)] hx:contrast-more:shadow-[0_0_0_1px_#000] hx:dark:shadow-[0_-1px_0_rgba(255,255,255,.1)_inset] hx:contrast-more:dark:shadow-[0_0_0_1px_#fff]"
|
||||||
|
></div>
|
||||||
|
|
||||||
|
<nav class="hextra-max-navbar-width hx:mx-auto hx:flex hx:items-center hx:justify-end hx:gap-2 hx:h-16 hx:px-6">
|
||||||
|
<a class="hx:flex hx:items-center hx:hover:opacity-75 hx:ltr:mr-auto hx:rtl:ml-auto" href="/">
|
||||||
|
<img class="hx:mr-2 hx:block hx:dark:hidden" src="/images/logo.svg" alt="Logo" height="20" width="20" />
|
||||||
|
<img class="hx:mr-2 hx:hidden hx:dark:block" src="/images/logo.svg" alt="Dark Logo" height="20" width="20" />
|
||||||
|
<span class="hx:mr-2 hx:font-extrabold hx:inline hx:select-none" title="CodeJava">CodeJava</span>
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
title=""
|
||||||
|
href="/courses"
|
||||||
|
|
||||||
|
class="hx:text-sm hx:contrast-more:text-gray-700 hx:contrast-more:dark:text-gray-100 hx:relative hx:-ml-2 hx:hidden hx:whitespace-nowrap hx:p-2 hx:md:inline-flex hx:items-center hx:gap-1 hx:text-gray-600 hx:hover:text-gray-800 hx:dark:text-gray-400 hx:dark:hover:text-gray-200"
|
||||||
|
><span class="hx:text-center">Courses</span>
|
||||||
|
</a><div class="hextra-search-wrapper hx:relative hx:md:w-64">
|
||||||
|
<div class="hx:relative hx:flex hx:items-center hx:text-gray-900 hx:contrast-more:text-gray-800 hx:dark:text-gray-300 hx:contrast-more:dark:text-gray-300">
|
||||||
|
<input
|
||||||
|
placeholder="Search..."
|
||||||
|
class="hextra-search-input hx:focus:hextra-focus hx:block hx:w-full hx:appearance-none hx:rounded-lg hx:px-3 hx:py-2 hx:transition-colors hx:text-base hx:leading-tight hx:md:text-sm hx:bg-black/[.05] hx:dark:bg-gray-50/10 hx:focus:bg-white hx:dark:focus:bg-dark hx:placeholder:text-gray-500 hx:dark:placeholder:text-gray-400 hx:contrast-more:border hx:contrast-more:border-current"
|
||||||
|
type="search"
|
||||||
|
value=""
|
||||||
|
spellcheck="false"
|
||||||
|
/>
|
||||||
|
<kbd
|
||||||
|
class="hx:absolute hx:my-1.5 hx:select-none hx:ltr:right-1.5 hx:rtl:left-1.5 hx:h-5 hx:rounded-sm hx:bg-white hx:px-1.5 hx:font-mono hx:text-[10px] hx:font-medium hx:text-gray-500 hx:border hx:border-gray-200 hx:dark:border-gray-100/20 hx:dark:bg-dark/50 hx:contrast-more:border-current hx:contrast-more:text-current hx:contrast-more:dark:border-current hx:items-center hx:gap-1 hx:transition-opacity hx:pointer-events-none hx:hidden hx:sm:flex"
|
||||||
|
>
|
||||||
|
CTRL K
|
||||||
|
</kbd>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<ul
|
||||||
|
class="hextra-search-results hextra-scrollbar hx:hidden hx:border hx:border-gray-200 hx:bg-white hx:text-gray-100 hx:dark:border-neutral-800 hx:dark:bg-neutral-900 hx:absolute hx:top-full hx:z-20 hx:mt-2 hx:overflow-auto hx:overscroll-contain hx:rounded-xl hx:py-2.5 hx:shadow-xl hx:max-h-[min(calc(50vh-11rem-env(safe-area-inset-bottom)),400px)] hx:md:max-h-[min(calc(100vh-5rem-env(safe-area-inset-bottom)),400px)] hx:inset-x-0 hx:ltr:md:left-auto hx:rtl:md:right-auto hx:contrast-more:border hx:contrast-more:border-gray-900 hx:contrast-more:dark:border-gray-50 hx:w-screen hx:min-h-[100px] hx:max-w-[min(calc(100vw-2rem),calc(100%+20rem))]"
|
||||||
|
style="transition: max-height 0.2s ease 0s;"
|
||||||
|
></ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button type="button" aria-label="Menu" class="hextra-hamburger-menu hx:cursor-pointer hx:-mr-2 hx:rounded-sm hx:p-2 hx:active:bg-gray-400/20 hx:md:hidden"><svg height=24 fill="none" viewBox="0 0 24 24" stroke="currentColor"><g><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 8H20"></path></g><g><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16H20"></path></g></svg></button>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class='hx:mx-auto hx:flex hextra-max-page-width'>
|
||||||
|
<aside class="hextra-sidebar-container hx:flex hx:flex-col hx:print:hidden hx:md:top-16 hx:md:shrink-0 hx:md:w-64 hx:md:self-start hx:max-md:[transform:translate3d(0,-100%,0)] hx:md:hidden hx:xl:block">
|
||||||
|
|
||||||
|
<div class="hx:px-4 hx:pt-4 hx:md:hidden">
|
||||||
|
<div class="hextra-search-wrapper hx:relative hx:md:w-64">
|
||||||
|
<div class="hx:relative hx:flex hx:items-center hx:text-gray-900 hx:contrast-more:text-gray-800 hx:dark:text-gray-300 hx:contrast-more:dark:text-gray-300">
|
||||||
|
<input
|
||||||
|
placeholder="Search..."
|
||||||
|
class="hextra-search-input hx:focus:hextra-focus hx:block hx:w-full hx:appearance-none hx:rounded-lg hx:px-3 hx:py-2 hx:transition-colors hx:text-base hx:leading-tight hx:md:text-sm hx:bg-black/[.05] hx:dark:bg-gray-50/10 hx:focus:bg-white hx:dark:focus:bg-dark hx:placeholder:text-gray-500 hx:dark:placeholder:text-gray-400 hx:contrast-more:border hx:contrast-more:border-current"
|
||||||
|
type="search"
|
||||||
|
value=""
|
||||||
|
spellcheck="false"
|
||||||
|
/>
|
||||||
|
<kbd
|
||||||
|
class="hx:absolute hx:my-1.5 hx:select-none hx:ltr:right-1.5 hx:rtl:left-1.5 hx:h-5 hx:rounded-sm hx:bg-white hx:px-1.5 hx:font-mono hx:text-[10px] hx:font-medium hx:text-gray-500 hx:border hx:border-gray-200 hx:dark:border-gray-100/20 hx:dark:bg-dark/50 hx:contrast-more:border-current hx:contrast-more:text-current hx:contrast-more:dark:border-current hx:items-center hx:gap-1 hx:transition-opacity hx:pointer-events-none hx:hidden hx:sm:flex"
|
||||||
|
>
|
||||||
|
CTRL K
|
||||||
|
</kbd>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<ul
|
||||||
|
class="hextra-search-results hextra-scrollbar hx:hidden hx:border hx:border-gray-200 hx:bg-white hx:text-gray-100 hx:dark:border-neutral-800 hx:dark:bg-neutral-900 hx:absolute hx:top-full hx:z-20 hx:mt-2 hx:overflow-auto hx:overscroll-contain hx:rounded-xl hx:py-2.5 hx:shadow-xl hx:max-h-[min(calc(50vh-11rem-env(safe-area-inset-bottom)),400px)] hx:md:max-h-[min(calc(100vh-5rem-env(safe-area-inset-bottom)),400px)] hx:inset-x-0 hx:ltr:md:left-auto hx:rtl:md:right-auto hx:contrast-more:border hx:contrast-more:border-gray-900 hx:contrast-more:dark:border-gray-50 hx:w-screen hx:min-h-[100px] hx:max-w-[min(calc(100vw-2rem),calc(100%+20rem))]"
|
||||||
|
style="transition: max-height 0.2s ease 0s;"
|
||||||
|
></ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="hextra-scrollbar hx:overflow-y-auto hx:overflow-x-hidden hx:p-4 hx:grow hx:md:h-[calc(100vh-var(--navbar-height)-var(--menu-height))]">
|
||||||
|
<ul class="hx:flex hx:flex-col hx:gap-1 hx:md:hidden">
|
||||||
|
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<div class="hx:max-xl:hidden hx:h-0 hx:w-64 hx:shrink-0"></div></div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="hx:md:hidden hx:sticky hx:bottom-0 hx:max-h-(--menu-height) hx:bg-white hx:dark:bg-dark hx:mx-4 hx:py-4 hx:shadow-[0_-12px_16px_#fff] hx:flex hx:items-center hx:gap-2 hx:border-gray-200 hx:dark:border-neutral-800 hx:dark:shadow-[0_-12px_16px_#111] hx:contrast-more:border-neutral-400 hx:contrast-more:shadow-none hx:contrast-more:dark:shadow-none hx:border-t" data-toggle-animation="show"><div class="hx:flex hx:grow hx:flex-col"><div class="hx:flex hx:justify-items-start hx:group" data-theme="light">
|
||||||
|
<button
|
||||||
|
title="Change theme"
|
||||||
|
data-state="closed"
|
||||||
|
data-location="bottom"
|
||||||
|
class="hextra-theme-toggle hx:cursor-pointer hx:rounded-md hx:text-left hx:font-medium hx:h-7 hx:px-2 hx:text-xs hx:hover:bg-gray-100 hx:hover:text-gray-900 hx:dark:hover:bg-primary-100/5 hx:dark:hover:text-gray-50 hx:font-medium hx:text-gray-600 hx:transition-colors hx:dark:text-gray-400 hx:grow"
|
||||||
|
type="button"
|
||||||
|
aria-label="Change theme"
|
||||||
|
>
|
||||||
|
<div class="hx:flex hx:items-center hx:gap-2 hx:capitalize"><svg height=12 class="hx:group-data-[theme=dark]:hidden hx:group-data-[theme=system]:hidden" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z"/></svg><span class="hx:group-data-[theme=dark]:hidden hx:group-data-[theme=system]:hidden">Light</span><svg height=12 class="hx:group-data-[theme=light]:hidden hx:group-data-[theme=system]:hidden" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z"/></svg><span class="hx:group-data-[theme=light]:hidden hx:group-data-[theme=system]:hidden">Dark</span><svg height=12 class="hx:group-data-[theme=dark]:hidden hx:group-data-[theme=light]:hidden" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
|
||||||
|
<path d="M 11.996094,2 C 6.4986225,2.0192368 2.03125,6.5024993 2.03125,12 c 0,5.497501 4.4673725,9.980763 9.964844,10 H 12 12.0039 c 5.497471,-0.01924 9.964844,-4.502499 9.964844,-10 0,-5.4975007 -4.467373,-9.9807632 -9.964844,-10 H 12 Z M 12,4 c 4.417218,0.017598 7.96875,3.5822356 7.96875,8 0,4.417764 -3.551532,7.982402 -7.96875,8 z" />
|
||||||
|
</svg>
|
||||||
|
<span class="hx:group-data-[theme=dark]:hidden hx:group-data-[theme=light]:hidden">System</span></div>
|
||||||
|
</button>
|
||||||
|
<ul
|
||||||
|
class="hextra-theme-toggle-options hx:hidden hx:z-20 hx:max-h-64 hx:overflow-auto hx:rounded-md hx:ring-1 hx:ring-black/5 hx:bg-white hx:py-1 hx:text-sm hx:shadow-lg hx:dark:ring-white/20 hx:dark:bg-neutral-800"
|
||||||
|
style="position: fixed; inset: auto auto 0px 0px; margin: 0px; min-width: 100px;"
|
||||||
|
data-theme="light"
|
||||||
|
>
|
||||||
|
<li class="hx:flex hx:flex-col">
|
||||||
|
<p
|
||||||
|
data-item="light"
|
||||||
|
class="hx:text-gray-800 hx:dark:text-gray-100 hx:hover:bg-primary-50 hx:hover:text-primary-600 hx:hover:dark:bg-primary-500/10 hx:hover:dark:text-primary-600 hx:relative hx:cursor-pointer hx:whitespace-nowrap hx:py-1.5 hx:transition-colors hx:ltr:pl-3 hx:ltr:pr-9 hx:rtl:pr-3 hx:rtl:pl-9"
|
||||||
|
>
|
||||||
|
Light
|
||||||
|
<span class="hx:absolute hx:inset-y-0 hx:flex hx:items-center hx:ltr:right-3 hx:rtl:left-3 hx:group-data-[theme=dark]:hidden hx:group-data-[theme=system]:hidden"><svg height=1em width=1em xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7"/></svg></span>
|
||||||
|
</p>
|
||||||
|
</li>
|
||||||
|
<li class="hx:flex hx:flex-col">
|
||||||
|
<p
|
||||||
|
data-item="dark"
|
||||||
|
class="hx:text-gray-800 hx:dark:text-gray-100 hx:hover:bg-primary-50 hx:hover:text-primary-600 hx:hover:dark:bg-primary-500/10 hx:hover:dark:text-primary-600 hx:relative hx:cursor-pointer hx:whitespace-nowrap hx:py-1.5 hx:transition-colors hx:ltr:pl-3 hx:ltr:pr-9 hx:rtl:pr-3 hx:rtl:pl-9"
|
||||||
|
>
|
||||||
|
Dark
|
||||||
|
<span class="hx:absolute hx:inset-y-0 hx:flex hx:items-center hx:ltr:right-3 hx:rtl:left-3 hx:group-data-[theme=light]:hidden hx:group-data-[theme=system]:hidden"><svg height=1em width=1em xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7"/></svg></span>
|
||||||
|
</p>
|
||||||
|
</li>
|
||||||
|
<li class="hx:flex hx:flex-col">
|
||||||
|
<p
|
||||||
|
data-item="system"
|
||||||
|
class="hx:text-gray-800 hx:dark:text-gray-100 hx:hover:bg-primary-50 hx:hover:text-primary-600 hx:hover:dark:bg-primary-500/10 hx:hover:dark:text-primary-600 hx:relative hx:cursor-pointer hx:whitespace-nowrap hx:py-1.5 hx:transition-colors hx:ltr:pl-3 hx:ltr:pr-9 hx:rtl:pr-3 hx:rtl:pl-9"
|
||||||
|
>
|
||||||
|
System
|
||||||
|
<span class="hx:absolute hx:inset-y-0 hx:flex hx:items-center hx:ltr:right-3 hx:rtl:left-3 hx:group-data-[theme=dark]:hidden hx:group-data-[theme=light]:hidden"><svg height=1em width=1em xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7"/></svg></span>
|
||||||
|
</p>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div></div></div></aside>
|
||||||
|
|
||||||
|
<nav class="hextra-toc hx:order-last hx:hidden hx:w-64 hx:shrink-0 hx:xl:block hx:print:hidden hx:px-4" aria-label="table of contents"></nav>
|
||||||
|
|
||||||
|
|
||||||
|
<article class="hx:w-full hx:break-words hx:flex hx:min-h-[calc(100vh-var(--navbar-height))] hx:min-w-0 hx:justify-center hx:pb-8 hx:pr-[calc(env(safe-area-inset-right)-1.5rem)]">
|
||||||
|
<main class="hx:w-full hx:min-w-0 hx:max-w-6xl hx:px-6 hx:pt-4 hx:md:px-12">
|
||||||
|
<br class="hx:mt-1.5 hx:text-sm" />
|
||||||
|
<h1 class="hx:text-center hx:mt-2 hx:text-4xl hx:font-bold hx:tracking-tight hx:text-slate-900 hx:dark:text-slate-100">Categories</h1>
|
||||||
|
<div class="hx:mb-16"></div>
|
||||||
|
<div class="content">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="hx:grid hx:grid-cols-1 hx:md:grid-cols-2 hx:lg:grid-cols-3 hx:xl:grid-cols-4 hx:gap-4">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
</article>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<footer class="hextra-footer hx:bg-gray-100 hx:pb-[env(safe-area-inset-bottom)] hx:dark:bg-neutral-900 hx:print:bg-transparent"><div class="hx:mx-auto hx:flex hx:gap-2 hx:py-2 hx:px-4 hextra-max-footer-width"><div class="hx:flex hx:justify-items-start hx:group" data-theme="light">
|
||||||
|
<button
|
||||||
|
title="Change theme"
|
||||||
|
data-state="closed"
|
||||||
|
data-location="bottom"
|
||||||
|
class="hextra-theme-toggle hx:cursor-pointer hx:rounded-md hx:text-left hx:font-medium hx:h-7 hx:px-2 hx:text-xs hx:hover:bg-gray-100 hx:hover:text-gray-900 hx:dark:hover:bg-primary-100/5 hx:dark:hover:text-gray-50 hx:font-medium hx:text-gray-600 hx:transition-colors hx:dark:text-gray-400 hx:grow"
|
||||||
|
type="button"
|
||||||
|
aria-label="Change theme"
|
||||||
|
>
|
||||||
|
<div class="hx:flex hx:items-center hx:gap-2 hx:capitalize"><svg height=12 class="hx:group-data-[theme=dark]:hidden hx:group-data-[theme=system]:hidden" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z"/></svg><span class="hx:group-data-[theme=dark]:hidden hx:group-data-[theme=system]:hidden">Light</span><svg height=12 class="hx:group-data-[theme=light]:hidden hx:group-data-[theme=system]:hidden" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z"/></svg><span class="hx:group-data-[theme=light]:hidden hx:group-data-[theme=system]:hidden">Dark</span><svg height=12 class="hx:group-data-[theme=dark]:hidden hx:group-data-[theme=light]:hidden" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
|
||||||
|
<path d="M 11.996094,2 C 6.4986225,2.0192368 2.03125,6.5024993 2.03125,12 c 0,5.497501 4.4673725,9.980763 9.964844,10 H 12 12.0039 c 5.497471,-0.01924 9.964844,-4.502499 9.964844,-10 0,-5.4975007 -4.467373,-9.9807632 -9.964844,-10 H 12 Z M 12,4 c 4.417218,0.017598 7.96875,3.5822356 7.96875,8 0,4.417764 -3.551532,7.982402 -7.96875,8 z" />
|
||||||
|
</svg>
|
||||||
|
<span class="hx:group-data-[theme=dark]:hidden hx:group-data-[theme=light]:hidden">System</span></div>
|
||||||
|
</button>
|
||||||
|
<ul
|
||||||
|
class="hextra-theme-toggle-options hx:hidden hx:z-20 hx:max-h-64 hx:overflow-auto hx:rounded-md hx:ring-1 hx:ring-black/5 hx:bg-white hx:py-1 hx:text-sm hx:shadow-lg hx:dark:ring-white/20 hx:dark:bg-neutral-800"
|
||||||
|
style="position: fixed; inset: auto auto 0px 0px; margin: 0px; min-width: 100px;"
|
||||||
|
data-theme="light"
|
||||||
|
>
|
||||||
|
<li class="hx:flex hx:flex-col">
|
||||||
|
<p
|
||||||
|
data-item="light"
|
||||||
|
class="hx:text-gray-800 hx:dark:text-gray-100 hx:hover:bg-primary-50 hx:hover:text-primary-600 hx:hover:dark:bg-primary-500/10 hx:hover:dark:text-primary-600 hx:relative hx:cursor-pointer hx:whitespace-nowrap hx:py-1.5 hx:transition-colors hx:ltr:pl-3 hx:ltr:pr-9 hx:rtl:pr-3 hx:rtl:pl-9"
|
||||||
|
>
|
||||||
|
Light
|
||||||
|
<span class="hx:absolute hx:inset-y-0 hx:flex hx:items-center hx:ltr:right-3 hx:rtl:left-3 hx:group-data-[theme=dark]:hidden hx:group-data-[theme=system]:hidden"><svg height=1em width=1em xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7"/></svg></span>
|
||||||
|
</p>
|
||||||
|
</li>
|
||||||
|
<li class="hx:flex hx:flex-col">
|
||||||
|
<p
|
||||||
|
data-item="dark"
|
||||||
|
class="hx:text-gray-800 hx:dark:text-gray-100 hx:hover:bg-primary-50 hx:hover:text-primary-600 hx:hover:dark:bg-primary-500/10 hx:hover:dark:text-primary-600 hx:relative hx:cursor-pointer hx:whitespace-nowrap hx:py-1.5 hx:transition-colors hx:ltr:pl-3 hx:ltr:pr-9 hx:rtl:pr-3 hx:rtl:pl-9"
|
||||||
|
>
|
||||||
|
Dark
|
||||||
|
<span class="hx:absolute hx:inset-y-0 hx:flex hx:items-center hx:ltr:right-3 hx:rtl:left-3 hx:group-data-[theme=light]:hidden hx:group-data-[theme=system]:hidden"><svg height=1em width=1em xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7"/></svg></span>
|
||||||
|
</p>
|
||||||
|
</li>
|
||||||
|
<li class="hx:flex hx:flex-col">
|
||||||
|
<p
|
||||||
|
data-item="system"
|
||||||
|
class="hx:text-gray-800 hx:dark:text-gray-100 hx:hover:bg-primary-50 hx:hover:text-primary-600 hx:hover:dark:bg-primary-500/10 hx:hover:dark:text-primary-600 hx:relative hx:cursor-pointer hx:whitespace-nowrap hx:py-1.5 hx:transition-colors hx:ltr:pl-3 hx:ltr:pr-9 hx:rtl:pr-3 hx:rtl:pl-9"
|
||||||
|
>
|
||||||
|
System
|
||||||
|
<span class="hx:absolute hx:inset-y-0 hx:flex hx:items-center hx:ltr:right-3 hx:rtl:left-3 hx:group-data-[theme=dark]:hidden hx:group-data-[theme=light]:hidden"><svg height=1em width=1em xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7"/></svg></span>
|
||||||
|
</p>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div></div><hr class="hx:border-gray-200 hx:dark:border-neutral-800" /><div class="hextra-custom-footer hextra-max-footer-width hx:pl-[max(env(safe-area-inset-left),1.5rem)] hx:pr-[max(env(safe-area-inset-right),1.5rem)] hx:text-gray-600 hx:dark:text-gray-400"></div><div
|
||||||
|
class="hextra-max-footer-width hx:mx-auto hx:flex hx:justify-center hx:py-12 hx:pl-[max(env(safe-area-inset-left),1.5rem)] hx:pr-[max(env(safe-area-inset-right),1.5rem)] hx:text-gray-600 hx:dark:text-gray-400 hx:md:justify-start"
|
||||||
|
>
|
||||||
|
<div class="hx:flex hx:w-full hx:flex-col hx:items-center hx:sm:items-start"><div class="hx:font-semibold"><a class="hx:flex hx:text-sm hx:items-center hx:gap-1 hx:text-current" target="_blank" rel="noopener noreferrer" title="Hextra GitHub Homepage" href="https://github.com/imfing/hextra">
|
||||||
|
<span>Powered by Hextra<svg height=1em class="hx:inline-block hx:ltr:ml-1 hx:rtl:mr-1 hx:align-[-2.5px]" viewBox="0 0 180 180" xmlns="http://www.w3.org/2000/svg" fill="currentColor"><path fill-rule="evenodd" clip-rule="evenodd" d="m 105.50024,22.224647 c -9.59169,-5.537563 -21.40871,-5.537563 -31.000093,0 L 39.054693,42.689119 C 29.463353,48.226675 23.55484,58.460531 23.55484,69.535642 v 40.928918 c 0,11.07542 5.908513,21.3092 15.499853,26.84652 l 35.445453,20.46446 c 9.591313,5.53732 21.408404,5.53732 31.000094,0 l 35.44507,-20.46446 c 9.59131,-5.53732 15.49985,-15.7711 15.49985,-26.84652 V 69.535642 c 0,-11.075111 -5.90854,-21.308967 -15.49985,-26.846523 z M 34.112797,85.737639 c -1.384445,2.397827 -1.384445,5.352099 0,7.749927 l 24.781554,42.922974 c 1.38437,2.39783 3.942853,3.87496 6.711592,3.87496 h 49.563107 c 2.76905,0 5.3273,-1.47713 6.71144,-3.87496 l 24.78194,-42.922974 c 1.38414,-2.397828 1.38414,-5.3521 0,-7.749927 L 121.88049,42.814746 c -1.38414,-2.397828 -3.94239,-3.874964 -6.71144,-3.874964 H 65.605944 c -2.768739,0 -5.327223,1.477059 -6.711592,3.874964 z" style="stroke-width:0.774993" /></svg></span>
|
||||||
|
</a></div></div>
|
||||||
|
</div></footer>
|
||||||
|
|
||||||
|
<script defer src="/js/main.js" integrity=""></script>
|
||||||
|
<script defer src="/js/flexsearch.9f5b5908f93ae86f1ecd4b043b799f580c2d1654e703dd9357d568ac41b2547a.js" integrity="sha256-n1tZCPk66G8ezUsEO3mfWAwtFlTnA92TV9VorEGyVHo=" crossorigin="anonymous"></script>
|
||||||
|
<script defer src="/en.search.js" integrity=""></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
18
public/categories/index.xml
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
||||||
|
<channel>
|
||||||
|
<title>CodeJava – Categories</title>
|
||||||
|
<link>http://localhost:1313/categories/</link>
|
||||||
|
<description>Recent content in Categories on CodeJava</description>
|
||||||
|
<generator>Hugo -- gohugo.io</generator>
|
||||||
|
<language>en</language>
|
||||||
|
|
||||||
|
<atom:link href="http://localhost:1313/categories/index.xml" rel="self" type="application/rss+xml" />
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</channel>
|
||||||
|
</rss>
|
||||||
2
public/css/compiled/main.css
Normal file
0
public/css/custom.css
Normal file
21
public/css/variables.css
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
/* Hugo template to derive CSS variables from site and page parameters */
|
||||||
|
|
||||||
|
/* Do not remove the following comment. It is used by Hugo to render CSS variables.*/
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--hextra-max-page-width: 80rem;
|
||||||
|
--hextra-max-navbar-width: 80rem;
|
||||||
|
--hextra-max-footer-width: 80rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hextra-max-page-width {
|
||||||
|
max-width: var(--hextra-max-page-width);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hextra-max-navbar-width {
|
||||||
|
max-width: var(--hextra-max-navbar-width);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hextra-max-footer-width {
|
||||||
|
max-width: var(--hextra-max-footer-width);
|
||||||
|
}
|
||||||
1
public/en.search-data.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{}
|
||||||
437
public/en.search.js
Normal file
@@ -0,0 +1,437 @@
|
|||||||
|
// Search functionality using FlexSearch.
|
||||||
|
|
||||||
|
// Change shortcut key to cmd+k on Mac, iPad or iPhone.
|
||||||
|
document.addEventListener("DOMContentLoaded", function () {
|
||||||
|
if (/iPad|iPhone|Macintosh/.test(navigator.userAgent)) {
|
||||||
|
// select the kbd element under the .hextra-search-wrapper class
|
||||||
|
const keys = document.querySelectorAll(".hextra-search-wrapper kbd");
|
||||||
|
keys.forEach(key => {
|
||||||
|
key.innerHTML = '<span class="hx:text-xs">⌘</span>K';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Render the search data as JSON.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
(function () {
|
||||||
|
const searchDataURL = '/en.search-data.json';
|
||||||
|
|
||||||
|
const inputElements = document.querySelectorAll('.hextra-search-input');
|
||||||
|
for (const el of inputElements) {
|
||||||
|
el.addEventListener('focus', init);
|
||||||
|
el.addEventListener('keyup', search);
|
||||||
|
el.addEventListener('keydown', handleKeyDown);
|
||||||
|
el.addEventListener('input', handleInputChange);
|
||||||
|
}
|
||||||
|
|
||||||
|
const shortcutElements = document.querySelectorAll('.hextra-search-wrapper kbd');
|
||||||
|
|
||||||
|
function setShortcutElementsOpacity(opacity) {
|
||||||
|
shortcutElements.forEach(el => {
|
||||||
|
el.style.opacity = opacity;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleInputChange(e) {
|
||||||
|
const opacity = e.target.value.length > 0 ? 0 : 100;
|
||||||
|
setShortcutElementsOpacity(opacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the search wrapper, input, and results elements.
|
||||||
|
function getActiveSearchElement() {
|
||||||
|
const inputs = Array.from(document.querySelectorAll('.hextra-search-wrapper')).filter(el => el.clientHeight > 0);
|
||||||
|
if (inputs.length === 1) {
|
||||||
|
return {
|
||||||
|
wrapper: inputs[0],
|
||||||
|
inputElement: inputs[0].querySelector('.hextra-search-input'),
|
||||||
|
resultsElement: inputs[0].querySelector('.hextra-search-results')
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
const INPUTS = ['input', 'select', 'button', 'textarea']
|
||||||
|
|
||||||
|
// Focus the search input when pressing ctrl+k/cmd+k or /.
|
||||||
|
document.addEventListener('keydown', function (e) {
|
||||||
|
const { inputElement } = getActiveSearchElement();
|
||||||
|
if (!inputElement) return;
|
||||||
|
|
||||||
|
const activeElement = document.activeElement;
|
||||||
|
const tagName = activeElement && activeElement.tagName;
|
||||||
|
if (
|
||||||
|
inputElement === activeElement ||
|
||||||
|
!tagName ||
|
||||||
|
INPUTS.includes(tagName) ||
|
||||||
|
(activeElement && activeElement.isContentEditable))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (
|
||||||
|
e.key === '/' ||
|
||||||
|
(e.key === 'k' &&
|
||||||
|
(e.metaKey /* for Mac */ || /* for non-Mac */ e.ctrlKey))
|
||||||
|
) {
|
||||||
|
e.preventDefault();
|
||||||
|
inputElement.focus();
|
||||||
|
} else if (e.key === 'Escape' && inputElement.value) {
|
||||||
|
inputElement.blur();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Dismiss the search results when clicking outside the search box.
|
||||||
|
document.addEventListener('mousedown', function (e) {
|
||||||
|
const { inputElement, resultsElement } = getActiveSearchElement();
|
||||||
|
if (!inputElement || !resultsElement) return;
|
||||||
|
if (
|
||||||
|
e.target !== inputElement &&
|
||||||
|
e.target !== resultsElement &&
|
||||||
|
!resultsElement.contains(e.target)
|
||||||
|
) {
|
||||||
|
setShortcutElementsOpacity(100);
|
||||||
|
hideSearchResults();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Get the currently active result and its index.
|
||||||
|
function getActiveResult() {
|
||||||
|
const { resultsElement } = getActiveSearchElement();
|
||||||
|
if (!resultsElement) return { result: undefined, index: -1 };
|
||||||
|
|
||||||
|
const result = resultsElement.querySelector('.hextra-search-active');
|
||||||
|
if (!result) return { result: undefined, index: -1 };
|
||||||
|
|
||||||
|
const index = parseInt(result.dataset.index, 10);
|
||||||
|
return { result, index };
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the active result by index.
|
||||||
|
function setActiveResult(index) {
|
||||||
|
const { resultsElement } = getActiveSearchElement();
|
||||||
|
if (!resultsElement) return;
|
||||||
|
|
||||||
|
const { result: activeResult } = getActiveResult();
|
||||||
|
activeResult && activeResult.classList.remove('hextra-search-active');
|
||||||
|
const result = resultsElement.querySelector(`[data-index="${index}"]`);
|
||||||
|
if (result) {
|
||||||
|
result.classList.add('hextra-search-active');
|
||||||
|
result.focus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the number of search results from the DOM.
|
||||||
|
function getResultsLength() {
|
||||||
|
const { resultsElement } = getActiveSearchElement();
|
||||||
|
if (!resultsElement) return 0;
|
||||||
|
return resultsElement.dataset.count;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finish the search by hiding the results and clearing the input.
|
||||||
|
function finishSearch() {
|
||||||
|
const { inputElement } = getActiveSearchElement();
|
||||||
|
if (!inputElement) return;
|
||||||
|
hideSearchResults();
|
||||||
|
inputElement.value = '';
|
||||||
|
inputElement.blur();
|
||||||
|
}
|
||||||
|
|
||||||
|
function hideSearchResults() {
|
||||||
|
const { resultsElement } = getActiveSearchElement();
|
||||||
|
if (!resultsElement) return;
|
||||||
|
resultsElement.classList.add('hx:hidden');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle keyboard events.
|
||||||
|
function handleKeyDown(e) {
|
||||||
|
const { inputElement } = getActiveSearchElement();
|
||||||
|
if (!inputElement) return;
|
||||||
|
|
||||||
|
const resultsLength = getResultsLength();
|
||||||
|
const { result: activeResult, index: activeIndex } = getActiveResult();
|
||||||
|
|
||||||
|
switch (e.key) {
|
||||||
|
case 'ArrowUp':
|
||||||
|
e.preventDefault();
|
||||||
|
if (activeIndex > 0) setActiveResult(activeIndex - 1);
|
||||||
|
break;
|
||||||
|
case 'ArrowDown':
|
||||||
|
e.preventDefault();
|
||||||
|
if (activeIndex + 1 < resultsLength) setActiveResult(activeIndex + 1);
|
||||||
|
break;
|
||||||
|
case 'Enter':
|
||||||
|
e.preventDefault();
|
||||||
|
if (activeResult) {
|
||||||
|
activeResult.click();
|
||||||
|
}
|
||||||
|
finishSearch();
|
||||||
|
case 'Escape':
|
||||||
|
e.preventDefault();
|
||||||
|
hideSearchResults();
|
||||||
|
// Clear the input when pressing escape
|
||||||
|
inputElement.value = '';
|
||||||
|
inputElement.dispatchEvent(new Event('input'));
|
||||||
|
// Remove focus from the input
|
||||||
|
inputElement.blur();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initializes the search.
|
||||||
|
function init(e) {
|
||||||
|
e.target.removeEventListener('focus', init);
|
||||||
|
if (!(window.pageIndex && window.sectionIndex)) {
|
||||||
|
preloadIndex();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Preloads the search index by fetching data and adding it to the FlexSearch index.
|
||||||
|
* @returns {Promise<void>} A promise that resolves when the index is preloaded.
|
||||||
|
*/
|
||||||
|
async function preloadIndex() {
|
||||||
|
const tokenize = 'forward';
|
||||||
|
|
||||||
|
// https://github.com/TryGhost/Ghost/pull/21148
|
||||||
|
const regex = new RegExp(
|
||||||
|
`[\u{4E00}-\u{9FFF}\u{3040}-\u{309F}\u{30A0}-\u{30FF}\u{AC00}-\u{D7A3}\u{3400}-\u{4DBF}\u{20000}-\u{2A6DF}\u{2A700}-\u{2B73F}\u{2B740}-\u{2B81F}\u{2B820}-\u{2CEAF}\u{2CEB0}-\u{2EBEF}\u{30000}-\u{3134F}\u{31350}-\u{323AF}\u{2EBF0}-\u{2EE5F}\u{F900}-\u{FAFF}\u{2F800}-\u{2FA1F}]|[0-9A-Za-zа-я\u00C0-\u017F\u0400-\u04FF\u0600-\u06FF\u0980-\u09FF\u1E00-\u1EFF\u0590-\u05FF]+`,
|
||||||
|
'mug'
|
||||||
|
);
|
||||||
|
const encode = (str) => { return ('' + str).toLowerCase().match(regex) ?? []; }
|
||||||
|
|
||||||
|
window.pageIndex = new FlexSearch.Document({
|
||||||
|
tokenize,
|
||||||
|
encode,
|
||||||
|
cache: 100,
|
||||||
|
document: {
|
||||||
|
id: 'id',
|
||||||
|
store: ['title', 'crumb'],
|
||||||
|
index: "content"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
window.sectionIndex = new FlexSearch.Document({
|
||||||
|
tokenize,
|
||||||
|
encode,
|
||||||
|
cache: 100,
|
||||||
|
document: {
|
||||||
|
id: 'id',
|
||||||
|
store: ['title', 'content', 'url', 'display', 'crumb'],
|
||||||
|
index: "content",
|
||||||
|
tag: [{
|
||||||
|
field: "pageId"
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const resp = await fetch(searchDataURL);
|
||||||
|
const data = await resp.json();
|
||||||
|
let pageId = 0;
|
||||||
|
for (const route in data) {
|
||||||
|
let pageContent = '';
|
||||||
|
++pageId;
|
||||||
|
const urlParts = route.split('/').filter(x => x != "" && !x.startsWith('#'));
|
||||||
|
|
||||||
|
let crumb = '';
|
||||||
|
let searchUrl = '/';
|
||||||
|
for (let i = 0; i < urlParts.length; i++) {
|
||||||
|
const urlPart = urlParts[i];
|
||||||
|
searchUrl += urlPart + '/'
|
||||||
|
|
||||||
|
const crumbData = data[searchUrl];
|
||||||
|
if (!crumbData) {
|
||||||
|
console.warn('Excluded page', searchUrl, '- will not be included for search result breadcrumb for', route);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let title = data[searchUrl].title;
|
||||||
|
if (title == "_index") {
|
||||||
|
title = urlPart.split("-").map(x => x).join(" ");
|
||||||
|
}
|
||||||
|
crumb += title;
|
||||||
|
|
||||||
|
if (i < urlParts.length - 1) {
|
||||||
|
crumb += ' > ';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const heading in data[route].data) {
|
||||||
|
const [hash, text] = heading.split('#');
|
||||||
|
const url = route.trimEnd('/') + (hash ? '#' + hash : '');
|
||||||
|
const title = text || data[route].title;
|
||||||
|
|
||||||
|
const content = data[route].data[heading] || '';
|
||||||
|
const paragraphs = content.split('\n').filter(Boolean);
|
||||||
|
|
||||||
|
sectionIndex.add({
|
||||||
|
id: url,
|
||||||
|
url,
|
||||||
|
title,
|
||||||
|
crumb,
|
||||||
|
pageId: `page_${pageId}`,
|
||||||
|
content: title,
|
||||||
|
...(paragraphs[0] && { display: paragraphs[0] })
|
||||||
|
});
|
||||||
|
|
||||||
|
for (let i = 0; i < paragraphs.length; i++) {
|
||||||
|
sectionIndex.add({
|
||||||
|
id: `${url}_${i}`,
|
||||||
|
url,
|
||||||
|
title,
|
||||||
|
crumb,
|
||||||
|
pageId: `page_${pageId}`,
|
||||||
|
content: paragraphs[i]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
pageContent += ` ${title} ${content}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
window.pageIndex.add({
|
||||||
|
id: pageId,
|
||||||
|
title: data[route].title,
|
||||||
|
crumb,
|
||||||
|
content: pageContent
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs a search based on the provided query and displays the results.
|
||||||
|
* @param {Event} e - The event object.
|
||||||
|
*/
|
||||||
|
function search(e) {
|
||||||
|
const query = e.target.value;
|
||||||
|
if (!e.target.value) {
|
||||||
|
hideSearchResults();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { resultsElement } = getActiveSearchElement();
|
||||||
|
while (resultsElement.firstChild) {
|
||||||
|
resultsElement.removeChild(resultsElement.firstChild);
|
||||||
|
}
|
||||||
|
resultsElement.classList.remove('hx:hidden');
|
||||||
|
|
||||||
|
const pageResults = window.pageIndex.search(query, 5, { enrich: true, suggest: true })[0]?.result || [];
|
||||||
|
|
||||||
|
const results = [];
|
||||||
|
const pageTitleMatches = {};
|
||||||
|
|
||||||
|
for (let i = 0; i < pageResults.length; i++) {
|
||||||
|
const result = pageResults[i];
|
||||||
|
pageTitleMatches[i] = 0;
|
||||||
|
|
||||||
|
// Show the top 5 results for each page
|
||||||
|
const sectionResults = window.sectionIndex.search(query, 5, { enrich: true, suggest: true, tag: { 'pageId': `page_${result.id}` } })[0]?.result || [];
|
||||||
|
let isFirstItemOfPage = true
|
||||||
|
const occurred = {}
|
||||||
|
|
||||||
|
for (let j = 0; j < sectionResults.length; j++) {
|
||||||
|
const { doc } = sectionResults[j]
|
||||||
|
const isMatchingTitle = doc.display !== undefined
|
||||||
|
if (isMatchingTitle) {
|
||||||
|
pageTitleMatches[i]++
|
||||||
|
}
|
||||||
|
const { url, title } = doc
|
||||||
|
const content = doc.display || doc.content
|
||||||
|
|
||||||
|
if (occurred[url + '@' + content]) continue
|
||||||
|
occurred[url + '@' + content] = true
|
||||||
|
results.push({
|
||||||
|
_page_rk: i,
|
||||||
|
_section_rk: j,
|
||||||
|
route: url,
|
||||||
|
prefix: isFirstItemOfPage ? result.doc.crumb : undefined,
|
||||||
|
children: { title, content }
|
||||||
|
})
|
||||||
|
isFirstItemOfPage = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const sortedResults = results
|
||||||
|
.sort((a, b) => {
|
||||||
|
// Sort by number of matches in the title.
|
||||||
|
if (a._page_rk === b._page_rk) {
|
||||||
|
return a._section_rk - b._section_rk
|
||||||
|
}
|
||||||
|
if (pageTitleMatches[a._page_rk] !== pageTitleMatches[b._page_rk]) {
|
||||||
|
return pageTitleMatches[b._page_rk] - pageTitleMatches[a._page_rk]
|
||||||
|
}
|
||||||
|
return a._page_rk - b._page_rk
|
||||||
|
})
|
||||||
|
.map(res => ({
|
||||||
|
id: `${res._page_rk}_${res._section_rk}`,
|
||||||
|
route: res.route,
|
||||||
|
prefix: res.prefix,
|
||||||
|
children: res.children
|
||||||
|
}));
|
||||||
|
displayResults(sortedResults, query);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Displays the search results on the page.
|
||||||
|
*
|
||||||
|
* @param {Array} results - The array of search results.
|
||||||
|
* @param {string} query - The search query.
|
||||||
|
*/
|
||||||
|
function displayResults(results, query) {
|
||||||
|
const { resultsElement } = getActiveSearchElement();
|
||||||
|
if (!resultsElement) return;
|
||||||
|
|
||||||
|
if (!results.length) {
|
||||||
|
resultsElement.innerHTML = `<span class="hextra-search-no-result">No results found.</span>`;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Highlight the query in the result text.
|
||||||
|
function highlightMatches(text, query) {
|
||||||
|
const escapedQuery = query.replace(/[-\\^$*+?.()|[\]{}]/g, '\\$&');
|
||||||
|
const regex = new RegExp(escapedQuery, 'gi');
|
||||||
|
return text.replace(regex, (match) => `<span class="hextra-search-match">${match}</span>`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a DOM element from the HTML string.
|
||||||
|
function createElement(str) {
|
||||||
|
const div = document.createElement('div');
|
||||||
|
div.innerHTML = str.trim();
|
||||||
|
return div.firstChild;
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleMouseMove(e) {
|
||||||
|
const target = e.target.closest('a');
|
||||||
|
if (target) {
|
||||||
|
const active = resultsElement.querySelector('a.hextra-search-active');
|
||||||
|
if (active) {
|
||||||
|
active.classList.remove('hextra-search-active');
|
||||||
|
}
|
||||||
|
target.classList.add('hextra-search-active');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const fragment = document.createDocumentFragment();
|
||||||
|
for (let i = 0; i < results.length; i++) {
|
||||||
|
const result = results[i];
|
||||||
|
if (result.prefix) {
|
||||||
|
fragment.appendChild(createElement(`
|
||||||
|
<div class="hextra-search-prefix">${result.prefix}</div>`));
|
||||||
|
}
|
||||||
|
let li = createElement(`
|
||||||
|
<li>
|
||||||
|
<a data-index="${i}" href="${result.route}" class=${i === 0 ? "hextra-search-active" : ""}>
|
||||||
|
<div class="hextra-search-title">`+ highlightMatches(result.children.title, query) + `</div>` +
|
||||||
|
(result.children.content ?
|
||||||
|
`<div class="hextra-search-excerpt">` + highlightMatches(result.children.content, query) + `</div>` : '') + `
|
||||||
|
</a>
|
||||||
|
</li>`);
|
||||||
|
li.addEventListener('mousemove', handleMouseMove);
|
||||||
|
li.addEventListener('keydown', handleKeyDown);
|
||||||
|
li.querySelector('a').addEventListener('click', finishSearch);
|
||||||
|
fragment.appendChild(li);
|
||||||
|
}
|
||||||
|
resultsElement.appendChild(fragment);
|
||||||
|
resultsElement.dataset.count = results.length;
|
||||||
|
}
|
||||||
|
})();
|
||||||
BIN
public/favicon-16x16.png
Normal file
|
After Width: | Height: | Size: 340 B |
BIN
public/favicon-32x32.png
Normal file
|
After Width: | Height: | Size: 753 B |
BIN
public/favicon.ico
Normal file
|
After Width: | Height: | Size: 15 KiB |
13
public/favicon.svg
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<svg
|
||||||
|
viewBox="0 0 180 180"
|
||||||
|
fill="#1E1E1E"
|
||||||
|
width="180"
|
||||||
|
height="180"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<path
|
||||||
|
fill-rule="evenodd"
|
||||||
|
clip-rule="evenodd"
|
||||||
|
d="m 105.50024,22.224647 c -9.59169,-5.537563 -21.40871,-5.537563 -31.000093,0 L 39.054693,42.689119 C 29.463353,48.226675 23.55484,58.460531 23.55484,69.535642 v 40.928918 c 0,11.07542 5.908513,21.3092 15.499853,26.84652 l 35.445453,20.46446 c 9.591313,5.53732 21.408404,5.53732 31.000094,0 l 35.44507,-20.46446 c 9.59131,-5.53732 15.49985,-15.7711 15.49985,-26.84652 V 69.535642 c 0,-11.075111 -5.90854,-21.308967 -15.49985,-26.846523 z M 34.112797,85.737639 c -1.384445,2.397827 -1.384445,5.352099 0,7.749927 l 24.781554,42.922974 c 1.38437,2.39783 3.942853,3.87496 6.711592,3.87496 h 49.563107 c 2.76905,0 5.3273,-1.47713 6.71144,-3.87496 l 24.78194,-42.922974 c 1.38414,-2.397828 1.38414,-5.3521 0,-7.749927 L 121.88049,42.814746 c -1.38414,-2.397828 -3.94239,-3.874964 -6.71144,-3.874964 H 65.605944 c -2.768739,0 -5.327223,1.477059 -6.711592,3.874964 z"
|
||||||
|
style="stroke-width:0.774993" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.1 KiB |
3
public/images/logo-dark.svg
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<svg viewBox="0 0 180 180" xmlns="http://www.w3.org/2000/svg" fill="white">
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="m 105.50024,22.224647 c -9.59169,-5.537563 -21.40871,-5.537563 -31.000093,0 L 39.054693,42.689119 C 29.463353,48.226675 23.55484,58.460531 23.55484,69.535642 v 40.928918 c 0,11.07542 5.908513,21.3092 15.499853,26.84652 l 35.445453,20.46446 c 9.591313,5.53732 21.408404,5.53732 31.000094,0 l 35.44507,-20.46446 c 9.59131,-5.53732 15.49985,-15.7711 15.49985,-26.84652 V 69.535642 c 0,-11.075111 -5.90854,-21.308967 -15.49985,-26.846523 z M 34.112797,85.737639 c -1.384445,2.397827 -1.384445,5.352099 0,7.749927 l 24.781554,42.922974 c 1.38437,2.39783 3.942853,3.87496 6.711592,3.87496 h 49.563107 c 2.76905,0 5.3273,-1.47713 6.71144,-3.87496 l 24.78194,-42.922974 c 1.38414,-2.397828 1.38414,-5.3521 0,-7.749927 L 121.88049,42.814746 c -1.38414,-2.397828 -3.94239,-3.874964 -6.71144,-3.874964 H 65.605944 c -2.768739,0 -5.327223,1.477059 -6.711592,3.874964 z" style="stroke-width:0.774993" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.0 KiB |
3
public/images/logo.svg
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<svg viewBox="0 0 180 180" xmlns="http://www.w3.org/2000/svg" fill="currentColor">
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="m 105.50024,22.224647 c -9.59169,-5.537563 -21.40871,-5.537563 -31.000093,0 L 39.054693,42.689119 C 29.463353,48.226675 23.55484,58.460531 23.55484,69.535642 v 40.928918 c 0,11.07542 5.908513,21.3092 15.499853,26.84652 l 35.445453,20.46446 c 9.591313,5.53732 21.408404,5.53732 31.000094,0 l 35.44507,-20.46446 c 9.59131,-5.53732 15.49985,-15.7711 15.49985,-26.84652 V 69.535642 c 0,-11.075111 -5.90854,-21.308967 -15.49985,-26.846523 z M 34.112797,85.737639 c -1.384445,2.397827 -1.384445,5.352099 0,7.749927 l 24.781554,42.922974 c 1.38437,2.39783 3.942853,3.87496 6.711592,3.87496 h 49.563107 c 2.76905,0 5.3273,-1.47713 6.71144,-3.87496 l 24.78194,-42.922974 c 1.38414,-2.397828 1.38414,-5.3521 0,-7.749927 L 121.88049,42.814746 c -1.38414,-2.397828 -3.94239,-3.874964 -6.71144,-3.874964 H 65.605944 c -2.768739,0 -5.327223,1.477059 -6.711592,3.874964 z" style="stroke-width:0.774993" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.0 KiB |
287
public/index.html
Normal file
@@ -0,0 +1,287 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en" dir="ltr"><head>
|
||||||
|
<meta name="generator" content="Hugo 0.155.3"><script src="/livereload.js?mindelay=10&v=2&port=1313&path=livereload" data-no-instant defer></script>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="robots" content="noindex, nofollow" />
|
||||||
|
<link rel="icon shortcut" href="/favicon.ico" sizes="32x32" />
|
||||||
|
<link rel="icon" href="/favicon.svg" type="image/svg+xml" id="favicon-svg" />
|
||||||
|
<link rel="icon" href="/favicon-16x16.png" type="image/png" sizes="16x16" />
|
||||||
|
<link rel="icon" href="/favicon-32x32.png" type="image/png" sizes="32x32" />
|
||||||
|
<link rel="apple-touch-icon" href="/apple-touch-icon.png" sizes="180x180" />
|
||||||
|
<link fetchpriority="low" href="/site.webmanifest" rel="manifest" />
|
||||||
|
<title>CodeJava</title>
|
||||||
|
<meta name="description" content="Learn Java programming" /><link rel="canonical" href="http://localhost:1313/" itemprop="url" />
|
||||||
|
|
||||||
|
<meta property="og:title" content="CodeJava">
|
||||||
|
<meta
|
||||||
|
property="og:description"
|
||||||
|
content="
|
||||||
|
|
||||||
|
Learn Java programming
|
||||||
|
|
||||||
|
">
|
||||||
|
<meta
|
||||||
|
property="og:type"
|
||||||
|
content="
|
||||||
|
website
|
||||||
|
">
|
||||||
|
<meta property="og:url" content="http://localhost:1313/">
|
||||||
|
|
||||||
|
|
||||||
|
<meta itemprop="name" content="CodeJava">
|
||||||
|
<meta itemprop="description" content="Learn Java programming">
|
||||||
|
<meta name="twitter:card" content="summary">
|
||||||
|
<meta name="twitter:title" content="CodeJava">
|
||||||
|
<meta name="twitter:description" content="Learn Java programming">
|
||||||
|
<link href="/css/compiled/main.css" rel="stylesheet" />
|
||||||
|
<link href="/css/variables.css" rel="stylesheet" />
|
||||||
|
<link href="/css/custom.css" rel="stylesheet" />
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
|
||||||
|
function setTheme(theme) {
|
||||||
|
document.documentElement.classList.remove("light", "dark");
|
||||||
|
|
||||||
|
if (theme !== "light" && theme !== "dark") {
|
||||||
|
theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
|
||||||
|
}
|
||||||
|
|
||||||
|
document.documentElement.classList.add(theme);
|
||||||
|
document.documentElement.style.colorScheme = theme;
|
||||||
|
}
|
||||||
|
|
||||||
|
setTheme("color-theme" in localStorage ? localStorage.getItem("color-theme") : 'system')
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
|
||||||
|
if (localStorage.getItem('banner-closed')) {
|
||||||
|
document.documentElement.style.setProperty("--hextra-banner-height", "0px");
|
||||||
|
document.documentElement.classList.add("hextra-banner-hidden");
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</head>
|
||||||
|
<body><div class="hextra-nav-container hx:sticky hx:top-0 hx:z-20 hx:w-full hx:bg-transparent hx:print:hidden">
|
||||||
|
<div
|
||||||
|
class="hextra-nav-container-blur hx:pointer-events-none hx:absolute hx:z-[-1] hx:h-full hx:w-full hx:bg-white hx:dark:bg-dark hx:shadow-[0_2px_4px_rgba(0,0,0,.02),0_1px_0_rgba(0,0,0,.06)] hx:contrast-more:shadow-[0_0_0_1px_#000] hx:dark:shadow-[0_-1px_0_rgba(255,255,255,.1)_inset] hx:contrast-more:dark:shadow-[0_0_0_1px_#fff]"
|
||||||
|
></div>
|
||||||
|
|
||||||
|
<nav class="hextra-max-navbar-width hx:mx-auto hx:flex hx:items-center hx:justify-end hx:gap-2 hx:h-16 hx:px-6">
|
||||||
|
<a class="hx:flex hx:items-center hx:hover:opacity-75 hx:ltr:mr-auto hx:rtl:ml-auto" href="/">
|
||||||
|
<img class="hx:mr-2 hx:block hx:dark:hidden" src="/images/logo.svg" alt="Logo" height="20" width="20" />
|
||||||
|
<img class="hx:mr-2 hx:hidden hx:dark:block" src="/images/logo.svg" alt="Dark Logo" height="20" width="20" />
|
||||||
|
<span class="hx:mr-2 hx:font-extrabold hx:inline hx:select-none" title="CodeJava">CodeJava</span>
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
title=""
|
||||||
|
href="/courses"
|
||||||
|
|
||||||
|
class="hx:text-sm hx:contrast-more:text-gray-700 hx:contrast-more:dark:text-gray-100 hx:relative hx:-ml-2 hx:hidden hx:whitespace-nowrap hx:p-2 hx:md:inline-flex hx:items-center hx:gap-1 hx:text-gray-600 hx:hover:text-gray-800 hx:dark:text-gray-400 hx:dark:hover:text-gray-200"
|
||||||
|
><span class="hx:text-center">Courses</span>
|
||||||
|
</a><div class="hextra-search-wrapper hx:relative hx:md:w-64">
|
||||||
|
<div class="hx:relative hx:flex hx:items-center hx:text-gray-900 hx:contrast-more:text-gray-800 hx:dark:text-gray-300 hx:contrast-more:dark:text-gray-300">
|
||||||
|
<input
|
||||||
|
placeholder="Search..."
|
||||||
|
class="hextra-search-input hx:focus:hextra-focus hx:block hx:w-full hx:appearance-none hx:rounded-lg hx:px-3 hx:py-2 hx:transition-colors hx:text-base hx:leading-tight hx:md:text-sm hx:bg-black/[.05] hx:dark:bg-gray-50/10 hx:focus:bg-white hx:dark:focus:bg-dark hx:placeholder:text-gray-500 hx:dark:placeholder:text-gray-400 hx:contrast-more:border hx:contrast-more:border-current"
|
||||||
|
type="search"
|
||||||
|
value=""
|
||||||
|
spellcheck="false"
|
||||||
|
/>
|
||||||
|
<kbd
|
||||||
|
class="hx:absolute hx:my-1.5 hx:select-none hx:ltr:right-1.5 hx:rtl:left-1.5 hx:h-5 hx:rounded-sm hx:bg-white hx:px-1.5 hx:font-mono hx:text-[10px] hx:font-medium hx:text-gray-500 hx:border hx:border-gray-200 hx:dark:border-gray-100/20 hx:dark:bg-dark/50 hx:contrast-more:border-current hx:contrast-more:text-current hx:contrast-more:dark:border-current hx:items-center hx:gap-1 hx:transition-opacity hx:pointer-events-none hx:hidden hx:sm:flex"
|
||||||
|
>
|
||||||
|
CTRL K
|
||||||
|
</kbd>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<ul
|
||||||
|
class="hextra-search-results hextra-scrollbar hx:hidden hx:border hx:border-gray-200 hx:bg-white hx:text-gray-100 hx:dark:border-neutral-800 hx:dark:bg-neutral-900 hx:absolute hx:top-full hx:z-20 hx:mt-2 hx:overflow-auto hx:overscroll-contain hx:rounded-xl hx:py-2.5 hx:shadow-xl hx:max-h-[min(calc(50vh-11rem-env(safe-area-inset-bottom)),400px)] hx:md:max-h-[min(calc(100vh-5rem-env(safe-area-inset-bottom)),400px)] hx:inset-x-0 hx:ltr:md:left-auto hx:rtl:md:right-auto hx:contrast-more:border hx:contrast-more:border-gray-900 hx:contrast-more:dark:border-gray-50 hx:w-screen hx:min-h-[100px] hx:max-w-[min(calc(100vw-2rem),calc(100%+20rem))]"
|
||||||
|
style="transition: max-height 0.2s ease 0s;"
|
||||||
|
></ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button type="button" aria-label="Menu" class="hextra-hamburger-menu hx:cursor-pointer hx:-mr-2 hx:rounded-sm hx:p-2 hx:active:bg-gray-400/20 hx:md:hidden"><svg height=24 fill="none" viewBox="0 0 24 24" stroke="currentColor"><g><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 8H20"></path></g><g><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16H20"></path></g></svg></button>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class='hx:mx-auto hx:flex hextra-max-page-width'>
|
||||||
|
<aside class="hextra-sidebar-container hx:flex hx:flex-col hx:print:hidden hx:md:top-16 hx:md:shrink-0 hx:md:w-64 hx:md:self-start hx:max-md:[transform:translate3d(0,-100%,0)] hx:md:hidden hx:xl:block">
|
||||||
|
|
||||||
|
<div class="hx:px-4 hx:pt-4 hx:md:hidden">
|
||||||
|
<div class="hextra-search-wrapper hx:relative hx:md:w-64">
|
||||||
|
<div class="hx:relative hx:flex hx:items-center hx:text-gray-900 hx:contrast-more:text-gray-800 hx:dark:text-gray-300 hx:contrast-more:dark:text-gray-300">
|
||||||
|
<input
|
||||||
|
placeholder="Search..."
|
||||||
|
class="hextra-search-input hx:focus:hextra-focus hx:block hx:w-full hx:appearance-none hx:rounded-lg hx:px-3 hx:py-2 hx:transition-colors hx:text-base hx:leading-tight hx:md:text-sm hx:bg-black/[.05] hx:dark:bg-gray-50/10 hx:focus:bg-white hx:dark:focus:bg-dark hx:placeholder:text-gray-500 hx:dark:placeholder:text-gray-400 hx:contrast-more:border hx:contrast-more:border-current"
|
||||||
|
type="search"
|
||||||
|
value=""
|
||||||
|
spellcheck="false"
|
||||||
|
/>
|
||||||
|
<kbd
|
||||||
|
class="hx:absolute hx:my-1.5 hx:select-none hx:ltr:right-1.5 hx:rtl:left-1.5 hx:h-5 hx:rounded-sm hx:bg-white hx:px-1.5 hx:font-mono hx:text-[10px] hx:font-medium hx:text-gray-500 hx:border hx:border-gray-200 hx:dark:border-gray-100/20 hx:dark:bg-dark/50 hx:contrast-more:border-current hx:contrast-more:text-current hx:contrast-more:dark:border-current hx:items-center hx:gap-1 hx:transition-opacity hx:pointer-events-none hx:hidden hx:sm:flex"
|
||||||
|
>
|
||||||
|
CTRL K
|
||||||
|
</kbd>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<ul
|
||||||
|
class="hextra-search-results hextra-scrollbar hx:hidden hx:border hx:border-gray-200 hx:bg-white hx:text-gray-100 hx:dark:border-neutral-800 hx:dark:bg-neutral-900 hx:absolute hx:top-full hx:z-20 hx:mt-2 hx:overflow-auto hx:overscroll-contain hx:rounded-xl hx:py-2.5 hx:shadow-xl hx:max-h-[min(calc(50vh-11rem-env(safe-area-inset-bottom)),400px)] hx:md:max-h-[min(calc(100vh-5rem-env(safe-area-inset-bottom)),400px)] hx:inset-x-0 hx:ltr:md:left-auto hx:rtl:md:right-auto hx:contrast-more:border hx:contrast-more:border-gray-900 hx:contrast-more:dark:border-gray-50 hx:w-screen hx:min-h-[100px] hx:max-w-[min(calc(100vw-2rem),calc(100%+20rem))]"
|
||||||
|
style="transition: max-height 0.2s ease 0s;"
|
||||||
|
></ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="hextra-scrollbar hx:overflow-y-auto hx:overflow-x-hidden hx:p-4 hx:grow hx:md:h-[calc(100vh-var(--navbar-height)-var(--menu-height))]">
|
||||||
|
<ul class="hx:flex hx:flex-col hx:gap-1 hx:md:hidden">
|
||||||
|
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<div class="hx:max-xl:hidden hx:h-0 hx:w-64 hx:shrink-0"></div></div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="hx:md:hidden hx:sticky hx:bottom-0 hx:max-h-(--menu-height) hx:bg-white hx:dark:bg-dark hx:mx-4 hx:py-4 hx:shadow-[0_-12px_16px_#fff] hx:flex hx:items-center hx:gap-2 hx:border-gray-200 hx:dark:border-neutral-800 hx:dark:shadow-[0_-12px_16px_#111] hx:contrast-more:border-neutral-400 hx:contrast-more:shadow-none hx:contrast-more:dark:shadow-none hx:border-t" data-toggle-animation="show"><div class="hx:flex hx:grow hx:flex-col"><div class="hx:flex hx:justify-items-start hx:group" data-theme="light">
|
||||||
|
<button
|
||||||
|
title="Change theme"
|
||||||
|
data-state="closed"
|
||||||
|
data-location="bottom"
|
||||||
|
class="hextra-theme-toggle hx:cursor-pointer hx:rounded-md hx:text-left hx:font-medium hx:h-7 hx:px-2 hx:text-xs hx:hover:bg-gray-100 hx:hover:text-gray-900 hx:dark:hover:bg-primary-100/5 hx:dark:hover:text-gray-50 hx:font-medium hx:text-gray-600 hx:transition-colors hx:dark:text-gray-400 hx:grow"
|
||||||
|
type="button"
|
||||||
|
aria-label="Change theme"
|
||||||
|
>
|
||||||
|
<div class="hx:flex hx:items-center hx:gap-2 hx:capitalize"><svg height=12 class="hx:group-data-[theme=dark]:hidden hx:group-data-[theme=system]:hidden" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z"/></svg><span class="hx:group-data-[theme=dark]:hidden hx:group-data-[theme=system]:hidden">Light</span><svg height=12 class="hx:group-data-[theme=light]:hidden hx:group-data-[theme=system]:hidden" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z"/></svg><span class="hx:group-data-[theme=light]:hidden hx:group-data-[theme=system]:hidden">Dark</span><svg height=12 class="hx:group-data-[theme=dark]:hidden hx:group-data-[theme=light]:hidden" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
|
||||||
|
<path d="M 11.996094,2 C 6.4986225,2.0192368 2.03125,6.5024993 2.03125,12 c 0,5.497501 4.4673725,9.980763 9.964844,10 H 12 12.0039 c 5.497471,-0.01924 9.964844,-4.502499 9.964844,-10 0,-5.4975007 -4.467373,-9.9807632 -9.964844,-10 H 12 Z M 12,4 c 4.417218,0.017598 7.96875,3.5822356 7.96875,8 0,4.417764 -3.551532,7.982402 -7.96875,8 z" />
|
||||||
|
</svg>
|
||||||
|
<span class="hx:group-data-[theme=dark]:hidden hx:group-data-[theme=light]:hidden">System</span></div>
|
||||||
|
</button>
|
||||||
|
<ul
|
||||||
|
class="hextra-theme-toggle-options hx:hidden hx:z-20 hx:max-h-64 hx:overflow-auto hx:rounded-md hx:ring-1 hx:ring-black/5 hx:bg-white hx:py-1 hx:text-sm hx:shadow-lg hx:dark:ring-white/20 hx:dark:bg-neutral-800"
|
||||||
|
style="position: fixed; inset: auto auto 0px 0px; margin: 0px; min-width: 100px;"
|
||||||
|
data-theme="light"
|
||||||
|
>
|
||||||
|
<li class="hx:flex hx:flex-col">
|
||||||
|
<p
|
||||||
|
data-item="light"
|
||||||
|
class="hx:text-gray-800 hx:dark:text-gray-100 hx:hover:bg-primary-50 hx:hover:text-primary-600 hx:hover:dark:bg-primary-500/10 hx:hover:dark:text-primary-600 hx:relative hx:cursor-pointer hx:whitespace-nowrap hx:py-1.5 hx:transition-colors hx:ltr:pl-3 hx:ltr:pr-9 hx:rtl:pr-3 hx:rtl:pl-9"
|
||||||
|
>
|
||||||
|
Light
|
||||||
|
<span class="hx:absolute hx:inset-y-0 hx:flex hx:items-center hx:ltr:right-3 hx:rtl:left-3 hx:group-data-[theme=dark]:hidden hx:group-data-[theme=system]:hidden"><svg height=1em width=1em xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7"/></svg></span>
|
||||||
|
</p>
|
||||||
|
</li>
|
||||||
|
<li class="hx:flex hx:flex-col">
|
||||||
|
<p
|
||||||
|
data-item="dark"
|
||||||
|
class="hx:text-gray-800 hx:dark:text-gray-100 hx:hover:bg-primary-50 hx:hover:text-primary-600 hx:hover:dark:bg-primary-500/10 hx:hover:dark:text-primary-600 hx:relative hx:cursor-pointer hx:whitespace-nowrap hx:py-1.5 hx:transition-colors hx:ltr:pl-3 hx:ltr:pr-9 hx:rtl:pr-3 hx:rtl:pl-9"
|
||||||
|
>
|
||||||
|
Dark
|
||||||
|
<span class="hx:absolute hx:inset-y-0 hx:flex hx:items-center hx:ltr:right-3 hx:rtl:left-3 hx:group-data-[theme=light]:hidden hx:group-data-[theme=system]:hidden"><svg height=1em width=1em xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7"/></svg></span>
|
||||||
|
</p>
|
||||||
|
</li>
|
||||||
|
<li class="hx:flex hx:flex-col">
|
||||||
|
<p
|
||||||
|
data-item="system"
|
||||||
|
class="hx:text-gray-800 hx:dark:text-gray-100 hx:hover:bg-primary-50 hx:hover:text-primary-600 hx:hover:dark:bg-primary-500/10 hx:hover:dark:text-primary-600 hx:relative hx:cursor-pointer hx:whitespace-nowrap hx:py-1.5 hx:transition-colors hx:ltr:pl-3 hx:ltr:pr-9 hx:rtl:pr-3 hx:rtl:pl-9"
|
||||||
|
>
|
||||||
|
System
|
||||||
|
<span class="hx:absolute hx:inset-y-0 hx:flex hx:items-center hx:ltr:right-3 hx:rtl:left-3 hx:group-data-[theme=dark]:hidden hx:group-data-[theme=light]:hidden"><svg height=1em width=1em xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7"/></svg></span>
|
||||||
|
</p>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div></div></div></aside>
|
||||||
|
|
||||||
|
<nav class="hextra-toc hx:order-last hx:hidden hx:w-64 hx:shrink-0 hx:xl:block hx:print:hidden hx:px-4" aria-label="table of contents">
|
||||||
|
<div class="hextra-scrollbar hx:sticky hx:top-16 hx:overflow-y-auto hx:pr-4 hx:pt-6 hx:text-sm [hyphens:auto] hx:max-h-[calc(100vh-var(--navbar-height)-env(safe-area-inset-bottom))] hx:ltr:-mr-4 hx:rtl:-ml-4">
|
||||||
|
<div class=" hx:sticky hx:bottom-0 hx:flex hx:flex-col hx:items-start hx:gap-2 hx:pb-8 hx:border-gray-200 hx:dark:border-neutral-800 hx:contrast-more:border-t hx:contrast-more:border-neutral-400 hx:contrast-more:shadow-none hx:contrast-more:dark:border-neutral-400">
|
||||||
|
<button aria-hidden="true" id="backToTop" onClick="scrollUp();" class="hx:cursor-pointer hx:transition-all hx:duration-75 hx:opacity-0 hx:text-xs hx:font-medium hx:text-gray-500 hx:hover:text-gray-900 hx:dark:text-gray-400 hx:dark:hover:text-gray-100 hx:contrast-more:text-gray-800 hx:contrast-more:dark:text-gray-50">
|
||||||
|
<span>Scroll to top</span>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="hx:inline hx:ltr:ml-1 hx:rtl:mr-1 hx:h-3.5 hx:w-3.5 hx:rounded-full hx:border hx:border-gray-500 hx:hover:border-gray-900 hx:dark:border-gray-400 hx:dark:hover:border-gray-100 hx:contrast-more:border-gray-800 hx:contrast-more:dark:border-gray-50">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" d="M4.5 15.75l7.5-7.5 7.5 7.5" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
|
||||||
|
<article class="hx:w-full hx:break-words hx:flex hx:min-h-[calc(100vh-var(--navbar-height))] hx:min-w-0 hx:justify-center hx:pb-8 hx:pr-[calc(env(safe-area-inset-right)-1.5rem)]">
|
||||||
|
<main class="hx:w-full hx:min-w-0 hx:max-w-6xl hx:px-6 hx:pt-4 hx:md:px-12">
|
||||||
|
<h1 class="hx:text-center hx:mt-2 hx:text-4xl hx:font-bold hx:tracking-tight hx:text-slate-900 hx:dark:text-slate-100">CodeJava</h1>
|
||||||
|
<div class="content">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
</article>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<footer class="hextra-footer hx:bg-gray-100 hx:pb-[env(safe-area-inset-bottom)] hx:dark:bg-neutral-900 hx:print:bg-transparent"><div class="hx:mx-auto hx:flex hx:gap-2 hx:py-2 hx:px-4 hextra-max-footer-width"><div class="hx:flex hx:justify-items-start hx:group" data-theme="light">
|
||||||
|
<button
|
||||||
|
title="Change theme"
|
||||||
|
data-state="closed"
|
||||||
|
data-location="bottom"
|
||||||
|
class="hextra-theme-toggle hx:cursor-pointer hx:rounded-md hx:text-left hx:font-medium hx:h-7 hx:px-2 hx:text-xs hx:hover:bg-gray-100 hx:hover:text-gray-900 hx:dark:hover:bg-primary-100/5 hx:dark:hover:text-gray-50 hx:font-medium hx:text-gray-600 hx:transition-colors hx:dark:text-gray-400 hx:grow"
|
||||||
|
type="button"
|
||||||
|
aria-label="Change theme"
|
||||||
|
>
|
||||||
|
<div class="hx:flex hx:items-center hx:gap-2 hx:capitalize"><svg height=12 class="hx:group-data-[theme=dark]:hidden hx:group-data-[theme=system]:hidden" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z"/></svg><span class="hx:group-data-[theme=dark]:hidden hx:group-data-[theme=system]:hidden">Light</span><svg height=12 class="hx:group-data-[theme=light]:hidden hx:group-data-[theme=system]:hidden" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z"/></svg><span class="hx:group-data-[theme=light]:hidden hx:group-data-[theme=system]:hidden">Dark</span><svg height=12 class="hx:group-data-[theme=dark]:hidden hx:group-data-[theme=light]:hidden" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
|
||||||
|
<path d="M 11.996094,2 C 6.4986225,2.0192368 2.03125,6.5024993 2.03125,12 c 0,5.497501 4.4673725,9.980763 9.964844,10 H 12 12.0039 c 5.497471,-0.01924 9.964844,-4.502499 9.964844,-10 0,-5.4975007 -4.467373,-9.9807632 -9.964844,-10 H 12 Z M 12,4 c 4.417218,0.017598 7.96875,3.5822356 7.96875,8 0,4.417764 -3.551532,7.982402 -7.96875,8 z" />
|
||||||
|
</svg>
|
||||||
|
<span class="hx:group-data-[theme=dark]:hidden hx:group-data-[theme=light]:hidden">System</span></div>
|
||||||
|
</button>
|
||||||
|
<ul
|
||||||
|
class="hextra-theme-toggle-options hx:hidden hx:z-20 hx:max-h-64 hx:overflow-auto hx:rounded-md hx:ring-1 hx:ring-black/5 hx:bg-white hx:py-1 hx:text-sm hx:shadow-lg hx:dark:ring-white/20 hx:dark:bg-neutral-800"
|
||||||
|
style="position: fixed; inset: auto auto 0px 0px; margin: 0px; min-width: 100px;"
|
||||||
|
data-theme="light"
|
||||||
|
>
|
||||||
|
<li class="hx:flex hx:flex-col">
|
||||||
|
<p
|
||||||
|
data-item="light"
|
||||||
|
class="hx:text-gray-800 hx:dark:text-gray-100 hx:hover:bg-primary-50 hx:hover:text-primary-600 hx:hover:dark:bg-primary-500/10 hx:hover:dark:text-primary-600 hx:relative hx:cursor-pointer hx:whitespace-nowrap hx:py-1.5 hx:transition-colors hx:ltr:pl-3 hx:ltr:pr-9 hx:rtl:pr-3 hx:rtl:pl-9"
|
||||||
|
>
|
||||||
|
Light
|
||||||
|
<span class="hx:absolute hx:inset-y-0 hx:flex hx:items-center hx:ltr:right-3 hx:rtl:left-3 hx:group-data-[theme=dark]:hidden hx:group-data-[theme=system]:hidden"><svg height=1em width=1em xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7"/></svg></span>
|
||||||
|
</p>
|
||||||
|
</li>
|
||||||
|
<li class="hx:flex hx:flex-col">
|
||||||
|
<p
|
||||||
|
data-item="dark"
|
||||||
|
class="hx:text-gray-800 hx:dark:text-gray-100 hx:hover:bg-primary-50 hx:hover:text-primary-600 hx:hover:dark:bg-primary-500/10 hx:hover:dark:text-primary-600 hx:relative hx:cursor-pointer hx:whitespace-nowrap hx:py-1.5 hx:transition-colors hx:ltr:pl-3 hx:ltr:pr-9 hx:rtl:pr-3 hx:rtl:pl-9"
|
||||||
|
>
|
||||||
|
Dark
|
||||||
|
<span class="hx:absolute hx:inset-y-0 hx:flex hx:items-center hx:ltr:right-3 hx:rtl:left-3 hx:group-data-[theme=light]:hidden hx:group-data-[theme=system]:hidden"><svg height=1em width=1em xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7"/></svg></span>
|
||||||
|
</p>
|
||||||
|
</li>
|
||||||
|
<li class="hx:flex hx:flex-col">
|
||||||
|
<p
|
||||||
|
data-item="system"
|
||||||
|
class="hx:text-gray-800 hx:dark:text-gray-100 hx:hover:bg-primary-50 hx:hover:text-primary-600 hx:hover:dark:bg-primary-500/10 hx:hover:dark:text-primary-600 hx:relative hx:cursor-pointer hx:whitespace-nowrap hx:py-1.5 hx:transition-colors hx:ltr:pl-3 hx:ltr:pr-9 hx:rtl:pr-3 hx:rtl:pl-9"
|
||||||
|
>
|
||||||
|
System
|
||||||
|
<span class="hx:absolute hx:inset-y-0 hx:flex hx:items-center hx:ltr:right-3 hx:rtl:left-3 hx:group-data-[theme=dark]:hidden hx:group-data-[theme=light]:hidden"><svg height=1em width=1em xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7"/></svg></span>
|
||||||
|
</p>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div></div><hr class="hx:border-gray-200 hx:dark:border-neutral-800" /><div class="hextra-custom-footer hextra-max-footer-width hx:pl-[max(env(safe-area-inset-left),1.5rem)] hx:pr-[max(env(safe-area-inset-right),1.5rem)] hx:text-gray-600 hx:dark:text-gray-400"></div><div
|
||||||
|
class="hextra-max-footer-width hx:mx-auto hx:flex hx:justify-center hx:py-12 hx:pl-[max(env(safe-area-inset-left),1.5rem)] hx:pr-[max(env(safe-area-inset-right),1.5rem)] hx:text-gray-600 hx:dark:text-gray-400 hx:md:justify-start"
|
||||||
|
>
|
||||||
|
<div class="hx:flex hx:w-full hx:flex-col hx:items-center hx:sm:items-start"><div class="hx:font-semibold"><a class="hx:flex hx:text-sm hx:items-center hx:gap-1 hx:text-current" target="_blank" rel="noopener noreferrer" title="Hextra GitHub Homepage" href="https://github.com/imfing/hextra">
|
||||||
|
<span>Powered by Hextra<svg height=1em class="hx:inline-block hx:ltr:ml-1 hx:rtl:mr-1 hx:align-[-2.5px]" viewBox="0 0 180 180" xmlns="http://www.w3.org/2000/svg" fill="currentColor"><path fill-rule="evenodd" clip-rule="evenodd" d="m 105.50024,22.224647 c -9.59169,-5.537563 -21.40871,-5.537563 -31.000093,0 L 39.054693,42.689119 C 29.463353,48.226675 23.55484,58.460531 23.55484,69.535642 v 40.928918 c 0,11.07542 5.908513,21.3092 15.499853,26.84652 l 35.445453,20.46446 c 9.591313,5.53732 21.408404,5.53732 31.000094,0 l 35.44507,-20.46446 c 9.59131,-5.53732 15.49985,-15.7711 15.49985,-26.84652 V 69.535642 c 0,-11.075111 -5.90854,-21.308967 -15.49985,-26.846523 z M 34.112797,85.737639 c -1.384445,2.397827 -1.384445,5.352099 0,7.749927 l 24.781554,42.922974 c 1.38437,2.39783 3.942853,3.87496 6.711592,3.87496 h 49.563107 c 2.76905,0 5.3273,-1.47713 6.71144,-3.87496 l 24.78194,-42.922974 c 1.38414,-2.397828 1.38414,-5.3521 0,-7.749927 L 121.88049,42.814746 c -1.38414,-2.397828 -3.94239,-3.874964 -6.71144,-3.874964 H 65.605944 c -2.768739,0 -5.327223,1.477059 -6.711592,3.874964 z" style="stroke-width:0.774993" /></svg></span>
|
||||||
|
</a></div></div>
|
||||||
|
</div></footer>
|
||||||
|
|
||||||
|
<script defer src="/js/main.js" integrity=""></script>
|
||||||
|
<script defer src="/js/flexsearch.9f5b5908f93ae86f1ecd4b043b799f580c2d1654e703dd9357d568ac41b2547a.js" integrity="sha256-n1tZCPk66G8ezUsEO3mfWAwtFlTnA92TV9VorEGyVHo=" crossorigin="anonymous"></script>
|
||||||
|
<script defer src="/en.search.js" integrity=""></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
17
public/index.xml
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
||||||
|
<channel>
|
||||||
|
<title>CodeJava – CodeJava</title>
|
||||||
|
<link>http://localhost:1313/</link>
|
||||||
|
<description>Recent content on CodeJava</description>
|
||||||
|
<generator>Hugo -- gohugo.io</generator>
|
||||||
|
<language>en</language>
|
||||||
|
|
||||||
|
<atom:link href="http://localhost:1313/index.xml" rel="self" type="application/rss+xml" />
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</channel>
|
||||||
|
</rss>
|
||||||
574
public/js/main.js
Normal file
@@ -0,0 +1,574 @@
|
|||||||
|
function computeMenuTranslation(switcher, optionsElement) {
|
||||||
|
// Calculate the position of a language options element.
|
||||||
|
const switcherRect = switcher.getBoundingClientRect();
|
||||||
|
|
||||||
|
// Must be called before optionsElement.clientWidth.
|
||||||
|
optionsElement.style.minWidth = `${Math.max(switcherRect.width, 50)}px`;
|
||||||
|
|
||||||
|
const isOnTop = switcher.dataset.location === 'top';
|
||||||
|
const isOnBottom = switcher.dataset.location === 'bottom';
|
||||||
|
const isOnBottomRight = switcher.dataset.location === 'bottom-right';
|
||||||
|
const isRTL = document.documentElement.dir === 'rtl'
|
||||||
|
|
||||||
|
// Stuck on the left side of the switcher.
|
||||||
|
let x = switcherRect.left;
|
||||||
|
|
||||||
|
if (isOnTop && !isRTL || isOnBottom && isRTL || isOnBottomRight && !isRTL) {
|
||||||
|
// Stuck on the right side of the switcher.
|
||||||
|
x = switcherRect.right - optionsElement.clientWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stuck on the top of the switcher.
|
||||||
|
let y = switcherRect.top - window.innerHeight - 10;
|
||||||
|
|
||||||
|
if (isOnTop) {
|
||||||
|
// Stuck on the bottom of the switcher.
|
||||||
|
y = switcherRect.top - window.innerHeight + optionsElement.clientHeight + switcher.clientHeight + 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
return { x: x, y: y };
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleMenu(switcher) {
|
||||||
|
const optionsElement = switcher.nextElementSibling;
|
||||||
|
|
||||||
|
optionsElement.classList.toggle('hx:hidden');
|
||||||
|
|
||||||
|
// Calculate the position of a language options element.
|
||||||
|
const translate = computeMenuTranslation(switcher, optionsElement);
|
||||||
|
|
||||||
|
optionsElement.style.transform = `translate3d(${translate.x}px, ${translate.y}px, 0)`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function resizeMenu(switcher) {
|
||||||
|
const optionsElement = switcher.nextElementSibling;
|
||||||
|
|
||||||
|
if (optionsElement.classList.contains('hx:hidden')) return;
|
||||||
|
|
||||||
|
// Calculate the position of a language options element.
|
||||||
|
const translate = computeMenuTranslation(switcher, optionsElement);
|
||||||
|
|
||||||
|
optionsElement.style.transform = `translate3d(${translate.x}px, ${translate.y}px, 0)`;
|
||||||
|
}
|
||||||
|
|
||||||
|
;
|
||||||
|
// Light / Dark theme toggle
|
||||||
|
(function () {
|
||||||
|
const defaultTheme = 'system'
|
||||||
|
const themes = ["light", "dark"];
|
||||||
|
|
||||||
|
const themeToggleButtons = document.querySelectorAll(".hextra-theme-toggle");
|
||||||
|
const themeToggleOptions = document.querySelectorAll(".hextra-theme-toggle-options p");
|
||||||
|
|
||||||
|
function applyTheme(theme) {
|
||||||
|
theme = themes.includes(theme) ? theme : "system";
|
||||||
|
|
||||||
|
themeToggleButtons.forEach((btn) => btn.parentElement.dataset.theme = theme );
|
||||||
|
|
||||||
|
localStorage.setItem("color-theme", theme);
|
||||||
|
}
|
||||||
|
|
||||||
|
function switchTheme(theme) {
|
||||||
|
setTheme(theme);
|
||||||
|
applyTheme(theme);
|
||||||
|
}
|
||||||
|
|
||||||
|
const colorTheme = "color-theme" in localStorage ? localStorage.getItem("color-theme") : defaultTheme;
|
||||||
|
switchTheme(colorTheme);
|
||||||
|
|
||||||
|
// Add click event handler to the menu items.
|
||||||
|
themeToggleOptions.forEach((option) => {
|
||||||
|
option.addEventListener("click", function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
switchTheme(option.dataset.item);
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
// Add click event handler to the buttons
|
||||||
|
themeToggleButtons.forEach((toggler) => {
|
||||||
|
toggler.addEventListener("click", function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
toggleMenu(toggler);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
window.addEventListener("resize", () => themeToggleButtons.forEach(resizeMenu))
|
||||||
|
|
||||||
|
// Dismiss the menu when clicking outside
|
||||||
|
document.addEventListener('click', (e) => {
|
||||||
|
if (e.target.closest('.hextra-theme-toggle') === null) {
|
||||||
|
themeToggleButtons.forEach((toggler) => {
|
||||||
|
toggler.dataset.state = 'closed';
|
||||||
|
toggler.nextElementSibling.classList.add('hx:hidden');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Listen for system theme changes
|
||||||
|
window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", () => {
|
||||||
|
if (localStorage.getItem("color-theme") === "system") {
|
||||||
|
setTheme("system");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
|
||||||
|
;
|
||||||
|
//
|
||||||
|
;
|
||||||
|
// Hamburger menu for mobile navigation
|
||||||
|
|
||||||
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
|
const menu = document.querySelector('.hextra-hamburger-menu');
|
||||||
|
const sidebarContainer = document.querySelector('.hextra-sidebar-container');
|
||||||
|
|
||||||
|
function toggleMenu() {
|
||||||
|
// Toggle the hamburger menu
|
||||||
|
menu.querySelector('svg').classList.toggle('open');
|
||||||
|
|
||||||
|
// When the menu is open, we want to show the navigation sidebar
|
||||||
|
sidebarContainer.classList.toggle('hx:max-md:[transform:translate3d(0,-100%,0)]');
|
||||||
|
sidebarContainer.classList.toggle('hx:max-md:[transform:translate3d(0,0,0)]');
|
||||||
|
|
||||||
|
// When the menu is open, we want to prevent the body from scrolling
|
||||||
|
document.body.classList.toggle('hx:overflow-hidden');
|
||||||
|
document.body.classList.toggle('hx:md:overflow-auto');
|
||||||
|
}
|
||||||
|
|
||||||
|
menu.addEventListener('click', (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
toggleMenu();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Select all anchor tags in the sidebar container
|
||||||
|
const sidebarLinks = sidebarContainer.querySelectorAll('a');
|
||||||
|
|
||||||
|
// Add click event listener to each anchor tag
|
||||||
|
sidebarLinks.forEach(link => {
|
||||||
|
link.addEventListener('click', (e) => {
|
||||||
|
// Check if the href attribute contains a hash symbol (links to a heading)
|
||||||
|
if (link.getAttribute('href') && link.getAttribute('href').startsWith('#')) {
|
||||||
|
// Only dismiss overlay on mobile view
|
||||||
|
if (window.innerWidth < 768) {
|
||||||
|
toggleMenu();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
;
|
||||||
|
// Copy button for code blocks
|
||||||
|
|
||||||
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
|
const getCopyIcon = () => {
|
||||||
|
const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
|
||||||
|
svg.innerHTML = `
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z" />
|
||||||
|
`;
|
||||||
|
svg.setAttribute('fill', 'none');
|
||||||
|
svg.setAttribute('viewBox', '0 0 24 24');
|
||||||
|
svg.setAttribute('stroke', 'currentColor');
|
||||||
|
svg.setAttribute('stroke-width', '2');
|
||||||
|
return svg;
|
||||||
|
}
|
||||||
|
|
||||||
|
const getSuccessIcon = () => {
|
||||||
|
const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
|
||||||
|
svg.innerHTML = `
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7" />
|
||||||
|
`;
|
||||||
|
svg.setAttribute('fill', 'none');
|
||||||
|
svg.setAttribute('viewBox', '0 0 24 24');
|
||||||
|
svg.setAttribute('stroke', 'currentColor');
|
||||||
|
svg.setAttribute('stroke-width', '2');
|
||||||
|
return svg;
|
||||||
|
}
|
||||||
|
|
||||||
|
document.querySelectorAll('.hextra-code-copy-btn').forEach(function (button) {
|
||||||
|
// Add copy and success icons
|
||||||
|
button.querySelector('.hextra-copy-icon')?.appendChild(getCopyIcon());
|
||||||
|
button.querySelector('.hextra-success-icon')?.appendChild(getSuccessIcon());
|
||||||
|
|
||||||
|
// Add click event listener for copy button
|
||||||
|
button.addEventListener('click', function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
// Get the code target
|
||||||
|
const target = button.parentElement.previousElementSibling;
|
||||||
|
let codeElement;
|
||||||
|
if (target.tagName === 'CODE') {
|
||||||
|
codeElement = target;
|
||||||
|
} else {
|
||||||
|
// Select the last code element in case line numbers are present
|
||||||
|
const codeElements = target.querySelectorAll('code');
|
||||||
|
codeElement = codeElements[codeElements.length - 1];
|
||||||
|
}
|
||||||
|
if (codeElement) {
|
||||||
|
let code = codeElement.innerText;
|
||||||
|
// Replace double newlines with single newlines in the innerText
|
||||||
|
// as each line inside <span> has trailing newline '\n'
|
||||||
|
if ("lang" in codeElement.dataset) {
|
||||||
|
code = code.replace(/\n\n/g, '\n');
|
||||||
|
}
|
||||||
|
navigator.clipboard.writeText(code).then(function () {
|
||||||
|
button.classList.add('copied');
|
||||||
|
setTimeout(function () {
|
||||||
|
button.classList.remove('copied');
|
||||||
|
}, 1000);
|
||||||
|
}).catch(function (err) {
|
||||||
|
console.error('Failed to copy text: ', err);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
console.error('Target element not found');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
;
|
||||||
|
(function () {
|
||||||
|
function updateGroup(container, index) {
|
||||||
|
const tabs = Array.from(container.querySelectorAll('.hextra-tabs-toggle'));
|
||||||
|
tabs.forEach((tab, i) => {
|
||||||
|
tab.dataset.state = i === index ? 'selected' : '';
|
||||||
|
if (i === index) {
|
||||||
|
tab.setAttribute('aria-selected', 'true');
|
||||||
|
tab.tabIndex = 0;
|
||||||
|
} else {
|
||||||
|
tab.removeAttribute('aria-selected');
|
||||||
|
tab.removeAttribute('tabindex');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const panelsContainer = container.parentElement.nextElementSibling;
|
||||||
|
if (!panelsContainer) return;
|
||||||
|
Array.from(panelsContainer.children).forEach((panel, i) => {
|
||||||
|
panel.dataset.state = i === index ? 'selected' : '';
|
||||||
|
if (i === index) {
|
||||||
|
panel.tabIndex = 0;
|
||||||
|
} else {
|
||||||
|
panel.removeAttribute('tabindex');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const syncGroups = document.querySelectorAll('[data-tab-group]');
|
||||||
|
|
||||||
|
syncGroups.forEach((group) => {
|
||||||
|
const key = encodeURIComponent(group.dataset.tabGroup);
|
||||||
|
const saved = localStorage.getItem('hextra-tab-' + key);
|
||||||
|
if (saved !== null) {
|
||||||
|
updateGroup(group, parseInt(saved, 10));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
document.querySelectorAll('.hextra-tabs-toggle').forEach((button) => {
|
||||||
|
button.addEventListener('click', function (e) {
|
||||||
|
const container = e.target.parentElement;
|
||||||
|
const index = Array.from(container.querySelectorAll('.hextra-tabs-toggle')).indexOf(
|
||||||
|
e.target
|
||||||
|
);
|
||||||
|
|
||||||
|
if (container.dataset.tabGroup) {
|
||||||
|
// Sync behavior: update all tab groups with the same name
|
||||||
|
const tabGroupValue = container.dataset.tabGroup;
|
||||||
|
const key = encodeURIComponent(tabGroupValue);
|
||||||
|
document
|
||||||
|
.querySelectorAll('[data-tab-group="' + tabGroupValue + '"]')
|
||||||
|
.forEach((grp) => updateGroup(grp, index));
|
||||||
|
localStorage.setItem('hextra-tab-' + key, index.toString());
|
||||||
|
} else {
|
||||||
|
// Non-sync behavior: update only this specific tab group
|
||||||
|
updateGroup(container, index);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
|
||||||
|
;
|
||||||
|
(function () {
|
||||||
|
const languageSwitchers = document.querySelectorAll('.hextra-language-switcher');
|
||||||
|
|
||||||
|
languageSwitchers.forEach((switcher) => {
|
||||||
|
switcher.addEventListener('click', (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
switcher.dataset.state = switcher.dataset.state === 'open' ? 'closed' : 'open';
|
||||||
|
|
||||||
|
toggleMenu(switcher);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
window.addEventListener("resize", () => languageSwitchers.forEach(resizeMenu))
|
||||||
|
|
||||||
|
// Dismiss language switcher when clicking outside
|
||||||
|
document.addEventListener('click', (e) => {
|
||||||
|
if (e.target.closest('.hextra-language-switcher') === null) {
|
||||||
|
languageSwitchers.forEach((switcher) => {
|
||||||
|
switcher.dataset.state = 'closed';
|
||||||
|
const optionsElement = switcher.nextElementSibling;
|
||||||
|
optionsElement.classList.add('hx:hidden');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
|
||||||
|
;
|
||||||
|
(function () {
|
||||||
|
const hiddenClass = "hx:hidden";
|
||||||
|
const dropdownToggles = document.querySelectorAll(".hextra-nav-menu-toggle");
|
||||||
|
|
||||||
|
dropdownToggles.forEach((toggle) => {
|
||||||
|
toggle.addEventListener("click", (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
|
||||||
|
// Close all other dropdowns first
|
||||||
|
dropdownToggles.forEach((otherToggle) => {
|
||||||
|
if (otherToggle !== toggle) {
|
||||||
|
otherToggle.dataset.state = "closed";
|
||||||
|
const otherMenuItems = otherToggle.nextElementSibling;
|
||||||
|
otherMenuItems.classList.add(hiddenClass);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Toggle current dropdown
|
||||||
|
const isOpen = toggle.dataset.state === "open";
|
||||||
|
toggle.dataset.state = isOpen ? "closed" : "open";
|
||||||
|
const menuItemsElement = toggle.nextElementSibling;
|
||||||
|
|
||||||
|
if (!isOpen) {
|
||||||
|
// Position dropdown centered with toggle
|
||||||
|
menuItemsElement.style.position = "absolute";
|
||||||
|
menuItemsElement.style.top = "100%";
|
||||||
|
menuItemsElement.style.left = "50%";
|
||||||
|
menuItemsElement.style.transform = "translateX(-50%)";
|
||||||
|
menuItemsElement.style.zIndex = "1000";
|
||||||
|
|
||||||
|
// Show dropdown
|
||||||
|
menuItemsElement.classList.remove(hiddenClass);
|
||||||
|
} else {
|
||||||
|
// Hide dropdown
|
||||||
|
menuItemsElement.classList.add(hiddenClass);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Dismiss dropdown when clicking outside
|
||||||
|
document.addEventListener("click", (e) => {
|
||||||
|
if (e.target.closest(".hextra-nav-menu-toggle") === null) {
|
||||||
|
dropdownToggles.forEach((toggle) => {
|
||||||
|
toggle.dataset.state = "closed";
|
||||||
|
const menuItemsElement = toggle.nextElementSibling;
|
||||||
|
menuItemsElement.classList.add(hiddenClass);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Close dropdowns on escape key
|
||||||
|
document.addEventListener("keydown", (e) => {
|
||||||
|
if (e.key === "Escape") {
|
||||||
|
dropdownToggles.forEach((toggle) => {
|
||||||
|
toggle.dataset.state = "closed";
|
||||||
|
const menuItemsElement = toggle.nextElementSibling;
|
||||||
|
menuItemsElement.classList.add(hiddenClass);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
|
||||||
|
;
|
||||||
|
// Script for filetree shortcode collapsing/expanding folders used in the theme
|
||||||
|
// ======================================================================
|
||||||
|
document.addEventListener("DOMContentLoaded", function () {
|
||||||
|
const folders = document.querySelectorAll(".hextra-filetree-folder");
|
||||||
|
folders.forEach(function (folder) {
|
||||||
|
folder.addEventListener("click", function () {
|
||||||
|
Array.from(folder.children).forEach(function (el) {
|
||||||
|
el.dataset.state = el.dataset.state === "open" ? "closed" : "open";
|
||||||
|
});
|
||||||
|
folder.nextElementSibling.dataset.state = folder.nextElementSibling.dataset.state === "open" ? "closed" : "open";
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
;
|
||||||
|
document.addEventListener("DOMContentLoaded", function () {
|
||||||
|
scrollToActiveItem();
|
||||||
|
enableCollapsibles();
|
||||||
|
});
|
||||||
|
|
||||||
|
function enableCollapsibles() {
|
||||||
|
const buttons = document.querySelectorAll(".hextra-sidebar-collapsible-button");
|
||||||
|
buttons.forEach(function (button) {
|
||||||
|
button.addEventListener("click", function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
const list = button.parentElement.parentElement;
|
||||||
|
if (list) {
|
||||||
|
list.classList.toggle("open")
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function scrollToActiveItem() {
|
||||||
|
const sidebarScrollbar = document.querySelector("aside.hextra-sidebar-container > .hextra-scrollbar");
|
||||||
|
const activeItems = document.querySelectorAll(".hextra-sidebar-active-item");
|
||||||
|
const visibleActiveItem = Array.from(activeItems).find(function (activeItem) {
|
||||||
|
return activeItem.getBoundingClientRect().height > 0;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!visibleActiveItem) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const yOffset = visibleActiveItem.clientHeight;
|
||||||
|
const yDistance = visibleActiveItem.getBoundingClientRect().top - sidebarScrollbar.getBoundingClientRect().top;
|
||||||
|
sidebarScrollbar.scrollTo({
|
||||||
|
behavior: "instant",
|
||||||
|
top: yDistance - yOffset
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
;
|
||||||
|
// Back to top button
|
||||||
|
|
||||||
|
document.addEventListener("DOMContentLoaded", function () {
|
||||||
|
const backToTop = document.querySelector("#backToTop");
|
||||||
|
if (backToTop) {
|
||||||
|
document.addEventListener("scroll", (e) => {
|
||||||
|
if (window.scrollY > 300) {
|
||||||
|
backToTop.classList.remove("hx:opacity-0");
|
||||||
|
} else {
|
||||||
|
backToTop.classList.add("hx:opacity-0");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function scrollUp() {
|
||||||
|
window.scroll({
|
||||||
|
top: 0,
|
||||||
|
left: 0,
|
||||||
|
behavior: "smooth",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
;
|
||||||
|
/**
|
||||||
|
* TOC Scroll - Highlights active TOC links based on visible headings
|
||||||
|
*
|
||||||
|
* Uses Intersection Observer to track heading visibility and applies
|
||||||
|
* 'hextra-toc-active' class to corresponding TOC links. Selects the
|
||||||
|
* topmost heading when multiple are visible.
|
||||||
|
*
|
||||||
|
* Requires: .hextra-toc element, matching heading IDs, toc.css styles
|
||||||
|
*/
|
||||||
|
document.addEventListener("DOMContentLoaded", function () {
|
||||||
|
const toc = document.querySelector(".hextra-toc");
|
||||||
|
if (!toc) return;
|
||||||
|
|
||||||
|
const tocLinks = toc.querySelectorAll('a[href^="#"]');
|
||||||
|
if (tocLinks.length === 0) return;
|
||||||
|
|
||||||
|
const headingIds = Array.from(tocLinks).map((link) => link.getAttribute("href").substring(1));
|
||||||
|
|
||||||
|
const headings = headingIds.map((id) => document.getElementById(decodeURIComponent(id))).filter(Boolean);
|
||||||
|
if (headings.length === 0) return;
|
||||||
|
|
||||||
|
let currentActiveLink = null;
|
||||||
|
let isHashNavigation = false;
|
||||||
|
|
||||||
|
// Create intersection observer
|
||||||
|
const observer = new IntersectionObserver(
|
||||||
|
(entries) => {
|
||||||
|
// Skip observer updates during hash navigation
|
||||||
|
if (isHashNavigation) return;
|
||||||
|
|
||||||
|
const visibleHeadings = entries.filter((entry) => entry.isIntersecting).map((entry) => entry.target);
|
||||||
|
|
||||||
|
if (visibleHeadings.length === 0) return;
|
||||||
|
|
||||||
|
// Find the heading closest to the top of the viewport
|
||||||
|
const topMostHeading = visibleHeadings.reduce((closest, heading) => {
|
||||||
|
const headingTop = heading.getBoundingClientRect().top;
|
||||||
|
const closestTop = closest.getBoundingClientRect().top;
|
||||||
|
return Math.abs(headingTop) < Math.abs(closestTop) ? heading : closest;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Encode the id and make it lowercase to match the TOC link
|
||||||
|
const targetId = encodeURIComponent(topMostHeading.id).toLowerCase();
|
||||||
|
const targetLink = toc.querySelector(`a[href="#${targetId}"]`);
|
||||||
|
|
||||||
|
if (targetLink && targetLink !== currentActiveLink) {
|
||||||
|
// Remove active class from previous link
|
||||||
|
if (currentActiveLink) {
|
||||||
|
currentActiveLink.classList.remove("hextra-toc-active");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add active class to current link
|
||||||
|
targetLink.classList.add("hextra-toc-active");
|
||||||
|
currentActiveLink = targetLink;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
rootMargin: "-20px 0px -60% 0px", // Adjust sensitivity
|
||||||
|
threshold: [0, 0.1, 0.5, 1],
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// Observe all headings
|
||||||
|
headings.forEach((heading) => observer.observe(heading));
|
||||||
|
|
||||||
|
// Handle direct navigation to page with hash
|
||||||
|
function handleHashNavigation() {
|
||||||
|
const hash = window.location.hash; // already url encoded
|
||||||
|
if (hash) {
|
||||||
|
const targetLink = toc.querySelector(`a[href="${hash}"]`);
|
||||||
|
if (targetLink) {
|
||||||
|
// Disable observer temporarily during hash navigation
|
||||||
|
isHashNavigation = true;
|
||||||
|
|
||||||
|
if (currentActiveLink) {
|
||||||
|
currentActiveLink.classList.remove("hextra-toc-active");
|
||||||
|
}
|
||||||
|
targetLink.classList.add("hextra-toc-active");
|
||||||
|
currentActiveLink = targetLink;
|
||||||
|
|
||||||
|
// Re-enable observer after scroll settles
|
||||||
|
setTimeout(() => { isHashNavigation = false; }, 500);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle hash changes navigation
|
||||||
|
window.addEventListener("hashchange", handleHashNavigation);
|
||||||
|
|
||||||
|
// Handle initial load
|
||||||
|
setTimeout(handleHashNavigation, 100);
|
||||||
|
});
|
||||||
|
|
||||||
|
;
|
||||||
|
//
|
||||||
|
(function () {
|
||||||
|
const faviconEl = document.getElementById("favicon-svg");
|
||||||
|
const faviconDarkExists = "false" === "true";
|
||||||
|
|
||||||
|
if (faviconEl && faviconDarkExists) {
|
||||||
|
const lightFavicon = '/favicon.svg';
|
||||||
|
const darkFavicon = '/favicon-dark.svg';
|
||||||
|
|
||||||
|
const darkModeQuery = window.matchMedia("(prefers-color-scheme: dark)");
|
||||||
|
|
||||||
|
function updateFavicon(e) {
|
||||||
|
faviconEl.href = e.matches ? darkFavicon : lightFavicon;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set favicon on load
|
||||||
|
updateFavicon(darkModeQuery);
|
||||||
|
|
||||||
|
// Listen for system preference changes
|
||||||
|
darkModeQuery.addEventListener("change", updateFavicon);
|
||||||
|
}
|
||||||
|
})();
|
||||||
20
public/site.webmanifest
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"name": "Hextra",
|
||||||
|
"short_name": "Hextra",
|
||||||
|
"start_url": "index.html",
|
||||||
|
"icons": [
|
||||||
|
{
|
||||||
|
"src": "android-chrome-192x192.png",
|
||||||
|
"sizes": "192x192",
|
||||||
|
"type": "image/png"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"src": "android-chrome-512x512.png",
|
||||||
|
"sizes": "512x512",
|
||||||
|
"type": "image/png"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"theme_color": "#000000",
|
||||||
|
"background_color": "#000000",
|
||||||
|
"display": "standalone"
|
||||||
|
}
|
||||||
11
public/sitemap.xml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
||||||
|
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
|
||||||
|
xmlns:xhtml="http://www.w3.org/1999/xhtml">
|
||||||
|
<url>
|
||||||
|
<loc>http://localhost:1313/categories/</loc>
|
||||||
|
</url><url>
|
||||||
|
<loc>http://localhost:1313/</loc>
|
||||||
|
</url><url>
|
||||||
|
<loc>http://localhost:1313/tags/</loc>
|
||||||
|
</url>
|
||||||
|
</urlset>
|
||||||
280
public/tags/index.html
Normal file
@@ -0,0 +1,280 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en" dir="ltr"><head><script src="/livereload.js?mindelay=10&v=2&port=1313&path=livereload" data-no-instant defer></script>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="robots" content="noindex, nofollow" />
|
||||||
|
<link rel="icon shortcut" href="/favicon.ico" sizes="32x32" />
|
||||||
|
<link rel="icon" href="/favicon.svg" type="image/svg+xml" id="favicon-svg" />
|
||||||
|
<link rel="icon" href="/favicon-16x16.png" type="image/png" sizes="16x16" />
|
||||||
|
<link rel="icon" href="/favicon-32x32.png" type="image/png" sizes="32x32" />
|
||||||
|
<link rel="apple-touch-icon" href="/apple-touch-icon.png" sizes="180x180" />
|
||||||
|
<link fetchpriority="low" href="/site.webmanifest" rel="manifest" />
|
||||||
|
<title>Tags – CodeJava</title>
|
||||||
|
<meta name="description" content="" /><link rel="canonical" href="http://localhost:1313/tags/" itemprop="url" />
|
||||||
|
|
||||||
|
<meta property="og:title" content="Tags">
|
||||||
|
<meta
|
||||||
|
property="og:description"
|
||||||
|
content="
|
||||||
|
|
||||||
|
Learn Java programming
|
||||||
|
|
||||||
|
">
|
||||||
|
<meta
|
||||||
|
property="og:type"
|
||||||
|
content="
|
||||||
|
website
|
||||||
|
">
|
||||||
|
<meta property="og:url" content="http://localhost:1313/tags/">
|
||||||
|
|
||||||
|
|
||||||
|
<meta itemprop="name" content="Tags">
|
||||||
|
<meta itemprop="description" content="Learn Java programming">
|
||||||
|
<meta name="twitter:card" content="summary">
|
||||||
|
<meta name="twitter:title" content="Tags">
|
||||||
|
<meta name="twitter:description" content="Learn Java programming">
|
||||||
|
<link href="/css/compiled/main.css" rel="stylesheet" />
|
||||||
|
<link href="/css/variables.css" rel="stylesheet" />
|
||||||
|
<link href="/css/custom.css" rel="stylesheet" />
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
|
||||||
|
function setTheme(theme) {
|
||||||
|
document.documentElement.classList.remove("light", "dark");
|
||||||
|
|
||||||
|
if (theme !== "light" && theme !== "dark") {
|
||||||
|
theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
|
||||||
|
}
|
||||||
|
|
||||||
|
document.documentElement.classList.add(theme);
|
||||||
|
document.documentElement.style.colorScheme = theme;
|
||||||
|
}
|
||||||
|
|
||||||
|
setTheme("color-theme" in localStorage ? localStorage.getItem("color-theme") : 'system')
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
|
||||||
|
if (localStorage.getItem('banner-closed')) {
|
||||||
|
document.documentElement.style.setProperty("--hextra-banner-height", "0px");
|
||||||
|
document.documentElement.classList.add("hextra-banner-hidden");
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</head>
|
||||||
|
<body><div class="hextra-nav-container hx:sticky hx:top-0 hx:z-20 hx:w-full hx:bg-transparent hx:print:hidden">
|
||||||
|
<div
|
||||||
|
class="hextra-nav-container-blur hx:pointer-events-none hx:absolute hx:z-[-1] hx:h-full hx:w-full hx:bg-white hx:dark:bg-dark hx:shadow-[0_2px_4px_rgba(0,0,0,.02),0_1px_0_rgba(0,0,0,.06)] hx:contrast-more:shadow-[0_0_0_1px_#000] hx:dark:shadow-[0_-1px_0_rgba(255,255,255,.1)_inset] hx:contrast-more:dark:shadow-[0_0_0_1px_#fff]"
|
||||||
|
></div>
|
||||||
|
|
||||||
|
<nav class="hextra-max-navbar-width hx:mx-auto hx:flex hx:items-center hx:justify-end hx:gap-2 hx:h-16 hx:px-6">
|
||||||
|
<a class="hx:flex hx:items-center hx:hover:opacity-75 hx:ltr:mr-auto hx:rtl:ml-auto" href="/">
|
||||||
|
<img class="hx:mr-2 hx:block hx:dark:hidden" src="/images/logo.svg" alt="Logo" height="20" width="20" />
|
||||||
|
<img class="hx:mr-2 hx:hidden hx:dark:block" src="/images/logo.svg" alt="Dark Logo" height="20" width="20" />
|
||||||
|
<span class="hx:mr-2 hx:font-extrabold hx:inline hx:select-none" title="CodeJava">CodeJava</span>
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
title=""
|
||||||
|
href="/courses"
|
||||||
|
|
||||||
|
class="hx:text-sm hx:contrast-more:text-gray-700 hx:contrast-more:dark:text-gray-100 hx:relative hx:-ml-2 hx:hidden hx:whitespace-nowrap hx:p-2 hx:md:inline-flex hx:items-center hx:gap-1 hx:text-gray-600 hx:hover:text-gray-800 hx:dark:text-gray-400 hx:dark:hover:text-gray-200"
|
||||||
|
><span class="hx:text-center">Courses</span>
|
||||||
|
</a><div class="hextra-search-wrapper hx:relative hx:md:w-64">
|
||||||
|
<div class="hx:relative hx:flex hx:items-center hx:text-gray-900 hx:contrast-more:text-gray-800 hx:dark:text-gray-300 hx:contrast-more:dark:text-gray-300">
|
||||||
|
<input
|
||||||
|
placeholder="Search..."
|
||||||
|
class="hextra-search-input hx:focus:hextra-focus hx:block hx:w-full hx:appearance-none hx:rounded-lg hx:px-3 hx:py-2 hx:transition-colors hx:text-base hx:leading-tight hx:md:text-sm hx:bg-black/[.05] hx:dark:bg-gray-50/10 hx:focus:bg-white hx:dark:focus:bg-dark hx:placeholder:text-gray-500 hx:dark:placeholder:text-gray-400 hx:contrast-more:border hx:contrast-more:border-current"
|
||||||
|
type="search"
|
||||||
|
value=""
|
||||||
|
spellcheck="false"
|
||||||
|
/>
|
||||||
|
<kbd
|
||||||
|
class="hx:absolute hx:my-1.5 hx:select-none hx:ltr:right-1.5 hx:rtl:left-1.5 hx:h-5 hx:rounded-sm hx:bg-white hx:px-1.5 hx:font-mono hx:text-[10px] hx:font-medium hx:text-gray-500 hx:border hx:border-gray-200 hx:dark:border-gray-100/20 hx:dark:bg-dark/50 hx:contrast-more:border-current hx:contrast-more:text-current hx:contrast-more:dark:border-current hx:items-center hx:gap-1 hx:transition-opacity hx:pointer-events-none hx:hidden hx:sm:flex"
|
||||||
|
>
|
||||||
|
CTRL K
|
||||||
|
</kbd>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<ul
|
||||||
|
class="hextra-search-results hextra-scrollbar hx:hidden hx:border hx:border-gray-200 hx:bg-white hx:text-gray-100 hx:dark:border-neutral-800 hx:dark:bg-neutral-900 hx:absolute hx:top-full hx:z-20 hx:mt-2 hx:overflow-auto hx:overscroll-contain hx:rounded-xl hx:py-2.5 hx:shadow-xl hx:max-h-[min(calc(50vh-11rem-env(safe-area-inset-bottom)),400px)] hx:md:max-h-[min(calc(100vh-5rem-env(safe-area-inset-bottom)),400px)] hx:inset-x-0 hx:ltr:md:left-auto hx:rtl:md:right-auto hx:contrast-more:border hx:contrast-more:border-gray-900 hx:contrast-more:dark:border-gray-50 hx:w-screen hx:min-h-[100px] hx:max-w-[min(calc(100vw-2rem),calc(100%+20rem))]"
|
||||||
|
style="transition: max-height 0.2s ease 0s;"
|
||||||
|
></ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button type="button" aria-label="Menu" class="hextra-hamburger-menu hx:cursor-pointer hx:-mr-2 hx:rounded-sm hx:p-2 hx:active:bg-gray-400/20 hx:md:hidden"><svg height=24 fill="none" viewBox="0 0 24 24" stroke="currentColor"><g><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 8H20"></path></g><g><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16H20"></path></g></svg></button>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class='hx:mx-auto hx:flex hextra-max-page-width'>
|
||||||
|
<aside class="hextra-sidebar-container hx:flex hx:flex-col hx:print:hidden hx:md:top-16 hx:md:shrink-0 hx:md:w-64 hx:md:self-start hx:max-md:[transform:translate3d(0,-100%,0)] hx:md:hidden hx:xl:block">
|
||||||
|
|
||||||
|
<div class="hx:px-4 hx:pt-4 hx:md:hidden">
|
||||||
|
<div class="hextra-search-wrapper hx:relative hx:md:w-64">
|
||||||
|
<div class="hx:relative hx:flex hx:items-center hx:text-gray-900 hx:contrast-more:text-gray-800 hx:dark:text-gray-300 hx:contrast-more:dark:text-gray-300">
|
||||||
|
<input
|
||||||
|
placeholder="Search..."
|
||||||
|
class="hextra-search-input hx:focus:hextra-focus hx:block hx:w-full hx:appearance-none hx:rounded-lg hx:px-3 hx:py-2 hx:transition-colors hx:text-base hx:leading-tight hx:md:text-sm hx:bg-black/[.05] hx:dark:bg-gray-50/10 hx:focus:bg-white hx:dark:focus:bg-dark hx:placeholder:text-gray-500 hx:dark:placeholder:text-gray-400 hx:contrast-more:border hx:contrast-more:border-current"
|
||||||
|
type="search"
|
||||||
|
value=""
|
||||||
|
spellcheck="false"
|
||||||
|
/>
|
||||||
|
<kbd
|
||||||
|
class="hx:absolute hx:my-1.5 hx:select-none hx:ltr:right-1.5 hx:rtl:left-1.5 hx:h-5 hx:rounded-sm hx:bg-white hx:px-1.5 hx:font-mono hx:text-[10px] hx:font-medium hx:text-gray-500 hx:border hx:border-gray-200 hx:dark:border-gray-100/20 hx:dark:bg-dark/50 hx:contrast-more:border-current hx:contrast-more:text-current hx:contrast-more:dark:border-current hx:items-center hx:gap-1 hx:transition-opacity hx:pointer-events-none hx:hidden hx:sm:flex"
|
||||||
|
>
|
||||||
|
CTRL K
|
||||||
|
</kbd>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<ul
|
||||||
|
class="hextra-search-results hextra-scrollbar hx:hidden hx:border hx:border-gray-200 hx:bg-white hx:text-gray-100 hx:dark:border-neutral-800 hx:dark:bg-neutral-900 hx:absolute hx:top-full hx:z-20 hx:mt-2 hx:overflow-auto hx:overscroll-contain hx:rounded-xl hx:py-2.5 hx:shadow-xl hx:max-h-[min(calc(50vh-11rem-env(safe-area-inset-bottom)),400px)] hx:md:max-h-[min(calc(100vh-5rem-env(safe-area-inset-bottom)),400px)] hx:inset-x-0 hx:ltr:md:left-auto hx:rtl:md:right-auto hx:contrast-more:border hx:contrast-more:border-gray-900 hx:contrast-more:dark:border-gray-50 hx:w-screen hx:min-h-[100px] hx:max-w-[min(calc(100vw-2rem),calc(100%+20rem))]"
|
||||||
|
style="transition: max-height 0.2s ease 0s;"
|
||||||
|
></ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="hextra-scrollbar hx:overflow-y-auto hx:overflow-x-hidden hx:p-4 hx:grow hx:md:h-[calc(100vh-var(--navbar-height)-var(--menu-height))]">
|
||||||
|
<ul class="hx:flex hx:flex-col hx:gap-1 hx:md:hidden">
|
||||||
|
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<div class="hx:max-xl:hidden hx:h-0 hx:w-64 hx:shrink-0"></div></div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="hx:md:hidden hx:sticky hx:bottom-0 hx:max-h-(--menu-height) hx:bg-white hx:dark:bg-dark hx:mx-4 hx:py-4 hx:shadow-[0_-12px_16px_#fff] hx:flex hx:items-center hx:gap-2 hx:border-gray-200 hx:dark:border-neutral-800 hx:dark:shadow-[0_-12px_16px_#111] hx:contrast-more:border-neutral-400 hx:contrast-more:shadow-none hx:contrast-more:dark:shadow-none hx:border-t" data-toggle-animation="show"><div class="hx:flex hx:grow hx:flex-col"><div class="hx:flex hx:justify-items-start hx:group" data-theme="light">
|
||||||
|
<button
|
||||||
|
title="Change theme"
|
||||||
|
data-state="closed"
|
||||||
|
data-location="bottom"
|
||||||
|
class="hextra-theme-toggle hx:cursor-pointer hx:rounded-md hx:text-left hx:font-medium hx:h-7 hx:px-2 hx:text-xs hx:hover:bg-gray-100 hx:hover:text-gray-900 hx:dark:hover:bg-primary-100/5 hx:dark:hover:text-gray-50 hx:font-medium hx:text-gray-600 hx:transition-colors hx:dark:text-gray-400 hx:grow"
|
||||||
|
type="button"
|
||||||
|
aria-label="Change theme"
|
||||||
|
>
|
||||||
|
<div class="hx:flex hx:items-center hx:gap-2 hx:capitalize"><svg height=12 class="hx:group-data-[theme=dark]:hidden hx:group-data-[theme=system]:hidden" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z"/></svg><span class="hx:group-data-[theme=dark]:hidden hx:group-data-[theme=system]:hidden">Light</span><svg height=12 class="hx:group-data-[theme=light]:hidden hx:group-data-[theme=system]:hidden" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z"/></svg><span class="hx:group-data-[theme=light]:hidden hx:group-data-[theme=system]:hidden">Dark</span><svg height=12 class="hx:group-data-[theme=dark]:hidden hx:group-data-[theme=light]:hidden" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
|
||||||
|
<path d="M 11.996094,2 C 6.4986225,2.0192368 2.03125,6.5024993 2.03125,12 c 0,5.497501 4.4673725,9.980763 9.964844,10 H 12 12.0039 c 5.497471,-0.01924 9.964844,-4.502499 9.964844,-10 0,-5.4975007 -4.467373,-9.9807632 -9.964844,-10 H 12 Z M 12,4 c 4.417218,0.017598 7.96875,3.5822356 7.96875,8 0,4.417764 -3.551532,7.982402 -7.96875,8 z" />
|
||||||
|
</svg>
|
||||||
|
<span class="hx:group-data-[theme=dark]:hidden hx:group-data-[theme=light]:hidden">System</span></div>
|
||||||
|
</button>
|
||||||
|
<ul
|
||||||
|
class="hextra-theme-toggle-options hx:hidden hx:z-20 hx:max-h-64 hx:overflow-auto hx:rounded-md hx:ring-1 hx:ring-black/5 hx:bg-white hx:py-1 hx:text-sm hx:shadow-lg hx:dark:ring-white/20 hx:dark:bg-neutral-800"
|
||||||
|
style="position: fixed; inset: auto auto 0px 0px; margin: 0px; min-width: 100px;"
|
||||||
|
data-theme="light"
|
||||||
|
>
|
||||||
|
<li class="hx:flex hx:flex-col">
|
||||||
|
<p
|
||||||
|
data-item="light"
|
||||||
|
class="hx:text-gray-800 hx:dark:text-gray-100 hx:hover:bg-primary-50 hx:hover:text-primary-600 hx:hover:dark:bg-primary-500/10 hx:hover:dark:text-primary-600 hx:relative hx:cursor-pointer hx:whitespace-nowrap hx:py-1.5 hx:transition-colors hx:ltr:pl-3 hx:ltr:pr-9 hx:rtl:pr-3 hx:rtl:pl-9"
|
||||||
|
>
|
||||||
|
Light
|
||||||
|
<span class="hx:absolute hx:inset-y-0 hx:flex hx:items-center hx:ltr:right-3 hx:rtl:left-3 hx:group-data-[theme=dark]:hidden hx:group-data-[theme=system]:hidden"><svg height=1em width=1em xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7"/></svg></span>
|
||||||
|
</p>
|
||||||
|
</li>
|
||||||
|
<li class="hx:flex hx:flex-col">
|
||||||
|
<p
|
||||||
|
data-item="dark"
|
||||||
|
class="hx:text-gray-800 hx:dark:text-gray-100 hx:hover:bg-primary-50 hx:hover:text-primary-600 hx:hover:dark:bg-primary-500/10 hx:hover:dark:text-primary-600 hx:relative hx:cursor-pointer hx:whitespace-nowrap hx:py-1.5 hx:transition-colors hx:ltr:pl-3 hx:ltr:pr-9 hx:rtl:pr-3 hx:rtl:pl-9"
|
||||||
|
>
|
||||||
|
Dark
|
||||||
|
<span class="hx:absolute hx:inset-y-0 hx:flex hx:items-center hx:ltr:right-3 hx:rtl:left-3 hx:group-data-[theme=light]:hidden hx:group-data-[theme=system]:hidden"><svg height=1em width=1em xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7"/></svg></span>
|
||||||
|
</p>
|
||||||
|
</li>
|
||||||
|
<li class="hx:flex hx:flex-col">
|
||||||
|
<p
|
||||||
|
data-item="system"
|
||||||
|
class="hx:text-gray-800 hx:dark:text-gray-100 hx:hover:bg-primary-50 hx:hover:text-primary-600 hx:hover:dark:bg-primary-500/10 hx:hover:dark:text-primary-600 hx:relative hx:cursor-pointer hx:whitespace-nowrap hx:py-1.5 hx:transition-colors hx:ltr:pl-3 hx:ltr:pr-9 hx:rtl:pr-3 hx:rtl:pl-9"
|
||||||
|
>
|
||||||
|
System
|
||||||
|
<span class="hx:absolute hx:inset-y-0 hx:flex hx:items-center hx:ltr:right-3 hx:rtl:left-3 hx:group-data-[theme=dark]:hidden hx:group-data-[theme=light]:hidden"><svg height=1em width=1em xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7"/></svg></span>
|
||||||
|
</p>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div></div></div></aside>
|
||||||
|
|
||||||
|
<nav class="hextra-toc hx:order-last hx:hidden hx:w-64 hx:shrink-0 hx:xl:block hx:print:hidden hx:px-4" aria-label="table of contents"></nav>
|
||||||
|
|
||||||
|
|
||||||
|
<article class="hx:w-full hx:break-words hx:flex hx:min-h-[calc(100vh-var(--navbar-height))] hx:min-w-0 hx:justify-center hx:pb-8 hx:pr-[calc(env(safe-area-inset-right)-1.5rem)]">
|
||||||
|
<main class="hx:w-full hx:min-w-0 hx:max-w-6xl hx:px-6 hx:pt-4 hx:md:px-12">
|
||||||
|
<br class="hx:mt-1.5 hx:text-sm" />
|
||||||
|
<h1 class="hx:text-center hx:mt-2 hx:text-4xl hx:font-bold hx:tracking-tight hx:text-slate-900 hx:dark:text-slate-100">Tags</h1>
|
||||||
|
<div class="hx:mb-16"></div>
|
||||||
|
<div class="content">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="hx:grid hx:grid-cols-1 hx:md:grid-cols-2 hx:lg:grid-cols-3 hx:xl:grid-cols-4 hx:gap-4">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
</article>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<footer class="hextra-footer hx:bg-gray-100 hx:pb-[env(safe-area-inset-bottom)] hx:dark:bg-neutral-900 hx:print:bg-transparent"><div class="hx:mx-auto hx:flex hx:gap-2 hx:py-2 hx:px-4 hextra-max-footer-width"><div class="hx:flex hx:justify-items-start hx:group" data-theme="light">
|
||||||
|
<button
|
||||||
|
title="Change theme"
|
||||||
|
data-state="closed"
|
||||||
|
data-location="bottom"
|
||||||
|
class="hextra-theme-toggle hx:cursor-pointer hx:rounded-md hx:text-left hx:font-medium hx:h-7 hx:px-2 hx:text-xs hx:hover:bg-gray-100 hx:hover:text-gray-900 hx:dark:hover:bg-primary-100/5 hx:dark:hover:text-gray-50 hx:font-medium hx:text-gray-600 hx:transition-colors hx:dark:text-gray-400 hx:grow"
|
||||||
|
type="button"
|
||||||
|
aria-label="Change theme"
|
||||||
|
>
|
||||||
|
<div class="hx:flex hx:items-center hx:gap-2 hx:capitalize"><svg height=12 class="hx:group-data-[theme=dark]:hidden hx:group-data-[theme=system]:hidden" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z"/></svg><span class="hx:group-data-[theme=dark]:hidden hx:group-data-[theme=system]:hidden">Light</span><svg height=12 class="hx:group-data-[theme=light]:hidden hx:group-data-[theme=system]:hidden" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z"/></svg><span class="hx:group-data-[theme=light]:hidden hx:group-data-[theme=system]:hidden">Dark</span><svg height=12 class="hx:group-data-[theme=dark]:hidden hx:group-data-[theme=light]:hidden" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
|
||||||
|
<path d="M 11.996094,2 C 6.4986225,2.0192368 2.03125,6.5024993 2.03125,12 c 0,5.497501 4.4673725,9.980763 9.964844,10 H 12 12.0039 c 5.497471,-0.01924 9.964844,-4.502499 9.964844,-10 0,-5.4975007 -4.467373,-9.9807632 -9.964844,-10 H 12 Z M 12,4 c 4.417218,0.017598 7.96875,3.5822356 7.96875,8 0,4.417764 -3.551532,7.982402 -7.96875,8 z" />
|
||||||
|
</svg>
|
||||||
|
<span class="hx:group-data-[theme=dark]:hidden hx:group-data-[theme=light]:hidden">System</span></div>
|
||||||
|
</button>
|
||||||
|
<ul
|
||||||
|
class="hextra-theme-toggle-options hx:hidden hx:z-20 hx:max-h-64 hx:overflow-auto hx:rounded-md hx:ring-1 hx:ring-black/5 hx:bg-white hx:py-1 hx:text-sm hx:shadow-lg hx:dark:ring-white/20 hx:dark:bg-neutral-800"
|
||||||
|
style="position: fixed; inset: auto auto 0px 0px; margin: 0px; min-width: 100px;"
|
||||||
|
data-theme="light"
|
||||||
|
>
|
||||||
|
<li class="hx:flex hx:flex-col">
|
||||||
|
<p
|
||||||
|
data-item="light"
|
||||||
|
class="hx:text-gray-800 hx:dark:text-gray-100 hx:hover:bg-primary-50 hx:hover:text-primary-600 hx:hover:dark:bg-primary-500/10 hx:hover:dark:text-primary-600 hx:relative hx:cursor-pointer hx:whitespace-nowrap hx:py-1.5 hx:transition-colors hx:ltr:pl-3 hx:ltr:pr-9 hx:rtl:pr-3 hx:rtl:pl-9"
|
||||||
|
>
|
||||||
|
Light
|
||||||
|
<span class="hx:absolute hx:inset-y-0 hx:flex hx:items-center hx:ltr:right-3 hx:rtl:left-3 hx:group-data-[theme=dark]:hidden hx:group-data-[theme=system]:hidden"><svg height=1em width=1em xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7"/></svg></span>
|
||||||
|
</p>
|
||||||
|
</li>
|
||||||
|
<li class="hx:flex hx:flex-col">
|
||||||
|
<p
|
||||||
|
data-item="dark"
|
||||||
|
class="hx:text-gray-800 hx:dark:text-gray-100 hx:hover:bg-primary-50 hx:hover:text-primary-600 hx:hover:dark:bg-primary-500/10 hx:hover:dark:text-primary-600 hx:relative hx:cursor-pointer hx:whitespace-nowrap hx:py-1.5 hx:transition-colors hx:ltr:pl-3 hx:ltr:pr-9 hx:rtl:pr-3 hx:rtl:pl-9"
|
||||||
|
>
|
||||||
|
Dark
|
||||||
|
<span class="hx:absolute hx:inset-y-0 hx:flex hx:items-center hx:ltr:right-3 hx:rtl:left-3 hx:group-data-[theme=light]:hidden hx:group-data-[theme=system]:hidden"><svg height=1em width=1em xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7"/></svg></span>
|
||||||
|
</p>
|
||||||
|
</li>
|
||||||
|
<li class="hx:flex hx:flex-col">
|
||||||
|
<p
|
||||||
|
data-item="system"
|
||||||
|
class="hx:text-gray-800 hx:dark:text-gray-100 hx:hover:bg-primary-50 hx:hover:text-primary-600 hx:hover:dark:bg-primary-500/10 hx:hover:dark:text-primary-600 hx:relative hx:cursor-pointer hx:whitespace-nowrap hx:py-1.5 hx:transition-colors hx:ltr:pl-3 hx:ltr:pr-9 hx:rtl:pr-3 hx:rtl:pl-9"
|
||||||
|
>
|
||||||
|
System
|
||||||
|
<span class="hx:absolute hx:inset-y-0 hx:flex hx:items-center hx:ltr:right-3 hx:rtl:left-3 hx:group-data-[theme=dark]:hidden hx:group-data-[theme=light]:hidden"><svg height=1em width=1em xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7"/></svg></span>
|
||||||
|
</p>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div></div><hr class="hx:border-gray-200 hx:dark:border-neutral-800" /><div class="hextra-custom-footer hextra-max-footer-width hx:pl-[max(env(safe-area-inset-left),1.5rem)] hx:pr-[max(env(safe-area-inset-right),1.5rem)] hx:text-gray-600 hx:dark:text-gray-400"></div><div
|
||||||
|
class="hextra-max-footer-width hx:mx-auto hx:flex hx:justify-center hx:py-12 hx:pl-[max(env(safe-area-inset-left),1.5rem)] hx:pr-[max(env(safe-area-inset-right),1.5rem)] hx:text-gray-600 hx:dark:text-gray-400 hx:md:justify-start"
|
||||||
|
>
|
||||||
|
<div class="hx:flex hx:w-full hx:flex-col hx:items-center hx:sm:items-start"><div class="hx:font-semibold"><a class="hx:flex hx:text-sm hx:items-center hx:gap-1 hx:text-current" target="_blank" rel="noopener noreferrer" title="Hextra GitHub Homepage" href="https://github.com/imfing/hextra">
|
||||||
|
<span>Powered by Hextra<svg height=1em class="hx:inline-block hx:ltr:ml-1 hx:rtl:mr-1 hx:align-[-2.5px]" viewBox="0 0 180 180" xmlns="http://www.w3.org/2000/svg" fill="currentColor"><path fill-rule="evenodd" clip-rule="evenodd" d="m 105.50024,22.224647 c -9.59169,-5.537563 -21.40871,-5.537563 -31.000093,0 L 39.054693,42.689119 C 29.463353,48.226675 23.55484,58.460531 23.55484,69.535642 v 40.928918 c 0,11.07542 5.908513,21.3092 15.499853,26.84652 l 35.445453,20.46446 c 9.591313,5.53732 21.408404,5.53732 31.000094,0 l 35.44507,-20.46446 c 9.59131,-5.53732 15.49985,-15.7711 15.49985,-26.84652 V 69.535642 c 0,-11.075111 -5.90854,-21.308967 -15.49985,-26.846523 z M 34.112797,85.737639 c -1.384445,2.397827 -1.384445,5.352099 0,7.749927 l 24.781554,42.922974 c 1.38437,2.39783 3.942853,3.87496 6.711592,3.87496 h 49.563107 c 2.76905,0 5.3273,-1.47713 6.71144,-3.87496 l 24.78194,-42.922974 c 1.38414,-2.397828 1.38414,-5.3521 0,-7.749927 L 121.88049,42.814746 c -1.38414,-2.397828 -3.94239,-3.874964 -6.71144,-3.874964 H 65.605944 c -2.768739,0 -5.327223,1.477059 -6.711592,3.874964 z" style="stroke-width:0.774993" /></svg></span>
|
||||||
|
</a></div></div>
|
||||||
|
</div></footer>
|
||||||
|
|
||||||
|
<script defer src="/js/main.js" integrity=""></script>
|
||||||
|
<script defer src="/js/flexsearch.9f5b5908f93ae86f1ecd4b043b799f580c2d1654e703dd9357d568ac41b2547a.js" integrity="sha256-n1tZCPk66G8ezUsEO3mfWAwtFlTnA92TV9VorEGyVHo=" crossorigin="anonymous"></script>
|
||||||
|
<script defer src="/en.search.js" integrity=""></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
18
public/tags/index.xml
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
||||||
|
<channel>
|
||||||
|
<title>CodeJava – Tags</title>
|
||||||
|
<link>http://localhost:1313/tags/</link>
|
||||||
|
<description>Recent content in Tags on CodeJava</description>
|
||||||
|
<generator>Hugo -- gohugo.io</generator>
|
||||||
|
<language>en</language>
|
||||||
|
|
||||||
|
<atom:link href="http://localhost:1313/tags/index.xml" rel="self" type="application/rss+xml" />
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</channel>
|
||||||
|
</rss>
|
||||||