Initial commit: DOSSIER Hugo website
This commit is contained in:
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"image": "mcr.microsoft.com/devcontainers/go:1",
|
||||
"features": {
|
||||
"ghcr.io/devcontainers/features/hugo:1": {
|
||||
"extended": true,
|
||||
"version": "0.161.1"
|
||||
},
|
||||
"ghcr.io/devcontainers/features/node:1": {}
|
||||
},
|
||||
"customizations": {
|
||||
"vscode": {
|
||||
"extensions": ["mhutchie.git-graph", "esbenp.prettier-vscode", "tamasfe.even-better-toml", "budparr.language-hugo-vscode"]
|
||||
}
|
||||
},
|
||||
"postCreateCommand": "npm install",
|
||||
"forwardPorts": [1313]
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
# Mark generated files so they are collapsed by default in GitHub diffs
|
||||
assets/css/compiled/main.css linguist-generated=true
|
||||
docs/hugo_stats.json linguist-generated=true
|
||||
@@ -0,0 +1,9 @@
|
||||
node_modules/
|
||||
public/
|
||||
resources/
|
||||
|
||||
.hugo_build.lock
|
||||
|
||||
# Playwright
|
||||
playwright-report/
|
||||
test-results/
|
||||
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"plugins": [
|
||||
"prettier-plugin-go-template"
|
||||
],
|
||||
"goTemplateBracketSpacing": true,
|
||||
"htmlWhitespaceSensitivity": "css",
|
||||
"printWidth": 200,
|
||||
"singleQuote": false,
|
||||
"tabWidth": 2,
|
||||
"trailingComma": "es5",
|
||||
"overrides": [
|
||||
{
|
||||
"files": [
|
||||
"*.html"
|
||||
],
|
||||
"options": {
|
||||
"parser": "go-template"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,193 @@
|
||||
# AGENTS.md
|
||||
|
||||
This file provides guidance to AI coding agents when working with code in this repository.
|
||||
|
||||
## Project Overview
|
||||
|
||||
Hextra is a modern, responsive Hugo theme designed for creating documentation websites, technical blogs, and static sites. Built with Tailwind CSS, it offers features like full-text search, dark mode, multi-language support, and extensive customization options.
|
||||
|
||||
## Development Commands
|
||||
|
||||
### Initial Setup
|
||||
|
||||
When working in a new worktree or fresh clone without `node_modules`, run `npm install` first to install dependencies:
|
||||
|
||||
```bash
|
||||
npm install
|
||||
```
|
||||
|
||||
### Development Server
|
||||
|
||||
```bash
|
||||
# Start development server with theme reloading (recommended for theme development)
|
||||
npm run dev:theme
|
||||
```
|
||||
|
||||
### Building
|
||||
|
||||
```bash
|
||||
# Build the example site
|
||||
npm run build
|
||||
|
||||
# Build CSS assets only
|
||||
npm run build:css
|
||||
```
|
||||
|
||||
## Architecture Overview
|
||||
|
||||
### Hugo Theme Structure
|
||||
|
||||
- **Base Layout**: `layouts/baseof.html` wraps all pages
|
||||
- **Specialized Layouts**: `layouts/docs/`, `layouts/blog/`, `layouts/hextra-home.html`
|
||||
- **Partials**: Reusable components in `layouts/_partials/`
|
||||
- Core UI: `navbar.html`, `sidebar.html`, `footer.html`, `breadcrumb.html`, `toc.html`
|
||||
- Utilities: `layouts/_partials/utils/` for helper functions
|
||||
- Custom overrides: `layouts/_partials/custom/` for user customizations
|
||||
- **Shortcodes**: Custom Markdown extensions in `layouts/_shortcodes/`
|
||||
- **Render Hooks**: Custom Markdown rendering in `layouts/_markup/` for codeblocks, headings, images, and links
|
||||
|
||||
### Asset Organization
|
||||
|
||||
```
|
||||
assets/
|
||||
├── css/
|
||||
│ ├── styles.css # Main stylesheet (Tailwind entry point)
|
||||
│ ├── compiled/main.css # Built CSS output (generated)
|
||||
│ ├── components/ # Component-specific styles
|
||||
│ ├── chroma/ # Syntax highlighting themes
|
||||
│ └── custom.css # User customization entry point
|
||||
└── js/
|
||||
├── core/ # Core JS components
|
||||
└── flexsearch.js # Search functionality
|
||||
```
|
||||
|
||||
### Key Components
|
||||
|
||||
- **Search**: FlexSearch-powered full-text search (`assets/js/flexsearch.js`)
|
||||
- **Navigation**: Responsive navbar and auto-generated sidebar
|
||||
- **Theme Toggle**: Dark/light mode switching
|
||||
- **Internationalization**: 20+ language support in `i18n/`
|
||||
|
||||
### Content Features
|
||||
|
||||
- **Shortcodes**: `callout`, `card`, `cards`, `tabs`, `tab`, `details`, `steps`, `filetree`, `jupyter`, `badge`, `icon`, `pdf`, `include`, `asciinema`, `term`
|
||||
- **Code Features**: Syntax highlighting (Chroma), copy buttons, line numbers via render hooks
|
||||
- **SEO**: Open Graph, Twitter Cards, structured data
|
||||
- **Performance**: Minimal JavaScript, optimized CSS with Tailwind
|
||||
|
||||
## Development Workflow
|
||||
|
||||
### Example Site Development
|
||||
|
||||
The `docs/` directory serves as both documentation and testing ground:
|
||||
|
||||
- Test new features here before releasing
|
||||
- Configuration examples in `docs/hugo.yaml` showing multi-language setup
|
||||
- Content examples demonstrate all theme capabilities
|
||||
- Run from docs with: `hugo server --themesDir=../..`
|
||||
|
||||
### CSS Development Workflow
|
||||
|
||||
- Source: `assets/css/styles.css` (main stylesheet)
|
||||
- Build process: Tailwind CSS → PostCSS → `assets/css/compiled/main.css`
|
||||
- Component styles organized in `assets/css/components/`
|
||||
- Chroma syntax highlighting themes in `assets/css/chroma/`
|
||||
- CSS compilation requires Node.js dependencies (PostCSS, Tailwind CSS v4+)
|
||||
|
||||
#### Rebuilding CSS after template changes
|
||||
|
||||
Tailwind CSS relies on `docs/hugo_stats.json` to know which HTML tags, classes, and IDs are actually used in the built site, so it can tree-shake unused styles. When you modify layouts, partials, or shortcodes you must **regenerate `hugo_stats.json` first**, then rebuild the CSS:
|
||||
|
||||
1. **Generate `docs/hugo_stats.json`** — Run Hugo with the `dev.toml` config (which sets `build.buildStats.enable = true`):
|
||||
|
||||
```bash
|
||||
# Using npm (starts a dev server that writes hugo_stats.json on every rebuild):
|
||||
npm run dev:theme
|
||||
|
||||
# Or a one-shot build using the raw Hugo command:
|
||||
hugo --config=hugo.yaml,../dev.toml --themesDir=../.. --source=docs
|
||||
```
|
||||
|
||||
2. **Build the CSS** — With an up-to-date `hugo_stats.json` in place, compile the stylesheet:
|
||||
|
||||
```bash
|
||||
npm run build:css
|
||||
```
|
||||
|
||||
> **Why two steps?** `dev.toml` mounts `docs/hugo_stats.json` into the Hugo asset pipeline (`assets/notwatching/hugo_stats.json`) and configures a cache-buster so that changes to the stats file trigger a CSS recompile during `dev:theme`. When running outside the dev server you need to perform these steps manually in order.
|
||||
|
||||
### Customization Points
|
||||
|
||||
- Custom partials: `layouts/_partials/custom/`
|
||||
- Custom CSS: `assets/css/custom.css`
|
||||
- Site-specific overrides: Copy any layout to your site's `layouts/` directory
|
||||
|
||||
## Configuration & Requirements
|
||||
|
||||
### Theme Requirements
|
||||
|
||||
- Hugo minimum version: 0.146.0 (extended version required - see `theme.toml`)
|
||||
- Go 1.20+ (as specified in `go.mod`)
|
||||
- Node.js for CSS compilation (PostCSS, Tailwind CSS v4+)
|
||||
|
||||
### Key Configuration Files
|
||||
|
||||
- `docs/hugo.yaml` - Example Hugo configuration with multi-language setup
|
||||
- `postcss.config.mjs` - PostCSS configuration for CSS processing
|
||||
- `package.json` - Node.js dependencies and build scripts
|
||||
|
||||
### Development Environment
|
||||
|
||||
- Default Hugo development server: Port 1313
|
||||
- Development server runs with `--disableFastRender -D` for better development experience
|
||||
- Theme development uses `--logLevel=debug` for detailed logging
|
||||
|
||||
### Multi-language Support
|
||||
|
||||
- Configure languages in `hugo.yaml` (supports 20+ languages including RTL)
|
||||
- Translation files in `i18n/` directory (e.g., `en.yaml`, `fa.yaml`, `ja.yaml`, `zh-cn.yaml`)
|
||||
- Example supports English, Persian (RTL), Japanese, and Simplified Chinese
|
||||
|
||||
## Theme Development Guidelines
|
||||
|
||||
### Hugo Theme Conventions
|
||||
|
||||
- Theme files in this repository override Hugo defaults
|
||||
- Follow Hugo's theme development guidelines for compatibility
|
||||
- Maintain backward compatibility with existing configurations
|
||||
|
||||
### JavaScript & Performance
|
||||
|
||||
- All JavaScript components are designed to have minimal footprint
|
||||
- Core JS components in `assets/js/core/`: `theme.js`, `nav-menu.js`, `code-copy.js`, `sidebar.js`, `tabs.js`, etc.
|
||||
- FlexSearch powers offline full-text search (`assets/js/flexsearch.js`)
|
||||
|
||||
### CSS Architecture
|
||||
|
||||
- Uses Tailwind CSS v4+ with PostCSS processing
|
||||
- Component-based CSS organization in `assets/css/components/`
|
||||
- Compiled output goes to `assets/css/compiled/main.css`
|
||||
- Prettier formatting for Go templates and code consistency
|
||||
|
||||
### Accessibility (WCAG Compliance)
|
||||
|
||||
All new features and UI changes must follow the [Web Content Accessibility Guidelines (WCAG) 2.2](https://www.w3.org/TR/WCAG22/) at the **AA** conformance level. Key requirements:
|
||||
|
||||
- **Semantic HTML**: Use appropriate elements (`<nav>`, `<main>`, `<aside>`, `<button>`, `<ul>`, etc.) instead of generic `<div>`/`<span>` where applicable.
|
||||
- **ARIA attributes**: Add `aria-label`, `aria-expanded`, `aria-controls`, `aria-current`, `role`, and other ARIA attributes to interactive components (menus, toggles, dropdowns, modals) so screen readers can interpret them.
|
||||
- **Keyboard navigation**: All interactive elements must be reachable and operable via keyboard (`Tab`, `Enter`, `Escape`, arrow keys). Manage focus appropriately when opening/closing menus, modals, and drawers.
|
||||
- **Focus indicators**: Never remove visible focus outlines. Use the existing `hextra-focus` utility or equivalent visible focus ring styles.
|
||||
- **Color contrast**: Text and interactive elements must meet WCAG AA contrast ratios (4.5:1 for normal text, 3:1 for large text). Verify in both light and dark modes.
|
||||
- **Images and icons**: Decorative SVGs/icons should have `aria-hidden="true"`. Meaningful images need descriptive `alt` text.
|
||||
- **Skip links and landmarks**: Preserve existing skip-navigation links and ARIA landmark roles (`role="navigation"`, `role="search"`, etc.).
|
||||
- **Live regions**: Use `aria-live` for dynamic content updates (e.g., search results, status messages) so assistive technology announces changes.
|
||||
- **Form controls**: Associate `<label>` elements with inputs. Provide accessible names for buttons that contain only icons.
|
||||
|
||||
When introducing a new component or modifying an existing one, verify it works with keyboard-only navigation and review the rendered HTML for proper semantics and ARIA usage.
|
||||
|
||||
### Testing & Quality Assurance
|
||||
|
||||
- Test all changes in `docs/` before releasing
|
||||
- Use `npm run dev:theme` for theme development with hot reloading
|
||||
- Format code with `npx prettier --write .` before committing
|
||||
- Verify multi-language functionality across supported languages
|
||||
@@ -0,0 +1,193 @@
|
||||
# AGENTS.md
|
||||
|
||||
This file provides guidance to AI coding agents when working with code in this repository.
|
||||
|
||||
## Project Overview
|
||||
|
||||
Hextra is a modern, responsive Hugo theme designed for creating documentation websites, technical blogs, and static sites. Built with Tailwind CSS, it offers features like full-text search, dark mode, multi-language support, and extensive customization options.
|
||||
|
||||
## Development Commands
|
||||
|
||||
### Initial Setup
|
||||
|
||||
When working in a new worktree or fresh clone without `node_modules`, run `npm install` first to install dependencies:
|
||||
|
||||
```bash
|
||||
npm install
|
||||
```
|
||||
|
||||
### Development Server
|
||||
|
||||
```bash
|
||||
# Start development server with theme reloading (recommended for theme development)
|
||||
npm run dev:theme
|
||||
```
|
||||
|
||||
### Building
|
||||
|
||||
```bash
|
||||
# Build the example site
|
||||
npm run build
|
||||
|
||||
# Build CSS assets only
|
||||
npm run build:css
|
||||
```
|
||||
|
||||
## Architecture Overview
|
||||
|
||||
### Hugo Theme Structure
|
||||
|
||||
- **Base Layout**: `layouts/baseof.html` wraps all pages
|
||||
- **Specialized Layouts**: `layouts/docs/`, `layouts/blog/`, `layouts/hextra-home.html`
|
||||
- **Partials**: Reusable components in `layouts/_partials/`
|
||||
- Core UI: `navbar.html`, `sidebar.html`, `footer.html`, `breadcrumb.html`, `toc.html`
|
||||
- Utilities: `layouts/_partials/utils/` for helper functions
|
||||
- Custom overrides: `layouts/_partials/custom/` for user customizations
|
||||
- **Shortcodes**: Custom Markdown extensions in `layouts/_shortcodes/`
|
||||
- **Render Hooks**: Custom Markdown rendering in `layouts/_markup/` for codeblocks, headings, images, and links
|
||||
|
||||
### Asset Organization
|
||||
|
||||
```
|
||||
assets/
|
||||
├── css/
|
||||
│ ├── styles.css # Main stylesheet (Tailwind entry point)
|
||||
│ ├── compiled/main.css # Built CSS output (generated)
|
||||
│ ├── components/ # Component-specific styles
|
||||
│ ├── chroma/ # Syntax highlighting themes
|
||||
│ └── custom.css # User customization entry point
|
||||
└── js/
|
||||
├── core/ # Core JS components
|
||||
└── flexsearch.js # Search functionality
|
||||
```
|
||||
|
||||
### Key Components
|
||||
|
||||
- **Search**: FlexSearch-powered full-text search (`assets/js/flexsearch.js`)
|
||||
- **Navigation**: Responsive navbar and auto-generated sidebar
|
||||
- **Theme Toggle**: Dark/light mode switching
|
||||
- **Internationalization**: 20+ language support in `i18n/`
|
||||
|
||||
### Content Features
|
||||
|
||||
- **Shortcodes**: `callout`, `card`, `cards`, `tabs`, `tab`, `details`, `steps`, `filetree`, `jupyter`, `badge`, `icon`, `pdf`, `include`, `asciinema`, `term`
|
||||
- **Code Features**: Syntax highlighting (Chroma), copy buttons, line numbers via render hooks
|
||||
- **SEO**: Open Graph, Twitter Cards, structured data
|
||||
- **Performance**: Minimal JavaScript, optimized CSS with Tailwind
|
||||
|
||||
## Development Workflow
|
||||
|
||||
### Example Site Development
|
||||
|
||||
The `docs/` directory serves as both documentation and testing ground:
|
||||
|
||||
- Test new features here before releasing
|
||||
- Configuration examples in `docs/hugo.yaml` showing multi-language setup
|
||||
- Content examples demonstrate all theme capabilities
|
||||
- Run from docs with: `hugo server --themesDir=../..`
|
||||
|
||||
### CSS Development Workflow
|
||||
|
||||
- Source: `assets/css/styles.css` (main stylesheet)
|
||||
- Build process: Tailwind CSS → PostCSS → `assets/css/compiled/main.css`
|
||||
- Component styles organized in `assets/css/components/`
|
||||
- Chroma syntax highlighting themes in `assets/css/chroma/`
|
||||
- CSS compilation requires Node.js dependencies (PostCSS, Tailwind CSS v4+)
|
||||
|
||||
#### Rebuilding CSS after template changes
|
||||
|
||||
Tailwind CSS relies on `docs/hugo_stats.json` to know which HTML tags, classes, and IDs are actually used in the built site, so it can tree-shake unused styles. When you modify layouts, partials, or shortcodes you must **regenerate `hugo_stats.json` first**, then rebuild the CSS:
|
||||
|
||||
1. **Generate `docs/hugo_stats.json`** — Run Hugo with the `dev.toml` config (which sets `build.buildStats.enable = true`):
|
||||
|
||||
```bash
|
||||
# Using npm (starts a dev server that writes hugo_stats.json on every rebuild):
|
||||
npm run dev:theme
|
||||
|
||||
# Or a one-shot build using the raw Hugo command:
|
||||
hugo --config=hugo.yaml,../dev.toml --themesDir=../.. --source=docs
|
||||
```
|
||||
|
||||
2. **Build the CSS** — With an up-to-date `hugo_stats.json` in place, compile the stylesheet:
|
||||
|
||||
```bash
|
||||
npm run build:css
|
||||
```
|
||||
|
||||
> **Why two steps?** `dev.toml` mounts `docs/hugo_stats.json` into the Hugo asset pipeline (`assets/notwatching/hugo_stats.json`) and configures a cache-buster so that changes to the stats file trigger a CSS recompile during `dev:theme`. When running outside the dev server you need to perform these steps manually in order.
|
||||
|
||||
### Customization Points
|
||||
|
||||
- Custom partials: `layouts/_partials/custom/`
|
||||
- Custom CSS: `assets/css/custom.css`
|
||||
- Site-specific overrides: Copy any layout to your site's `layouts/` directory
|
||||
|
||||
## Configuration & Requirements
|
||||
|
||||
### Theme Requirements
|
||||
|
||||
- Hugo minimum version: 0.146.0 (extended version required - see `theme.toml`)
|
||||
- Go 1.20+ (as specified in `go.mod`)
|
||||
- Node.js for CSS compilation (PostCSS, Tailwind CSS v4+)
|
||||
|
||||
### Key Configuration Files
|
||||
|
||||
- `docs/hugo.yaml` - Example Hugo configuration with multi-language setup
|
||||
- `postcss.config.mjs` - PostCSS configuration for CSS processing
|
||||
- `package.json` - Node.js dependencies and build scripts
|
||||
|
||||
### Development Environment
|
||||
|
||||
- Default Hugo development server: Port 1313
|
||||
- Development server runs with `--disableFastRender -D` for better development experience
|
||||
- Theme development uses `--logLevel=debug` for detailed logging
|
||||
|
||||
### Multi-language Support
|
||||
|
||||
- Configure languages in `hugo.yaml` (supports 20+ languages including RTL)
|
||||
- Translation files in `i18n/` directory (e.g., `en.yaml`, `fa.yaml`, `ja.yaml`, `zh-cn.yaml`)
|
||||
- Example supports English, Persian (RTL), Japanese, and Simplified Chinese
|
||||
|
||||
## Theme Development Guidelines
|
||||
|
||||
### Hugo Theme Conventions
|
||||
|
||||
- Theme files in this repository override Hugo defaults
|
||||
- Follow Hugo's theme development guidelines for compatibility
|
||||
- Maintain backward compatibility with existing configurations
|
||||
|
||||
### JavaScript & Performance
|
||||
|
||||
- All JavaScript components are designed to have minimal footprint
|
||||
- Core JS components in `assets/js/core/`: `theme.js`, `nav-menu.js`, `code-copy.js`, `sidebar.js`, `tabs.js`, etc.
|
||||
- FlexSearch powers offline full-text search (`assets/js/flexsearch.js`)
|
||||
|
||||
### CSS Architecture
|
||||
|
||||
- Uses Tailwind CSS v4+ with PostCSS processing
|
||||
- Component-based CSS organization in `assets/css/components/`
|
||||
- Compiled output goes to `assets/css/compiled/main.css`
|
||||
- Prettier formatting for Go templates and code consistency
|
||||
|
||||
### Accessibility (WCAG Compliance)
|
||||
|
||||
All new features and UI changes must follow the [Web Content Accessibility Guidelines (WCAG) 2.2](https://www.w3.org/TR/WCAG22/) at the **AA** conformance level. Key requirements:
|
||||
|
||||
- **Semantic HTML**: Use appropriate elements (`<nav>`, `<main>`, `<aside>`, `<button>`, `<ul>`, etc.) instead of generic `<div>`/`<span>` where applicable.
|
||||
- **ARIA attributes**: Add `aria-label`, `aria-expanded`, `aria-controls`, `aria-current`, `role`, and other ARIA attributes to interactive components (menus, toggles, dropdowns, modals) so screen readers can interpret them.
|
||||
- **Keyboard navigation**: All interactive elements must be reachable and operable via keyboard (`Tab`, `Enter`, `Escape`, arrow keys). Manage focus appropriately when opening/closing menus, modals, and drawers.
|
||||
- **Focus indicators**: Never remove visible focus outlines. Use the existing `hextra-focus` utility or equivalent visible focus ring styles.
|
||||
- **Color contrast**: Text and interactive elements must meet WCAG AA contrast ratios (4.5:1 for normal text, 3:1 for large text). Verify in both light and dark modes.
|
||||
- **Images and icons**: Decorative SVGs/icons should have `aria-hidden="true"`. Meaningful images need descriptive `alt` text.
|
||||
- **Skip links and landmarks**: Preserve existing skip-navigation links and ARIA landmark roles (`role="navigation"`, `role="search"`, etc.).
|
||||
- **Live regions**: Use `aria-live` for dynamic content updates (e.g., search results, status messages) so assistive technology announces changes.
|
||||
- **Form controls**: Associate `<label>` elements with inputs. Provide accessible names for buttons that contain only icons.
|
||||
|
||||
When introducing a new component or modifying an existing one, verify it works with keyboard-only navigation and review the rendered HTML for proper semantics and ARIA usage.
|
||||
|
||||
### Testing & Quality Assurance
|
||||
|
||||
- Test all changes in `docs/` before releasing
|
||||
- Use `npm run dev:theme` for theme development with hot reloading
|
||||
- Format code with `npx prettier --write .` before committing
|
||||
- Verify multi-language functionality across supported languages
|
||||
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2023 Xin
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -0,0 +1,49 @@
|
||||
<div align="center">
|
||||
<h1 align="center">هگزترا</h1>
|
||||
<sup align="center"><a href="README.md">English</a> | <a href="README.zh-cn.md">简体中文</a> | <a href="README.fa.md">فارسی</a></sup>
|
||||
<p align="center">تم هیوگو مدرن، پاسخگو و دارای امکانات کامل برای ایجاد وبسایتهای استاتیک زیبا.</p>
|
||||
|
||||
نسخهی نمایشی → [imfing.github.io/hextra](https://imfing.github.io/hextra/fa)
|
||||
</div>
|
||||
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="https://user-images.githubusercontent.com/5097752/263550533-c18343ca-3848-4230-b5c0-ee989d7916da.png">
|
||||
<img alt="Hextra" src="https://user-images.githubusercontent.com/5097752/263550528-663599f9-17a1-4686-b5c4-3da233b5034d.png">
|
||||
</picture>
|
||||
|
||||
<div align="right">
|
||||
<a href="https://github.com/imfing/hextra/actions/workflows/pages.yml"><img alt="GitHub Actions Status" src="https://github.com/imfing/hextra/actions/workflows/pages.yml/badge.svg"></a> <a href="https://app.netlify.com/sites/hugo-hextra/deploys"><img alt="Netlify Status" src="https://api.netlify.com/api/v1/badges/61d6e55a-2447-487e-b59f-c9537e5df175/deploy-status"></a>
|
||||
</div>
|
||||
|
||||
## ویژگیها
|
||||
|
||||
- **طراحی زیبا** - با الهام از Nextra، هگزترا از Tailwind CSS برای ارائه یک طراحی مدرن که سایت شما را برجسته میکند، استفاده میکند.
|
||||
- **طراحی واکنشگرا و حالت تیره** - در تمام دستگاهها، از تلفن همراه، تبلت تا دسکتاپ، عالی به نظر میرسد. حالت تیره نیز برای انطباق با شرایط مختلف روشنایی پشتیبانی میشود.
|
||||
- **سریع و سبک** - طراحی شده توسط Hugo، یک ایجادکننده سایت استاتیک سریع مثل رعد و برق که در یک فایل باینری قرار گرفته است، هگزترا ردپای خود را به حداقل میرساند. برای استفاده از آن به جاوااسکریپت یا Node.js نیازی ندارید.
|
||||
- **جستجوی متن کامل** - جستجوی متن کاملا آفلاین داخلی طراحی شده توسط FlexSearch، بدون نیاز به پیکربندی اضافی.
|
||||
- **امکانات کامل** - برای بهتر کردن محتوای شما مارکداون، برجستهکردن سینتکس، فرمولهای ریاضی LaTeX، نمودارها و عناصر Shortcodeها را شامل میشه. فهرست مطالب، بردکرامب، صفحهبندی، پیمایش نوار کناری و موارد دیگر همه به صورت خودکار تولید میشوند.
|
||||
- **چند زبانه و سئو آماده** - سایتهای چند زبانه با حالت چند زبانه Hugo راحت ساخته میشوند. پشتیبانی خارج از جعبه برای برچسبهای سئو، Open Graph و کارتهای توییتر گنجانده شده است.
|
||||
- **پشتیبانی از دسترسپذیری** - اجزای تعاملی از نشانهگذاری معنایی، رفتار سازگار با صفحهکلید و بررسیهای خودکار دسترسپذیری استفاده میکنند تا رابط کاربری در گردشکارهای رایج فناوریهای کمکی قابل استفاده بماند.
|
||||
|
||||
## شروع کنید
|
||||
|
||||
### شروع سریع از طریق Template
|
||||
|
||||
استفاده از [Hextra Starter Template](https://github.com/imfing/hextra-starter-template) سادهترین روش برای راهاندازی سریع یک وبسایت جدید با تم هگزترا است. با کلیک بر روی دکمه "Use this template" در بالای صفحه مخزن شروع کنید.
|
||||
|
||||
مخزن تم همچنین شامل یک [گردش کار گیتهاب Actions](https://docs.github.com/en/pages/getting-started-with-github-pages/configuring-a-publishing-source-for-your-github-pages-site#publishing-with-a-custom-github-actions-workflow) رای بهکاراندازی وبسایت شما در گیتهاب Pages است.
|
||||
|
||||
<img alt="Hextra Starter Template" src="https://user-images.githubusercontent.com/5097752/263551418-c403b9a9-a76c-47a6-8466-513d772ef0b7.jpg" width=600/>
|
||||
|
||||
### استفاده
|
||||
|
||||
برای اطلاعات بیشتر به بخش [مستندات](https://imfing.github.io/hextra/fa/docs) مراجعه کنید.
|
||||
|
||||
## مشارکت کردن
|
||||
|
||||
از مشارکت افراد جدید استقبال میکنیم.
|
||||
برای شروع، [راهنمای مشارکت](.github/CONTRIBUTING.md) را بررسی کنید.
|
||||
|
||||
## مجوز
|
||||
|
||||
[مجوز MIT](./LICENSE)
|
||||
@@ -0,0 +1,49 @@
|
||||
<div align="center">
|
||||
<h1 align="center">Hextra</h1>
|
||||
<sup align="center"><a href="README.md">English</a> | <a href="README.zh-cn.md">简体中文</a> | <a href="README.fa.md">فارسی</a></sup>
|
||||
<p align="center">Modern, responsive, batteries-included Hugo theme for creating beautiful static websites.</p>
|
||||
|
||||
Demo → [imfing.github.io/hextra](https://imfing.github.io/hextra/)
|
||||
</div>
|
||||
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="https://user-images.githubusercontent.com/5097752/263550533-c18343ca-3848-4230-b5c0-ee989d7916da.png">
|
||||
<img alt="Hextra" src="https://user-images.githubusercontent.com/5097752/263550528-663599f9-17a1-4686-b5c4-3da233b5034d.png">
|
||||
</picture>
|
||||
|
||||
<div align="right">
|
||||
<a href="https://github.com/imfing/hextra/actions/workflows/pages.yml"><img alt="GitHub Actions Status" src="https://github.com/imfing/hextra/actions/workflows/pages.yml/badge.svg"></a> <a href="https://app.netlify.com/sites/hugo-hextra/deploys"><img alt="Netlify Status" src="https://api.netlify.com/api/v1/badges/61d6e55a-2447-487e-b59f-c9537e5df175/deploy-status"></a>
|
||||
</div>
|
||||
|
||||
## Features
|
||||
|
||||
- **Beautiful Design** - Inspired by Nextra, Hextra utilizes Tailwind CSS to offer a modern design that makes your site look outstanding.
|
||||
- **Responsive Layout and Dark Mode** - It looks great on all devices, from mobile to desktop. Dark mode is also supported to accommodate various lighting conditions.
|
||||
- **Fast and Lightweight** - Powered by Hugo, a lightning-fast static-site generator housed in a single binary file, Hextra keeps its footprint minimal. No JavaScript or Node.js are needed to use it.
|
||||
- **Full-text Search** - Built-in offline full-text search powered by FlexSearch, no extra configuration required.
|
||||
- **Battery-included** - Markdown, syntax highlighting, LaTeX math formulae, diagrams and Shortcodes elements to enhance your content. Table of contents, breadcrumbs, pagination, sidebar navigation and more are all automatically generated.
|
||||
- **Multi-language and SEO Ready** - Multi-language sites made easy with Hugo's multilingual mode. Out-of-the-box support is included for SEO tags, Open Graph, and Twitter Cards.
|
||||
- **Accessibility Support** - Interactive components use semantic markup, keyboard-friendly behavior, and automated accessibility checks to keep the UI usable across common assistive workflows.
|
||||
|
||||
## Quick Start
|
||||
|
||||
### Use the template
|
||||
|
||||
Using the [Hextra Starter Template](https://github.com/imfing/hextra-starter-template) is the simplest method to bootstrap a new website with Hextra theme. Get started by clicking the "Use this template" button on the template repository page.
|
||||
|
||||
The template repository also includes a [GitHub Actions workflow](https://docs.github.com/en/pages/getting-started-with-github-pages/configuring-a-publishing-source-for-your-github-pages-site#publishing-with-a-custom-github-actions-workflow) for deploying your website to GitHub Pages.
|
||||
|
||||
<img alt="Hextra Starter Template" src="https://user-images.githubusercontent.com/5097752/263551418-c403b9a9-a76c-47a6-8466-513d772ef0b7.jpg" width=600/>
|
||||
|
||||
### Usage
|
||||
|
||||
Refer to the [documentation](https://imfing.github.io/hextra/docs) for more information.
|
||||
|
||||
## Contributing
|
||||
|
||||
Contributions are welcome.
|
||||
Check out the [contributing guide](.github/CONTRIBUTING.md) to get started.
|
||||
|
||||
## License
|
||||
|
||||
[MIT License](./LICENSE)
|
||||
@@ -0,0 +1,46 @@
|
||||
<div align="center">
|
||||
<h1 align="center">Hextra</h1>
|
||||
<sup align="center"><a href="README.md">English</a> | <a href="README.zh-cn.md">简体中文</a> | <a href="README.fa.md">فارسی</a></sup>
|
||||
<p align="center">用于创建美观的静态站点的现代化, 响应式, 功能强大的 Hugo 主题.</p>
|
||||
|
||||
演示 → [imfing.github.io/hextra](https://imfing.github.io/hextra/)
|
||||
</div>
|
||||
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="https://user-images.githubusercontent.com/5097752/263550533-c18343ca-3848-4230-b5c0-ee989d7916da.png">
|
||||
<img alt="Hextra" src="https://user-images.githubusercontent.com/5097752/263550528-663599f9-17a1-4686-b5c4-3da233b5034d.png">
|
||||
</picture>
|
||||
|
||||
<div align="right">
|
||||
<a href="https://github.com/imfing/hextra/actions/workflows/pages.yml"><img alt="GitHub Actions Status" src="https://github.com/imfing/hextra/actions/workflows/pages.yml/badge.svg"></a> <a href="https://app.netlify.com/sites/hugo-hextra/deploys"><img alt="Netlify Status" src="https://api.netlify.com/api/v1/badges/61d6e55a-2447-487e-b59f-c9537e5df175/deploy-status"></a>
|
||||
</div>
|
||||
|
||||
## 特性
|
||||
|
||||
- **美观的设计** - 受 Nextra 的启发,Hextra 利用 Tailwind CSS 提供现代化的设计,使您的网站看起来美观有加.
|
||||
- **响应式布局和深色模式支持** - 在任何设备上看起来都足够美观, 无论是手机, 平板电脑或者电脑. 深色模式的支持使 Hextra 可以应对各种照明环境.
|
||||
- **快速且轻量** - 由 Hugo 强力支持, Hugo 是一个快如闪电的静态站点生成器, 这一切都只需一个可执行文件, Hextra 始终保持最小化, 无需 Javascript 或者 Node.js.
|
||||
- **全文搜索** - 集成了 Flexsearch 的全文搜索, 无需额外的配置.
|
||||
- **功能齐全** - Markdown, 代码高亮, LaTex 数学公式, diagrams 图表和 Shortcodes 都可以用于丰富你的内容. 目录, 面包屑导航, 分页, 侧边栏等均由 Hextra 自动生成。
|
||||
- **多语言和 SEO Ready** - Hugo 的多语言模式使得构建多语言网站更简单. 具有 SEO tags, Open Graph, 和 Twitter Cards 等诸多开箱即用的功能.
|
||||
- **无障碍支持** - 交互组件使用语义化标记、友好的键盘交互以及自动化无障碍检查,以便在常见辅助技术工作流中保持良好的可用性。
|
||||
|
||||
## 快速开始
|
||||
|
||||
### 使用模板
|
||||
|
||||
使用 [Hextra stater template](https://github.com/imfing/hextra-starter-template) 是使用 Hextra 主题的最简单方法. 点击仓库页面上的 `Use this template` 按钮开始使用.
|
||||
|
||||
此仓库中包含一个 [GitHub Actions workflow](https://docs.github.com/en/pages/getting-started-with-github-pages/configuring-a-publishing-source-for-your-github-pages-site#publishing-with-a-custom-github-actions-workflow) 来帮助你免费在 GitHub Pages 上自动构建和部署网站.
|
||||
|
||||
### 使用
|
||||
|
||||
转至[文档](https://imfing.github.io/hextra/zh-cn/docs)
|
||||
|
||||
## 贡献
|
||||
|
||||
该项目正在积极开发中. 欢迎贡献!
|
||||
|
||||
## 许可证
|
||||
|
||||
[MIT License](./LICENSE)
|
||||
@@ -0,0 +1,89 @@
|
||||
.dark .highlight {
|
||||
/* Background .bg { color: #c9d1d9; background-color: #0d1117; }
|
||||
/* PreWrapper .chroma { color: #c9d1d9; background-color: #0d1117; } */
|
||||
/* Other */ .chroma .x { }
|
||||
/* Error */ .chroma .err { color: #f85149 }
|
||||
/* CodeLine */ .chroma .cl { }
|
||||
/* LineLink */ .chroma .lnlinks { outline: none; text-decoration: none; color: inherit }
|
||||
/* LineTableTD .chroma .lntd { vertical-align: top; padding: 0; margin: 0; border: 0; } */
|
||||
/* LineTable .chroma .lntable { border-spacing: 0; padding: 0; margin: 0; border: 0; } */
|
||||
/* LineHighlight .chroma .hl { background-color: #ffffcc } */
|
||||
/* LineNumbersTable .chroma .lnt { white-space: pre; -webkit-user-select: none; user-select: none; margin-right: 0.4em; padding: 0 0.4em 0 0.4em;color: #64686c } */
|
||||
/* LineNumbers .chroma .ln { white-space: pre; -webkit-user-select: none; user-select: none; margin-right: 0.4em; padding: 0 0.4em 0 0.4em;color: #6e7681 } */
|
||||
/* Line */ .chroma .line { display: flex; }
|
||||
/* Keyword */ .chroma .k { color: #ff7b72 }
|
||||
/* KeywordConstant */ .chroma .kc { color: #79c0ff }
|
||||
/* KeywordDeclaration */ .chroma .kd { color: #ff7b72 }
|
||||
/* KeywordNamespace */ .chroma .kn { color: #ff7b72 }
|
||||
/* KeywordPseudo */ .chroma .kp { color: #79c0ff }
|
||||
/* KeywordReserved */ .chroma .kr { color: #ff7b72 }
|
||||
/* KeywordType */ .chroma .kt { color: #ff7b72 }
|
||||
/* Name */ .chroma .n { }
|
||||
/* NameAttribute */ .chroma .na { }
|
||||
/* NameBuiltin */ .chroma .nb { }
|
||||
/* NameBuiltinPseudo */ .chroma .bp { }
|
||||
/* NameClass */ .chroma .nc { color: #f0883e; font-weight: bold }
|
||||
/* NameConstant */ .chroma .no { color: #79c0ff; font-weight: bold }
|
||||
/* NameDecorator */ .chroma .nd { color: #d2a8ff; font-weight: bold }
|
||||
/* NameEntity */ .chroma .ni { color: #ffa657 }
|
||||
/* NameException */ .chroma .ne { color: #f0883e; font-weight: bold }
|
||||
/* NameFunction */ .chroma .nf { color: #d2a8ff; font-weight: bold }
|
||||
/* NameFunctionMagic */ .chroma .fm { }
|
||||
/* NameLabel */ .chroma .nl { color: #79c0ff; font-weight: bold }
|
||||
/* NameNamespace */ .chroma .nn { color: #ff7b72 }
|
||||
/* NameOther */ .chroma .nx { }
|
||||
/* NameProperty */ .chroma .py { color: #79c0ff }
|
||||
/* NameTag */ .chroma .nt { color: #7ee787 }
|
||||
/* NameVariable */ .chroma .nv { color: #79c0ff }
|
||||
/* NameVariableClass */ .chroma .vc { }
|
||||
/* NameVariableGlobal */ .chroma .vg { }
|
||||
/* NameVariableInstance */ .chroma .vi { }
|
||||
/* NameVariableMagic */ .chroma .vm { }
|
||||
/* Literal */ .chroma .l { color: #a5d6ff }
|
||||
/* LiteralDate */ .chroma .ld { color: #79c0ff }
|
||||
/* LiteralString */ .chroma .s { color: #a5d6ff }
|
||||
/* LiteralStringAffix */ .chroma .sa { color: #79c0ff }
|
||||
/* LiteralStringBacktick */ .chroma .sb { color: #a5d6ff }
|
||||
/* LiteralStringChar */ .chroma .sc { color: #a5d6ff }
|
||||
/* LiteralStringDelimiter */ .chroma .dl { color: #79c0ff }
|
||||
/* LiteralStringDoc */ .chroma .sd { color: #a5d6ff }
|
||||
/* LiteralStringDouble */ .chroma .s2 { color: #a5d6ff }
|
||||
/* LiteralStringEscape */ .chroma .se { color: #79c0ff }
|
||||
/* LiteralStringHeredoc */ .chroma .sh { color: #79c0ff }
|
||||
/* LiteralStringInterpol */ .chroma .si { color: #a5d6ff }
|
||||
/* LiteralStringOther */ .chroma .sx { color: #a5d6ff }
|
||||
/* LiteralStringRegex */ .chroma .sr { color: #79c0ff }
|
||||
/* LiteralStringSingle */ .chroma .s1 { color: #a5d6ff }
|
||||
/* LiteralStringSymbol */ .chroma .ss { color: #a5d6ff }
|
||||
/* LiteralNumber */ .chroma .m { color: #a5d6ff }
|
||||
/* LiteralNumberBin */ .chroma .mb { color: #a5d6ff }
|
||||
/* LiteralNumberFloat */ .chroma .mf { color: #a5d6ff }
|
||||
/* LiteralNumberHex */ .chroma .mh { color: #a5d6ff }
|
||||
/* LiteralNumberInteger */ .chroma .mi { color: #a5d6ff }
|
||||
/* LiteralNumberIntegerLong */ .chroma .il { color: #a5d6ff }
|
||||
/* LiteralNumberOct */ .chroma .mo { color: #a5d6ff }
|
||||
/* Operator */ .chroma .o { color: #ff7b72; font-weight: bold }
|
||||
/* OperatorWord */ .chroma .ow { color: #ff7b72; font-weight: bold }
|
||||
/* Punctuation */ .chroma .p { }
|
||||
/* Comment */ .chroma .c { color: #8b949e; font-style: italic }
|
||||
/* CommentHashbang */ .chroma .ch { color: #8b949e; font-style: italic }
|
||||
/* CommentMultiline */ .chroma .cm { color: #8b949e; font-style: italic }
|
||||
/* CommentSingle */ .chroma .c1 { color: #8b949e; font-style: italic }
|
||||
/* CommentSpecial */ .chroma .cs { color: #8b949e; font-weight: bold; font-style: italic }
|
||||
/* CommentPreproc */ .chroma .cp { color: #8b949e; font-weight: bold; font-style: italic }
|
||||
/* CommentPreprocFile */ .chroma .cpf { color: #8b949e; font-weight: bold; font-style: italic }
|
||||
/* Generic */ .chroma .g { }
|
||||
/* GenericDeleted */ .chroma .gd { color: #ffa198; background-color: #490202 }
|
||||
/* GenericEmph */ .chroma .ge { color: inherit; font-style: italic }
|
||||
/* GenericError */ .chroma .gr { color: #ffa198 }
|
||||
/* GenericHeading */ .chroma .gh { color: #79c0ff; font-weight: bold }
|
||||
/* GenericInserted */ .chroma .gi { color: #56d364; background-color: #0f5323 }
|
||||
/* GenericOutput */ .chroma .go { color: #8b949e }
|
||||
/* GenericPrompt */ .chroma .gp { color: #8b949e }
|
||||
/* GenericStrong */ .chroma .gs { font-weight: bold }
|
||||
/* GenericSubheading */ .chroma .gu { color: #79c0ff }
|
||||
/* GenericTraceback */ .chroma .gt { color: #ff7b72 }
|
||||
/* GenericUnderline */ .chroma .gl { text-decoration: underline }
|
||||
/* TextWhitespace */ .chroma .w { color: #6e7681 }
|
||||
}
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
/* Light theme for syntax highlight */
|
||||
/* Generated using `hugo gen chromastyles --style=github` */
|
||||
.highlight {
|
||||
/* Background .bg { background-color: #ffffff; } */
|
||||
/* PreWrapper .chroma { background-color: #ffffff; } */
|
||||
/* Other .chroma .x { } */
|
||||
/* Error */ .chroma .err { color: #a61717; background-color: #e3d2d2 }
|
||||
/* CodeLine .chroma .cl { } */
|
||||
/* LineLink */ .chroma .lnlinks { outline: none; text-decoration: none; color: inherit }
|
||||
/* LineTableTD .chroma .lntd { vertical-align: top; padding: 0; margin: 0; border: 0; } */
|
||||
/* LineTable .chroma .lntable { border-spacing: 0; padding: 0; margin: 0; border: 0; } */
|
||||
/* LineHighlight .chroma .hl { background-color: #ffffcc } */
|
||||
/* LineNumbersTable .chroma .lnt { white-space: pre; -webkit-user-select: none; user-select: none; margin-right: 0.4em; padding: 0 0.4em 0 0.4em;color: #7f7f7f } */
|
||||
/* LineNumbers .chroma .ln { white-space: pre; -webkit-user-select: none; user-select: none; margin-right: 0.4em; padding: 0 0.4em 0 0.4em;color: #7f7f7f } */
|
||||
/* Line */ .chroma .line { display: flex; }
|
||||
/* Keyword */ .chroma .k { color: #000000; font-weight: bold }
|
||||
/* KeywordConstant */ .chroma .kc { color: #000000; font-weight: bold }
|
||||
/* KeywordDeclaration */ .chroma .kd { color: #000000; font-weight: bold }
|
||||
/* KeywordNamespace */ .chroma .kn { color: #000000; font-weight: bold }
|
||||
/* KeywordPseudo */ .chroma .kp { color: #000000; font-weight: bold }
|
||||
/* KeywordReserved */ .chroma .kr { color: #000000; font-weight: bold }
|
||||
/* KeywordType */ .chroma .kt { color: #445588; font-weight: bold }
|
||||
/* Name .chroma .n { } */
|
||||
/* NameAttribute */ .chroma .na { color: #008080 }
|
||||
/* NameBuiltin */ .chroma .nb { color: #0086b3 }
|
||||
/* NameBuiltinPseudo */ .chroma .bp { color: #999999 }
|
||||
/* NameClass */ .chroma .nc { color: #445588; font-weight: bold }
|
||||
/* NameConstant */ .chroma .no { color: #008080 }
|
||||
/* NameDecorator */ .chroma .nd { color: #3c5d5d; font-weight: bold }
|
||||
/* NameEntity */ .chroma .ni { color: #800080 }
|
||||
/* NameException */ .chroma .ne { color: #990000; font-weight: bold }
|
||||
/* NameFunction */ .chroma .nf { color: #990000; font-weight: bold }
|
||||
/* NameFunctionMagic .chroma .fm { } */
|
||||
/* NameLabel */ .chroma .nl { color: #990000; font-weight: bold }
|
||||
/* NameNamespace */ .chroma .nn { color: #555555 }
|
||||
/* NameOther .chroma .nx { } */
|
||||
/* NameProperty .chroma .py { } */
|
||||
/* NameTag */ .chroma .nt { color: #000080 }
|
||||
/* NameVariable */ .chroma .nv { color: #008080 }
|
||||
/* NameVariableClass */ .chroma .vc { color: #008080 }
|
||||
/* NameVariableGlobal */ .chroma .vg { color: #008080 }
|
||||
/* NameVariableInstance */ .chroma .vi { color: #008080 }
|
||||
/* NameVariableMagic .chroma .vm { } */
|
||||
/* Literal .chroma .l { } */
|
||||
/* LiteralDate .chroma .ld { } */
|
||||
/* LiteralString */ .chroma .s { color: #dd1144 }
|
||||
/* LiteralStringAffix */ .chroma .sa { color: #dd1144 }
|
||||
/* LiteralStringBacktick */ .chroma .sb { color: #dd1144 }
|
||||
/* LiteralStringChar */ .chroma .sc { color: #dd1144 }
|
||||
/* LiteralStringDelimiter */ .chroma .dl { color: #dd1144 }
|
||||
/* LiteralStringDoc */ .chroma .sd { color: #dd1144 }
|
||||
/* LiteralStringDouble */ .chroma .s2 { color: #dd1144 }
|
||||
/* LiteralStringEscape */ .chroma .se { color: #dd1144 }
|
||||
/* LiteralStringHeredoc */ .chroma .sh { color: #dd1144 }
|
||||
/* LiteralStringInterpol */ .chroma .si { color: #dd1144 }
|
||||
/* LiteralStringOther */ .chroma .sx { color: #dd1144 }
|
||||
/* LiteralStringRegex */ .chroma .sr { color: #009926 }
|
||||
/* LiteralStringSingle */ .chroma .s1 { color: #dd1144 }
|
||||
/* LiteralStringSymbol */ .chroma .ss { color: #990073 }
|
||||
/* LiteralNumber */ .chroma .m { color: #009999 }
|
||||
/* LiteralNumberBin */ .chroma .mb { color: #009999 }
|
||||
/* LiteralNumberFloat */ .chroma .mf { color: #009999 }
|
||||
/* LiteralNumberHex */ .chroma .mh { color: #009999 }
|
||||
/* LiteralNumberInteger */ .chroma .mi { color: #009999 }
|
||||
/* LiteralNumberIntegerLong */ .chroma .il { color: #009999 }
|
||||
/* LiteralNumberOct */ .chroma .mo { color: #009999 }
|
||||
/* Operator */ .chroma .o { color: #000000; font-weight: bold }
|
||||
/* OperatorWord */ .chroma .ow { color: #000000; font-weight: bold }
|
||||
/* Punctuation .chroma .p { } */
|
||||
/* Comment */ .chroma .c { color: #999988; font-style: italic }
|
||||
/* CommentHashbang */ .chroma .ch { color: #999988; font-style: italic }
|
||||
/* CommentMultiline */ .chroma .cm { color: #999988; font-style: italic }
|
||||
/* CommentSingle */ .chroma .c1 { color: #999988; font-style: italic }
|
||||
/* CommentSpecial */ .chroma .cs { color: #999999; font-weight: bold; font-style: italic }
|
||||
/* CommentPreproc */ .chroma .cp { color: #999999; font-weight: bold; font-style: italic }
|
||||
/* CommentPreprocFile */ .chroma .cpf { color: #999999; font-weight: bold; font-style: italic }
|
||||
/* Generic .chroma .g { } */
|
||||
/* GenericDeleted */ .chroma .gd { color: #000000; background-color: #ffdddd }
|
||||
/* GenericEmph */ .chroma .ge { color: #000000; font-style: italic }
|
||||
/* GenericError */ .chroma .gr { color: #aa0000 }
|
||||
/* GenericHeading */ .chroma .gh { color: #999999 }
|
||||
/* GenericInserted */ .chroma .gi { color: #000000; background-color: #ddffdd }
|
||||
/* GenericOutput */ .chroma .go { color: #888888 }
|
||||
/* GenericPrompt */ .chroma .gp { color: #555555 }
|
||||
/* GenericStrong */ .chroma .gs { font-weight: bold }
|
||||
/* GenericSubheading */ .chroma .gu { color: #aaaaaa }
|
||||
/* GenericTraceback */ .chroma .gt { color: #aa0000 }
|
||||
/* GenericUnderline */ .chroma .gl { text-decoration: underline }
|
||||
/* TextWhitespace */ .chroma .w { color: #bbbbbb }
|
||||
}
|
||||
+2
File diff suppressed because one or more lines are too long
@@ -0,0 +1,3 @@
|
||||
.hextra-archive-timeline {
|
||||
@apply hx:border-l-2 hx:border-black/15 hx:dark:border-white/15;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
.hextra-badge {
|
||||
@apply hx:inline-flex hx:items-center;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
.hextra-banner-hidden .hextra-banner {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.hextra-banner {
|
||||
:where(a):not(:where([class~=not-prose],[class~=not-prose] *)) {
|
||||
@apply hx:underline hx:decoration-from-font;
|
||||
}
|
||||
:where(p):not(:where([class~=not-prose],[class~=not-prose] *)) {
|
||||
@apply hx:leading-7 hx:first:mt-0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
.hextra-cards {
|
||||
grid-template-columns: repeat(auto-fill, minmax(max(250px, calc((100% - 1rem * 2) / var(--hextra-cards-grid-cols))), 1fr));
|
||||
}
|
||||
|
||||
.hextra-card {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.hextra-card img {
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.hextra-card:hover .hextra-card-icon svg {
|
||||
color: currentColor;
|
||||
}
|
||||
|
||||
.hextra-card .hextra-card-icon svg {
|
||||
width: 1.5rem;
|
||||
color: #00000033;
|
||||
transition: color 0.3s ease;
|
||||
}
|
||||
|
||||
.hextra-card p {
|
||||
margin-top: 0.5rem;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.dark .hextra-card .hextra-card-icon svg {
|
||||
color: #ffffff66;
|
||||
}
|
||||
|
||||
.dark .hextra-card:hover .hextra-card-icon svg {
|
||||
color: currentColor;
|
||||
}
|
||||
|
||||
.hextra-card-tag {
|
||||
position: absolute;
|
||||
z-index: 10;
|
||||
top: 5px;
|
||||
&:where(:dir(ltr)) {
|
||||
right: 5px;
|
||||
}
|
||||
&:where(:dir(rtl)) {
|
||||
left: 5px;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
@supports (
|
||||
(-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))
|
||||
) {
|
||||
.hextra-code-copy-btn {
|
||||
@apply hx:backdrop-blur-md hx:opacity-85 hx:dark:opacity-80;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
.hextra-feature-grid {
|
||||
@media (min-width: 1024px) {
|
||||
grid-template-columns: repeat(var(--hextra-feature-grid-cols), minmax(0, 1fr));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
.hextra-jupyter-code-cell {
|
||||
scrollbar-gutter: auto;
|
||||
|
||||
@apply hx:mt-6;
|
||||
|
||||
.hextra-jupyter-code-cell-outputs-container {
|
||||
@apply hx:text-xs hx:overflow-hidden;
|
||||
|
||||
.hextra-jupyter-code-cell-outputs {
|
||||
@apply hx:overflow-auto hx:max-h-[50vh];
|
||||
|
||||
pre {
|
||||
@apply hx:text-xs hx:overflow-auto hx:max-w-full;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
nav {
|
||||
.hextra-search-wrapper {
|
||||
@apply hx:hidden hx:md:inline-block;
|
||||
}
|
||||
}
|
||||
|
||||
@supports (
|
||||
(-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))
|
||||
) {
|
||||
.hextra-nav-container-blur {
|
||||
@apply hx:backdrop-blur-md hx:bg-white/[.85] hx:dark:bg-dark/80!;
|
||||
}
|
||||
}
|
||||
|
||||
/* Hamburger Menu - Flattened Structure */
|
||||
.hextra-hamburger-menu svg g {
|
||||
@apply hx:origin-center hx:transition-all hx:duration-100 hx:ease-out;
|
||||
}
|
||||
|
||||
.hextra-hamburger-menu svg path {
|
||||
@apply hx:opacity-100 hx:transition-all hx:duration-100 hx:ease-out hx:delay-100;
|
||||
}
|
||||
|
||||
.hextra-hamburger-menu svg.open path {
|
||||
@apply hx:transition-transform hx:duration-100 hx:ease-out hx:delay-0;
|
||||
}
|
||||
|
||||
.hextra-hamburger-menu svg.open g {
|
||||
@apply hx:transition-transform hx:duration-100 hx:ease-out hx:delay-100;
|
||||
}
|
||||
|
||||
.hextra-hamburger-menu svg.open > path {
|
||||
@apply hx:opacity-0;
|
||||
}
|
||||
|
||||
.hextra-hamburger-menu svg.open > g:nth-of-type(1) {
|
||||
@apply hx:rotate-45;
|
||||
}
|
||||
|
||||
.hextra-hamburger-menu svg.open > g:nth-of-type(1) path {
|
||||
@apply hx:translate-y-1;
|
||||
}
|
||||
|
||||
.hextra-hamburger-menu svg.open > g:nth-of-type(2) {
|
||||
@apply hx:-rotate-45;
|
||||
}
|
||||
|
||||
.hextra-hamburger-menu svg.open > g:nth-of-type(2) path {
|
||||
@apply hx:-translate-y-1;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
.hextra-scrollbar, .hextra-scrollbar * {
|
||||
scrollbar-width: thin; /* Firefox */
|
||||
scrollbar-color: oklch(55.55% 0 0 / 40%) transparent; /* Firefox */
|
||||
|
||||
scrollbar-gutter: stable;
|
||||
&::-webkit-scrollbar {
|
||||
@apply hx:w-3 hx:h-3;
|
||||
}
|
||||
&::-webkit-scrollbar-track {
|
||||
@apply hx:bg-transparent;
|
||||
}
|
||||
&::-webkit-scrollbar-thumb {
|
||||
@apply hx:rounded-[10px];
|
||||
}
|
||||
&:hover::-webkit-scrollbar-thumb {
|
||||
border: 3px solid transparent;
|
||||
background-color: var(--tw-shadow-color);
|
||||
background-clip: content-box;
|
||||
@apply hx:shadow-neutral-500/20 hx:hover:shadow-neutral-500/40;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
.hextra-search-wrapper {
|
||||
li {
|
||||
@apply hx:mx-2.5 hx:wrap-break-word hx:rounded-md hx:contrast-more:border hx:text-gray-800 hx:contrast-more:border-transparent hx:dark:text-gray-300;
|
||||
a {
|
||||
@apply hx:focus-visible:outline-none hx:block hx:scroll-m-12 hx:px-2.5 hx:py-2;
|
||||
}
|
||||
|
||||
.hextra-search-title {
|
||||
@apply hx:text-base hx:font-semibold hx:leading-5;
|
||||
}
|
||||
|
||||
.hextra-search-active {
|
||||
@apply hx:rounded-md hx:bg-primary-500/10 hx:contrast-more:border-primary-500;
|
||||
}
|
||||
}
|
||||
|
||||
.hextra-search-no-result {
|
||||
@apply hx:block hx:select-none hx:p-8 hx:text-center hx:text-sm hx:text-gray-400;
|
||||
}
|
||||
|
||||
.hextra-search-prefix {
|
||||
@apply hx:mx-2.5 hx:mb-2 hx:mt-6 hx:select-none hx:border-b hx:border-black/10 hx:px-2.5 hx:pb-1.5 hx:text-xs hx:font-semibold
|
||||
hx:uppercase hx:text-gray-500 hx:first:mt-0 hx:dark:border-white/20 hx:dark:text-gray-300 hx:contrast-more:border-gray-600
|
||||
hx:contrast-more:text-gray-900 hx:contrast-more:dark:border-gray-50 hx:contrast-more:dark:text-gray-50;
|
||||
}
|
||||
|
||||
.hextra-search-excerpt {
|
||||
@apply hx:overflow-hidden hx:text-ellipsis hx:mt-1 hx:text-sm hx:leading-[1.35rem] hx:text-gray-600 hx:dark:text-gray-400 hx:contrast-more:dark:text-gray-50;
|
||||
display: -webkit-box;
|
||||
line-clamp: 1;
|
||||
-webkit-line-clamp: 1;
|
||||
-webkit-box-orient: vertical;
|
||||
}
|
||||
|
||||
.hextra-search-match {
|
||||
@apply hx:text-primary-600;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
@media (max-width: 48rem) {
|
||||
.hextra-sidebar-container {
|
||||
@apply hx:fixed hx:pt-[calc(var(--navbar-height)+var(--hextra-banner-height))] hx:top-0 hx:w-full hx:bottom-0 hx:z-15 hx:overscroll-contain hx:bg-white hx:dark:bg-dark;
|
||||
transition: transform 0.4s cubic-bezier(0.52, 0.16, 0.04, 1);
|
||||
will-change: transform, opacity;
|
||||
contain: layout style;
|
||||
backface-visibility: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
.hextra-sidebar-container {
|
||||
li > .hextra-sidebar-children {
|
||||
@apply hx:h-0;
|
||||
}
|
||||
li.open > .hextra-sidebar-children {
|
||||
@apply hx:h-auto hx:pt-1;
|
||||
}
|
||||
li.open > .hextra-sidebar-item > .hextra-sidebar-collapsible-button > svg > path {
|
||||
@apply hx:rotate-90;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
.hextra-steps {
|
||||
:where(h2, h3, h4, h5, h6):not(.no-step-marker) {
|
||||
counter-increment: step;
|
||||
@apply hx:ltr:before:ml-[-41px] hx:rtl:before:mr-[-44px];
|
||||
/* https://github.com/tailwindlabs/tailwindcss/issues/15597#issuecomment-2582673546 */
|
||||
@apply hx:before:bg-gray-100 hx:dark:before:bg-neutral-800;
|
||||
@apply hx:before:border-4 hx:before:border-white hx:dark:before:border-dark;
|
||||
&:before {
|
||||
content: counter(step);
|
||||
@apply hx:absolute hx:size-[33px];
|
||||
@apply hx:rounded-full hx:text-neutral-400 hx:text-base hx:font-normal hx:text-center hx:-indent-px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
:lang(fa) .hextra-steps {
|
||||
:where(h2, h3, h4, h5, h6):not(.no-step-marker) {
|
||||
&:before {
|
||||
content: counter(step, persian);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
/* Table of Contents Scroll Spy Styles */
|
||||
.hextra-toc a.hextra-toc-active {
|
||||
@apply hx:text-gray-900! hx:dark:text-gray-50! hx:transition-all hx:duration-200;
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/* Code syntax highlight */
|
||||
@import "./chroma/light.css";
|
||||
@import "./chroma/dark.css";
|
||||
|
||||
.hextra-code-block {
|
||||
@apply hx:text-[.9em] hx:leading-5;
|
||||
|
||||
pre {
|
||||
@apply hx:text-[.9em] hx:bg-primary-700/5 hx:overflow-x-auto hx:font-medium hx:subpixel-antialiased hx:dark:bg-primary-300/10 hx:contrast-more:border hx:contrast-more:border-primary-900/20 hx:contrast-more:contrast-150 hx:contrast-more:dark:border-primary-100/40;
|
||||
}
|
||||
|
||||
.hextra-code-filename {
|
||||
@apply hx:absolute hx:top-0 hx:z-1 hx:w-full hx:truncate hx:rounded-t-xl hx:bg-primary-700/5 hx:py-2 hx:px-4 hx:text-xs hx:text-gray-700 hx:dark:bg-primary-300/10 hx:dark:text-gray-200;
|
||||
}
|
||||
|
||||
.hextra-code-filename + pre:not(.lntable pre) {
|
||||
/* Override padding for code blocks with filename but no highlight */
|
||||
@apply hx:pt-12;
|
||||
}
|
||||
}
|
||||
|
||||
.hextra-code-block pre:not(.lntable pre) {
|
||||
@apply hx:px-4 hx:mb-4 hx:py-4 hx:rounded-xl;
|
||||
}
|
||||
|
||||
.hextra-code-block div:nth-of-type(2) pre {
|
||||
@apply hx:pt-12 hx:pb-4;
|
||||
}
|
||||
|
||||
.chroma {
|
||||
.lntable {
|
||||
@apply hx:m-0 hx:block hx:w-auto hx:overflow-auto hx:rounded-xl;
|
||||
|
||||
pre {
|
||||
@apply hx:pt-4 hx:pb-4;
|
||||
}
|
||||
}
|
||||
.ln,
|
||||
.lnt:not(.hl > .lnt),
|
||||
.hl:not(.line) {
|
||||
@apply hx:pl-4 hx:pr-4 hx:min-w-[2.6rem] hx:text-neutral-600 hx:dark:text-neutral-300;
|
||||
}
|
||||
.lntd {
|
||||
@apply hx:p-0 hx:align-top;
|
||||
}
|
||||
.lntd:last-of-type {
|
||||
@apply hx:w-full;
|
||||
}
|
||||
/* LineHighlight */
|
||||
.hl {
|
||||
@apply hx:block hx:w-full hx:bg-primary-800/10;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
hx:max-w-full
|
||||
@@ -0,0 +1,91 @@
|
||||
@import "tailwindcss" prefix(hx);
|
||||
|
||||
@custom-variant dark (&:where(.dark, .dark *));
|
||||
|
||||
@theme {
|
||||
--color-primary-50: hsl(var(--primary-hue) var(--primary-saturation) calc(var(--primary-lightness) + calc(calc(100% - var(--primary-lightness)) / 50) * 47));
|
||||
--color-primary-100: hsl(var(--primary-hue) var(--primary-saturation) calc(var(--primary-lightness) + calc(calc(100% - var(--primary-lightness)) / 50) * 44));
|
||||
--color-primary-200: hsl(var(--primary-hue) var(--primary-saturation) calc(var(--primary-lightness) + calc(calc(100% - var(--primary-lightness)) / 50) * 36));
|
||||
--color-primary-300: hsl(var(--primary-hue) var(--primary-saturation) calc(var(--primary-lightness) + calc(calc(100% - var(--primary-lightness)) / 50) * 27));
|
||||
--color-primary-400: hsl(var(--primary-hue) var(--primary-saturation) calc(var(--primary-lightness) + calc(calc(100% - var(--primary-lightness)) / 50) * 16));
|
||||
--color-primary-500: hsl(var(--primary-hue) var(--primary-saturation) var(--primary-lightness));
|
||||
--color-primary-600: hsl(var(--primary-hue) var(--primary-saturation) calc(calc(var(--primary-lightness) / 50) * 45));
|
||||
--color-primary-700: hsl(var(--primary-hue) var(--primary-saturation) calc(calc(var(--primary-lightness) / 50) * 39));
|
||||
--color-primary-800: hsl(var(--primary-hue) var(--primary-saturation) calc(calc(var(--primary-lightness) / 50) * 32));
|
||||
--color-primary-900: hsl(var(--primary-hue) var(--primary-saturation) calc(calc(var(--primary-lightness) / 50) * 24));
|
||||
--color-dark: #111;
|
||||
}
|
||||
|
||||
html {
|
||||
@apply hx:text-base hx:antialiased;
|
||||
}
|
||||
|
||||
body {
|
||||
@apply hx:w-full hx:bg-white hx:dark:bg-dark hx:dark:text-gray-100;
|
||||
}
|
||||
|
||||
:root {
|
||||
--primary-hue: 212deg;
|
||||
--primary-saturation: 100%;
|
||||
--primary-lightness: 50%;
|
||||
--navbar-height: 4rem;
|
||||
--hextra-banner-height: 2rem;
|
||||
--menu-height: 3.75rem; /* 60px */
|
||||
}
|
||||
|
||||
.dark {
|
||||
--primary-hue: 204deg;
|
||||
--primary-saturation: 100%;
|
||||
--primary-lightness: 50%;
|
||||
}
|
||||
|
||||
@utility hextra-focus {
|
||||
@apply hx:outline-none hx:ring-2 hx:ring-primary-200 hx:ring-offset-1 hx:ring-offset-primary-300 hx:dark:ring-primary-800 hx:dark:ring-offset-primary-700;
|
||||
}
|
||||
|
||||
@utility hextra-focus-visible {
|
||||
@apply hx:focus-visible:outline-none hx:focus-visible:ring-2 hx:focus-visible:ring-primary-200 hx:focus-visible:ring-offset-1 hx:focus-visible:ring-offset-primary-300 hx:dark:focus-visible:ring-primary-800 hx:dark:focus-visible:ring-offset-primary-700;
|
||||
}
|
||||
|
||||
@utility hextra-focus-visible-inset {
|
||||
@apply hx:focus-visible:outline-none hx:focus-visible:ring-inset hx:focus-visible:ring-2 hx:focus-visible:ring-primary-200 hx:dark:focus-visible:ring-primary-800 hx:focus-visible:ring-offset-0;
|
||||
}
|
||||
|
||||
@layer base {
|
||||
abbr:where([title]) {
|
||||
cursor: help;
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
*, *::before, *::after {
|
||||
animation-duration: 0.01ms !important;
|
||||
animation-iteration-count: 1 !important;
|
||||
transition-duration: 0.01ms !important;
|
||||
scroll-behavior: auto !important;
|
||||
}
|
||||
}
|
||||
|
||||
@layer base {
|
||||
:where(a, button, [role="tab"], [role="menuitem"], [role="menuitemradio"], input, select, textarea, [tabindex="0"]):not(
|
||||
[class*="hextra-focus-visible"]
|
||||
):focus-visible {
|
||||
@apply hx:hextra-focus;
|
||||
}
|
||||
}
|
||||
|
||||
@import "./typography.css";
|
||||
@import "./highlight.css";
|
||||
@import "./components/cards.css";
|
||||
@import "./components/steps.css";
|
||||
@import "./components/search.css";
|
||||
@import "./components/sidebar.css";
|
||||
@import "./components/banner.css";
|
||||
@import "./components/navbar.css";
|
||||
@import "./components/scrollbar.css";
|
||||
@import "./components/code-copy.css";
|
||||
@import "./components/hextra/feature-grid.css";
|
||||
@import "./components/jupyter.css";
|
||||
@import "./components/badge.css";
|
||||
@import "./components/toc.css";
|
||||
@import "./components/archives.css";
|
||||
@@ -0,0 +1,147 @@
|
||||
.content {
|
||||
:where(h1):not(:where([class~=not-prose],[class~=not-prose] *)) {
|
||||
@apply hx:mt-2 hx:text-4xl hx:font-bold hx:tracking-tight hx:text-slate-900 hx:dark:text-slate-100;
|
||||
}
|
||||
:where(h2):not(:where([class~=not-prose],[class~=not-prose] *)) {
|
||||
@apply hx:font-semibold hx:tracking-tight hx:text-slate-900 hx:dark:text-slate-100 hx:mt-10 hx:border-b hx:pb-1 hx:text-3xl hx:border-neutral-200/70 hx:contrast-more:border-neutral-400 hx:dark:border-primary-100/10 hx:contrast-more:dark:border-neutral-400;
|
||||
}
|
||||
:where(h3):not(:where([class~=not-prose],[class~=not-prose] *)) {
|
||||
@apply hx:font-semibold hx:tracking-tight hx:text-slate-900 hx:dark:text-slate-100 hx:mt-8 hx:text-2xl;
|
||||
}
|
||||
:where(h4):not(:where([class~=not-prose],[class~=not-prose] *)) {
|
||||
@apply hx:font-semibold hx:tracking-tight hx:text-slate-900 hx:dark:text-slate-100 hx:mt-8 hx:text-xl;
|
||||
}
|
||||
:where(h5):not(:where([class~=not-prose],[class~=not-prose] *)) {
|
||||
@apply hx:font-semibold hx:tracking-tight hx:text-slate-900 hx:dark:text-slate-100 hx:mt-8 hx:text-lg;
|
||||
}
|
||||
:where(h6):not(:where([class~=not-prose],[class~=not-prose] *)) {
|
||||
@apply hx:font-semibold hx:tracking-tight hx:text-slate-900 hx:dark:text-slate-100 hx:mt-8 hx:text-base;
|
||||
}
|
||||
:where(p):not(:where([class~=not-prose],[class~=not-prose] *)) {
|
||||
@apply hx:mt-6 hx:leading-7 hx:first:mt-0;
|
||||
}
|
||||
:where(a):not(:where([class~=not-prose],[class~=not-prose] *)) {
|
||||
@apply hx:text-primary-600 hx:underline hx:decoration-from-font;
|
||||
}
|
||||
:where(blockquote):not(:where([class~=not-prose],[class~=not-prose] *)) {
|
||||
@apply hx:mt-6 hx:border-gray-300 hx:italic hx:text-gray-700 hx:dark:border-gray-700 hx:dark:text-gray-400 hx:first:mt-0 hx:ltr:border-l-2 hx:ltr:pl-6 hx:rtl:border-r-2 hx:rtl:pr-6;
|
||||
}
|
||||
:where(pre):not(:where(.hextra-code-block pre, [class~=not-prose],[class~=not-prose] *)) {
|
||||
@apply hx:bg-primary-700/5 hx:mb-4 hx:overflow-x-auto hx:rounded-xl hx:font-medium hx:subpixel-antialiased hx:dark:bg-primary-300/10 hx:text-[.9em] hx:contrast-more:border hx:contrast-more:border-primary-900/20 hx:contrast-more:contrast-150 hx:contrast-more:dark:border-primary-100/40 hx:py-4;
|
||||
}
|
||||
:where(code):not(:where(.hextra-code-block code, [class~=not-prose],[class~=not-prose] *)) {
|
||||
@apply hx:border-black/4 hx:bg-black/3 hx:wrap-break-word hx:rounded-md hx:border hx:py-0.5 hx:px-[.25em] hx:text-[.9em] hx:dark:border-white/10 hx:dark:bg-white/10;
|
||||
}
|
||||
:where(table):not(:where(.hextra-code-block table, [class~=not-prose],[class~=not-prose] *)) {
|
||||
@apply hx:block hx:overflow-x-auto hx:my-6 hx:p-0 hx:first:mt-0 hx:w-full hx:text-sm hx:leading-5 hx:border-collapse;
|
||||
|
||||
thead {
|
||||
@apply hx:bg-gray-50 hx:dark:bg-gray-600/20;
|
||||
}
|
||||
tr {
|
||||
@apply hx:m-0 hx:border-t hx:border-gray-300 hx:p-0 hx:dark:border-gray-600;
|
||||
}
|
||||
th {
|
||||
@apply hx:m-0 hx:border hx:border-gray-300 hx:p-2 hx:font-semibold hx:dark:border-gray-600;
|
||||
}
|
||||
td {
|
||||
@apply hx:m-0 hx:border hx:border-gray-300 hx:p-2 hx:dark:border-gray-600;
|
||||
}
|
||||
}
|
||||
:where(ol):not(:where([class~=not-prose],[class~=not-prose] *)) {
|
||||
@apply hx:mt-6 hx:list-decimal hx:first:mt-0 hx:ltr:ml-6 hx:rtl:mr-6;
|
||||
li {
|
||||
@apply hx:my-2;
|
||||
}
|
||||
}
|
||||
:where(ul):not(:where([class~=not-prose],[class~=not-prose] *)) {
|
||||
@apply hx:mt-6 hx:list-disc hx:first:mt-0 hx:ltr:ml-6 hx:rtl:mr-6;
|
||||
li {
|
||||
@apply hx:my-2;
|
||||
}
|
||||
}
|
||||
/* Task lists - hide list markers for lists containing checkboxes */
|
||||
:where(ul):not(:where([class~=not-prose],[class~=not-prose] *)):has(li input[type="checkbox"]) {
|
||||
@apply hx:list-none;
|
||||
}
|
||||
/* This CSS rule targets the first nested unordered (ul) or ordered (ol) list
|
||||
inside the list item (li) of any parent ul or ol.
|
||||
The rule sets the top margin of the selected list to zero. */
|
||||
:where(ul, ol) > li > :where(ul, ol):not(:where([class~=not-prose],[class~=not-prose] *)) {
|
||||
@apply hx:mt-0;
|
||||
}
|
||||
:where(kbd):not(:where([class~=not-prose],[class~=not-prose] *)) {
|
||||
@apply hx:border-black/4 hx:bg-black/3 hx:wrap-break-word hx:rounded-md hx:border hx:py-0.5 hx:px-[.25em] hx:text-[.9em] hx:dark:border-white/10 hx:dark:bg-white/10;
|
||||
}
|
||||
:where(pre.mermaid):not(:where(.hextra-code-block pre, [class~=not-prose],[class~=not-prose] *)) {
|
||||
@apply hx:bg-transparent hx:rounded-none hx:dark:bg-transparent;
|
||||
}
|
||||
:where(img):not(:where([class~=not-prose],[class~=not-prose] *)) {
|
||||
@apply hx:mx-auto hx:my-4 hx:rounded-md;
|
||||
}
|
||||
:where(figure):not(:where([class~=not-prose],[class~=not-prose] *)) {
|
||||
figcaption {
|
||||
@apply hx:text-sm hx:text-gray-500 hx:dark:text-gray-400 hx:mt-2 hx:block hx:text-center;
|
||||
}
|
||||
}
|
||||
/* Definition list */
|
||||
:where(dl):not(:where([class~=not-prose],[class~=not-prose] *)) {
|
||||
dt {
|
||||
@apply hx:mt-6 hx:font-semibold;
|
||||
}
|
||||
dd {
|
||||
@apply hx:my-2 hx:ps-6;
|
||||
}
|
||||
}
|
||||
/* Horizontal line */
|
||||
:where(hr):not(:where([class~=not-prose],[class~=not-prose] *)) {
|
||||
@apply hx:my-10 hx:first:mt-0 hx:last:mb-0 hx:border-gray-200 hx:dark:border-neutral-800;
|
||||
}
|
||||
.footnotes {
|
||||
@apply hx:mt-12 hx:text-sm;
|
||||
|
||||
hr {
|
||||
@apply hx:border-gray-200 hx:dark:border-neutral-800;
|
||||
}
|
||||
}
|
||||
.subheading-anchor {
|
||||
@apply hx:opacity-0 hx:transition-opacity hx:ltr:ml-1 hx:rtl:mr-1;
|
||||
|
||||
span:target + &,
|
||||
:hover > &,
|
||||
&:focus-visible {
|
||||
@apply hx:opacity-100;
|
||||
}
|
||||
|
||||
span + &,
|
||||
:hover > & {
|
||||
@apply hx:no-underline!;
|
||||
}
|
||||
|
||||
@apply hx:after:text-gray-300 hx:dark:after:text-neutral-700;
|
||||
&:after {
|
||||
@apply hx:content-['#'] hx:px-1;
|
||||
span:target + & {
|
||||
@apply hx:text-gray-400;
|
||||
@apply hx:dark:text-neutral-500;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
article details > summary {
|
||||
&::-webkit-details-marker {
|
||||
@apply hx:hidden;
|
||||
}
|
||||
&::before {
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' class='hx:h-5 hx:w-5' viewBox='0 0 20 20' fill='currentColor'%3E%3Cpath fill-rule='evenodd' d='M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z' clip-rule='evenodd' /%3E%3C/svg%3E");
|
||||
height: 1.2em;
|
||||
width: 1.2em;
|
||||
vertical-align: -4px;
|
||||
padding: 0 0.6em;
|
||||
}
|
||||
}
|
||||
|
||||
:lang(fa) ol {
|
||||
list-style-type: persian;
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/* 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.
|
||||
{{- $layoutWidthValues := dict "normal" "80rem" "wide" "90rem" "full" "100%" -}}
|
||||
{{- $layoutWidthDefault := index $layoutWidthValues "normal" -}}
|
||||
|
||||
{{- $maxPageWidth := (index $layoutWidthValues (site.Params.page.width | default "normal")) | default $layoutWidthDefault -}}
|
||||
{{- $maxNavbarWidth := (index $layoutWidthValues (site.Params.navbar.width | default "normal")) | default $layoutWidthDefault -}}
|
||||
{{- $maxFooterWidth := (index $layoutWidthValues (site.Params.footer.width | default "normal")) | default $layoutWidthDefault -}}
|
||||
|
||||
{{- $maxContentWidth := "72rem" -}}
|
||||
*/
|
||||
|
||||
:root {
|
||||
--hextra-max-page-width: {{ $maxPageWidth }};
|
||||
--hextra-max-content-width: {{ $maxContentWidth }};
|
||||
--hextra-max-navbar-width: {{ $maxNavbarWidth }};
|
||||
--hextra-max-footer-width: {{ $maxFooterWidth }};
|
||||
}
|
||||
|
||||
.hextra-max-page-width {
|
||||
max-width: var(--hextra-max-page-width);
|
||||
}
|
||||
|
||||
.hextra-max-content-width {
|
||||
max-width: var(--hextra-max-content-width);
|
||||
}
|
||||
|
||||
.hextra-max-navbar-width {
|
||||
max-width: var(--hextra-max-navbar-width);
|
||||
}
|
||||
|
||||
.hextra-max-footer-width {
|
||||
max-width: var(--hextra-max-footer-width);
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
// Back to top button
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
const backToTop = document.querySelector("#backToTop");
|
||||
if (backToTop) {
|
||||
backToTop.addEventListener("click", scrollUp);
|
||||
document.addEventListener("scroll", (e) => {
|
||||
if (window.scrollY > 300) {
|
||||
backToTop.classList.remove("hx:opacity-0");
|
||||
backToTop.removeAttribute("tabindex");
|
||||
} else {
|
||||
backToTop.classList.add("hx:opacity-0");
|
||||
backToTop.setAttribute("tabindex", "-1");
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
function scrollUp() {
|
||||
const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
|
||||
window.scroll({
|
||||
top: 0,
|
||||
left: 0,
|
||||
behavior: prefersReducedMotion ? 'auto' : 'smooth',
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
// {{- if site.Params.banner }}
|
||||
(function () {
|
||||
const banner = document.querySelector(".hextra-banner")
|
||||
document.documentElement.style.setProperty("--hextra-banner-height", banner.clientHeight+"px");
|
||||
|
||||
const closeBtn = banner.querySelector(".hextra-banner-close-button");
|
||||
|
||||
closeBtn.addEventListener("click", () => {
|
||||
document.documentElement.classList.add("hextra-banner-hidden");
|
||||
document.documentElement.style.setProperty("--hextra-banner-height", "0px");
|
||||
|
||||
localStorage.setItem('{{ site.Params.banner.key | default `banner-closed` }}', "0");
|
||||
});
|
||||
})();
|
||||
// {{- end -}}
|
||||
@@ -0,0 +1,91 @@
|
||||
// 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;
|
||||
}
|
||||
|
||||
// Make scrollable code blocks focusable for keyboard users.
|
||||
const updateScrollableCodeBlocks = () => {
|
||||
document.querySelectorAll('.hextra-code-block pre, .highlight pre').forEach(function (pre) {
|
||||
if (pre.scrollWidth > pre.clientWidth) {
|
||||
pre.setAttribute('tabindex', '0');
|
||||
} else {
|
||||
pre.removeAttribute('tabindex');
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
updateScrollableCodeBlocks();
|
||||
|
||||
let resizeRaf;
|
||||
window.addEventListener('resize', () => {
|
||||
if (resizeRaf) {
|
||||
cancelAnimationFrame(resizeRaf);
|
||||
}
|
||||
resizeRaf = requestAnimationFrame(updateScrollableCodeBlocks);
|
||||
});
|
||||
|
||||
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');
|
||||
var originalLabel = button.getAttribute('aria-label');
|
||||
var copiedLabel = button.dataset.copiedLabel || 'Copied!';
|
||||
button.setAttribute('aria-label', copiedLabel);
|
||||
setTimeout(function () {
|
||||
button.classList.remove('copied');
|
||||
button.setAttribute('aria-label', originalLabel);
|
||||
}, 1000);
|
||||
}).catch(function (err) {
|
||||
console.error('Failed to copy text: ', err);
|
||||
});
|
||||
} else {
|
||||
console.error('Target element not found');
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,22 @@
|
||||
// {{ $faviconDarkExists := fileExists (path.Join "static" "favicon-dark.svg") }}
|
||||
(function () {
|
||||
const faviconEl = document.getElementById("favicon-svg");
|
||||
const faviconDarkExists = "{{ $faviconDarkExists }}" === "true";
|
||||
|
||||
if (faviconEl && faviconDarkExists) {
|
||||
const lightFavicon = '{{ "favicon.svg" | relURL }}';
|
||||
const darkFavicon = '{{ "favicon-dark.svg" | relURL }}';
|
||||
|
||||
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);
|
||||
}
|
||||
})();
|
||||
@@ -0,0 +1,15 @@
|
||||
// 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";
|
||||
});
|
||||
var newState = folder.nextElementSibling.dataset.state === "open" ? "closed" : "open";
|
||||
folder.nextElementSibling.dataset.state = newState;
|
||||
folder.setAttribute('aria-expanded', newState === 'open' ? 'true' : 'false');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,103 @@
|
||||
(function () {
|
||||
const languageSwitchers = document.querySelectorAll('.hextra-language-switcher');
|
||||
const closeSwitcher = (switcher, focusSwitcher = false) => {
|
||||
switcher.dataset.state = 'closed';
|
||||
switcher.setAttribute('aria-expanded', 'false');
|
||||
const optionsElement = switcher.nextElementSibling;
|
||||
optionsElement.classList.add('hx:hidden');
|
||||
if (focusSwitcher) {
|
||||
switcher.focus();
|
||||
}
|
||||
};
|
||||
|
||||
const openSwitcher = (switcher, focusTarget = "none") => {
|
||||
switcher.dataset.state = 'open';
|
||||
switcher.setAttribute('aria-expanded', 'true');
|
||||
const optionsElement = switcher.nextElementSibling;
|
||||
if (optionsElement.classList.contains('hx:hidden')) {
|
||||
toggleMenu(switcher);
|
||||
} else {
|
||||
resizeMenu(switcher);
|
||||
}
|
||||
|
||||
if (focusTarget !== "none") {
|
||||
const items = Array.from(optionsElement.querySelectorAll('[role="menuitem"]'));
|
||||
if (items.length > 0) {
|
||||
const target = focusTarget === "last" ? items[items.length - 1] : items[0];
|
||||
target.focus();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
languageSwitchers.forEach((switcher) => {
|
||||
switcher.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
if (switcher.dataset.state === 'open') {
|
||||
closeSwitcher(switcher);
|
||||
} else {
|
||||
openSwitcher(switcher);
|
||||
}
|
||||
});
|
||||
|
||||
switcher.addEventListener('keydown', (e) => {
|
||||
if (e.key === 'ArrowDown') {
|
||||
e.preventDefault();
|
||||
openSwitcher(switcher, 'first');
|
||||
} else if (e.key === 'ArrowUp') {
|
||||
e.preventDefault();
|
||||
openSwitcher(switcher, 'last');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
document.querySelectorAll('.hextra-language-options[role=menu]').forEach((menu) => {
|
||||
menu.addEventListener('keydown', (e) => {
|
||||
const items = Array.from(menu.querySelectorAll('[role="menuitem"]'));
|
||||
if (items.length === 0) return;
|
||||
|
||||
const currentIndex = items.indexOf(document.activeElement);
|
||||
let newIndex;
|
||||
|
||||
switch (e.key) {
|
||||
case 'ArrowDown':
|
||||
e.preventDefault();
|
||||
newIndex = (currentIndex + 1) % items.length;
|
||||
items[newIndex].focus();
|
||||
break;
|
||||
case 'ArrowUp':
|
||||
e.preventDefault();
|
||||
newIndex = (currentIndex - 1 + items.length) % items.length;
|
||||
items[newIndex].focus();
|
||||
break;
|
||||
case 'Home':
|
||||
e.preventDefault();
|
||||
items[0].focus();
|
||||
break;
|
||||
case 'End':
|
||||
e.preventDefault();
|
||||
items[items.length - 1].focus();
|
||||
break;
|
||||
case 'Escape': {
|
||||
e.preventDefault();
|
||||
const switcher = menu.previousElementSibling;
|
||||
if (switcher) {
|
||||
closeSwitcher(switcher, true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
window.addEventListener("resize", () => languageSwitchers.forEach(resizeMenu));
|
||||
|
||||
// Dismiss language switcher when clicking outside.
|
||||
document.addEventListener('click', (e) => {
|
||||
if (!e.target.closest('.hextra-language-switcher') && !e.target.closest('.hextra-language-options')) {
|
||||
languageSwitchers.forEach((switcher) => {
|
||||
closeSwitcher(switcher);
|
||||
});
|
||||
}
|
||||
});
|
||||
})();
|
||||
@@ -0,0 +1,84 @@
|
||||
// Hamburger menu for mobile navigation
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
const menu = document.querySelector('.hextra-hamburger-menu');
|
||||
const sidebarContainer = document.querySelector('.hextra-sidebar-container');
|
||||
const mobileQuery = window.matchMedia('(max-width: 767px)');
|
||||
|
||||
function isMenuOpen() {
|
||||
return menu.querySelector('svg').classList.contains('open');
|
||||
}
|
||||
|
||||
// On mobile, the sidebar is off-screen so hide it from assistive tech
|
||||
function syncAriaHidden() {
|
||||
if (mobileQuery.matches) {
|
||||
sidebarContainer.setAttribute('aria-hidden', isMenuOpen() ? 'false' : 'true');
|
||||
} else {
|
||||
sidebarContainer.removeAttribute('aria-hidden');
|
||||
}
|
||||
}
|
||||
|
||||
// Set initial state
|
||||
syncAriaHidden();
|
||||
mobileQuery.addEventListener('change', syncAriaHidden);
|
||||
|
||||
function toggleMenu(options = {}) {
|
||||
const { focusOnOpen = true } = options;
|
||||
|
||||
// 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');
|
||||
|
||||
// Sync aria-expanded and aria-hidden
|
||||
const isOpen = isMenuOpen();
|
||||
menu.setAttribute('aria-expanded', isOpen ? 'true' : 'false');
|
||||
syncAriaHidden();
|
||||
|
||||
// Move focus into sidebar when opening, restore when closing
|
||||
if (isOpen) {
|
||||
if (focusOnOpen) {
|
||||
const firstFocusable = sidebarContainer.querySelector('a, button, input, [tabindex="0"]');
|
||||
if (firstFocusable) firstFocusable.focus();
|
||||
}
|
||||
} else {
|
||||
menu.focus();
|
||||
}
|
||||
}
|
||||
|
||||
menu.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
// Pointer-initiated clicks on mobile should not force focus into the search input,
|
||||
// which opens the software keyboard immediately.
|
||||
toggleMenu({ focusOnOpen: e.detail === 0 });
|
||||
});
|
||||
|
||||
// Close menu on Escape key (mobile only)
|
||||
document.addEventListener('keydown', (e) => {
|
||||
if (e.key === 'Escape' && mobileQuery.matches && isMenuOpen()) {
|
||||
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();
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,126 @@
|
||||
(function () {
|
||||
const hiddenClass = "hx:hidden";
|
||||
const dropdownToggles = document.querySelectorAll(".hextra-nav-menu-toggle");
|
||||
const closeDropdown = (toggle, focusToggle = false) => {
|
||||
toggle.dataset.state = "closed";
|
||||
toggle.setAttribute("aria-expanded", "false");
|
||||
const menuItemsElement = toggle.nextElementSibling;
|
||||
menuItemsElement.classList.add(hiddenClass);
|
||||
if (focusToggle) {
|
||||
toggle.focus();
|
||||
}
|
||||
};
|
||||
|
||||
const openDropdown = (toggle, focusTarget = "none") => {
|
||||
// Close all other dropdowns first.
|
||||
dropdownToggles.forEach((otherToggle) => {
|
||||
if (otherToggle !== toggle) {
|
||||
closeDropdown(otherToggle);
|
||||
}
|
||||
});
|
||||
|
||||
toggle.dataset.state = "open";
|
||||
toggle.setAttribute("aria-expanded", "true");
|
||||
const menuItemsElement = toggle.nextElementSibling;
|
||||
|
||||
// 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";
|
||||
menuItemsElement.classList.remove(hiddenClass);
|
||||
|
||||
if (focusTarget !== "none") {
|
||||
const items = Array.from(menuItemsElement.querySelectorAll('[role="menuitem"]'));
|
||||
if (items.length > 0) {
|
||||
const target = focusTarget === "last" ? items[items.length - 1] : items[0];
|
||||
target.focus();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
dropdownToggles.forEach((toggle) => {
|
||||
toggle.addEventListener("click", (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
// Toggle current dropdown.
|
||||
const isOpen = toggle.dataset.state === "open";
|
||||
if (isOpen) {
|
||||
closeDropdown(toggle);
|
||||
} else {
|
||||
openDropdown(toggle);
|
||||
}
|
||||
});
|
||||
|
||||
toggle.addEventListener("keydown", (e) => {
|
||||
if (e.key === "ArrowDown") {
|
||||
e.preventDefault();
|
||||
openDropdown(toggle, "first");
|
||||
} else if (e.key === "ArrowUp") {
|
||||
e.preventDefault();
|
||||
openDropdown(toggle, "last");
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
document.querySelectorAll(".hextra-nav-menu-items[role=menu]").forEach((menu) => {
|
||||
menu.addEventListener("keydown", (e) => {
|
||||
const items = Array.from(menu.querySelectorAll('[role="menuitem"]'));
|
||||
if (items.length === 0) return;
|
||||
|
||||
const currentIndex = items.indexOf(document.activeElement);
|
||||
let newIndex;
|
||||
|
||||
switch (e.key) {
|
||||
case "ArrowDown":
|
||||
e.preventDefault();
|
||||
newIndex = (currentIndex + 1) % items.length;
|
||||
items[newIndex].focus();
|
||||
break;
|
||||
case "ArrowUp":
|
||||
e.preventDefault();
|
||||
newIndex = (currentIndex - 1 + items.length) % items.length;
|
||||
items[newIndex].focus();
|
||||
break;
|
||||
case "Home":
|
||||
e.preventDefault();
|
||||
items[0].focus();
|
||||
break;
|
||||
case "End":
|
||||
e.preventDefault();
|
||||
items[items.length - 1].focus();
|
||||
break;
|
||||
case "Escape": {
|
||||
e.preventDefault();
|
||||
const toggle = menu.previousElementSibling;
|
||||
if (toggle) {
|
||||
closeDropdown(toggle, true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Dismiss dropdown when clicking outside.
|
||||
document.addEventListener("click", (e) => {
|
||||
if (!e.target.closest(".hextra-nav-menu-toggle") && !e.target.closest(".hextra-nav-menu-items")) {
|
||||
dropdownToggles.forEach((toggle) => {
|
||||
closeDropdown(toggle);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Close dropdowns on escape key.
|
||||
document.addEventListener("keydown", (e) => {
|
||||
if (e.key === "Escape") {
|
||||
dropdownToggles.forEach((toggle) => {
|
||||
if (toggle.dataset.state === "open") {
|
||||
closeDropdown(toggle, true);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
})();
|
||||
@@ -0,0 +1,172 @@
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
// Pre-fetch markdown content for all copy buttons to avoid Safari NotAllowedError
|
||||
// Safari requires clipboard writes to happen synchronously within user gesture
|
||||
const copyButtons = document.querySelectorAll('.hextra-page-context-menu-copy');
|
||||
const contentCache = new Map();
|
||||
|
||||
// Pre-fetch content for each button on page load
|
||||
copyButtons.forEach(button => {
|
||||
const url = button.dataset.url;
|
||||
if (url) {
|
||||
fetch(url)
|
||||
.then(response => {
|
||||
if (response.ok) return response.text();
|
||||
throw new Error('Failed to fetch');
|
||||
})
|
||||
.then(markdown => contentCache.set(url, markdown))
|
||||
.catch(error => console.error('Failed to pre-fetch markdown:', error));
|
||||
}
|
||||
});
|
||||
|
||||
// Initialize copy buttons with synchronous clipboard access
|
||||
copyButtons.forEach(button => {
|
||||
button.addEventListener('click', () => {
|
||||
const url = button.dataset.url;
|
||||
const markdown = contentCache.get(url);
|
||||
|
||||
if (markdown) {
|
||||
// Synchronous clipboard write initiation - works in Safari
|
||||
navigator.clipboard.writeText(markdown)
|
||||
.then(() => {
|
||||
button.classList.add('copied');
|
||||
setTimeout(() => button.classList.remove('copied'), 1000);
|
||||
})
|
||||
.catch(error => console.error('Failed to copy markdown:', error));
|
||||
} else {
|
||||
// Fallback: fetch and copy (may fail in Safari if content not pre-fetched)
|
||||
fetch(url)
|
||||
.then(response => {
|
||||
if (!response.ok) throw new Error('Failed to fetch');
|
||||
return response.text();
|
||||
})
|
||||
.then(text => {
|
||||
contentCache.set(url, text);
|
||||
return navigator.clipboard.writeText(text);
|
||||
})
|
||||
.then(() => {
|
||||
button.classList.add('copied');
|
||||
setTimeout(() => button.classList.remove('copied'), 1000);
|
||||
})
|
||||
.catch(error => console.error('Failed to copy markdown:', error));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Initialize dropdown toggles
|
||||
const dropdownToggles = document.querySelectorAll('.hextra-page-context-menu-toggle');
|
||||
dropdownToggles.forEach(toggle => {
|
||||
const container = toggle.closest('.hextra-page-context-menu');
|
||||
const menu = container.querySelector('.hextra-page-context-menu-dropdown');
|
||||
const chevron = toggle.querySelector('[data-chevron]');
|
||||
|
||||
toggle.addEventListener('click', (e) => {
|
||||
e.stopPropagation();
|
||||
const isOpen = toggle.dataset.state === 'open';
|
||||
|
||||
// Close all other dropdowns first
|
||||
dropdownToggles.forEach(t => {
|
||||
if (t !== toggle) {
|
||||
t.dataset.state = 'closed';
|
||||
t.setAttribute('aria-expanded', 'false');
|
||||
const otherContainer = t.closest('.hextra-page-context-menu');
|
||||
const otherMenu = otherContainer.querySelector('.hextra-page-context-menu-dropdown');
|
||||
const otherChevron = t.querySelector('[data-chevron]');
|
||||
otherMenu.classList.add('hx:hidden');
|
||||
if (otherChevron) {
|
||||
otherChevron.style.transform = '';
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Toggle current
|
||||
toggle.dataset.state = isOpen ? 'closed' : 'open';
|
||||
toggle.setAttribute('aria-expanded', isOpen ? 'false' : 'true');
|
||||
menu.classList.toggle('hx:hidden', isOpen);
|
||||
|
||||
// Rotate chevron icon
|
||||
if (chevron) {
|
||||
chevron.style.transform = isOpen ? '' : 'rotate(180deg)';
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Close dropdown when clicking outside
|
||||
document.addEventListener('click', (e) => {
|
||||
// Check if click is outside any dropdown container
|
||||
const isOutside = !e.target.closest('.hextra-page-context-menu');
|
||||
if (isOutside) {
|
||||
dropdownToggles.forEach(toggle => {
|
||||
toggle.dataset.state = 'closed';
|
||||
toggle.setAttribute('aria-expanded', 'false');
|
||||
const container = toggle.closest('.hextra-page-context-menu');
|
||||
const menu = container.querySelector('.hextra-page-context-menu-dropdown');
|
||||
const chevron = toggle.querySelector('[data-chevron]');
|
||||
menu.classList.add('hx:hidden');
|
||||
if (chevron) {
|
||||
chevron.style.transform = '';
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Close dropdown on Escape key and return focus to toggle
|
||||
document.addEventListener('keydown', (e) => {
|
||||
if (e.key === 'Escape') {
|
||||
dropdownToggles.forEach(toggle => {
|
||||
if (toggle.dataset.state === 'open') {
|
||||
const container = toggle.closest('.hextra-page-context-menu');
|
||||
closeDropdown(container);
|
||||
toggle.focus();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Helper to close dropdown
|
||||
const closeDropdown = (container) => {
|
||||
if (!container) return;
|
||||
|
||||
const toggle = container.querySelector('.hextra-page-context-menu-toggle');
|
||||
const menu = container.querySelector('.hextra-page-context-menu-dropdown');
|
||||
|
||||
if (!toggle || !menu) return;
|
||||
|
||||
const chevron = toggle.querySelector('[data-chevron]');
|
||||
toggle.dataset.state = 'closed';
|
||||
toggle.setAttribute('aria-expanded', 'false');
|
||||
menu.classList.add('hx:hidden');
|
||||
if (chevron) {
|
||||
chevron.style.transform = '';
|
||||
}
|
||||
};
|
||||
|
||||
// Handle dropdown menu copy action
|
||||
document.querySelectorAll('.hextra-page-context-menu-dropdown button[data-action="copy"]').forEach(btn => {
|
||||
btn.addEventListener('click', async (e) => {
|
||||
e.stopPropagation();
|
||||
const container = btn.closest('.hextra-page-context-menu');
|
||||
if (!container) return;
|
||||
|
||||
const copyBtn = container.querySelector('.hextra-page-context-menu-copy');
|
||||
if (!copyBtn) return;
|
||||
|
||||
closeDropdown(container);
|
||||
copyBtn.click();
|
||||
});
|
||||
});
|
||||
|
||||
// Handle dropdown menu view action
|
||||
document.querySelectorAll('.hextra-page-context-menu-dropdown button[data-action="view"]').forEach(btn => {
|
||||
btn.addEventListener('click', (e) => {
|
||||
e.stopPropagation();
|
||||
const container = btn.closest('.hextra-page-context-menu');
|
||||
if (!container) return;
|
||||
|
||||
const url = btn.dataset.url;
|
||||
if (!url) return;
|
||||
|
||||
closeDropdown(container);
|
||||
window.open(url, '_blank', 'noopener,noreferrer');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,37 @@
|
||||
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.closest('li');
|
||||
if (list) {
|
||||
list.classList.toggle("open");
|
||||
button.setAttribute('aria-expanded', list.classList.contains('open') ? 'true' : 'false');
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
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
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
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)`;
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
(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.setAttribute('aria-selected', 'false');
|
||||
tab.tabIndex = -1;
|
||||
}
|
||||
});
|
||||
const panelsContainer = container.parentElement.nextElementSibling;
|
||||
if (!panelsContainer) return;
|
||||
Array.from(panelsContainer.children).forEach((panel, i) => {
|
||||
panel.dataset.state = i === index ? 'selected' : '';
|
||||
panel.setAttribute('aria-hidden', i === index ? 'false' : 'true');
|
||||
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 targetButton = e.currentTarget;
|
||||
const container = targetButton.parentElement;
|
||||
const index = Array.from(container.querySelectorAll('.hextra-tabs-toggle')).indexOf(
|
||||
targetButton
|
||||
);
|
||||
|
||||
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);
|
||||
}
|
||||
});
|
||||
|
||||
// Keyboard navigation for tabs
|
||||
button.addEventListener('keydown', function (e) {
|
||||
const container = button.parentElement;
|
||||
const tabs = Array.from(container.querySelectorAll('.hextra-tabs-toggle'));
|
||||
const currentIndex = tabs.indexOf(button);
|
||||
let newIndex;
|
||||
|
||||
switch (e.key) {
|
||||
case 'ArrowRight':
|
||||
case 'ArrowDown':
|
||||
e.preventDefault();
|
||||
newIndex = (currentIndex + 1) % tabs.length;
|
||||
break;
|
||||
case 'ArrowLeft':
|
||||
case 'ArrowUp':
|
||||
e.preventDefault();
|
||||
newIndex = (currentIndex - 1 + tabs.length) % tabs.length;
|
||||
break;
|
||||
case 'Home':
|
||||
e.preventDefault();
|
||||
newIndex = 0;
|
||||
break;
|
||||
case 'End':
|
||||
e.preventDefault();
|
||||
newIndex = tabs.length - 1;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
if (container.dataset.tabGroup) {
|
||||
const tabGroupValue = container.dataset.tabGroup;
|
||||
const key = encodeURIComponent(tabGroupValue);
|
||||
document
|
||||
.querySelectorAll('[data-tab-group="' + tabGroupValue + '"]')
|
||||
.forEach((grp) => updateGroup(grp, newIndex));
|
||||
localStorage.setItem('hextra-tab-' + key, newIndex.toString());
|
||||
} else {
|
||||
updateGroup(container, newIndex);
|
||||
}
|
||||
tabs[newIndex].focus();
|
||||
});
|
||||
});
|
||||
})();
|
||||
@@ -0,0 +1,15 @@
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
// Hugo task lists render bare checkboxes; provide an accessible name.
|
||||
document.querySelectorAll("main#content li > input[type='checkbox']").forEach(function (checkbox) {
|
||||
if (checkbox.hasAttribute("aria-label") || checkbox.hasAttribute("aria-labelledby")) {
|
||||
return;
|
||||
}
|
||||
var listItem = checkbox.closest("li");
|
||||
if (!listItem) return;
|
||||
|
||||
var labelText = listItem.textContent.replace(/\s+/g, " ").trim();
|
||||
if (labelText) {
|
||||
checkbox.setAttribute("aria-label", labelText);
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,112 @@
|
||||
// Light / Dark theme toggle
|
||||
(function () {
|
||||
const defaultTheme = '{{ site.Params.theme.default | default `system`}}'
|
||||
const themes = ["light", "dark"];
|
||||
|
||||
const themeToggleButtons = document.querySelectorAll(".hextra-theme-toggle");
|
||||
const themeToggleOptions = document.querySelectorAll(".hextra-theme-toggle-options button[role=menuitemradio]");
|
||||
|
||||
function applyTheme(theme) {
|
||||
theme = themes.includes(theme) ? theme : "system";
|
||||
|
||||
themeToggleButtons.forEach((btn) => btn.parentElement.dataset.theme = theme );
|
||||
themeToggleOptions.forEach((option) => {
|
||||
option.setAttribute('aria-checked', option.dataset.item === theme ? 'true' : 'false');
|
||||
});
|
||||
|
||||
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();
|
||||
|
||||
toggler.dataset.state = toggler.dataset.state === 'open' ? 'closed' : 'open';
|
||||
toggleMenu(toggler);
|
||||
const isOpen = toggler.dataset.state === 'open';
|
||||
toggler.setAttribute('aria-expanded', isOpen ? 'true' : 'false');
|
||||
|
||||
// Focus first menuitem when opening
|
||||
if (isOpen) {
|
||||
const firstItem = toggler.nextElementSibling.querySelector('button[role=menuitemradio]');
|
||||
if (firstItem) firstItem.focus();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
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.setAttribute('aria-expanded', 'false');
|
||||
toggler.nextElementSibling.classList.add('hx:hidden');
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Keyboard navigation for the theme menu
|
||||
document.querySelectorAll('.hextra-theme-toggle-options[role=menu]').forEach(function (menu) {
|
||||
menu.addEventListener('keydown', function (e) {
|
||||
const items = Array.from(menu.querySelectorAll('button[role=menuitemradio]'));
|
||||
const currentIndex = items.indexOf(document.activeElement);
|
||||
let newIndex;
|
||||
|
||||
switch (e.key) {
|
||||
case 'ArrowDown':
|
||||
e.preventDefault();
|
||||
newIndex = (currentIndex + 1) % items.length;
|
||||
items[newIndex].focus();
|
||||
break;
|
||||
case 'ArrowUp':
|
||||
e.preventDefault();
|
||||
newIndex = (currentIndex - 1 + items.length) % items.length;
|
||||
items[newIndex].focus();
|
||||
break;
|
||||
case 'Home':
|
||||
e.preventDefault();
|
||||
items[0].focus();
|
||||
break;
|
||||
case 'End':
|
||||
e.preventDefault();
|
||||
items[items.length - 1].focus();
|
||||
break;
|
||||
case 'Escape':
|
||||
e.preventDefault();
|
||||
var toggler = menu.previousElementSibling;
|
||||
toggler.dataset.state = 'closed';
|
||||
toggler.setAttribute('aria-expanded', 'false');
|
||||
menu.classList.add('hx:hidden');
|
||||
toggler.focus();
|
||||
break;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Listen for system theme changes
|
||||
window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", () => {
|
||||
if (localStorage.getItem("color-theme") === "system") {
|
||||
setTheme("system");
|
||||
}
|
||||
});
|
||||
})();
|
||||
@@ -0,0 +1,97 @@
|
||||
/**
|
||||
* 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");
|
||||
currentActiveLink.removeAttribute("aria-current");
|
||||
}
|
||||
|
||||
// Add active class to current link
|
||||
targetLink.classList.add("hextra-toc-active");
|
||||
targetLink.setAttribute("aria-current", "location");
|
||||
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");
|
||||
currentActiveLink.removeAttribute("aria-current");
|
||||
}
|
||||
targetLink.classList.add("hextra-toc-active");
|
||||
targetLink.setAttribute("aria-current", "location");
|
||||
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);
|
||||
});
|
||||
@@ -0,0 +1,492 @@
|
||||
// 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.
|
||||
// {{ $searchDataFile := printf "%s.search-data.json" .Language.Lang }}
|
||||
// {{ $searchData := resources.Get "json/search-data.json" | resources.ExecuteAsTemplate $searchDataFile . }}
|
||||
// {{ if hugo.IsProduction }}
|
||||
// {{ $searchData := $searchData | minify | fingerprint }}
|
||||
// {{ end }}
|
||||
// {{ $noResultsFound := (T "noResultsFound") | default "No results found." }}
|
||||
|
||||
(function () {
|
||||
const searchDataURL = '{{ $searchData.RelPermalink }}';
|
||||
const resultsFoundTemplate = '{{ (T "resultsFound") | default "%d results found" }}';
|
||||
|
||||
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 = '{{- site.Params.search.flexsearch.tokenize | default "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.debug('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');
|
||||
|
||||
// Configurable search limits with sensible defaults
|
||||
const maxPageResults = parseInt('{{- site.Params.search.flexsearch.maxPageResults | default 20 -}}', 10);
|
||||
const maxSectionResults = parseInt('{{- site.Params.search.flexsearch.maxSectionResults | default 10 -}}', 10);
|
||||
const pageResults = window.pageIndex.search(query, maxPageResults, { 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;
|
||||
|
||||
const sectionResults = window.sectionIndex.search(query,
|
||||
{ enrich: true, suggest: true, tag: { 'pageId': `page_${result.id}` } })[0]?.result || [];
|
||||
let isFirstItemOfPage = true
|
||||
const occurred = {}
|
||||
|
||||
const nResults = Math.min(sectionResults.length, maxSectionResults);
|
||||
for (let j = 0; j < nResults; 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">{{ $noResultsFound | safeHTML }}</span>`;
|
||||
// Announce no results to screen readers
|
||||
const wrapper = resultsElement.closest('.hextra-search-wrapper');
|
||||
const statusEl = wrapper ? wrapper.querySelector('.hextra-search-status') : null;
|
||||
if (statusEl) {
|
||||
statusEl.textContent = '{{ $noResultsFound | safeHTML }}';
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Append text with highlighted matches using safe text nodes.
|
||||
function appendHighlightedText(container, text, query) {
|
||||
if (!text) return;
|
||||
if (!query) {
|
||||
container.textContent = text;
|
||||
return;
|
||||
}
|
||||
|
||||
const escapedQuery = query.replace(/[-\\^$*+?.()|[\]{}]/g, '\\$&');
|
||||
if (!escapedQuery) {
|
||||
container.textContent = text;
|
||||
return;
|
||||
}
|
||||
|
||||
const regex = new RegExp(escapedQuery, 'gi');
|
||||
let lastIndex = 0;
|
||||
let match;
|
||||
while ((match = regex.exec(text)) !== null) {
|
||||
if (match.index > lastIndex) {
|
||||
container.appendChild(document.createTextNode(text.slice(lastIndex, match.index)));
|
||||
}
|
||||
const span = document.createElement('span');
|
||||
span.className = 'hextra-search-match';
|
||||
span.textContent = match[0];
|
||||
container.appendChild(span);
|
||||
lastIndex = match.index + match[0].length;
|
||||
}
|
||||
if (lastIndex < text.length) {
|
||||
container.appendChild(document.createTextNode(text.slice(lastIndex)));
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
const prefix = document.createElement('div');
|
||||
prefix.className = 'hextra-search-prefix';
|
||||
prefix.textContent = result.prefix;
|
||||
fragment.appendChild(prefix);
|
||||
}
|
||||
const li = document.createElement('li');
|
||||
const link = document.createElement('a');
|
||||
link.dataset.index = i;
|
||||
link.href = result.route;
|
||||
if (i === 0) {
|
||||
link.classList.add('hextra-search-active');
|
||||
}
|
||||
|
||||
const title = document.createElement('div');
|
||||
title.className = 'hextra-search-title';
|
||||
appendHighlightedText(title, result.children.title, query);
|
||||
link.appendChild(title);
|
||||
|
||||
if (result.children.content) {
|
||||
const excerpt = document.createElement('div');
|
||||
excerpt.className = 'hextra-search-excerpt';
|
||||
appendHighlightedText(excerpt, result.children.content, query);
|
||||
link.appendChild(excerpt);
|
||||
}
|
||||
|
||||
li.appendChild(link);
|
||||
li.addEventListener('mousemove', handleMouseMove);
|
||||
li.addEventListener('keydown', handleKeyDown);
|
||||
link.addEventListener('click', finishSearch);
|
||||
fragment.appendChild(li);
|
||||
}
|
||||
resultsElement.appendChild(fragment);
|
||||
resultsElement.dataset.count = results.length;
|
||||
|
||||
// Announce results count to screen readers
|
||||
const wrapper = resultsElement.closest('.hextra-search-wrapper');
|
||||
const statusEl = wrapper ? wrapper.querySelector('.hextra-search-status') : null;
|
||||
if (statusEl) {
|
||||
statusEl.textContent = results.length > 0
|
||||
? resultsFoundTemplate.replace('%d', results.length.toString())
|
||||
: '{{ $noResultsFound | safeHTML }}';
|
||||
}
|
||||
}
|
||||
})();
|
||||
@@ -0,0 +1,6 @@
|
||||
// The section must not be in the banner.js (body) file because it can create a quick flash.
|
||||
|
||||
if (localStorage.getItem('{{ site.Params.banner.key | default `banner-closed` }}')) {
|
||||
document.documentElement.style.setProperty("--hextra-banner-height", "0px");
|
||||
document.documentElement.classList.add("hextra-banner-hidden");
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
// The section must not be in the theme.js (body) file because it can create a quick flash (switch between light and dark).
|
||||
|
||||
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") : '{{ site.Params.theme.default | default `system`}}')
|
||||
@@ -0,0 +1,38 @@
|
||||
{{/* FlexSearch Index Data */}}
|
||||
{{- $indexType := site.Params.search.flexsearch.index | default "content" -}}
|
||||
|
||||
{{- if not (in (slice "content" "summary" "heading" "title" ) $indexType) -}}
|
||||
{{- errorf "unknown flexsearch index type: %s" $indexType -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- $pages := where .Site.Pages "Kind" "in" (slice "page" "section") -}}
|
||||
{{- $pages = where $pages "Params.excludeSearch" "!=" true -}}
|
||||
{{- $pages = where $pages "Content" "!=" "" -}}
|
||||
|
||||
{{- $output := dict -}}
|
||||
|
||||
{{- range $index, $page := $pages -}}
|
||||
{{- $pageTitle := $page.LinkTitle | default $page.File.BaseFileName -}}
|
||||
{{- $pageLink := $page.RelPermalink -}}
|
||||
{{- $data := partial "utils/fragments" (dict "context" $page "type" $indexType) -}}
|
||||
{{- $output = $output | merge (dict $pageLink (dict "title" $pageTitle "data" $data)) -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/* Extract glossary data entries */}}
|
||||
{{- $glossaryEntries := dict -}}
|
||||
{{- $siteData := partial "utils/hugo-compat/site-data.html" . -}}
|
||||
{{- with (index $siteData .Site.Language.Lang "termbase") -}}
|
||||
{{- range . -}}
|
||||
{{- $entry := cond (.abbr) (printf "%s %s %s" .abbr .term .definition) (printf "%s %s" .term .definition) -}}
|
||||
{{- $glossaryEntries = $glossaryEntries | merge (dict .term $entry) -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- $glossary := dict
|
||||
"title" "Glossary"
|
||||
"data" $glossaryEntries
|
||||
-}}
|
||||
|
||||
{{- $output = $output | merge (dict (relLangURL "glossary") $glossary )}}
|
||||
|
||||
{{- $output | jsonify -}}
|
||||
Executable
+56
@@ -0,0 +1,56 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Specify the base URL
|
||||
BASE_URL=${1:-"http://localhost:1313"}
|
||||
|
||||
echo "Using base URL: $BASE_URL"
|
||||
|
||||
# Version configuration - modify these arrays to specify versions to build
|
||||
# MAIN_VERSION format: "ref:display_name:source_dir"
|
||||
# VERSIONS format: "ref:display_name:source_dir" where source_dir is either "docs" or "exampleSite"
|
||||
MAIN_VERSION="$(git tag --list "v[0-9]*" --sort=-v:refname | head -n 1):latest:docs"
|
||||
VERSIONS=(
|
||||
"main:latest:docs" # latest version always builds from main
|
||||
"v0.11.3:v0.11:docs"
|
||||
"v0.10.3:v0.10:exampleSite"
|
||||
)
|
||||
|
||||
# Parse main version
|
||||
IFS=':' read -r MAIN_REF MAIN_NAME MAIN_DIR <<< "$MAIN_VERSION"
|
||||
|
||||
# Ensure clean public directory
|
||||
rm -rf public
|
||||
mkdir -p public
|
||||
mkdir -p public/versions
|
||||
|
||||
# Checkout and build main site
|
||||
git checkout $MAIN_REF
|
||||
GIT_HASH=$(git rev-parse --short HEAD)
|
||||
echo "Building main site from $MAIN_REF (commit: $GIT_HASH)"
|
||||
hugo \
|
||||
--minify \
|
||||
--themesDir=../.. --source=$MAIN_DIR \
|
||||
--baseURL "$BASE_URL/" \
|
||||
--destination=../public
|
||||
|
||||
# Build all versions
|
||||
for VERSION in "${VERSIONS[@]}"; do
|
||||
IFS=':' read -r REF NAME DIR <<< "$VERSION"
|
||||
|
||||
git checkout $REF
|
||||
GIT_HASH=$(git rev-parse --short HEAD)
|
||||
echo "Building version $NAME from $REF (commit: $GIT_HASH)"
|
||||
|
||||
mkdir -p "public/versions/$NAME"
|
||||
hugo \
|
||||
--minify \
|
||||
--themesDir=../.. --source=$DIR \
|
||||
--baseURL "$BASE_URL/versions/$NAME/" \
|
||||
--destination="../public/versions/$NAME"
|
||||
done
|
||||
|
||||
# Return to main branch
|
||||
git checkout main
|
||||
|
||||
echo "Build completed"
|
||||
@@ -0,0 +1,312 @@
|
||||
# SVG icons
|
||||
#
|
||||
# Example usage in templates using the icon.html partial:
|
||||
#
|
||||
# {{ partial "utils/icon.html" (dict "name" "github" "attributes" "height=24") }}
|
||||
|
||||
contrast: >
|
||||
<svg 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>
|
||||
|
||||
github: >
|
||||
<svg fill="currentColor" viewBox="3 3 18 18">
|
||||
<path d="M12 3C7.0275 3 3 7.12937 3 12.2276C3 16.3109 5.57625 19.7597 9.15374 20.9824C9.60374 21.0631 9.77249 20.7863 9.77249 20.5441C9.77249 20.3249 9.76125 19.5982 9.76125 18.8254C7.5 19.2522 6.915 18.2602 6.735 17.7412C6.63375 17.4759 6.19499 16.6569 5.8125 16.4378C5.4975 16.2647 5.0475 15.838 5.80124 15.8264C6.51 15.8149 7.01625 16.4954 7.18499 16.7723C7.99499 18.1679 9.28875 17.7758 9.80625 17.5335C9.885 16.9337 10.1212 16.53 10.38 16.2993C8.3775 16.0687 6.285 15.2728 6.285 11.7432C6.285 10.7397 6.63375 9.9092 7.20749 9.26326C7.1175 9.03257 6.8025 8.08674 7.2975 6.81794C7.2975 6.81794 8.05125 6.57571 9.77249 7.76377C10.4925 7.55615 11.2575 7.45234 12.0225 7.45234C12.7875 7.45234 13.5525 7.55615 14.2725 7.76377C15.9937 6.56418 16.7475 6.81794 16.7475 6.81794C17.2424 8.08674 16.9275 9.03257 16.8375 9.26326C17.4113 9.9092 17.76 10.7281 17.76 11.7432C17.76 15.2843 15.6563 16.0687 13.6537 16.2993C13.98 16.5877 14.2613 17.1414 14.2613 18.0065C14.2613 19.2407 14.25 20.2326 14.25 20.5441C14.25 20.7863 14.4188 21.0746 14.8688 20.9824C16.6554 20.364 18.2079 19.1866 19.3078 17.6162C20.4077 16.0457 20.9995 14.1611 21 12.2276C21 7.12937 16.9725 3 12 3Z"></path>
|
||||
</svg>
|
||||
|
||||
codeberg: >
|
||||
<svg fill="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M11.955.49A12 12 0 0 0 0 12.49a12 12 0 0 0 1.832 6.373L11.838 5.928a.187.14 0 0 1 .324 0l10.006 12.935A12 12 0 0 0 24 12.49a12 12 0 0 0-12-12 12 12 0 0 0-.045 0zm.375 6.467 4.416 16.553a12 12 0 0 0 5.137-4.213z"/>
|
||||
</svg>
|
||||
|
||||
gitlab: >
|
||||
<svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<path d="m23.6 9.593l-.033-.086L20.3.98a.851.851 0 0 0-.336-.405a.875.875 0 0 0-1 .054a.875.875 0 0 0-.29.44L16.47 7.818H7.537L5.333 1.07a.857.857 0 0 0-.29-.441a.875.875 0 0 0-1-.054a.859.859 0 0 0-.336.405L.433 9.502l-.032.086a6.066 6.066 0 0 0 2.012 7.01l.01.009l.03.021l4.977 3.727l2.462 1.863l1.5 1.132a1.009 1.009 0 0 0 1.22 0l1.499-1.132l2.461-1.863l5.006-3.75l.013-.01a6.068 6.068 0 0 0 2.01-7.002"/>
|
||||
</svg>
|
||||
|
||||
bitbucket: >
|
||||
<svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<path d="M.778 1.213a.768.768 0 0 0-.768.892l3.263 19.81c.084.5.515.868 1.022.873H19.95a.772.772 0 0 0 .77-.646l3.27-20.03a.768.768 0 0 0-.768-.891zM14.52 15.53H9.522L8.17 8.466h7.561z" />
|
||||
</svg>
|
||||
|
||||
hextra: <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>
|
||||
|
||||
hugo: <svg viewBox="0 0 370 391" xmlns="http://www.w3.org/2000/svg"><g clip-rule="evenodd" fill-rule="evenodd"><path d="m207.5 22.4 114.4 66.6c13.5 7.9 21.9 22.4 21.9 38v136.4c0 17.3-9.3 33.3-24.5 41.8l-113.5 63.9a49.06 49.06 0 0 1 -48.5-.2l-104.5-60.1c-16.4-9.5-26.6-27-26.6-45.9v-129.5c0-19.1 9.9-36.8 26.1-46.8l102.8-63.5c16-9.9 36.2-10.1 52.4-.7z" fill="#ff4088" stroke="#c9177e" stroke-width="27" /><path d="m105.6 298.2v-207.2h43.4v75.5h71.9v-75.5h43.5v207.2h-43.5v-90.6h-71.9v90.6z" fill="#fff" /></g></svg>
|
||||
hugo-full: >
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd" stroke-width="27" aria-label="Logo" viewBox="0 0 1493 391">
|
||||
<path fill="#ebb951" stroke="#fcd804" d="M1345.211 24.704l112.262 64.305a43 43 0 0 1 21.627 37.312v142.237a40 40 0 0 1-20.702 35.037l-120.886 66.584a42 42 0 0 1-41.216-.389l-106.242-61.155a57 57 0 0 1-28.564-49.4V138.71a64 64 0 0 1 31.172-54.939l98.01-58.564a54 54 0 0 1 54.54-.503z"/>
|
||||
<path fill="#33ba91" stroke="#00a88a" d="M958.07 22.82l117.31 66.78a41 41 0 0 1 20.72 35.64v139.5a45 45 0 0 1-23.1 39.32L955.68 369.4a44 44 0 0 1-43.54-.41l-105.82-61.6a56 56 0 0 1-27.83-48.4V140.07a68 68 0 0 1 33.23-58.44l98.06-58.35a48 48 0 0 1 48.3-.46z"/>
|
||||
<path fill="#0594cb" stroke="#0083c0" d="M575.26 20.97l117.23 68.9a40 40 0 0 1 19.73 34.27l.73 138.67a48 48 0 0 1-24.64 42.2l-115.13 64.11a45 45 0 0 1-44.53-.42l-105.83-61.6a55 55 0 0 1-27.33-47.53V136.52a63 63 0 0 1 29.87-53.59l99.3-61.4a49 49 0 0 1 50.6-.56z"/>
|
||||
<path fill="#ff4088" stroke="#c9177e" d="M195.81 24.13l114.41 66.54a44 44 0 0 1 21.88 38.04v136.43a48 48 0 0 1-24.45 41.82L194.1 370.9a49 49 0 0 1-48.48-.23L41.05 310.48a53 53 0 0 1-26.56-45.93V135.08a55 55 0 0 1 26.1-46.8l102.8-63.46a51 51 0 0 1 52.42-.69z"/>
|
||||
<path fill="#fff" d="M1320.72 89.15c58.79 0 106.52 47.73 106.52 106.51 0 58.8-47.73 106.52-106.52 106.52-58.78 0-106.52-47.73-106.52-106.52 0-58.78 47.74-106.51 106.52-106.51zm0 39.57c36.95 0 66.94 30 66.94 66.94a66.97 66.97 0 0 1-66.94 66.94c-36.95 0-66.94-29.99-66.94-66.94a66.97 66.97 0 0 1 66.93-66.94h.01zm-283.8 65.31c0 47.18-8.94 60.93-26.81 80.58-17.87 19.65-41.57 27.57-71.1 27.57-27 0-48.75-9.58-67.61-26.23-20.88-18.45-36.08-47.04-36.08-78.95 0-31.37 11.72-58.48 32.49-78.67 18.22-17.67 45.34-29.18 73.3-29.18 33.77 0 68.83 15.98 90.44 47.53l-31.73 26.82c-13.45-25.03-32.94-33.46-60.82-34.26-30.83-.88-64.77 28.53-62.25 67.75 1.4 21.94 11.65 59.65 60.96 66.57 25.9 3.63 55.36-24.02 55.36-39.04H944.4v-37.5h92.5V194l.02.03zm-562.6-94.65h42.29v112.17c0 17.8.49 29.33 1.47 34.61 1.69 8.48 4.81 14.37 11.17 19.5 6.37 5.13 13.8 6.59 24.84 6.59 11.2 0 14.96-1.74 20.66-6.6 5.69-4.85 9.12-9.46 10.28-16.53 1.15-7.07 3.07-18.8 3.07-35.18V99.38h42.28v108.78c0 24.86-1.07 42.43-3.21 52.69-2.14 10.27-6.08 18.93-11.82 26-5.74 7.06-13.42 12.69-23.03 16.88-9.62 4.19-22.16 6.28-37.65 6.28-18.7 0-32.87-2.28-42.52-6.85-9.66-4.57-17.3-10.5-22.9-17.8-5.61-7.3-9.3-14.95-11.08-22.96-2.58-11.86-3.88-29.38-3.88-52.55V99.38h.03zM93.91 299.92V92.7h43.35v75.48h71.92V92.7h43.48v207.22h-43.48v-90.61h-71.92v90.61z"/>
|
||||
</svg>
|
||||
|
||||
jupyter: <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="currentColor" d="M7.157 22.201A1.784 1.799 0 0 1 5.374 24a1.784 1.799 0 0 1-1.784-1.799a1.784 1.799 0 0 1 1.784-1.799a1.784 1.799 0 0 1 1.783 1.799M20.582 1.427a1.415 1.427 0 0 1-1.415 1.428a1.415 1.427 0 0 1-1.416-1.428A1.415 1.427 0 0 1 19.167 0a1.415 1.427 0 0 1 1.415 1.427M4.992 3.336A1.047 1.056 0 0 1 3.946 4.39a1.047 1.056 0 0 1-1.047-1.055A1.047 1.056 0 0 1 3.946 2.28a1.047 1.056 0 0 1 1.046 1.056m7.336 1.517c3.769 0 7.06 1.38 8.768 3.424a9.36 9.36 0 0 0-3.393-4.547a9.24 9.24 0 0 0-5.377-1.728A9.24 9.24 0 0 0 6.95 3.73a9.36 9.36 0 0 0-3.394 4.547c1.713-2.04 5.004-3.424 8.772-3.424m.001 13.295c-3.768 0-7.06-1.381-8.768-3.425a9.36 9.36 0 0 0 3.394 4.547A9.24 9.24 0 0 0 12.33 21a9.24 9.24 0 0 0 5.377-1.729a9.36 9.36 0 0 0 3.393-4.547c-1.712 2.044-5.003 3.425-8.772 3.425Z" /></svg>
|
||||
|
||||
warning: <svg xmlns="http://www.w3.org/2000/svg" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126zM12 15.75h.007v.008H12v-.008z"></path></svg>
|
||||
one: <svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="-1 0 19 19"><path d="M16.417 9.6A7.917 7.917 0 1 1 8.5 1.683 7.917 7.917 0 0 1 16.417 9.6zM9.666 6.508H8.248L6.09 8.09l.806 1.103 1.222-.945v4.816h1.547z"></path></svg>
|
||||
cards: <svg xmlns="http://www.w3.org/2000/svg" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M6 6.878V6a2.25 2.25 0 0 1 2.25-2.25h7.5A2.25 2.25 0 0 1 18 6v.878m-12 0c.235-.083.487-.128.75-.128h10.5c.263 0 .515.045.75.128m-12 0A2.25 2.25 0 0 0 4.5 9v.878m13.5-3A2.25 2.25 0 0 1 19.5 9v.878m0 0a2.246 2.246 0 0 0-.75-.128H5.25c-.263 0-.515.045-.75.128m15 0A2.25 2.25 0 0 1 21 12v6a2.25 2.25 0 0 1-2.25 2.25H5.25A2.25 2.25 0 0 1 3 18v-6c0-.98.626-1.813 1.5-2.122"></path></svg>
|
||||
copy: <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><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>
|
||||
hamburger-menu: <svg 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>
|
||||
markdown: <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="currentColor" d="M20.56 18H3.44C2.65 18 2 17.37 2 16.59V7.41C2 6.63 2.65 6 3.44 6h17.12c.79 0 1.44.63 1.44 1.41v9.18c0 .78-.65 1.41-1.44 1.41M6.81 15.19v-3.66l1.92 2.35l1.92-2.35v3.66h1.93V8.81h-1.93l-1.92 2.35l-1.92-2.35H4.89v6.38h1.92M19.69 12h-1.92V8.81h-1.92V12h-1.93l2.89 3.28L19.69 12Z"/></svg>
|
||||
folder-tree: <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path fill="currentColor" d="m 114.47781,81.538059 c 0,-13.785609 -11.07754,-24.923135 -24.78889,-24.923135 -13.711352,0 -24.788885,11.137526 -24.788885,24.923135 V 355.69254 c 0,27.49333 22.232532,49.84627 49.577775,49.84627 H 263.21112 V 355.69254 H 114.47781 V 181.2306 H 263.21112 V 131.38433 H 114.47781 Z M 288,206.15373 c 0,13.78561 11.07753,24.92314 24.78888,24.92314 h 173.5222 c 13.71135,0 24.78888,-11.13753 24.78888,-24.92314 v -99.69254 c 0,-13.785605 -11.07753,-24.923131 -24.78888,-24.923131 h -76.45822 c -6.58454,0 -12.85923,-2.648083 -17.50715,-7.321171 L 382.04283,63.936095 c -4.64791,-4.673088 -10.9226,-7.321171 -17.50715,-7.321171 h -51.7468 C 299.07753,56.614924 288,67.75245 288,81.538059 Z m 0,224.30821 c 0,13.78561 11.07753,24.92314 24.78888,24.92314 h 173.5222 c 13.71135,0 24.78888,-11.13753 24.78888,-24.92314 V 330.7694 c 0,-13.78561 -11.07753,-24.92313 -24.78888,-24.92313 h -76.45822 c -6.58454,0 -12.85923,-2.64808 -17.50715,-7.32117 l -10.30288,-10.35868 c -4.64791,-4.67309 -10.9226,-7.32117 -17.50715,-7.32117 h -51.7468 C 299.07753,280.84525 288,291.98278 288,305.76838 Z" style="stroke-width:0.776747" /></svg>
|
||||
card: <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15 15"><path fill="currentColor" fill-rule="evenodd" d="M14 11V4H1v7h13Zm1-7v7a1 1 0 0 1-1 1H1a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h13a1 1 0 0 1 1 1ZM2 5.25A.25.25 0 0 1 2.25 5h3.5a.25.25 0 0 1 .25.25v4.5a.25.25 0 0 1-.25.25h-3.5A.25.25 0 0 1 2 9.75v-4.5ZM7.5 7a.5.5 0 0 0 0 1h3a.5.5 0 0 0 0-1h-3ZM7 9.5a.5.5 0 0 1 .5-.5h5a.5.5 0 0 1 0 1h-5a.5.5 0 0 1-.5-.5ZM7.5 5a.5.5 0 0 0 0 1h4a.5.5 0 0 0 0-1h-4Z" clip-rule="evenodd"/></svg>
|
||||
|
||||
arrow-up-right: >-
|
||||
<svg fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="m9.1716 7.7574h7.0711m0 0v7.0711m0-7.0711-8.4853 8.4853" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
arrow-up-left: >-
|
||||
<svg fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="m7.7574 14.828v-7.0711m0 0 7.0711 1e-7m-7.0711-1e-7 8.4853 8.4853" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
||||
# Icons from heroicons v1 outlined https://github.com/tailwindlabs/heroicons/tree/v1
|
||||
academic-cap: <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"><path d="M12 14l9-5-9-5-9 5 9 5z"/><path d="M12 14l6.16-3.422a12.083 12.083 0 01.665 6.479A11.952 11.952 0 0012 20.055a11.952 11.952 0 00-6.824-2.998 12.078 12.078 0 01.665-6.479L12 14z"/><path stroke-linecap="round" stroke-linejoin="round" d="M12 14l9-5-9-5-9 5 9 5zm0 0l6.16-3.422a12.083 12.083 0 01.665 6.479A11.952 11.952 0 0012 20.055a11.952 11.952 0 00-6.824-2.998 12.078 12.078 0 01.665-6.479L12 14zm-4 6v-7.5l4-2.222"/></svg>
|
||||
adjustments: <svg 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 6V4m0 2a2 2 0 100 4m0-4a2 2 0 110 4m-6 8a2 2 0 100-4m0 4a2 2 0 110-4m0 4v2m0-6V4m6 6v10m6-2a2 2 0 100-4m0 4a2 2 0 110-4m0 4v2m0-6V4"/></svg>
|
||||
annotation: <svg 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="M7 8h10M7 12h4m1 8l-4-4H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-3l-4 4z"/></svg>
|
||||
archive: <svg 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 8h14M5 8a2 2 0 110-4h14a2 2 0 110 4M5 8v10a2 2 0 002 2h10a2 2 0 002-2V8m-9 4h4"/></svg>
|
||||
arrow-circle-down: <svg 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="M15 13l-3 3m0 0l-3-3m3 3V8m0 13a9 9 0 110-18 9 9 0 010 18z"/></svg>
|
||||
arrow-circle-left: <svg 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="M11 15l-3-3m0 0l3-3m-3 3h8M3 12a9 9 0 1118 0 9 9 0 01-18 0z"/></svg>
|
||||
arrow-circle-right: <svg 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="M13 9l3 3m0 0l-3 3m3-3H8m13 0a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>
|
||||
arrow-circle-up: <svg 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="M9 11l3-3m0 0l3 3m-3-3v8m0-13a9 9 0 110 18 9 9 0 010-18z"/></svg>
|
||||
arrow-down: <svg 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="M19 14l-7 7m0 0l-7-7m7 7V3"/></svg>
|
||||
arrow-left: <svg 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="M10 19l-7-7m0 0l7-7m-7 7h18"/></svg>
|
||||
arrow-narrow-down: <svg 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="M16 17l-4 4m0 0l-4-4m4 4V3"/></svg>
|
||||
arrow-narrow-left: <svg 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="M7 16l-4-4m0 0l4-4m-4 4h18"/></svg>
|
||||
arrow-narrow-right: <svg 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="M17 8l4 4m0 0l-4 4m4-4H3"/></svg>
|
||||
arrow-narrow-up: <svg 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="M8 7l4-4m0 0l4 4m-4-4v18"/></svg>
|
||||
arrow-right: <svg 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="M14 5l7 7m0 0l-7 7m7-7H3"/></svg>
|
||||
arrow-sm-down: <svg 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="M17 13l-5 5m0 0l-5-5m5 5V6"/></svg>
|
||||
arrow-sm-left: <svg 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="M11 17l-5-5m0 0l5-5m-5 5h12"/></svg>
|
||||
arrow-sm-right: <svg 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="M13 7l5 5m0 0l-5 5m5-5H6"/></svg>
|
||||
arrow-sm-up: <svg 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="M7 11l5-5m0 0l5 5m-5-5v12"/></svg>
|
||||
arrow-up: <svg 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 10l7-7m0 0l7 7m-7-7v18"/></svg>
|
||||
arrows-expand: <svg 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="M4 8V4m0 0h4M4 4l5 5m11-1V4m0 0h-4m4 0l-5 5M4 16v4m0 0h4m-4 0l5-5m11 5l-5-5m5 5v-4m0 4h-4"/></svg>
|
||||
at-symbol: <svg 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="M16 12a4 4 0 10-8 0 4 4 0 008 0zm0 0v1.5a2.5 2.5 0 005 0V12a9 9 0 10-9 9m4.5-1.206a8.959 8.959 0 01-4.5 1.207"/></svg>
|
||||
backspace: <svg 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 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2M3 12l6.414 6.414a2 2 0 001.414.586H19a2 2 0 002-2V7a2 2 0 00-2-2h-8.172a2 2 0 00-1.414.586L3 12z"/></svg>
|
||||
badge-check: <svg 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="M9 12l2 2 4-4M7.835 4.697a3.42 3.42 0 001.946-.806 3.42 3.42 0 014.438 0 3.42 3.42 0 001.946.806 3.42 3.42 0 013.138 3.138 3.42 3.42 0 00.806 1.946 3.42 3.42 0 010 4.438 3.42 3.42 0 00-.806 1.946 3.42 3.42 0 01-3.138 3.138 3.42 3.42 0 00-1.946.806 3.42 3.42 0 01-4.438 0 3.42 3.42 0 00-1.946-.806 3.42 3.42 0 01-3.138-3.138 3.42 3.42 0 00-.806-1.946 3.42 3.42 0 010-4.438 3.42 3.42 0 00.806-1.946 3.42 3.42 0 013.138-3.138z"/></svg>
|
||||
ban: <svg 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="M18.364 18.364A9 9 0 005.636 5.636m12.728 12.728A9 9 0 015.636 5.636m12.728 12.728L5.636 5.636"/></svg>
|
||||
beaker: <svg 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="M19.428 15.428a2 2 0 00-1.022-.547l-2.387-.477a6 6 0 00-3.86.517l-.318.158a6 6 0 01-3.86.517L6.05 15.21a2 2 0 00-1.806.547M8 4h8l-1 1v5.172a2 2 0 00.586 1.414l5 5c1.26 1.26.367 3.414-1.415 3.414H4.828c-1.782 0-2.674-2.154-1.414-3.414l5-5A2 2 0 009 10.172V5L8 4z"/></svg>
|
||||
bell: <svg 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="M15 17h5l-1.405-1.405A2.032 2.032 0 0118 14.158V11a6.002 6.002 0 00-4-5.659V5a2 2 0 10-4 0v.341C7.67 6.165 6 8.388 6 11v3.159c0 .538-.214 1.055-.595 1.436L4 17h5m6 0v1a3 3 0 11-6 0v-1m6 0H9"/></svg>
|
||||
book-open: <svg 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 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253"/></svg>
|
||||
bookmark: <svg 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 5a2 2 0 012-2h10a2 2 0 012 2v16l-7-3.5L5 21V5z"/></svg>
|
||||
bookmark-alt: <svg 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="M16 4v12l-4-2-4 2V4M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"/></svg>
|
||||
briefcase: <svg 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="M21 13.255A23.931 23.931 0 0112 15c-3.183 0-6.22-.62-9-1.745M16 6V4a2 2 0 00-2-2h-4a2 2 0 00-2 2v2m4 6h.01M5 20h14a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"/></svg>
|
||||
cake: <svg 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="M21 15.546c-.523 0-1.046.151-1.5.454a2.704 2.704 0 01-3 0 2.704 2.704 0 00-3 0 2.704 2.704 0 01-3 0 2.704 2.704 0 00-3 0 2.704 2.704 0 01-3 0 2.701 2.701 0 00-1.5-.454M9 6v2m3-2v2m3-2v2M9 3h.01M12 3h.01M15 3h.01M21 21v-7a2 2 0 00-2-2H5a2 2 0 00-2 2v7h18zm-3-9v-2a2 2 0 00-2-2H8a2 2 0 00-2 2v2h12z"/></svg>
|
||||
calculator: <svg 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="M9 7h6m0 10v-3m-3 3h.01M9 17h.01M9 14h.01M12 14h.01M15 11h.01M12 11h.01M9 11h.01M7 21h10a2 2 0 002-2V5a2 2 0 00-2-2H7a2 2 0 00-2 2v14a2 2 0 002 2z"/></svg>
|
||||
calendar: <svg 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="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"/></svg>
|
||||
camera: <svg 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="M3 9a2 2 0 012-2h.93a2 2 0 001.664-.89l.812-1.22A2 2 0 0110.07 4h3.86a2 2 0 011.664.89l.812 1.22A2 2 0 0018.07 7H19a2 2 0 012 2v9a2 2 0 01-2 2H5a2 2 0 01-2-2V9z"/><path stroke-linecap="round" stroke-linejoin="round" d="M15 13a3 3 0 11-6 0 3 3 0 016 0z"/></svg>
|
||||
cash: <svg 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="M17 9V7a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2m2 4h10a2 2 0 002-2v-6a2 2 0 00-2-2H9a2 2 0 00-2 2v6a2 2 0 002 2zm7-5a2 2 0 11-4 0 2 2 0 014 0z"/></svg>
|
||||
chart-bar: <svg 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="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"/></svg>
|
||||
chart-pie: <svg 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="M11 3.055A9.001 9.001 0 1020.945 13H11V3.055z"/><path stroke-linecap="round" stroke-linejoin="round" d="M20.488 9H15V3.512A9.025 9.025 0 0120.488 9z"/></svg>
|
||||
chart-square-bar: <svg 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="M16 8v8m-4-5v5m-4-2v2m-2 4h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"/></svg>
|
||||
chat: <svg 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="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z"/></svg>
|
||||
chat-alt: <svg 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="M8 10h.01M12 10h.01M16 10h.01M9 16H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-5l-5 5v-5z"/></svg>
|
||||
chat-alt-2: <svg 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="M17 8h2a2 2 0 012 2v6a2 2 0 01-2 2h-2v4l-4-4H9a1.994 1.994 0 01-1.414-.586m0 0L11 14h4a2 2 0 002-2V6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2v4l.586-.586z"/></svg>
|
||||
check: <svg 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>
|
||||
check-circle: <svg 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="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>
|
||||
chevron-double-down: <svg 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="M19 13l-7 7-7-7m14-8l-7 7-7-7"/></svg>
|
||||
chevron-double-left: <svg 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="M11 19l-7-7 7-7m8 14l-7-7 7-7"/></svg>
|
||||
chevron-double-right: <svg 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="M13 5l7 7-7 7M5 5l7 7-7 7"/></svg>
|
||||
chevron-double-up: <svg 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 11l7-7 7 7M5 19l7-7 7 7"/></svg>
|
||||
chevron-down: <svg 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="M19 9l-7 7-7-7"/></svg>
|
||||
chevron-left: <svg 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="M15 19l-7-7 7-7"/></svg>
|
||||
chevron-right: <svg 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="M9 5l7 7-7 7"/></svg>
|
||||
chevron-up: <svg 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 15l7-7 7 7"/></svg>
|
||||
chip: <svg 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="M9 3v2m6-2v2M9 19v2m6-2v2M5 9H3m2 6H3m18-6h-2m2 6h-2M7 19h10a2 2 0 002-2V7a2 2 0 00-2-2H7a2 2 0 00-2 2v10a2 2 0 002 2zM9 9h6v6H9V9z"/></svg>
|
||||
clipboard: <svg 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="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"/></svg>
|
||||
clipboard-check: <svg 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="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"/></svg>
|
||||
clipboard-copy: <svg 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="M8 5H6a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2v-1M8 5a2 2 0 002 2h2a2 2 0 002-2M8 5a2 2 0 012-2h2a2 2 0 012 2m0 0h2a2 2 0 012 2v3m2 4H10m0 0l3-3m-3 3l3 3"/></svg>
|
||||
clipboard-list: <svg 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="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-3 7h3m-3 4h3m-6-4h.01M9 16h.01"/></svg>
|
||||
clock: <svg 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 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>
|
||||
cloud: <svg 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="M3 15a4 4 0 004 4h9a5 5 0 10-.1-9.999 5.002 5.002 0 10-9.78 2.096A4.001 4.001 0 003 15z"/></svg>
|
||||
cloud-download: <svg 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="M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M9 19l3 3m0 0l3-3m-3 3V10"/></svg>
|
||||
cloud-upload: <svg 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="M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12"/></svg>
|
||||
code: <svg 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="M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4"/></svg>
|
||||
cog: <svg 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="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"/><path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/></svg>
|
||||
collection: <svg 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="M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10"/></svg>
|
||||
color-swatch: <svg 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="M7 21a4 4 0 01-4-4V5a2 2 0 012-2h4a2 2 0 012 2v12a4 4 0 01-4 4zm0 0h12a2 2 0 002-2v-4a2 2 0 00-2-2h-2.343M11 7.343l1.657-1.657a2 2 0 012.828 0l2.829 2.829a2 2 0 010 2.828l-8.486 8.485M7 17h.01"/></svg>
|
||||
credit-card: <svg 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="M3 10h18M7 15h1m4 0h1m-7 4h12a3 3 0 003-3V8a3 3 0 00-3-3H6a3 3 0 00-3 3v8a3 3 0 003 3z"/></svg>
|
||||
cube: <svg 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 7l-8-4-8 4m16 0l-8 4m8-4v10l-8 4m0-10L4 7m8 4v10M4 7v10l8 4"/></svg>
|
||||
cube-transparent: <svg 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="M14 10l-2 1m0 0l-2-1m2 1v2.5M20 7l-2 1m2-1l-2-1m2 1v2.5M14 4l-2-1-2 1M4 7l2-1M4 7l2 1M4 7v2.5M12 21l-2-1m2 1l2-1m-2 1v-2.5M6 18l-2-1v-2.5M18 18l2-1v-2.5"/></svg>
|
||||
currency-bangladeshi: <svg 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="M11 11V9a2 2 0 00-2-2m2 4v4a2 2 0 104 0v-1m-4-3H9m2 0h4m6 1a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>
|
||||
currency-dollar: <svg 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 8c-1.657 0-3 .895-3 2s1.343 2 3 2 3 .895 3 2-1.343 2-3 2m0-8c1.11 0 2.08.402 2.599 1M12 8V7m0 1v8m0 0v1m0-1c-1.11 0-2.08-.402-2.599-1M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>
|
||||
currency-euro: <svg 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="M14.121 15.536c-1.171 1.952-3.07 1.952-4.242 0-1.172-1.953-1.172-5.119 0-7.072 1.171-1.952 3.07-1.952 4.242 0M8 10.5h4m-4 3h4m9-1.5a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>
|
||||
currency-pound: <svg 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="M15 9a2 2 0 10-4 0v5a2 2 0 01-2 2h6m-6-4h4m8 0a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>
|
||||
currency-rupee: <svg 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="M9 8h6m-5 0a3 3 0 110 6H9l3 3m-3-6h6m6 1a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>
|
||||
currency-yen: <svg 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="M9 8l3 5m0 0l3-5m-3 5v4m-3-5h6m-6 3h6m6-3a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>
|
||||
cursor-click: <svg 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="M15 15l-2 5L9 9l11 4-5 2zm0 0l5 5M7.188 2.239l.777 2.897M5.136 7.965l-2.898-.777M13.95 4.05l-2.122 2.122m-5.657 5.656l-2.12 2.122"/></svg>
|
||||
database: <svg 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="M4 7v10c0 2.21 3.582 4 8 4s8-1.79 8-4V7M4 7c0 2.21 3.582 4 8 4s8-1.79 8-4M4 7c0-2.21 3.582-4 8-4s8 1.79 8 4m0 5c0 2.21-3.582 4-8 4s-8-1.79-8-4"/></svg>
|
||||
desktop-computer: <svg 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="M9.75 17L9 20l-1 1h8l-1-1-.75-3M3 13h18M5 17h14a2 2 0 002-2V5a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"/></svg>
|
||||
device-mobile: <svg 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 18h.01M8 21h8a2 2 0 002-2V5a2 2 0 00-2-2H8a2 2 0 00-2 2v14a2 2 0 002 2z"/></svg>
|
||||
device-tablet: <svg 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 18h.01M7 21h10a2 2 0 002-2V5a2 2 0 00-2-2H7a2 2 0 00-2 2v14a2 2 0 002 2z"/></svg>
|
||||
document: <svg 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="M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z"/></svg>
|
||||
document-add: <svg 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="M9 13h6m-3-3v6m5 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/></svg>
|
||||
document-download: <svg 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 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/></svg>
|
||||
document-duplicate: <svg 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="M8 7v8a2 2 0 002 2h6M8 7V5a2 2 0 012-2h4.586a1 1 0 01.707.293l4.414 4.414a1 1 0 01.293.707V15a2 2 0 01-2 2h-2M8 7H6a2 2 0 00-2 2v10a2 2 0 002 2h8a2 2 0 002-2v-2"/></svg>
|
||||
document-remove: <svg 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="M9 13h6m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/></svg>
|
||||
document-report: <svg 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="M9 17v-2m3 2v-4m3 4v-6m2 10H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/></svg>
|
||||
document-search: <svg 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="M10 21h7a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v11m0 5l4.879-4.879m0 0a3 3 0 104.243-4.242 3 3 0 00-4.243 4.242z"/></svg>
|
||||
document-text: <svg 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="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/></svg>
|
||||
dots-circle-horizontal: <svg 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="M8 12h.01M12 12h.01M16 12h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>
|
||||
dots-horizontal: <svg 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 12h.01M12 12h.01M19 12h.01M6 12a1 1 0 11-2 0 1 1 0 012 0zm7 0a1 1 0 11-2 0 1 1 0 012 0zm7 0a1 1 0 11-2 0 1 1 0 012 0z"/></svg>
|
||||
dots-vertical: <svg 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 5v.01M12 12v.01M12 19v.01M12 6a1 1 0 110-2 1 1 0 010 2zm0 7a1 1 0 110-2 1 1 0 010 2zm0 7a1 1 0 110-2 1 1 0 010 2z"/></svg>
|
||||
download: <svg 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="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4"/></svg>
|
||||
duplicate: <svg 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="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>
|
||||
emoji-happy: <svg 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="M14.828 14.828a4 4 0 01-5.656 0M9 10h.01M15 10h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>
|
||||
emoji-sad: <svg 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="M9.172 16.172a4 4 0 015.656 0M9 10h.01M15 10h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>
|
||||
exclamation: <svg 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 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"/></svg>
|
||||
exclamation-circle: <svg 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 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>
|
||||
external-link: <svg 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="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"/></svg>
|
||||
eye: <svg 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="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/><path stroke-linecap="round" stroke-linejoin="round" d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z"/></svg>
|
||||
eye-off: <svg 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="M13.875 18.825A10.05 10.05 0 0112 19c-4.478 0-8.268-2.943-9.543-7a9.97 9.97 0 011.563-3.029m5.858.908a3 3 0 114.243 4.243M9.878 9.878l4.242 4.242M9.88 9.88l-3.29-3.29m7.532 7.532l3.29 3.29M3 3l3.59 3.59m0 0A9.953 9.953 0 0112 5c4.478 0 8.268 2.943 9.543 7a10.025 10.025 0 01-4.132 5.411m0 0L21 21"/></svg>
|
||||
fast-forward: <svg 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="M11.933 12.8a1 1 0 000-1.6L6.6 7.2A1 1 0 005 8v8a1 1 0 001.6.8l5.333-4zM19.933 12.8a1 1 0 000-1.6l-5.333-4A1 1 0 0013 8v8a1 1 0 001.6.8l5.333-4z"/></svg>
|
||||
film: <svg 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="M7 4v16M17 4v16M3 8h4m10 0h4M3 12h18M3 16h4m10 0h4M4 20h16a1 1 0 001-1V5a1 1 0 00-1-1H4a1 1 0 00-1 1v14a1 1 0 001 1z"/></svg>
|
||||
filter: <svg 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="M3 4a1 1 0 011-1h16a1 1 0 011 1v2.586a1 1 0 01-.293.707l-6.414 6.414a1 1 0 00-.293.707V17l-4 4v-6.586a1 1 0 00-.293-.707L3.293 7.293A1 1 0 013 6.586V4z"/></svg>
|
||||
finger-print: <svg 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 11c0 3.517-1.009 6.799-2.753 9.571m-3.44-2.04l.054-.09A13.916 13.916 0 008 11a4 4 0 118 0c0 1.017-.07 2.019-.203 3m-2.118 6.844A21.88 21.88 0 0015.171 17m3.839 1.132c.645-2.266.99-4.659.99-7.132A8 8 0 008 4.07M3 15.364c.64-1.319 1-2.8 1-4.364 0-1.457.39-2.823 1.07-4"/></svg>
|
||||
fire: <svg 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="M17.657 18.657A8 8 0 016.343 7.343S7 9 9 10c0-2 .5-5 2.986-7C14 5 16.09 5.777 17.656 7.343A7.975 7.975 0 0120 13a7.975 7.975 0 01-2.343 5.657z"/><path stroke-linecap="round" stroke-linejoin="round" d="M9.879 16.121A3 3 0 1012.015 11L11 14H9c0 .768.293 1.536.879 2.121z"/></svg>
|
||||
flag: <svg 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="M3 21v-4m0 0V5a2 2 0 012-2h6.5l1 1H21l-3 6 3 6h-8.5l-1-1H5a2 2 0 00-2 2zm9-13.5V9"/></svg>
|
||||
folder: <svg 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="M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-6l-2-2H5a2 2 0 00-2 2z"/></svg>
|
||||
folder-add: <svg 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="M9 13h6m-3-3v6m-9 1V7a2 2 0 012-2h6l2 2h6a2 2 0 012 2v8a2 2 0 01-2 2H5a2 2 0 01-2-2z"/></svg>
|
||||
folder-download: <svg 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 10v6m0 0l-3-3m3 3l3-3M3 17V7a2 2 0 012-2h6l2 2h6a2 2 0 012 2v8a2 2 0 01-2 2H5a2 2 0 01-2-2z"/></svg>
|
||||
folder-open: <svg 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 19a2 2 0 01-2-2V7a2 2 0 012-2h4l2 2h4a2 2 0 012 2v1M5 19h14a2 2 0 002-2v-5a2 2 0 00-2-2H9a2 2 0 00-2 2v5a2 2 0 01-2 2z"/></svg>
|
||||
folder-remove: <svg 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="M9 13h6M3 17V7a2 2 0 012-2h6l2 2h6a2 2 0 012 2v8a2 2 0 01-2 2H5a2 2 0 01-2-2z"/></svg>
|
||||
gift: <svg 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 8v13m0-13V6a2 2 0 112 2h-2zm0 0V5.5A2.5 2.5 0 109.5 8H12zm-7 4h14M5 12a2 2 0 110-4h14a2 2 0 110 4M5 12v7a2 2 0 002 2h10a2 2 0 002-2v-7"/></svg>
|
||||
globe: <svg 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="M3.055 11H5a2 2 0 012 2v1a2 2 0 002 2 2 2 0 012 2v2.945M8 3.935V5.5A2.5 2.5 0 0010.5 8h.5a2 2 0 012 2 2 2 0 104 0 2 2 0 012-2h1.064M15 20.488V18a2 2 0 012-2h3.064M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>
|
||||
globe-alt: <svg 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="M21 12a9 9 0 01-9 9m9-9a9 9 0 00-9-9m9 9H3m9 9a9 9 0 01-9-9m9 9c1.657 0 3-4.03 3-9s-1.343-9-3-9m0 18c-1.657 0-3-4.03-3-9s1.343-9 3-9m-9 9a9 9 0 019-9"/></svg>
|
||||
hand: <svg 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="M7 11.5V14m0-2.5v-6a1.5 1.5 0 113 0m-3 6a1.5 1.5 0 00-3 0v2a7.5 7.5 0 0015 0v-5a1.5 1.5 0 00-3 0m-6-3V11m0-5.5v-1a1.5 1.5 0 013 0v1m0 0V11m0-5.5a1.5 1.5 0 013 0v3m0 0V11"/></svg>
|
||||
hashtag: <svg 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="M7 20l4-16m2 16l4-16M6 9h14M4 15h14"/></svg>
|
||||
heart: <svg 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="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z"/></svg>
|
||||
home: <svg 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="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6"/></svg>
|
||||
identification: <svg 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="M10 6H5a2 2 0 00-2 2v9a2 2 0 002 2h14a2 2 0 002-2V8a2 2 0 00-2-2h-5m-4 0V5a2 2 0 114 0v1m-4 0a2 2 0 104 0m-5 8a2 2 0 100-4 2 2 0 000 4zm0 0c1.306 0 2.417.835 2.83 2M9 14a3.001 3.001 0 00-2.83 2M15 11h3m-3 4h2"/></svg>
|
||||
inbox: <svg 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 13V6a2 2 0 00-2-2H6a2 2 0 00-2 2v7m16 0v5a2 2 0 01-2 2H6a2 2 0 01-2-2v-5m16 0h-2.586a1 1 0 00-.707.293l-2.414 2.414a1 1 0 01-.707.293h-3.172a1 1 0 01-.707-.293l-2.414-2.414A1 1 0 006.586 13H4"/></svg>
|
||||
inbox-in: <svg 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="M8 4H6a2 2 0 00-2 2v12a2 2 0 002 2h12a2 2 0 002-2V6a2 2 0 00-2-2h-2m-4-1v8m0 0l3-3m-3 3L9 8m-5 5h2.586a1 1 0 01.707.293l2.414 2.414a1 1 0 00.707.293h3.172a1 1 0 00.707-.293l2.414-2.414a1 1 0 01.707-.293H20"/></svg>
|
||||
information-circle: <svg 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="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>
|
||||
key: <svg 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="M15 7a2 2 0 012 2m4 0a6 6 0 01-7.743 5.743L11 17H9v2H7v2H4a1 1 0 01-1-1v-2.586a1 1 0 01.293-.707l5.964-5.964A6 6 0 1121 9z"/></svg>
|
||||
library: <svg 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="M8 14v3m4-3v3m4-3v3M3 21h18M3 10h18M3 7l9-4 9 4M4 10h16v11H4V10z"/></svg>
|
||||
light-bulb: <svg 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="M9.663 17h4.673M12 3v1m6.364 1.636l-.707.707M21 12h-1M4 12H3m3.343-5.657l-.707-.707m2.828 9.9a5 5 0 117.072 0l-.548.547A3.374 3.374 0 0014 18.469V19a2 2 0 11-4 0v-.531c0-.895-.356-1.754-.988-2.386l-.548-.547z"/></svg>
|
||||
lightning-bolt: <svg 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="M13 10V3L4 14h7v7l9-11h-7z"/></svg>
|
||||
link: <svg 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="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1"/></svg>
|
||||
location-marker: <svg 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="M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z"/><path stroke-linecap="round" stroke-linejoin="round" d="M15 11a3 3 0 11-6 0 3 3 0 016 0z"/></svg>
|
||||
lock-closed: <svg 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 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z"/></svg>
|
||||
lock-open: <svg 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="M8 11V7a4 4 0 118 0m-4 8v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2z"/></svg>
|
||||
login: <svg 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="M11 16l-4-4m0 0l4-4m-4 4h14m-5 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h7a3 3 0 013 3v1"/></svg>
|
||||
logout: <svg 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="M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1"/></svg>
|
||||
mail: <svg 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="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"/></svg>
|
||||
mail-open: <svg 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="M3 19v-8.93a2 2 0 01.89-1.664l7-4.666a2 2 0 012.22 0l7 4.666A2 2 0 0121 10.07V19M3 19a2 2 0 002 2h14a2 2 0 002-2M3 19l6.75-4.5M21 19l-6.75-4.5M3 10l6.75 4.5M21 10l-6.75 4.5m0 0l-1.14.76a2 2 0 01-2.22 0l-1.14-.76"/></svg>
|
||||
map: <svg 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="M9 20l-5.447-2.724A1 1 0 013 16.382V5.618a1 1 0 011.447-.894L9 7m0 13l6-3m-6 3V7m6 10l4.553 2.276A1 1 0 0021 18.382V7.618a1 1 0 00-.553-.894L15 4m0 13V4m0 0L9 7"/></svg>
|
||||
menu: <svg 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="M4 6h16M4 12h16M4 18h16"/></svg>
|
||||
menu-alt-1: <svg 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="M4 6h16M4 12h8m-8 6h16"/></svg>
|
||||
menu-alt-2: <svg 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="M4 6h16M4 12h16M4 18h7"/></svg>
|
||||
menu-alt-3: <svg 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="M4 6h16M4 12h16m-7 6h7"/></svg>
|
||||
menu-alt-4: <svg 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="M4 8h16M4 16h16"/></svg>
|
||||
microphone: <svg 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="M19 11a7 7 0 01-7 7m0 0a7 7 0 01-7-7m7 7v4m0 0H8m4 0h4m-4-8a3 3 0 01-3-3V5a3 3 0 116 0v6a3 3 0 01-3 3z"/></svg>
|
||||
minus: <svg 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 12H4"/></svg>
|
||||
minus-circle: <svg 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="M15 12H9m12 0a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>
|
||||
minus-sm: <svg 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="M18 12H6"/></svg>
|
||||
moon: <svg 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>
|
||||
music-note: <svg 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="M9 19V6l12-3v13M9 19c0 1.105-1.343 2-3 2s-3-.895-3-2 1.343-2 3-2 3 .895 3 2zm12-3c0 1.105-1.343 2-3 2s-3-.895-3-2 1.343-2 3-2 3 .895 3 2zM9 10l12-3"/></svg>
|
||||
newspaper: <svg 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="M19 20H5a2 2 0 01-2-2V6a2 2 0 012-2h10a2 2 0 012 2v1m2 13a2 2 0 01-2-2V7m2 13a2 2 0 002-2V9a2 2 0 00-2-2h-2m-4-3H9M7 16h6M7 8h6v4H7V8z"/></svg>
|
||||
office-building: <svg 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="M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16m14 0h2m-2 0h-5m-9 0H3m2 0h5M9 7h1m-1 4h1m4-4h1m-1 4h1m-5 10v-5a1 1 0 011-1h2a1 1 0 011 1v5m-4 0h4"/></svg>
|
||||
paper-airplane: <svg 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 19l9 2-9-18-9 18 9-2zm0 0v-8"/></svg>
|
||||
paper-clip: <svg 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="M15.172 7l-6.586 6.586a2 2 0 102.828 2.828l6.414-6.586a4 4 0 00-5.656-5.656l-6.415 6.585a6 6 0 108.486 8.486L20.5 13"/></svg>
|
||||
pause: <svg 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="M10 9v6m4-6v6m7-3a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>
|
||||
pencil: <svg 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="M15.232 5.232l3.536 3.536m-2.036-5.036a2.5 2.5 0 113.536 3.536L6.5 21.036H3v-3.572L16.732 3.732z"/></svg>
|
||||
pencil-alt: <svg 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="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"/></svg>
|
||||
phone: <svg 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="M3 5a2 2 0 012-2h3.28a1 1 0 01.948.684l1.498 4.493a1 1 0 01-.502 1.21l-2.257 1.13a11.042 11.042 0 005.516 5.516l1.13-2.257a1 1 0 011.21-.502l4.493 1.498a1 1 0 01.684.949V19a2 2 0 01-2 2h-1C9.716 21 3 14.284 3 6V5z"/></svg>
|
||||
phone-incoming: <svg 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="M21 3l-6 6m0 0V4m0 5h5M5 3a2 2 0 00-2 2v1c0 8.284 6.716 15 15 15h1a2 2 0 002-2v-3.28a1 1 0 00-.684-.948l-4.493-1.498a1 1 0 00-1.21.502l-1.13 2.257a11.042 11.042 0 01-5.516-5.517l2.257-1.128a1 1 0 00.502-1.21L9.228 3.683A1 1 0 008.279 3H5z"/></svg>
|
||||
phone-missed-call: <svg 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="M16 8l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2M5 3a2 2 0 00-2 2v1c0 8.284 6.716 15 15 15h1a2 2 0 002-2v-3.28a1 1 0 00-.684-.948l-4.493-1.498a1 1 0 00-1.21.502l-1.13 2.257a11.042 11.042 0 01-5.516-5.517l2.257-1.128a1 1 0 00.502-1.21L9.228 3.683A1 1 0 008.279 3H5z"/></svg>
|
||||
phone-outgoing: <svg 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="M16 3h5m0 0v5m0-5l-6 6M5 3a2 2 0 00-2 2v1c0 8.284 6.716 15 15 15h1a2 2 0 002-2v-3.28a1 1 0 00-.684-.948l-4.493-1.498a1 1 0 00-1.21.502l-1.13 2.257a11.042 11.042 0 01-5.516-5.517l2.257-1.128a1 1 0 00.502-1.21L9.228 3.683A1 1 0 008.279 3H5z"/></svg>
|
||||
photograph: <svg 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="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"/></svg>
|
||||
play: <svg 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="M14.752 11.168l-3.197-2.132A1 1 0 0010 9.87v4.263a1 1 0 001.555.832l3.197-2.132a1 1 0 000-1.664z"/><path stroke-linecap="round" stroke-linejoin="round" d="M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>
|
||||
plus: <svg 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 4v16m8-8H4"/></svg>
|
||||
plus-circle: <svg 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 9v3m0 0v3m0-3h3m-3 0H9m12 0a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>
|
||||
plus-sm: <svg 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 6v6m0 0v6m0-6h6m-6 0H6"/></svg>
|
||||
presentation-chart-bar: <svg 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="M8 13v-1m4 1v-3m4 3V8M8 21l4-4 4 4M3 4h18M4 4h16v12a1 1 0 01-1 1H5a1 1 0 01-1-1V4z"/></svg>
|
||||
presentation-chart-line: <svg 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="M7 12l3-3 3 3 4-4M8 21l4-4 4 4M3 4h18M4 4h16v12a1 1 0 01-1 1H5a1 1 0 01-1-1V4z"/></svg>
|
||||
printer: <svg 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="M17 17h2a2 2 0 002-2v-4a2 2 0 00-2-2H5a2 2 0 00-2 2v4a2 2 0 002 2h2m2 4h6a2 2 0 002-2v-4a2 2 0 00-2-2H9a2 2 0 00-2 2v4a2 2 0 002 2zm8-12V5a2 2 0 00-2-2H9a2 2 0 00-2 2v4h10z"/></svg>
|
||||
puzzle: <svg 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="M11 4a2 2 0 114 0v1a1 1 0 001 1h3a1 1 0 011 1v3a1 1 0 01-1 1h-1a2 2 0 100 4h1a1 1 0 011 1v3a1 1 0 01-1 1h-3a1 1 0 01-1-1v-1a2 2 0 10-4 0v1a1 1 0 01-1 1H7a1 1 0 01-1-1v-3a1 1 0 00-1-1H4a2 2 0 110-4h1a1 1 0 001-1V7a1 1 0 011-1h3a1 1 0 001-1V4z"/></svg>
|
||||
qrcode: <svg 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 4v1m6 11h2m-6 0h-2v4m0-11v3m0 0h.01M12 12h4.01M16 20h4M4 12h4m12 0h.01M5 8h2a1 1 0 001-1V5a1 1 0 00-1-1H5a1 1 0 00-1 1v2a1 1 0 001 1zm12 0h2a1 1 0 001-1V5a1 1 0 00-1-1h-2a1 1 0 00-1 1v2a1 1 0 001 1zM5 20h2a1 1 0 001-1v-2a1 1 0 00-1-1H5a1 1 0 00-1 1v2a1 1 0 001 1z"/></svg>
|
||||
question-mark-circle: <svg 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="M8.228 9c.549-1.165 2.03-2 3.772-2 2.21 0 4 1.343 4 3 0 1.4-1.278 2.575-3.006 2.907-.542.104-.994.54-.994 1.093m0 3h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>
|
||||
receipt-refund: <svg 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="M16 15v-1a4 4 0 00-4-4H8m0 0l3 3m-3-3l3-3m9 14V5a2 2 0 00-2-2H6a2 2 0 00-2 2v16l4-2 4 2 4-2 4 2z"/></svg>
|
||||
receipt-tax: <svg 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="M9 14l6-6m-5.5.5h.01m4.99 5h.01M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16l3.5-2 3.5 2 3.5-2 3.5 2zM10 8.5a.5.5 0 11-1 0 .5.5 0 011 0zm5 5a.5.5 0 11-1 0 .5.5 0 011 0z"/></svg>
|
||||
refresh: <svg 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="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"/></svg>
|
||||
reply: <svg 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="M3 10h10a8 8 0 018 8v2M3 10l6 6m-6-6l6-6"/></svg>
|
||||
rewind: <svg 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.066 11.2a1 1 0 000 1.6l5.334 4A1 1 0 0019 16V8a1 1 0 00-1.6-.8l-5.333 4zM4.066 11.2a1 1 0 000 1.6l5.334 4A1 1 0 0011 16V8a1 1 0 00-1.6-.8l-5.334 4z"/></svg>
|
||||
rss: <svg 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="M6 5c7.18 0 13 5.82 13 13M6 11a7 7 0 017 7m-6 0a1 1 0 11-2 0 1 1 0 012 0z"/></svg>
|
||||
save: <svg 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="M8 7H5a2 2 0 00-2 2v9a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2h-3m-1 4l-3 3m0 0l-3-3m3 3V4"/></svg>
|
||||
save-as: <svg 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="M17 16v2a2 2 0 01-2 2H5a2 2 0 01-2-2v-7a2 2 0 012-2h2m3-4H9a2 2 0 00-2 2v7a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-1m-1 4l-3 3m0 0l-3-3m3 3V3"/></svg>
|
||||
scale: <svg 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="M3 6l3 1m0 0l-3 9a5.002 5.002 0 006.001 0M6 7l3 9M6 7l6-2m6 2l3-1m-3 1l-3 9a5.002 5.002 0 006.001 0M18 7l3 9m-3-9l-6-2m0-2v2m0 16V5m0 16H9m3 0h3"/></svg>
|
||||
scissors: <svg 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="M14.121 14.121L19 19m-7-7l7-7m-7 7l-2.879 2.879M12 12L9.121 9.121m0 5.758a3 3 0 10-4.243 4.243 3 3 0 004.243-4.243zm0-5.758a3 3 0 10-4.243-4.243 3 3 0 004.243 4.243z"/></svg>
|
||||
search: <svg 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="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"/></svg>
|
||||
search-circle: <svg 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="M8 16l2.879-2.879m0 0a3 3 0 104.243-4.242 3 3 0 00-4.243 4.242zM21 12a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>
|
||||
selector: <svg 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="M8 9l4-4 4 4m0 6l-4 4-4-4"/></svg>
|
||||
server: <svg 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 12h14M5 12a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v4a2 2 0 01-2 2M5 12a2 2 0 00-2 2v4a2 2 0 002 2h14a2 2 0 002-2v-4a2 2 0 00-2-2m-2-4h.01M17 16h.01"/></svg>
|
||||
share: <svg 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="M8.684 13.342C8.886 12.938 9 12.482 9 12c0-.482-.114-.938-.316-1.342m0 2.684a3 3 0 110-2.684m0 2.684l6.632 3.316m-6.632-6l6.632-3.316m0 0a3 3 0 105.367-2.684 3 3 0 00-5.367 2.684zm0 9.316a3 3 0 105.368 2.684 3 3 0 00-5.368-2.684z"/></svg>
|
||||
shield-check: <svg 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="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z"/></svg>
|
||||
shield-exclamation: <svg 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.618 5.984A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016zM12 9v2m0 4h.01"/></svg>
|
||||
shopping-bag: <svg 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="M16 11V7a4 4 0 00-8 0v4M5 9h14l1 12H4L5 9z"/></svg>
|
||||
shopping-cart: <svg 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="M3 3h2l.4 2M7 13h10l4-8H5.4M7 13L5.4 5M7 13l-2.293 2.293c-.63.63-.184 1.707.707 1.707H17m0 0a2 2 0 100 4 2 2 0 000-4zm-8 2a2 2 0 11-4 0 2 2 0 014 0z"/></svg>
|
||||
sort-ascending: <svg 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="M3 4h13M3 8h9m-9 4h6m4 0l4-4m0 0l4 4m-4-4v12"/></svg>
|
||||
sort-descending: <svg 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="M3 4h13M3 8h9m-9 4h9m5-4v12m0 0l-4-4m4 4l4-4"/></svg>
|
||||
sparkles: <svg 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 3v4M3 5h4M6 17v4m-2-2h4m5-16l2.286 6.857L21 12l-5.714 2.143L13 21l-2.286-6.857L5 12l5.714-2.143L13 3z"/></svg>
|
||||
speakerphone: <svg 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="M11 5.882V19.24a1.76 1.76 0 01-3.417.592l-2.147-6.15M18 13a3 3 0 100-6M5.436 13.683A4.001 4.001 0 017 6h1.832c4.1 0 7.625-1.234 9.168-3v14c-1.543-1.766-5.067-3-9.168-3H7a3.988 3.988 0 01-1.564-.317z"/></svg>
|
||||
star: <svg 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="M11.049 2.927c.3-.921 1.603-.921 1.902 0l1.519 4.674a1 1 0 00.95.69h4.915c.969 0 1.371 1.24.588 1.81l-3.976 2.888a1 1 0 00-.363 1.118l1.518 4.674c.3.922-.755 1.688-1.538 1.118l-3.976-2.888a1 1 0 00-1.176 0l-3.976 2.888c-.783.57-1.838-.197-1.538-1.118l1.518-4.674a1 1 0 00-.363-1.118l-3.976-2.888c-.784-.57-.38-1.81.588-1.81h4.914a1 1 0 00.951-.69l1.519-4.674z"/></svg>
|
||||
status-offline: <svg 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="M18.364 5.636a9 9 0 010 12.728m0 0l-2.829-2.829m2.829 2.829L21 21M15.536 8.464a5 5 0 010 7.072m0 0l-2.829-2.829m-4.243 2.829a4.978 4.978 0 01-1.414-2.83m-1.414 5.658a9 9 0 01-2.167-9.238m7.824 2.167a1 1 0 111.414 1.414m-1.414-1.414L3 3m8.293 8.293l1.414 1.414"/></svg>
|
||||
status-online: <svg 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.636 18.364a9 9 0 010-12.728m12.728 0a9 9 0 010 12.728m-9.9-2.829a5 5 0 010-7.07m7.072 0a5 5 0 010 7.07M13 12a1 1 0 11-2 0 1 1 0 012 0z"/></svg>
|
||||
stop: <svg 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="M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/><path stroke-linecap="round" stroke-linejoin="round" d="M9 10a1 1 0 011-1h4a1 1 0 011 1v4a1 1 0 01-1 1h-4a1 1 0 01-1-1v-4z"/></svg>
|
||||
sun: <svg 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>
|
||||
support: <svg 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="M18.364 5.636l-3.536 3.536m0 5.656l3.536 3.536M9.172 9.172L5.636 5.636m3.536 9.192l-3.536 3.536M21 12a9 9 0 11-18 0 9 9 0 0118 0zm-5 0a4 4 0 11-8 0 4 4 0 018 0z"/></svg>
|
||||
switch-horizontal: <svg 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="M8 7h12m0 0l-4-4m4 4l-4 4m0 6H4m0 0l4 4m-4-4l4-4"/></svg>
|
||||
switch-vertical: <svg 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="M7 16V4m0 0L3 8m4-4l4 4m6 0v12m0 0l4-4m-4 4l-4-4"/></svg>
|
||||
table: <svg 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="M3 10h18M3 14h18m-9-4v8m-7 0h14a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 00-2 2v8a2 2 0 002 2z"/></svg>
|
||||
tag: <svg 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="M7 7h.01M7 3h5c.512 0 1.024.195 1.414.586l7 7a2 2 0 010 2.828l-7 7a2 2 0 01-2.828 0l-7-7A1.994 1.994 0 013 12V7a4 4 0 014-4z"/></svg>
|
||||
template: <svg 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="M4 5a1 1 0 011-1h14a1 1 0 011 1v2a1 1 0 01-1 1H5a1 1 0 01-1-1V5zM4 13a1 1 0 011-1h6a1 1 0 011 1v6a1 1 0 01-1 1H5a1 1 0 01-1-1v-6zM16 13a1 1 0 011-1h2a1 1 0 011 1v6a1 1 0 01-1 1h-2a1 1 0 01-1-1v-6z"/></svg>
|
||||
terminal: <svg 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="M8 9l3 3-3 3m5 0h3M5 20h14a2 2 0 002-2V6a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"/></svg>
|
||||
thumb-down: <svg 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="M10 14H5.236a2 2 0 01-1.789-2.894l3.5-7A2 2 0 018.736 3h4.018a2 2 0 01.485.06l3.76.94m-7 10v5a2 2 0 002 2h.096c.5 0 .905-.405.905-.904 0-.715.211-1.413.608-2.008L17 13V4m-7 10h2m5-10h2a2 2 0 012 2v6a2 2 0 01-2 2h-2.5"/></svg>
|
||||
thumb-up: <svg 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="M14 10h4.764a2 2 0 011.789 2.894l-3.5 7A2 2 0 0115.263 21h-4.017c-.163 0-.326-.02-.485-.06L7 20m7-10V5a2 2 0 00-2-2h-.095c-.5 0-.905.405-.905.905 0 .714-.211 1.412-.608 2.006L7 11v9m7-10h-2M7 20H5a2 2 0 01-2-2v-6a2 2 0 012-2h2.5"/></svg>
|
||||
ticket: <svg 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="M15 5v2m0 4v2m0 4v2M5 5a2 2 0 00-2 2v3a2 2 0 110 4v3a2 2 0 002 2h14a2 2 0 002-2v-3a2 2 0 110-4V7a2 2 0 00-2-2H5z"/></svg>
|
||||
translate: <svg 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="M3 5h12M9 3v2m1.048 9.5A18.022 18.022 0 016.412 9m6.088 9h7M11 21l5-10 5 10M12.751 5C11.783 10.77 8.07 15.61 3 18.129"/></svg>
|
||||
trash: <svg 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="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"/></svg>
|
||||
trending-down: <svg 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="M13 17h8m0 0V9m0 8l-8-8-4 4-6-6"/></svg>
|
||||
trending-up: <svg 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="M13 7h8m0 0v8m0-8l-8 8-4-4-6 6"/></svg>
|
||||
truck: <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"><path d="M9 17a2 2 0 11-4 0 2 2 0 014 0zM19 17a2 2 0 11-4 0 2 2 0 014 0z"/><path stroke-linecap="round" stroke-linejoin="round" d="M13 16V6a1 1 0 00-1-1H4a1 1 0 00-1 1v10a1 1 0 001 1h1m8-1a1 1 0 01-1 1H9m4-1V8a1 1 0 011-1h2.586a1 1 0 01.707.293l3.414 3.414a1 1 0 01.293.707V16a1 1 0 01-1 1h-1m-6-1a1 1 0 001 1h1M5 17a2 2 0 104 0m-4 0a2 2 0 114 0m6 0a2 2 0 104 0m-4 0a2 2 0 114 0"/></svg>
|
||||
upload: <svg 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="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-8l-4-4m0 0L8 8m4-4v12"/></svg>
|
||||
user: <svg 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="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"/></svg>
|
||||
user-add: <svg 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="M18 9v3m0 0v3m0-3h3m-3 0h-3m-2-5a4 4 0 11-8 0 4 4 0 018 0zM3 20a6 6 0 0112 0v1H3v-1z"/></svg>
|
||||
user-circle: <svg 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.121 17.804A13.937 13.937 0 0112 16c2.5 0 4.847.655 6.879 1.804M15 10a3 3 0 11-6 0 3 3 0 016 0zm6 2a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>
|
||||
user-group: <svg 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="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z"/></svg>
|
||||
user-remove: <svg 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="M13 7a4 4 0 11-8 0 4 4 0 018 0zM9 14a6 6 0 00-6 6v1h12v-1a6 6 0 00-6-6zM21 12h-6"/></svg>
|
||||
users: <svg 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 4.354a4 4 0 110 5.292M15 21H3v-1a6 6 0 0112 0v1zm0 0h6v-1a6 6 0 00-9-5.197M13 7a4 4 0 11-8 0 4 4 0 018 0z"/></svg>
|
||||
variable: <svg 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="M4.871 4A17.926 17.926 0 003 12c0 2.874.673 5.59 1.871 8m14.13 0a17.926 17.926 0 001.87-8c0-2.874-.673-5.59-1.87-8M9 9h1.246a1 1 0 01.961.725l1.586 5.55a1 1 0 00.961.725H15m1-7h-.08a2 2 0 00-1.519.698L9.6 15.302A2 2 0 018.08 16H8"/></svg>
|
||||
video-camera: <svg 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="M15 10l4.553-2.276A1 1 0 0121 8.618v6.764a1 1 0 01-1.447.894L15 14M5 18h8a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 00-2 2v8a2 2 0 002 2z"/></svg>
|
||||
view-boards: <svg 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="M9 17V7m0 10a2 2 0 01-2 2H5a2 2 0 01-2-2V7a2 2 0 012-2h2a2 2 0 012 2m0 10a2 2 0 002 2h2a2 2 0 002-2M9 7a2 2 0 012-2h2a2 2 0 012 2m0 10V7m0 10a2 2 0 002 2h2a2 2 0 002-2V7a2 2 0 00-2-2h-2a2 2 0 00-2 2"/></svg>
|
||||
view-grid: <svg 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="M4 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2V6zM14 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2V6zM4 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2v-2zM14 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2v-2z"/></svg>
|
||||
view-grid-add: <svg 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="M17 14v6m-3-3h6M6 10h2a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v2a2 2 0 002 2zm10 0h2a2 2 0 002-2V6a2 2 0 00-2-2h-2a2 2 0 00-2 2v2a2 2 0 002 2zM6 20h2a2 2 0 002-2v-2a2 2 0 00-2-2H6a2 2 0 00-2 2v2a2 2 0 002 2z"/></svg>
|
||||
view-list: <svg 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="M4 6h16M4 10h16M4 14h16M4 18h16"/></svg>
|
||||
volume-off: <svg 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.586 15H4a1 1 0 01-1-1v-4a1 1 0 011-1h1.586l4.707-4.707C10.923 3.663 12 4.109 12 5v14c0 .891-1.077 1.337-1.707.707L5.586 15z" clip-rule="evenodd"/><path stroke-linecap="round" stroke-linejoin="round" d="M17 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2"/></svg>
|
||||
volume-up: <svg 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="M15.536 8.464a5 5 0 010 7.072m2.828-9.9a9 9 0 010 12.728M5.586 15H4a1 1 0 01-1-1v-4a1 1 0 011-1h1.586l4.707-4.707C10.923 3.663 12 4.109 12 5v14c0 .891-1.077 1.337-1.707.707L5.586 15z"/></svg>
|
||||
wifi: <svg 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="M8.111 16.404a5.5 5.5 0 017.778 0M12 20h.01m-7.08-7.071c3.904-3.905 10.236-3.905 14.141 0M1.394 9.393c5.857-5.857 15.355-5.857 21.213 0"/></svg>
|
||||
x: <svg 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="M6 18L18 6M6 6l12 12"/></svg>
|
||||
x-circle: <svg 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="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>
|
||||
zoom-in: <svg 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="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0zM10 7v3m0 0v3m0-3h3m-3 0H7"/></svg>
|
||||
zoom-out: <svg 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="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0zM13 10H7"/></svg>
|
||||
|
||||
# Socials
|
||||
instagram: <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15 15"><path fill="currentColor" fill-rule="evenodd" d="M12.91 12.909c.326-.327.582-.72.749-1.151c.16-.414.27-.886.302-1.578c.032-.693.04-.915.04-2.68c0-1.765-.008-1.987-.04-2.68c-.032-.692-.142-1.164-.302-1.578a3.185 3.185 0 0 0-.75-1.151a3.187 3.187 0 0 0-1.151-.75c-.414-.16-.886-.27-1.578-.302C9.487 1.007 9.265 1 7.5 1c-1.765 0-1.987.007-2.68.04c-.692.03-1.164.14-1.578.301a3.2 3.2 0 0 0-1.151.75a3.2 3.2 0 0 0-.75 1.151c-.16.414-.27.886-.302 1.578C1.007 5.513 1 5.735 1 7.5c0 1.765.007 1.987.04 2.68c.03.692.14 1.164.301 1.578c.164.434.42.826.75 1.151c.325.33.718.586 1.151.75c.414.16.886.27 1.578.302c.693.031.915.039 2.68.039c1.765 0 1.987-.008 2.68-.04c.692-.03 1.164-.14 1.578-.301a3.323 3.323 0 0 0 1.151-.75ZM2 6.735v1.53c-.002.821-.002 1.034.02 1.5c.026.586.058 1.016.156 1.34c.094.312.199.63.543 1.012c.344.383.675.556 1.097.684c.423.127.954.154 1.415.175c.522.024.73.024 1.826.024H8.24c.842.001 1.054.002 1.526-.02c.585-.027 1.015-.059 1.34-.156c.311-.094.629-.2 1.011-.543c.383-.344.556-.676.684-1.098c.127-.422.155-.953.176-1.414C13 9.247 13 9.04 13 7.947v-.89c0-1.096 0-1.303-.023-1.826c-.021-.461-.049-.992-.176-1.414c-.127-.423-.3-.754-.684-1.098c-.383-.344-.7-.449-1.011-.543c-.325-.097-.755-.13-1.34-.156A27.29 27.29 0 0 0 8.24 2H7.057c-1.096 0-1.304 0-1.826.023c-.461.021-.992.049-1.415.176c-.422.128-.753.301-1.097.684c-.344.383-.45.7-.543 1.012c-.098.324-.13.754-.156 1.34c-.022.466-.022.679-.02 1.5ZM7.5 5.25a2.25 2.25 0 1 0 0 4.5a2.25 2.25 0 0 0 0-4.5ZM4.25 7.5a3.25 3.25 0 1 1 6.5 0a3.25 3.25 0 0 1-6.5 0Zm6.72-2.72a.75.75 0 1 0 0-1.5a.75.75 0 0 0 0 1.5Z" clip-rule="evenodd"/></svg>
|
||||
facebook: <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="currentColor" d="M22 12c0-5.52-4.48-10-10-10S2 6.48 2 12c0 4.84 3.44 8.87 8 9.8V15H8v-3h2V9.5C10 7.57 11.57 6 13.5 6H16v3h-2c-.55 0-1 .45-1 1v2h3v3h-3v6.95c5.05-.5 9-4.76 9-9.95z"/></svg>
|
||||
discord: <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="currentColor" d="M20.317 4.3698a19.7913 19.7913 0 00-4.8851-1.5152.0741.0741 0 00-.0785.0371c-.211.3753-.4447.8648-.6083 1.2495-1.8447-.2762-3.68-.2762-5.4868 0-.1636-.3933-.4058-.8742-.6177-1.2495a.077.077 0 00-.0785-.037 19.7363 19.7363 0 00-4.8852 1.515.0699.0699 0 00-.0321.0277C.5334 9.0458-.319 13.5799.0992 18.0578a.0824.0824 0 00.0312.0561c2.0528 1.5076 4.0413 2.4228 5.9929 3.0294a.0777.0777 0 00.0842-.0276c.4616-.6304.8731-1.2952 1.226-1.9942a.076.076 0 00-.0416-.1057c-.6528-.2476-1.2743-.5495-1.8722-.8923a.077.077 0 01-.0076-.1277c.1258-.0943.2517-.1923.3718-.2914a.0743.0743 0 01.0776-.0105c3.9278 1.7933 8.18 1.7933 12.0614 0a.0739.0739 0 01.0785.0095c.1202.099.246.1981.3728.2924a.077.077 0 01-.0066.1276 12.2986 12.2986 0 01-1.873.8914.0766.0766 0 00-.0407.1067c.3604.698.7719 1.3628 1.225 1.9932a.076.076 0 00.0842.0286c1.961-.6067 3.9495-1.5219 6.0023-3.0294a.077.077 0 00.0313-.0552c.5004-5.177-.8382-9.6739-3.5485-13.6604a.061.061 0 00-.0312-.0286zM8.02 15.3312c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9555-2.4189 2.157-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.9555 2.4189-2.1569 2.4189zm7.9748 0c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9554-2.4189 2.1569-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.946 2.4189-2.1568 2.4189Z"></path></svg>
|
||||
twitter: <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="currentColor" d="M23.953 4.57a10 10 0 01-2.825.775 4.958 4.958 0 002.163-2.723c-.951.555-2.005.959-3.127 1.184a4.92 4.92 0 00-8.384 4.482C7.69 8.095 4.067 6.13 1.64 3.162a4.822 4.822 0 00-.666 2.475c0 1.71.87 3.213 2.188 4.096a4.904 4.904 0 01-2.228-.616v.06a4.923 4.923 0 003.946 4.827 4.996 4.996 0 01-2.212.085 4.936 4.936 0 004.604 3.417 9.867 9.867 0 01-6.102 2.105c-.39 0-.779-.023-1.17-.067a13.995 13.995 0 007.557 2.209c9.053 0 13.998-7.496 13.998-13.985 0-.21 0-.42-.015-.63A9.935 9.935 0 0024 4.59z"></path></svg>
|
||||
mastodon: <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="currentColor" d="M23.268 5.313c-.35-2.578-2.617-4.61-5.304-5.004C17.51.242 15.792 0 11.813 0h-.03c-3.98 0-4.835.242-5.288.309C3.882.692 1.496 2.518.917 5.127.64 6.412.61 7.837.661 9.143c.074 1.874.088 3.745.26 5.611.118 1.24.325 2.47.62 3.68.55 2.237 2.777 4.098 4.96 4.857 2.336.792 4.849.923 7.256.38.265-.061.527-.132.786-.213.585-.184 1.27-.39 1.774-.753a.057.057 0 0 0 .023-.043v-1.809a.052.052 0 0 0-.02-.041.053.053 0 0 0-.046-.01 20.282 20.282 0 0 1-4.709.545c-2.73 0-3.463-1.284-3.674-1.818a5.593 5.593 0 0 1-.319-1.433.053.053 0 0 1 .066-.054c1.517.363 3.072.546 4.632.546.376 0 .75 0 1.125-.01 1.57-.044 3.224-.124 4.768-.422.038-.008.077-.015.11-.024 2.435-.464 4.753-1.92 4.989-5.604.008-.145.03-1.52.03-1.67.002-.512.167-3.63-.024-5.545zm-3.748 9.195h-2.561V8.29c0-1.309-.55-1.976-1.67-1.976-1.23 0-1.846.79-1.846 2.35v3.403h-2.546V8.663c0-1.56-.617-2.35-1.848-2.35-1.112 0-1.668.668-1.67 1.977v6.218H4.822V8.102c0-1.31.337-2.35 1.011-3.12.696-.77 1.608-1.164 2.74-1.164 1.311 0 2.302.5 2.962 1.498l.638 1.06.638-1.06c.66-.999 1.65-1.498 2.96-1.498 1.13 0 2.043.395 2.74 1.164.675.77 1.012 1.81 1.012 3.12z"></path></svg>
|
||||
youtube: <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill="currentColor" d="M8.051 1.999h.089c.822.003 4.987.033 6.11.335a2.01 2.01 0 0 1 1.415 1.42c.101.38.172.883.22 1.402l.01.104l.022.26l.008.104c.065.914.073 1.77.074 1.957v.075c-.001.194-.01 1.108-.082 2.06l-.008.105l-.009.104c-.05.572-.124 1.14-.235 1.558a2.007 2.007 0 0 1-1.415 1.42c-1.16.312-5.569.334-6.18.335h-.142c-.309 0-1.587-.006-2.927-.052l-.17-.006l-.087-.004l-.171-.007l-.171-.007c-1.11-.049-2.167-.128-2.654-.26a2.007 2.007 0 0 1-1.415-1.419c-.111-.417-.185-.986-.235-1.558L.09 9.82l-.008-.104A31.4 31.4 0 0 1 0 7.68v-.123c.002-.215.01-.958.064-1.778l.007-.103l.003-.052l.008-.104l.022-.26l.01-.104c.048-.519.119-1.023.22-1.402a2.007 2.007 0 0 1 1.415-1.42c.487-.13 1.544-.21 2.654-.26l.17-.007l.172-.006l.086-.003l.171-.007A99.788 99.788 0 0 1 7.858 2h.193zM6.4 5.209v4.818l4.157-2.408L6.4 5.209z"/></svg>
|
||||
x-twitter: <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M389.2 48h70.6L305.6 224.2 487 464H345L233.7 318.6 106.5 464H35.8L200.7 275.5 26.8 48H172.4L272.9 180.9 389.2 48zM364.4 421.8h39.1L151.1 88h-42L364.4 421.8z"/></svg>
|
||||
linkedin: <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="currentColor" d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037c-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85c3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433a2.062 2.062 0 0 1-2.063-2.065a2.064 2.064 0 1 1 2.063 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z"/></svg>
|
||||
slack: <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="currentColor" d="M5.042 15.165a2.528 2.528 0 0 1-2.52 2.523A2.528 2.528 0 0 1 0 15.165a2.527 2.527 0 0 1 2.522-2.52h2.52zm1.271 0a2.527 2.527 0 0 1 2.521-2.52a2.527 2.527 0 0 1 2.521 2.52v6.313A2.528 2.528 0 0 1 8.834 24a2.528 2.528 0 0 1-2.521-2.522zM8.834 5.042a2.528 2.528 0 0 1-2.521-2.52A2.528 2.528 0 0 1 8.834 0a2.528 2.528 0 0 1 2.521 2.522v2.52zm0 1.271a2.528 2.528 0 0 1 2.521 2.521a2.528 2.528 0 0 1-2.521 2.521H2.522A2.528 2.528 0 0 1 0 8.834a2.528 2.528 0 0 1 2.522-2.521zm10.122 2.521a2.528 2.528 0 0 1 2.522-2.521A2.528 2.528 0 0 1 24 8.834a2.528 2.528 0 0 1-2.522 2.521h-2.522zm-1.268 0a2.528 2.528 0 0 1-2.523 2.521a2.527 2.527 0 0 1-2.52-2.521V2.522A2.527 2.527 0 0 1 15.165 0a2.528 2.528 0 0 1 2.523 2.522zm-2.523 10.122a2.528 2.528 0 0 1 2.523 2.522A2.528 2.528 0 0 1 15.165 24a2.527 2.527 0 0 1-2.52-2.522v-2.522zm0-1.268a2.527 2.527 0 0 1-2.52-2.523a2.526 2.526 0 0 1 2.52-2.52h6.313A2.527 2.527 0 0 1 24 15.165a2.528 2.528 0 0 1-2.522 2.523z" /></svg>
|
||||
bluesky: <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 530"><path fill="currentColor" d="M136 44c66 50 138 151 164 205 26-54 98-155 164-205 48-36 126-64 126 25 0 18-10 149-16 170-21 74-96 93-163 81 117 20 147 86 82 153-122 125-176-32-189-72-3-8-4-11-4-8 0-3-1 0-4 8-13 40-67 197-189 72-65-67-35-133 82-153-67 12-142-7-163-81-6-21-16-152-16-170 0-89 78-61 126-25z"/></svg>
|
||||
telegram: <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512"><path fill="currentColor" d="M248 8C111.033 8 0 119.033 0 256s111.033 248 248 248 248-111.033 248-248S384.967 8 248 8m114.952 168.66c-3.732 39.215-19.881 134.378-28.1 178.3-3.476 18.584-10.322 24.816-16.948 25.425-14.4 1.326-25.338-9.517-39.287-18.661-21.827-14.308-34.158-23.215-55.346-37.177-24.485-16.135-8.612-25 5.342-39.5 3.652-3.793 67.107-61.51 68.335-66.746.153-.655.3-3.1-1.154-4.384s-3.59-.849-5.135-.5q-3.283.746-104.608 69.142-14.845 10.194-26.894 9.934c-8.855-.191-25.888-5.006-38.551-9.123-15.531-5.048-27.875-7.717-26.8-16.291q.84-6.7 18.45-13.7 108.446-47.248 144.628-62.3c68.872-28.647 83.183-33.623 92.511-33.789 2.052-.034 6.639.474 9.61 2.885a10.45 10.45 0 0 1 3.53 6.716 43.8 43.8 0 0 1 .417 9.769"/></svg>
|
||||
|
||||
# ai
|
||||
claude: <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 257"><path fill="currentColor" d="m50.228 170.321 50.357-28.257.843-2.463-.843-1.361h-2.462l-8.426-.518-28.775-.778-24.952-1.037-24.175-1.296-6.092-1.297L0 125.796l.583-3.759 5.12-3.434 7.324.648 16.202 1.101 24.304 1.685 17.629 1.037 26.118 2.722h4.148l.583-1.685-1.426-1.037-1.101-1.037-25.147-17.045-27.22-18.017-14.258-10.37-7.713-5.25-3.888-4.925-1.685-10.758 7-7.713 9.397.649 2.398.648 9.527 7.323 20.35 15.75L94.817 91.9l3.889 3.24 1.555-1.102.195-.777-1.75-2.917-14.453-26.118-15.425-26.572-6.87-11.018-1.814-6.61c-.648-2.723-1.102-4.991-1.102-7.778l7.972-10.823L71.42 0 82.05 1.426l4.472 3.888 6.61 15.101 10.694 23.786 16.591 32.34 4.861 9.592 2.592 8.879.973 2.722h1.685v-1.556l1.36-18.211 2.528-22.36 2.463-28.776.843-8.1 4.018-9.722 7.971-5.25 6.222 2.981 5.12 7.324-.713 4.73-3.046 19.768-5.962 30.98-3.889 20.739h2.268l2.593-2.593 10.499-13.934 17.628-22.036 7.778-8.749 9.073-9.657 5.833-4.601h11.018l8.1 12.055-3.628 12.443-11.342 14.388-9.398 12.184-13.48 18.147-8.426 14.518.778 1.166 2.01-.194 30.46-6.481 16.462-2.982 19.637-3.37 8.88 4.148.971 4.213-3.5 8.62-20.998 5.184-24.628 4.926-36.682 8.685-.454.324.519.648 16.526 1.555 7.065.389h17.304l32.21 2.398 8.426 5.574 5.055 6.805-.843 5.184-12.962 6.611-17.498-4.148-40.83-9.721-14-3.5h-1.944v1.167l11.666 11.406 21.387 19.314 26.767 24.887 1.36 6.157-3.434 4.86-3.63-.518-23.526-17.693-9.073-7.972-20.545-17.304h-1.36v1.814l4.73 6.935 25.017 37.59 1.296 11.536-1.814 3.76-6.481 2.268-7.13-1.297-14.647-20.544-15.1-23.138-12.185-20.739-1.49.843-7.194 77.448-3.37 3.953-7.778 2.981-6.48-4.925-3.436-7.972 3.435-15.749 4.148-20.544 3.37-16.333 3.046-20.285 1.815-6.74-.13-.454-1.49.194-15.295 20.999-23.267 31.433-18.406 19.702-4.407 1.75-7.648-3.954.713-7.064 4.277-6.286 25.47-32.405 15.36-20.092 9.917-11.6-.065-1.686h-.583L44.07 198.125l-12.055 1.555-5.185-4.86.648-7.972 2.463-2.593 20.35-13.999-.064.065Z"/></svg>
|
||||
chatgpt: <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 260"><path fill="currentColor" d="M239.184 106.203a64.716 64.716 0 0 0-5.576-53.103C219.452 28.459 191 15.784 163.213 21.74A65.586 65.586 0 0 0 52.096 45.22a64.716 64.716 0 0 0-43.23 31.36c-14.31 24.602-11.061 55.634 8.033 76.74a64.665 64.665 0 0 0 5.525 53.102c14.174 24.65 42.644 37.324 70.446 31.36a64.72 64.72 0 0 0 48.754 21.744c28.481.025 53.714-18.361 62.414-45.481a64.767 64.767 0 0 0 43.229-31.36c14.137-24.558 10.875-55.423-8.083-76.483Zm-97.56 136.338a48.397 48.397 0 0 1-31.105-11.255l1.535-.87 51.67-29.825a8.595 8.595 0 0 0 4.247-7.367v-72.85l21.845 12.636c.218.111.37.32.409.563v60.367c-.056 26.818-21.783 48.545-48.601 48.601Zm-104.466-44.61a48.345 48.345 0 0 1-5.781-32.589l1.534.921 51.722 29.826a8.339 8.339 0 0 0 8.441 0l63.181-36.425v25.221a.87.87 0 0 1-.358.665l-52.335 30.184c-23.257 13.398-52.97 5.431-66.404-17.803ZM23.549 85.38a48.499 48.499 0 0 1 25.58-21.333v61.39a8.288 8.288 0 0 0 4.195 7.316l62.874 36.272-21.845 12.636a.819.819 0 0 1-.767 0L41.353 151.53c-23.211-13.454-31.171-43.144-17.804-66.405v.256Zm179.466 41.695-63.08-36.63L161.73 77.86a.819.819 0 0 1 .768 0l52.233 30.184a48.6 48.6 0 0 1-7.316 87.635v-61.391a8.544 8.544 0 0 0-4.4-7.213Zm21.742-32.69-1.535-.922-51.619-30.081a8.39 8.39 0 0 0-8.492 0L99.98 99.808V74.587a.716.716 0 0 1 .307-.665l52.233-30.133a48.652 48.652 0 0 1 72.236 50.391v.205ZM88.061 139.097l-21.845-12.585a.87.87 0 0 1-.41-.614V65.685a48.652 48.652 0 0 1 79.757-37.346l-1.535.87-51.67 29.825a8.595 8.595 0 0 0-4.246 7.367l-.051 72.697Zm11.868-25.58 28.138-16.217 28.188 16.218v32.434l-28.086 16.218-28.188-16.218-.052-32.434Z"/></svg>
|
||||
gemini: <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 192 192"><path fill="currentColor" d="M164.93 86.68c-13.56-5.84-25.42-13.84-35.6-24.01-10.17-10.17-18.18-22.04-24.01-35.6-2.23-5.19-4.04-10.54-5.42-16.02C99.45 9.26 97.85 8 96 8s-3.45 1.26-3.9 3.05c-1.38 5.48-3.18 10.81-5.42 16.02-5.84 13.56-13.84 25.43-24.01 35.6-10.17 10.16-22.04 18.17-35.6 24.01-5.19 2.23-10.54 4.04-16.02 5.42C9.26 92.55 8 94.15 8 96s1.26 3.45 3.05 3.9c5.48 1.38 10.81 3.18 16.02 5.42 13.56 5.84 25.42 13.84 35.6 24.01 10.17 10.17 18.18 22.04 24.01 35.6 2.24 5.2 4.04 10.54 5.42 16.02A4.03 4.03 0 0 0 96 184c1.85 0 3.45-1.26 3.9-3.05 1.38-5.48 3.18-10.81 5.42-16.02 5.84-13.56 13.84-25.42 24.01-35.6 10.17-10.17 22.04-18.18 35.6-24.01 5.2-2.24 10.54-4.04 16.02-5.42A4.03 4.03 0 0 0 184 96c0-1.85-1.26-3.45-3.05-3.9-5.48-1.38-10.81-3.18-16.02-5.42"/></svg>
|
||||
@@ -0,0 +1,35 @@
|
||||
# Theme development config for documentation site
|
||||
# https://gohugo.io/configuration/build/#cache-busters
|
||||
[build]
|
||||
[build.buildStats]
|
||||
enable = true
|
||||
disableIDs = true
|
||||
[[build.cachebusters]]
|
||||
source = 'assets/notwatching/hugo_stats\.json'
|
||||
target = 'styles\.css'
|
||||
[[build.cachebusters]]
|
||||
source = '(postcss|tailwind)\.config\.mjs'
|
||||
target = 'css'
|
||||
[[build.cachebusters]]
|
||||
source = 'assets/.*\.(js|ts|jsx|tsx)'
|
||||
target = 'js'
|
||||
[[build.cachebusters]]
|
||||
source = 'assets/.*\.(.*)$'
|
||||
target = '$1'
|
||||
|
||||
[module]
|
||||
[[module.mounts]]
|
||||
source = "assets"
|
||||
target = "assets"
|
||||
[[module.mounts]]
|
||||
source = "hugo_stats.json"
|
||||
target = "assets/notwatching/hugo_stats.json"
|
||||
disableWatch = true
|
||||
|
||||
# Theme dev mode runs PostCSS from docs/, while Tailwind v4 loads native
|
||||
# dependencies from the theme root. Disable Hugo's Node permission sandbox
|
||||
# for this dev-only pipeline so the CSS is compiled instead of served raw.
|
||||
[security]
|
||||
[security.node]
|
||||
[security.node.permissions]
|
||||
disable = true
|
||||
File diff suppressed because one or more lines are too long
Binary file not shown.
|
After Width: | Height: | Size: 168 KiB |
@@ -0,0 +1,76 @@
|
||||
---
|
||||
title: تم هگزترا
|
||||
layout: hextra-home
|
||||
---
|
||||
|
||||
{{< hextra/hero-badge >}}
|
||||
<div class="hx:w-2 hx:h-2 hx:rounded-full hx:bg-primary-400"></div>
|
||||
<span>آزاد، متنباز</span>
|
||||
{{< icon name="arrow-circle-left" attributes="height=14" >}}
|
||||
{{< /hextra/hero-badge >}}
|
||||
|
||||
<div class="hx:mt-6 hx:mb-6">
|
||||
{{< hextra/hero-headline >}}
|
||||
ساخت وبسایتهای مدرن <br class="hx:sm:block hx:hidden" />با مارکداون و هیوگو
|
||||
{{< /hextra/hero-headline >}}
|
||||
</div>
|
||||
|
||||
<div class="hx:mb-12">
|
||||
{{< hextra/hero-subtitle >}}
|
||||
تم هیوگو سریع و دارای امکانات کامل <br class="hx:sm:block hx:hidden" />برای ایجاد وبسایتهای استاتیک زیبا
|
||||
{{< /hextra/hero-subtitle >}}
|
||||
</div>
|
||||
|
||||
<div class="hx:mb-6">
|
||||
{{< hextra/hero-button text="شروع کنید" link="docs" >}}
|
||||
</div>
|
||||
|
||||
<div class="hx:mt-6"></div>
|
||||
|
||||
{{< hextra/feature-grid >}}
|
||||
{{< hextra/feature-card
|
||||
title="سریع و با امکانات کامل"
|
||||
subtitle="ساده و آسان برای استفاده، در عین حال قدرتمند و غنی از ویژگیها متنوع."
|
||||
class="hx:aspect-auto hx:md:aspect-[1.1/1] hx:max-md:min-h-[340px]"
|
||||
image="/images/hextra-doc.webp"
|
||||
imageClass="hx:top-[40%] hx:left-[24px] hx:w-[180%] hx:sm:w-[110%] hx:dark:opacity-80"
|
||||
style="background: radial-gradient(ellipse at 50% 80%,rgba(194,97,254,0.15),hsla(0,0%,100%,0));"
|
||||
>}}
|
||||
{{< hextra/feature-card
|
||||
title="مارکداون تنها چیزی است که شما نیاز دارید"
|
||||
subtitle="فقط با مارکداون بنویسید. تکمیل و کامل با کامپوننتهای کد کوتاه."
|
||||
class="hx:aspect-auto hx:md:aspect-[1.1/1] hx:max-lg:min-h-[340px]"
|
||||
image="/images/hextra-markdown.webp"
|
||||
imageClass="hx:top-[40%] hx:left-[36px] hx:w-[180%] hx:sm:w-[110%] hx:dark:opacity-80"
|
||||
style="background: radial-gradient(ellipse at 50% 80%,rgba(142,53,74,0.15),hsla(0,0%,100%,0));"
|
||||
>}}
|
||||
{{< hextra/feature-card
|
||||
title="جستجوی کامل متن"
|
||||
subtitle="جستجوی متن کامل داخلی با FlexSearch، بدون نیاز به نصب موارد اضافی."
|
||||
class="hx:aspect-auto hx:md:aspect-[1.1/1] hx:max-md:min-h-[340px]"
|
||||
image="/images/hextra-search.webp"
|
||||
imageClass="hx:top-[40%] hx:left-[36px] hx:w-[110%] hx:sm:w-[110%] hx:dark:opacity-80"
|
||||
style="background: radial-gradient(ellipse at 50% 80%,rgba(221,210,59,0.15),hsla(0,0%,100%,0));"
|
||||
>}}
|
||||
{{< hextra/feature-card
|
||||
title="سبک مانند یک پر"
|
||||
subtitle="برای استفاده از هگزترا به هیچ وابستگی یا Node.js نیاز نیست. با پشتیبانی از هیوگو، یکی از سریعترین تولیدکنندگان سایت استاتیک، سایت شما را تنها در چند ثانیه با یک باینری میسازد."
|
||||
>}}
|
||||
{{< hextra/feature-card
|
||||
title=" واکنشگرا با حالت تیره"
|
||||
subtitle="در اندازههای مختلف صفحه نمایش عالی به نظر میرسد. پشتیبانی از حالت تیره داخلی، با تغییر خودکار براساس اولویت سیستم کاربر."
|
||||
>}}
|
||||
{{< hextra/feature-card
|
||||
title="ساخت و میزبانی رایگان"
|
||||
subtitle="با گیتهاب Actions بسازید و به صورت رایگان در گیتهاب Pages میزبانی کنید. یا میتوانید آن را در هر سرویس میزبانی استاتیک میزبانی کنید."
|
||||
>}}
|
||||
{{< hextra/feature-card
|
||||
title="چند زبانه آسان"
|
||||
subtitle="فقط با افزودن پسوند محلی به پرونده مارکداون صفحات وبسایت چند زبانه ایجاد کنید. افزودن پشتیبانی i18n به سایت شما بصری است."
|
||||
>}}
|
||||
{{< hextra/feature-card
|
||||
title="و خیلی بیشتر..."
|
||||
icon="sparkles"
|
||||
subtitle="برجستهکردن سینتکس / فهرست مطالب / سئو / RSS / LaTeX / Mermaid / سفارشیسازی / و موارد دیگر…"
|
||||
>}}
|
||||
{{< /hextra/feature-grid >}}
|
||||
@@ -0,0 +1,76 @@
|
||||
---
|
||||
title: Hextra テーマ
|
||||
layout: hextra-home
|
||||
---
|
||||
|
||||
{{< hextra/hero-badge >}}
|
||||
<div class="hx:w-2 hx:h-2 hx:rounded-full hx:bg-primary-400"></div>
|
||||
<span>無料、オープンソース</span>
|
||||
{{< icon name="arrow-circle-right" attributes="height=14" >}}
|
||||
{{< /hextra/hero-badge >}}
|
||||
|
||||
<div class="hx:mt-6 hx:mb-6">
|
||||
{{< hextra/hero-headline >}}
|
||||
MarkdownとHugoで <br class="hx:sm:block hx:hidden" />モダンなウェブサイトを構築
|
||||
{{< /hextra/hero-headline >}}
|
||||
</div>
|
||||
|
||||
<div class="hx:mb-12">
|
||||
{{< hextra/hero-subtitle >}}
|
||||
美しい静的ウェブサイトを作るための <br class="hx:sm:block hx:hidden" />高速でバッテリー同梱型のHugoテーマ
|
||||
{{< /hextra/hero-subtitle >}}
|
||||
</div>
|
||||
|
||||
<div class="hx:mb-6">
|
||||
{{< hextra/hero-button text="始める" link="docs" >}}
|
||||
</div>
|
||||
|
||||
<div class="hx:mt-6"></div>
|
||||
|
||||
{{< hextra/feature-grid >}}
|
||||
{{< hextra/feature-card
|
||||
title="高速かつ多機能"
|
||||
subtitle="シンプルで使いやすく、それでいて強力で豊富な機能を備えています。"
|
||||
class="hx:aspect-auto hx:md:aspect-[1.1/1] hx:max-md:min-h-[340px]"
|
||||
image="/images/hextra-doc.webp"
|
||||
imageClass="hx:top-[40%] hx:left-[24px] hx:w-[180%] hx:sm:w-[110%] hx:dark:opacity-80"
|
||||
style="background: radial-gradient(ellipse at 50% 80%,rgba(194,97,254,0.15),hsla(0,0%,100%,0));"
|
||||
>}}
|
||||
{{< hextra/feature-card
|
||||
title="MarkdownだけでOK"
|
||||
subtitle="Markdownだけで作成可能。ショートコードコンポーネントで充実させることもできます。"
|
||||
class="hx:aspect-auto hx:md:aspect-[1.1/1] hx:max-lg:min-h-[340px]"
|
||||
image="/images/hextra-markdown.webp"
|
||||
imageClass="hx:top-[40%] hx:left-[36px] hx:w-[180%] hx:sm:w-[110%] hx:dark:opacity-80"
|
||||
style="background: radial-gradient(ellipse at 50% 80%,rgba(142,53,74,0.15),hsla(0,0%,100%,0));"
|
||||
>}}
|
||||
{{< hextra/feature-card
|
||||
title="全文検索"
|
||||
subtitle="FlexSearchによる全文検索が内蔵されており、追加の設定は不要です。"
|
||||
class="hx:aspect-auto hx:md:aspect-[1.1/1] hx:max-md:min-h-[340px]"
|
||||
image="/images/hextra-search.webp"
|
||||
imageClass="hx:top-[40%] hx:left-[36px] hx:w-[110%] hx:sm:w-[110%] hx:dark:opacity-80"
|
||||
style="background: radial-gradient(ellipse at 50% 80%,rgba(221,210,59,0.15),hsla(0,0%,100%,0));"
|
||||
>}}
|
||||
{{< hextra/feature-card
|
||||
title="羽のように軽量"
|
||||
subtitle="Hextraを使用するために依存関係やNode.jsは必要ありません。Hugoによって動力を得ており、単一のバイナリで数秒でサイトを構築できます。"
|
||||
>}}
|
||||
{{< hextra/feature-card
|
||||
title="レスポンシブ対応とダークモード"
|
||||
subtitle="さまざまな画面サイズで美しく見えます。内蔵のダークモードサポートにより、ユーザーのシステム設定に基づいて自動切り替えが可能です。"
|
||||
>}}
|
||||
{{< hextra/feature-card
|
||||
title="無料で構築とホスティング"
|
||||
subtitle="GitHub Actionsを使って構築し、GitHub Pagesで無料でホスティングできます。また、他の静的ホスティングサービスでもホスティング可能です。"
|
||||
>}}
|
||||
{{< hextra/feature-card
|
||||
title="簡単な多言語対応"
|
||||
subtitle="Markdownファイルにロケールサフィックスを追加するだけで多言語ページを作成できます。i18nサポートの追加も直感的です。"
|
||||
>}}
|
||||
{{< hextra/feature-card
|
||||
title="さらに多くの機能"
|
||||
icon="sparkles"
|
||||
subtitle="構文ハイライト / 目次 / SEO / RSS / LaTeX / Mermaid / カスタマイズ可能 / など多数..."
|
||||
>}}
|
||||
{{< /hextra/feature-grid >}}
|
||||
@@ -0,0 +1,76 @@
|
||||
---
|
||||
title: Hextra Theme
|
||||
layout: hextra-home
|
||||
---
|
||||
|
||||
{{< hextra/hero-badge >}}
|
||||
<div class="hx:w-2 hx:h-2 hx:rounded-full hx:bg-primary-400"></div>
|
||||
<span>Free, open source</span>
|
||||
{{< icon name="arrow-circle-right" attributes="height=14" >}}
|
||||
{{< /hextra/hero-badge >}}
|
||||
|
||||
<div class="hx:mt-6 hx:mb-6">
|
||||
{{< hextra/hero-headline >}}
|
||||
Build modern websites <br class="hx:sm:block hx:hidden" />with Markdown and Hugo
|
||||
{{< /hextra/hero-headline >}}
|
||||
</div>
|
||||
|
||||
<div class="hx:mb-12">
|
||||
{{< hextra/hero-subtitle >}}
|
||||
Fast, batteries-included Hugo theme <br class="hx:sm:block hx:hidden" />for creating beautiful static websites
|
||||
{{< /hextra/hero-subtitle >}}
|
||||
</div>
|
||||
|
||||
<div class="hx:mb-6">
|
||||
{{< hextra/hero-button text="Get Started" link="docs" >}}
|
||||
</div>
|
||||
|
||||
<div class="hx:mt-6"></div>
|
||||
|
||||
{{< hextra/feature-grid >}}
|
||||
{{< hextra/feature-card
|
||||
title="Fast and Full-featured"
|
||||
subtitle="Simple and easy to use, yet powerful and feature-rich."
|
||||
class="hx:aspect-auto hx:md:aspect-[1.1/1] hx:max-md:min-h-[340px]"
|
||||
image="images/hextra-doc.webp"
|
||||
imageClass="hx:top-[40%] hx:left-[24px] hx:w-[180%] hx:sm:w-[110%] hx:dark:opacity-80"
|
||||
style="background: radial-gradient(ellipse at 50% 80%,rgba(194,97,254,0.15),hsla(0,0%,100%,0));"
|
||||
>}}
|
||||
{{< hextra/feature-card
|
||||
title="Markdown is All You Need"
|
||||
subtitle="Compose with just Markdown. Enrich with Shortcode components."
|
||||
class="hx:aspect-auto hx:md:aspect-[1.1/1] hx:max-lg:min-h-[340px]"
|
||||
image="images/hextra-markdown.webp"
|
||||
imageClass="hx:top-[40%] hx:left-[36px] hx:w-[180%] hx:sm:w-[110%] hx:dark:opacity-80"
|
||||
style="background: radial-gradient(ellipse at 50% 80%,rgba(142,53,74,0.15),hsla(0,0%,100%,0));"
|
||||
>}}
|
||||
{{< hextra/feature-card
|
||||
title="Full Text Search"
|
||||
subtitle="Built-in full text search with FlexSearch, no extra setup required."
|
||||
class="hx:aspect-auto hx:md:aspect-[1.1/1] hx:max-md:min-h-[340px]"
|
||||
image="images/hextra-search.webp"
|
||||
imageClass="hx:top-[40%] hx:left-[36px] hx:w-[110%] hx:sm:w-[110%] hx:dark:opacity-80"
|
||||
style="background: radial-gradient(ellipse at 50% 80%,rgba(221,210,59,0.15),hsla(0,0%,100%,0));"
|
||||
>}}
|
||||
{{< hextra/feature-card
|
||||
title="Lightweight as a Feather"
|
||||
subtitle="No dependency or Node.js is needed to use Hextra. Powered by Hugo, one of *the fastest* static site generators, building your site in just seconds with a single binary."
|
||||
>}}
|
||||
{{< hextra/feature-card
|
||||
title="Responsive with Dark Mode Included"
|
||||
subtitle="Looks great on different screen sizes. Built-in dark mode support, with auto-switching based on user's system preference."
|
||||
>}}
|
||||
{{< hextra/feature-card
|
||||
title="Build and Host for Free"
|
||||
subtitle="Build with GitHub Actions, and host for free on GitHub Pages. Alternatively it can be hosted on any static hosting service."
|
||||
>}}
|
||||
{{< hextra/feature-card
|
||||
title="Multi-Language Made Easy"
|
||||
subtitle="Create multi-language pages by just adding locales suffix to the Markdown file. Adding i18n support to your site is intuitive."
|
||||
>}}
|
||||
{{< hextra/feature-card
|
||||
title="And Much More..."
|
||||
icon="sparkles"
|
||||
subtitle="Syntax highlighting / Table of contents / SEO / RSS / LaTeX / Mermaid / Customizable / and more..."
|
||||
>}}
|
||||
{{< /hextra/feature-grid >}}
|
||||
@@ -0,0 +1,76 @@
|
||||
---
|
||||
title: Hextra 主题
|
||||
layout: hextra-home
|
||||
---
|
||||
|
||||
{{< hextra/hero-badge >}}
|
||||
<div class="hx:w-2 hx:h-2 hx:rounded-full hx:bg-primary-400"></div>
|
||||
<span>免费 开源</span>
|
||||
{{< icon name="arrow-circle-right" attributes="height=14" >}}
|
||||
{{< /hextra/hero-badge >}}
|
||||
|
||||
<div class="hx:mt-6 hx:mb-6">
|
||||
{{< hextra/hero-headline >}}
|
||||
创建现代化网站 <br class="hx:sm:block hx:hidden" />由 Markdown 和 Hugo 驱动
|
||||
{{< /hextra/hero-headline >}}
|
||||
</div>
|
||||
|
||||
<div class="hx:mb-12">
|
||||
{{< hextra/hero-subtitle >}}
|
||||
极速且全能的 Hugo 主题框架 <br class="hx:sm:block hx:hidden" />为构建现代化的静态网站而生
|
||||
{{< /hextra/hero-subtitle >}}
|
||||
</div>
|
||||
|
||||
<div class="hx:mb-6">
|
||||
{{< hextra/hero-button text="现在开始" link="docs" >}}
|
||||
</div>
|
||||
|
||||
<div class="hx:mt-6"></div>
|
||||
|
||||
{{< hextra/feature-grid >}}
|
||||
{{< hextra/feature-card
|
||||
title="快速且功能全面"
|
||||
subtitle="简单易用,功能强大丰富。"
|
||||
class="hx:aspect-auto hx:md:aspect-[1.1/1] hx:max-md:min-h-[340px]"
|
||||
image="/images/hextra-doc.webp"
|
||||
imageClass="hx:top-[40%] hx:left-[24px] hx:w-[180%] hx:sm:w-[110%] hx:dark:opacity-80"
|
||||
style="background: radial-gradient(ellipse at 50% 80%,rgba(194,97,254,0.15),hsla(0,0%,100%,0));"
|
||||
>}}
|
||||
{{< hextra/feature-card
|
||||
title="Markdown 写作"
|
||||
subtitle="只需使用 Markdown 进行编辑。多样的 Shortcode 组件开箱即用。"
|
||||
class="hx:aspect-auto hx:md:aspect-[1.1/1] hx:max-lg:min-h-[340px]"
|
||||
image="/images/hextra-markdown.webp"
|
||||
imageClass="hx:top-[40%] hx:left-[36px] hx:w-[180%] hx:sm:w-[110%] hx:dark:opacity-80"
|
||||
style="background: radial-gradient(ellipse at 50% 80%,rgba(142,53,74,0.15),hsla(0,0%,100%,0));"
|
||||
>}}
|
||||
{{< hextra/feature-card
|
||||
title="全文搜索"
|
||||
subtitle="内置 FlexSearch 全文搜索,无需额外设置。"
|
||||
class="hx:aspect-auto hx:md:aspect-[1.1/1] hx:max-md:min-h-[340px]"
|
||||
image="/images/hextra-search.webp"
|
||||
imageClass="hx:top-[40%] hx:left-[36px] hx:w-[110%] hx:sm:w-[110%] hx:dark:opacity-80"
|
||||
style="background: radial-gradient(ellipse at 50% 80%,rgba(221,210,59,0.15),hsla(0,0%,100%,0));"
|
||||
>}}
|
||||
{{< hextra/feature-card
|
||||
title="轻如羽毛"
|
||||
subtitle="使用 Hextra 无需依赖 Node.js。由 Hugo 提供支持,Hugo 是最快的静态网站生成器之一,只需一个二进制文件即可在数秒内创建网站。"
|
||||
>}}
|
||||
{{< hextra/feature-card
|
||||
title="响应式布局,暗黑模式"
|
||||
subtitle="适应不同的屏幕尺寸。内置暗黑模式支持,并根据用户的系统偏好自动切换。"
|
||||
>}}
|
||||
{{< hextra/feature-card
|
||||
title="免费构建和托管"
|
||||
subtitle="使用 GitHub Actions 进行构建,并在 GitHub Pages 上免费托管。也可以托管在任何静态托管服务上。"
|
||||
>}}
|
||||
{{< hextra/feature-card
|
||||
title="多语言轻松实现"
|
||||
subtitle="仅需通过在 Markdown 文件后添加语言代码即可创建多语言页面。向您的站点添加 i18n 支持直观易行。"
|
||||
>}}
|
||||
{{< hextra/feature-card
|
||||
title="还有更多..."
|
||||
icon="sparkles"
|
||||
subtitle="代码高亮 / 目录 / SEO / RSS / LaTeX 公式 / Mermaid 图标 / 自定义 / 等等..."
|
||||
>}}
|
||||
{{< /hextra/feature-grid >}}
|
||||
@@ -0,0 +1,22 @@
|
||||
---
|
||||
title: درباره ما
|
||||
toc: false
|
||||
---
|
||||
|
||||
هگزترا به گونهای طراحی شده است که یک موضوع ساده، سریع و انعطاف پذیر برای ساخت وبسایتهای استاتیک مدرن باشد. این به ویژه برای وبسایتهای مستندسازی مناسب است اما میتواند برای انواع مختلف سایتها مانند وبلاگها، نمونهکار و موارد دیگر نیز استفاده شود.
|
||||
|
||||
Hugo مانند Jekyll، یک ایجادکننده سایت استاتیک است. چیزی که Hugo را متمایز میکند این است که یک باینری واحد است و نصب و اجرای آن بر روی پلتفرمهای مختلف را آسان میکند. همچنین بسیار سریع و قابل اعتماد است و میتواند یک سایت را با هزاران صفحه در میلیثانیه ارائه دهد.
|
||||
|
||||
هگزترا با ذهنیتی ساخته شده است که بر داشتن حداقل ردپا متمرکز شده است. برای شروع، هیچ وابستگی اضافی مانند بستههای Node.js لازم نیست. تنها چیزی که نیاز دارید یک پرونده پیکربندی YAML به همراه محتوای مارکداون شما است. بنابراین، شما میتوانید به جای تنظیم ابزار، روی نوشتن محتوای با کیفیت تمرکز کنید.
|
||||
|
||||
## اعتبار
|
||||
|
||||
ترجمه فارسی مستندات توسط [گودرز جعفری](https://goudarzjafari.com/) انجام شده است.
|
||||
|
||||
هگزترا بدون ابزار و الهامات زیر ساخته نمیشود:
|
||||
|
||||
- [هیوگو](https://gohugo.io/)
|
||||
- [Tailwind CSS](https://tailwindcss.com/)
|
||||
- [Heroicons](https://heroicons.com/)
|
||||
- [Nextra](https://nextra.vercel.app/)
|
||||
- [Next.js](https://nextjs.org/)
|
||||
@@ -0,0 +1,20 @@
|
||||
---
|
||||
title: このサイトについて
|
||||
toc: false
|
||||
---
|
||||
|
||||
Hextra は、モダンな静的サイトを構築するためのシンプルで高速かつ柔軟なテーマとして設計されています。特にドキュメントサイトの構築に適していますが、ブログやポートフォリオなど様々な種類のサイトにも利用可能です。
|
||||
|
||||
Hugo は Jekyll と同様に静的サイトジェネレータですが、単一のバイナリで構成されている点が特徴です。これにより様々なプラットフォームでのインストールと実行が容易で、極めて高速かつ信頼性が高く、数千ページあるサイトでもミリ秒単位でレンダリング可能です。
|
||||
|
||||
Hextra は最小限のフットプリントに焦点を当てた思想で構築されています。開始するにあたり、Node.js パッケージなどの追加依存関係は不要で、必要なのは単一の YAML 設定ファイルと Markdown コンテンツのみです。これにより、ツールのセットアップではなく質の高いコンテンツの作成に集中できます。
|
||||
|
||||
## クレジット
|
||||
|
||||
Hextra は以下のツールとインスピレーションなしには成り立ちません:
|
||||
|
||||
- [Hugo](https://gohugo.io/)
|
||||
- [Tailwind CSS](https://tailwindcss.com/)
|
||||
- [Heroicons](https://heroicons.com/)
|
||||
- [Nextra](https://nextra.vercel.app/)
|
||||
- [Next.js](https://nextjs.org/)
|
||||
@@ -0,0 +1,20 @@
|
||||
---
|
||||
title: About
|
||||
toc: false
|
||||
---
|
||||
|
||||
Hextra is designed to be a simple, fast, and flexible theme for building modern static websites. It is especially well-suited for documentation websites but can also be used for various types of sites, such as blogs, portfolios, and more.
|
||||
|
||||
Hugo, like Jekyll, is a static site generator. What sets Hugo apart is that it is a single binary, making it easy to install and run on various platforms. It is also extremely fast and reliable, capable of rendering a site with thousands of pages in milliseconds.
|
||||
|
||||
Hextra is built with a mindset focused on having a minimal footprint. To get started, no extra dependencies like Node.js packages are required; all you need is a single YAML configuration file, along with your Markdown content. Thus, we can focus on writing quality content instead of setting up tooling.
|
||||
|
||||
## Credits
|
||||
|
||||
Hextra cannot be built without the following tools and inspirations:
|
||||
|
||||
- [Hugo](https://gohugo.io/)
|
||||
- [Tailwind CSS](https://tailwindcss.com/)
|
||||
- [Heroicons](https://heroicons.com/)
|
||||
- [Nextra](https://nextra.vercel.app/)
|
||||
- [Next.js](https://nextjs.org/)
|
||||
@@ -0,0 +1,20 @@
|
||||
---
|
||||
title: 关于
|
||||
toc: false
|
||||
---
|
||||
|
||||
Hextra 是一款专为构建现代化静态网站而设计的简洁、快速且灵活的主题。它尤其适合搭建文档类网站,同时也能轻松驾驭博客、作品集等多种站点类型。
|
||||
|
||||
与 Jekyll 类似,Hugo 同样是一款静态网站生成器。其独特之处在于采用单一二进制文件,可在多平台轻松安装运行。Hugo 以极致的速度与稳定性著称,能在毫秒间渲染包含数千页面的网站。
|
||||
|
||||
Hextra 秉持极简理念开发。您无需安装 Node.js 等额外依赖,仅需一个 YAML 配置文件搭配 Markdown 内容即可快速开始。这让我们能专注于创作优质内容,而非配置工具链。
|
||||
|
||||
## 致谢
|
||||
|
||||
Hextra 的诞生离不开以下工具与灵感的启发:
|
||||
|
||||
- [Hugo](https://gohugo.io/)
|
||||
- [Tailwind CSS](https://tailwindcss.com/)
|
||||
- [Heroicons](https://heroicons.com/)
|
||||
- [Nextra](https://nextra.vercel.app/)
|
||||
- [Next.js](https://nextjs.org/)
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
title: آرشیو
|
||||
layout: archives
|
||||
toc: false
|
||||
---
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
title: アーカイブ
|
||||
layout: archives
|
||||
toc: false
|
||||
---
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
title: Archives
|
||||
layout: archives
|
||||
toc: false
|
||||
---
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
title: 归档
|
||||
layout: archives
|
||||
toc: false
|
||||
---
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
title: "وبلاگ"
|
||||
---
|
||||
|
||||
<div style="text-align: center; margin-top: 1em;">
|
||||
{{< hextra/hero-badge link="index.xml" >}}
|
||||
<span>فید RSS</span>
|
||||
{{< icon name="rss" attributes="height=14" >}}
|
||||
{{< /hextra/hero-badge >}}
|
||||
</div>
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
title: "ブログ"
|
||||
---
|
||||
|
||||
<div style="text-align: center; margin-top: 1em;">
|
||||
{{< hextra/hero-badge link="index.xml" >}}
|
||||
<span>RSS フィード</span>
|
||||
{{< icon name="rss" attributes="height=14" >}}
|
||||
{{< /hextra/hero-badge >}}
|
||||
</div>
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
title: "Blog"
|
||||
---
|
||||
|
||||
<div style="text-align: center; margin-top: 1em;">
|
||||
{{< hextra/hero-badge link="index.xml" >}}
|
||||
<span>RSS Feed</span>
|
||||
{{< icon name="rss" attributes="height=14" >}}
|
||||
{{< /hextra/hero-badge >}}
|
||||
</div>
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
title: "博客"
|
||||
---
|
||||
|
||||
<div style="text-align: center; margin-top: 1em;">
|
||||
{{< hextra/hero-badge link="index.xml" >}}
|
||||
<span>RSS 订阅</span>
|
||||
{{< icon name="rss" attributes="height=14" >}}
|
||||
{{< /hextra/hero-badge >}}
|
||||
</div>
|
||||
@@ -0,0 +1,160 @@
|
||||
---
|
||||
title: راهنمای نحو Markdown
|
||||
date: 2020-01-01
|
||||
authors:
|
||||
- name: imfing
|
||||
link: https://github.com/imfing
|
||||
image: https://github.com/imfing.png
|
||||
- name: Octocat
|
||||
link: https://github.com/octocat
|
||||
image: https://github.com/octocat.png
|
||||
- name: Goudarz Jafari
|
||||
link: https://github.com/Goudarz
|
||||
image: https://github.com/Goudarz.png
|
||||
tags:
|
||||
- Markdown
|
||||
- مثال
|
||||
- راهنما
|
||||
excludeSearch: true
|
||||
---
|
||||
|
||||
این مقاله نمونهای از نحو پایهای Markdown را ارائه میدهد که میتوان در فایلهای محتوای Hugo استفاده کرد.
|
||||
<!--more-->
|
||||
|
||||
## نحو پایه
|
||||
|
||||
### سرتیترها
|
||||
|
||||
```
|
||||
# سرتیتر 1
|
||||
## سرتیتر 2
|
||||
### سرتیتر 3
|
||||
#### سرتیتر 4
|
||||
##### سرتیتر 5
|
||||
###### سرتیتر 6
|
||||
```
|
||||
|
||||
## سرتیتر 2
|
||||
### سرتیتر 3
|
||||
#### سرتیتر 4
|
||||
##### سرتیتر 5
|
||||
###### سرتیتر 6
|
||||
|
||||
### تأکید
|
||||
|
||||
```text
|
||||
*این متن به صورت ایتالیک نمایش داده میشود*
|
||||
_این نیز به صورت ایتالیک نمایش داده میشود_
|
||||
|
||||
**این متن به صورت پررنگ نمایش داده میشود**
|
||||
__این نیز به صورت پررنگ نمایش داده میشود__
|
||||
|
||||
_شما میتوانید **آنها را ترکیب** کنید_
|
||||
```
|
||||
|
||||
*این متن به صورت ایتالیک نمایش داده میشود*
|
||||
|
||||
_این نیز به صورت ایتالیک نمایش داده میشود_
|
||||
|
||||
**این متن به صورت پررنگ نمایش داده میشود**
|
||||
|
||||
__این نیز به صورت پررنگ نمایش داده میشود__
|
||||
|
||||
_شما میتوانید **آنها را ترکیب** کنید_
|
||||
|
||||
### فهرستها
|
||||
|
||||
#### بدون ترتیب
|
||||
|
||||
```
|
||||
* مورد ۱
|
||||
* مورد ۲
|
||||
* مورد ۲الف
|
||||
* مورد ۲ب
|
||||
```
|
||||
|
||||
* مورد ۱
|
||||
* مورد ۲
|
||||
* مورد ۲الف
|
||||
* مورد ۲ب
|
||||
|
||||
#### با ترتیب
|
||||
|
||||
```
|
||||
۱. مورد ۱
|
||||
۲. مورد ۲
|
||||
۳. مورد ۳
|
||||
۱. مورد ۳الف
|
||||
۲. مورد ۳ب
|
||||
```
|
||||
|
||||
### تصاویر
|
||||
|
||||
```markdown
|
||||

|
||||
```
|
||||
|
||||

|
||||
|
||||
### پیوندها
|
||||
|
||||
```markdown
|
||||
[Hugo](https://gohugo.io)
|
||||
```
|
||||
|
||||
[Hugo](https://gohugo.io)
|
||||
|
||||
### نقلقولها
|
||||
|
||||
```markdown
|
||||
همانطور که نیوتن گفت:
|
||||
|
||||
> اگر من دورتر را دیدهام، به این دلیل است که بر شانههای غولها ایستادهام.
|
||||
```
|
||||
|
||||
> اگر من دورتر را دیدهام، به این دلیل است که بر شانههای غولها ایستادهام.
|
||||
|
||||
### کد درونخطی
|
||||
|
||||
```markdown
|
||||
کد `درونخطی` با `علامت back-tick` احاطه شده است.
|
||||
```
|
||||
|
||||
کد `درونخطی` با `علامت back-tick` احاطه شده است.
|
||||
|
||||
### بلوکهای کد
|
||||
|
||||
#### هایلایت سینتکس
|
||||
|
||||
````markdown
|
||||
```go
|
||||
func main() {
|
||||
fmt.Println("Hello World")
|
||||
}
|
||||
```
|
||||
````
|
||||
|
||||
```go
|
||||
func main() {
|
||||
fmt.Println("Hello World")
|
||||
}
|
||||
```
|
||||
|
||||
### جداول
|
||||
|
||||
```markdown
|
||||
| سینتکس | توضیحات |
|
||||
| --------- | ----------- |
|
||||
| هدر | عنوان |
|
||||
| پاراگراف | متن |
|
||||
```
|
||||
|
||||
| سینتکس | توضیحات |
|
||||
| --------- | ----------- |
|
||||
| هدر | عنوان |
|
||||
| پاراگراف | متن |
|
||||
|
||||
## منابع
|
||||
|
||||
- [نحو Markdown](https://www.markdownguide.org/basic-syntax/)
|
||||
- [Markdown در Hugo](https://gohugo.io/content-management/formats/#markdown)
|
||||
@@ -0,0 +1,157 @@
|
||||
---
|
||||
title: Markdown 構文ガイド
|
||||
date: 2020-01-01
|
||||
authors:
|
||||
- name: imfing
|
||||
link: https://github.com/imfing
|
||||
image: https://github.com/imfing.png
|
||||
- name: Octocat
|
||||
link: https://github.com/octocat
|
||||
image: https://github.com/octocat.png
|
||||
tags:
|
||||
- Markdown
|
||||
- サンプル
|
||||
- ガイド
|
||||
excludeSearch: true
|
||||
---
|
||||
|
||||
この記事では、Hugo のコンテンツファイルで使用できる基本的な Markdown 構文のサンプルを紹介します。
|
||||
<!--more-->
|
||||
|
||||
## 基本構文
|
||||
|
||||
### 見出し
|
||||
|
||||
```
|
||||
# 見出し1
|
||||
## 見出し2
|
||||
### 見出し3
|
||||
#### 見出し4
|
||||
##### 見出し5
|
||||
###### 見出し6
|
||||
```
|
||||
|
||||
## 見出し2
|
||||
### 見出し3
|
||||
#### 見出し4
|
||||
##### 見出し5
|
||||
###### 見出し6
|
||||
|
||||
### 強調
|
||||
|
||||
```text
|
||||
*このテキストは斜体になります*
|
||||
_これも斜体になります_
|
||||
|
||||
**このテキストは太字になります**
|
||||
__これも太字になります__
|
||||
|
||||
_これらを**組み合わせる**こともできます_
|
||||
```
|
||||
|
||||
*このテキストは斜体になります*
|
||||
|
||||
_これも斜体になります_
|
||||
|
||||
**このテキストは太字になります**
|
||||
|
||||
__これも太字になります__
|
||||
|
||||
_これらを**組み合わせる**こともできます_
|
||||
|
||||
### リスト
|
||||
|
||||
#### 順序なしリスト
|
||||
|
||||
```
|
||||
* 項目1
|
||||
* 項目2
|
||||
* 項目2a
|
||||
* 項目2b
|
||||
```
|
||||
|
||||
* 項目1
|
||||
* 項目2
|
||||
* 項目2a
|
||||
* 項目2b
|
||||
|
||||
#### 順序付きリスト
|
||||
|
||||
```
|
||||
1. 項目1
|
||||
2. 項目2
|
||||
3. 項目3
|
||||
1. 項目3a
|
||||
2. 項目3b
|
||||
```
|
||||
|
||||
### 画像
|
||||
|
||||
```markdown
|
||||

|
||||
```
|
||||
|
||||

|
||||
|
||||
### リンク
|
||||
|
||||
```markdown
|
||||
[Hugo](https://gohugo.io)
|
||||
```
|
||||
|
||||
[Hugo](https://gohugo.io)
|
||||
|
||||
### ブロッククォート
|
||||
|
||||
```markdown
|
||||
ニュートンはこう言いました:
|
||||
|
||||
> 私が遠くを見渡せたとしたら、それは巨人の肩の上に立っていたからです。
|
||||
```
|
||||
|
||||
> 私が遠くを見渡せたとしたら、それは巨人の肩の上に立っていたからです。
|
||||
|
||||
### インラインコード
|
||||
|
||||
```markdown
|
||||
インライン `コード` は `バッククォートで囲みます`。
|
||||
```
|
||||
|
||||
インライン `コード` は `バッククォートで囲みます`。
|
||||
|
||||
### コードブロック
|
||||
|
||||
#### シンタックスハイライト
|
||||
|
||||
````markdown
|
||||
```go
|
||||
func main() {
|
||||
fmt.Println("Hello World")
|
||||
}
|
||||
```
|
||||
````
|
||||
|
||||
```go
|
||||
func main() {
|
||||
fmt.Println("Hello World")
|
||||
}
|
||||
```
|
||||
|
||||
### テーブル
|
||||
|
||||
```markdown
|
||||
| 構文 | 説明 |
|
||||
| --------- | ----------- |
|
||||
| 見出し | タイトル |
|
||||
| 段落 | テキスト |
|
||||
```
|
||||
|
||||
| 構文 | 説明 |
|
||||
| --------- | ----------- |
|
||||
| 見出し | タイトル |
|
||||
| 段落 | テキスト |
|
||||
|
||||
## 参考資料
|
||||
|
||||
- [Markdown 構文](https://www.markdownguide.org/basic-syntax/)
|
||||
- [Hugo Markdown](https://gohugo.io/content-management/formats/#markdown)
|
||||
@@ -0,0 +1,157 @@
|
||||
---
|
||||
title: Markdown Syntax Guide
|
||||
date: 2020-01-01
|
||||
authors:
|
||||
- name: imfing
|
||||
link: https://github.com/imfing
|
||||
image: https://github.com/imfing.png
|
||||
- name: Octocat
|
||||
link: https://github.com/octocat
|
||||
image: https://github.com/octocat.png
|
||||
tags:
|
||||
- Markdown
|
||||
- Example
|
||||
- Guide
|
||||
excludeSearch: true
|
||||
---
|
||||
|
||||
This article offers a sample of basic Markdown syntax that can be used in Hugo content files.
|
||||
<!--more-->
|
||||
|
||||
## Basic Syntax
|
||||
|
||||
### Headings
|
||||
|
||||
```
|
||||
# Heading 1
|
||||
## Heading 2
|
||||
### Heading 3
|
||||
#### Heading 4
|
||||
##### Heading 5
|
||||
###### Heading 6
|
||||
```
|
||||
|
||||
## Heading 2
|
||||
### Heading 3
|
||||
#### Heading 4
|
||||
##### Heading 5
|
||||
###### Heading 6
|
||||
|
||||
### Emphasis
|
||||
|
||||
```text
|
||||
*This text will be italic*
|
||||
_This will also be italic_
|
||||
|
||||
**This text will be bold**
|
||||
__This will also be bold__
|
||||
|
||||
_You **can** combine them_
|
||||
```
|
||||
|
||||
*This text will be italic*
|
||||
|
||||
_This will also be italic_
|
||||
|
||||
**This text will be bold**
|
||||
|
||||
__This will also be bold__
|
||||
|
||||
_You **can** combine them_
|
||||
|
||||
### Lists
|
||||
|
||||
#### Unordered
|
||||
|
||||
```
|
||||
* Item 1
|
||||
* Item 2
|
||||
* Item 2a
|
||||
* Item 2b
|
||||
```
|
||||
|
||||
* Item 1
|
||||
* Item 2
|
||||
* Item 2a
|
||||
* Item 2b
|
||||
|
||||
#### Ordered
|
||||
|
||||
```
|
||||
1. Item 1
|
||||
2. Item 2
|
||||
3. Item 3
|
||||
1. Item 3a
|
||||
2. Item 3b
|
||||
```
|
||||
|
||||
### Images
|
||||
|
||||
```markdown
|
||||

|
||||
```
|
||||
|
||||

|
||||
|
||||
### Links
|
||||
|
||||
```markdown
|
||||
[Hugo](https://gohugo.io)
|
||||
```
|
||||
|
||||
[Hugo](https://gohugo.io)
|
||||
|
||||
### Blockquotes
|
||||
|
||||
```markdown
|
||||
As Newton said:
|
||||
|
||||
> If I have seen further it is by standing on the shoulders of Giants.
|
||||
```
|
||||
|
||||
> If I have seen further it is by standing on the shoulders of Giants.
|
||||
|
||||
### Inline Code
|
||||
|
||||
```markdown
|
||||
Inline `code` has `back-ticks around` it.
|
||||
```
|
||||
|
||||
Inline `code` has `back-ticks around` it.
|
||||
|
||||
### Code Blocks
|
||||
|
||||
#### Syntax Highlighting
|
||||
|
||||
````markdown
|
||||
```go
|
||||
func main() {
|
||||
fmt.Println("Hello World")
|
||||
}
|
||||
```
|
||||
````
|
||||
|
||||
```go
|
||||
func main() {
|
||||
fmt.Println("Hello World")
|
||||
}
|
||||
```
|
||||
|
||||
### Tables
|
||||
|
||||
```markdown
|
||||
| Syntax | Description |
|
||||
| --------- | ----------- |
|
||||
| Header | Title |
|
||||
| Paragraph | Text |
|
||||
```
|
||||
|
||||
| Syntax | Description |
|
||||
| --------- | ----------- |
|
||||
| Header | Title |
|
||||
| Paragraph | Text |
|
||||
|
||||
## References
|
||||
|
||||
- [Markdown Syntax](https://www.markdownguide.org/basic-syntax/)
|
||||
- [Hugo Markdown](https://gohugo.io/content-management/formats/#markdown)
|
||||
@@ -0,0 +1,157 @@
|
||||
---
|
||||
title: Markdown 语法指南
|
||||
date: 2020-01-01
|
||||
authors:
|
||||
- name: imfing
|
||||
link: https://github.com/imfing
|
||||
image: https://github.com/imfing.png
|
||||
- name: Octocat
|
||||
link: https://github.com/octocat
|
||||
image: https://github.com/octocat.png
|
||||
tags:
|
||||
- Markdown
|
||||
- 示例
|
||||
- 指南
|
||||
excludeSearch: true
|
||||
---
|
||||
|
||||
本文展示了 Hugo 内容文件中可用的基础 Markdown 语法示例。
|
||||
<!--more-->
|
||||
|
||||
## 基础语法
|
||||
|
||||
### 标题
|
||||
|
||||
```
|
||||
# 一级标题
|
||||
## 二级标题
|
||||
### 三级标题
|
||||
#### 四级标题
|
||||
##### 五级标题
|
||||
###### 六级标题
|
||||
```
|
||||
|
||||
## 二级标题
|
||||
### 三级标题
|
||||
#### 四级标题
|
||||
##### 五级标题
|
||||
###### 六级标题
|
||||
|
||||
### 强调
|
||||
|
||||
```text
|
||||
*这段文字会显示为斜体*
|
||||
_这段文字也会显示为斜体_
|
||||
|
||||
**这段文字会显示为粗体**
|
||||
__这段文字也会显示为粗体__
|
||||
|
||||
_你可以**组合**使用_
|
||||
```
|
||||
|
||||
*这段文字会显示为斜体*
|
||||
|
||||
_这段文字也会显示为斜体_
|
||||
|
||||
**这段文字会显示为粗体**
|
||||
|
||||
__这段文字也会显示为粗体__
|
||||
|
||||
_你可以**组合**使用_
|
||||
|
||||
### 列表
|
||||
|
||||
#### 无序列表
|
||||
|
||||
```
|
||||
* 项目1
|
||||
* 项目2
|
||||
* 子项目2a
|
||||
* 子项目2b
|
||||
```
|
||||
|
||||
* 项目1
|
||||
* 项目2
|
||||
* 子项目2a
|
||||
* 子项目2b
|
||||
|
||||
#### 有序列表
|
||||
|
||||
```
|
||||
1. 项目1
|
||||
2. 项目2
|
||||
3. 项目3
|
||||
1. 子项目3a
|
||||
2. 子项目3b
|
||||
```
|
||||
|
||||
### 图片
|
||||
|
||||
```markdown
|
||||

|
||||
```
|
||||
|
||||

|
||||
|
||||
### 链接
|
||||
|
||||
```markdown
|
||||
[Hugo](https://gohugo.io)
|
||||
```
|
||||
|
||||
[Hugo](https://gohugo.io)
|
||||
|
||||
### 引用块
|
||||
|
||||
```markdown
|
||||
正如牛顿所说:
|
||||
|
||||
> 如果说我看得比别人更远些,那是因为我站在巨人的肩膀上。
|
||||
```
|
||||
|
||||
> 如果说我看得比别人更远些,那是因为我站在巨人的肩膀上。
|
||||
|
||||
### 行内代码
|
||||
|
||||
```markdown
|
||||
行内`代码`会用`反引号包裹`起来。
|
||||
```
|
||||
|
||||
行内`代码`会用`反引号包裹`起来。
|
||||
|
||||
### 代码块
|
||||
|
||||
#### 语法高亮
|
||||
|
||||
````markdown
|
||||
```go
|
||||
func main() {
|
||||
fmt.Println("Hello World")
|
||||
}
|
||||
```
|
||||
````
|
||||
|
||||
```go
|
||||
func main() {
|
||||
fmt.Println("Hello World")
|
||||
}
|
||||
```
|
||||
|
||||
### 表格
|
||||
|
||||
```markdown
|
||||
| 语法 | 描述 |
|
||||
| --------- | ----------- |
|
||||
| 标题 | 标题文本 |
|
||||
| 段落 | 正文内容 |
|
||||
```
|
||||
|
||||
| 语法 | 描述 |
|
||||
| --------- | ----------- |
|
||||
| 标题 | 标题文本 |
|
||||
| 段落 | 正文内容 |
|
||||
|
||||
## 参考资料
|
||||
|
||||
- [Markdown 语法](https://www.markdownguide.org/basic-syntax/)
|
||||
- [Hugo Markdown](https://gohugo.io/content-management/formats/#markdown)
|
||||
@@ -0,0 +1,247 @@
|
||||
---
|
||||
title: "Hextra v0.10"
|
||||
date: 2025-08-14
|
||||
authors:
|
||||
- name: imfing
|
||||
link: https://github.com/imfing
|
||||
image: https://github.com/imfing.png
|
||||
tags:
|
||||
- انتشار
|
||||
---
|
||||
|
||||
Hextra v0.10.0 یک انتشار بزرگ است که مملو از قابلیتهای جدید، ارتقاهای معماری و بهبودهای کیفیت زندگی میباشد.
|
||||
|
||||
<!--more-->
|
||||
|
||||
همچنین شامل مشارکتهای 10 [مشارکتکننده جدید](#contributors) بوده و درخواستهای دیرینه جامعه را برطرف میکند.
|
||||
|
||||
## راهنمای ارتقا
|
||||
|
||||
> [!IMPORTANT]
|
||||
> **تغییرات شکستآمیز**: این انتشار شامل چندین تغییر شکستآمیز است. لطفاً قبل از ارتقا، چکلیست و [راهنمای مهاجرت](#migration-guide) را بررسی کنید.
|
||||
|
||||
قبل از ارتقا به v0.10.0، مطمئن شوید که:
|
||||
|
||||
- Hugo v0.146.0+ (نسخه extended) نصب شده است
|
||||
- CSS سفارشی را برای تغییرات نام کلاس بررسی کردهاید (به [تغییرات پیشوند کلاسهای CSS](#css-class-prefix-changes) و [Tailwind CSS v4](#tailwind-css-v4) مراجعه کنید)
|
||||
- تأیید کردهاید که محیط ساخت دسترسی به اینترنت برای دانلود داراییها هنگام استفاده از LaTeX و/یا Mermaid دارد
|
||||
|
||||
پس از آمادهسازی، ماژول Hugo را بهروزرسانی کنید:
|
||||
|
||||
```bash
|
||||
hugo mod get -u github.com/imfing/hextra@v0.10.0
|
||||
```
|
||||
|
||||
## ویژگیهای جدید
|
||||
|
||||
در زیر لیستی از ویژگیهای جدید قابل توجه در این انتشار آمده است:
|
||||
|
||||
- [**پشتیبانی از منوی کشویی در نوار ناوبری**](#dropdown-menu-support-in-navbar): ایجاد منوهای ناوبری سلسلهمراتبی
|
||||
- [**تجربه جستجوی بهبودیافته**](#enhanced-search-experience): جستجوی بهبودیافته در تمام سرتیترها با دقت بهتر
|
||||
- [**پشتیبانی از llms.txt**](#llmstxt-support): تولید خلاصه سایت مناسب برای هوش مصنوعی
|
||||
- [**هایلایت کردن اسکرول فهرست مطالب**](#table-of-contents-scroll-highlighting): هایلایت کردن خودکار سرتیترها هنگام اسکرول صفحه
|
||||
- [**تبدیل همگام تبها**](#synchronized-tab-switching): همگامسازی انتخاب تبها در چندین گروه تب
|
||||
- [**صفحهبندی لیست وبلاگ**](#blog-list-pagination): اضافه کردن کنترلهای صفحهبندی به صفحات لیست وبلاگ
|
||||
- [**پشتیبانی از MathJax**](#mathjax-support): موتور رندر ریاضی جایگزین در کنار KaTeX
|
||||
|
||||
### پشتیبانی از منوی کشویی در نوار ناوبری
|
||||
|
||||
منوهای کشویی را در نوار ناوبری خود برای سازماندهی بهتر موارد ناوبری ایجاد کنید.
|
||||
|
||||
```yaml {filename="hugo.yaml"}
|
||||
menu:
|
||||
main:
|
||||
- identifier: products
|
||||
name: "محصولات"
|
||||
- name: "محصول الف"
|
||||
parent: products
|
||||
url: "/product-a"
|
||||
- name: "محصول ب"
|
||||
parent: products
|
||||
url: "/product-b"
|
||||
```
|
||||
|
||||

|
||||
|
||||
### تجربه جستجوی بهبودیافته
|
||||
|
||||
- **جستجو در تمام سرتیترها**: یافتن محتوا در تمام سطوح سرتیترها، نه فقط عنوان صفحات
|
||||
- **دقت بهتر نتایج**: مدیریت بهتر عنوانها و دقت پیونددهی
|
||||
- **ناوبری ثابت نتایج**: نتایج جستجو اکنون به بخشهای صحیح صفحه پیوند میخورند
|
||||
|
||||
با تشکر ویژه از [@ldez](https://github.com/ldez) برای پیشبرد قابلیتهای جستجو!
|
||||
|
||||

|
||||
|
||||
### پشتیبانی از llms.txt
|
||||
|
||||
Hextra اکنون از فرمت خروجی [llms.txt](https://llmstxt.org/) برای سایت شما پشتیبانی میکند، که سایت شما را برای ابزارهای هوش مصنوعی و مدلهای زبانی برای زمینه و مرجع قابل دسترستر میسازد.
|
||||
|
||||
```yaml {filename="hugo.yaml"}
|
||||
outputs:
|
||||
home: [html, llms]
|
||||
```
|
||||
|
||||
این یک فایل `llms.txt` در ریشه سایت شما ایجاد میکند.
|
||||
|
||||

|
||||
|
||||
### هایلایت کردن اسکرول فهرست مطالب
|
||||
|
||||
فهرست مطالب اکنون بهطور خودکار بخش فعلی را هنگام اسکرول صفحه هایلایت میکند، که ناوبری را شهودیتر میسازد.
|
||||
|
||||

|
||||
|
||||
### تبدیل همگام تبها
|
||||
|
||||
تبهایی با موارد یکسان اکنون در سراسر صفحه همگام میشوند. هنگامی که همگامسازی فعال است، انتخاب یک تب تمام گروههای تب که لیست موارد یکسانی دارند را بهروزرسانی میکند (و انتخاب شما به خاطر سپرده میشود).
|
||||
|
||||
```yaml {filename="hugo.yaml"}
|
||||
params:
|
||||
page:
|
||||
tabs:
|
||||
sync: true
|
||||
```
|
||||
|
||||
### صفحهبندی لیست وبلاگ
|
||||
|
||||
کنترلهای صفحهبندی پایه به صفحات لیست وبلاگ اضافه شدهاند.
|
||||
|
||||
```yaml {filename="hugo.yaml"}
|
||||
params:
|
||||
blog:
|
||||
list:
|
||||
pagerSize: 20 # پستها در هر صفحه
|
||||
```
|
||||
|
||||

|
||||
|
||||
### پشتیبانی از MathJax
|
||||
|
||||
عبارات ریاضی را با [MathJax](https://www.mathjax.org/) در کنار پشتیبانی پیشفرض KaTeX رندر کنید. موتوری را انتخاب کنید که بهترین تناسب را با نیازهای شما دارد.
|
||||
|
||||
```yaml {filename="hugo.yaml"}
|
||||
params:
|
||||
math:
|
||||
engine: "mathjax" # پیشفرض "katex" است
|
||||
```
|
||||
|
||||
## بهبودهای فنی
|
||||
|
||||
### چارچوب و سیستم ساخت
|
||||
|
||||
- **مهاجرت به Tailwind CSS v4**: مهاجرت کامل به [Tailwind CSS v4](https://tailwindcss.com/blog/tailwindcss-v4) با پشتیبانی بهبودیافته سفارشیسازی.
|
||||
- **سیستم قالب Hugo**: سازگار با [سیستم قالب جدید Hugo](https://gohugo.io/templates/new-templatesystem-overview/) (v0.146.0+) برای سازگاری آینده.
|
||||
- **رندر سمت سرور ریاضی**: مدیریت بهتر رندر معادلات ریاضی با استفاده از رندر بومی Hugo بهصورت پیشفرض.
|
||||
- **ارتقای FlexSearch 0.8**: ارتقای موتور جستجو [FlexSearch](https://github.com/nextapps-de/flexsearch) برای نتایج سریعتر و دقیقتر با رمزگذاری بهبودیافته محتوای CJK (چینی، ژاپنی، کرهای).
|
||||
- **مدیریت بهبودیافته داراییها**: داراییهای KaTeX و Mermaid از بارگیری از CDN یا محلی پشتیبانی میکنند
|
||||
|
||||
## بهبودهای کیفیت زندگی
|
||||
|
||||
- **تغییر دینامیک favicon**: بهروزرسانی خودکار favicon بر اساس ترجیحات طرح رنگ
|
||||
- **صفحهبندی معکوس**: نویسندگان اکنون میتوانند `reversePagination` را در front matter صفحه تنظیم کنند
|
||||
- **کنترل نمایهسازی گوگل**: پارامتر صفحه جدید برای مسدود کردن نمایهسازی گوگل در صورت نیاز
|
||||
- **بهبودهای مدیریت عرض**: کنترلهای طراحی پاسخگو بهتر از طریق متغیرهای CSS
|
||||
- **بهبودهای استایل**: استایلهای مدرن برای جدول Markdown و خط افقی
|
||||
|
||||
## رفع اشکالات و پایداری
|
||||
|
||||
- **همگامسازی تم Giscus**: نظرات اکنون به درستی تغییرات حالت تاریک/روشن را دنبال میکنند
|
||||
- **دقت نتایج جستجو**: رفع مشکلات پیونددهی و فرار عنوان در نتایج جستجو
|
||||
- **تبدیل تبها**: رفع مشکلات ناوبری در حالت غیرهمگام تب
|
||||
- **اسکرول فانتوم**: رفع رفتار ناخواسته اسکرول هنگام غیرفعال بودن پاورقی
|
||||
- **دسترسی تصویر**: جلوگیری از رندر تکراری متن alt
|
||||
- **رندر پیوند**: بهبود مدیریت URL پایه برای ساختارهای پیچیده سایت
|
||||
|
||||
---
|
||||
|
||||
## راهنمای مهاجرت
|
||||
|
||||
- [**نیازمندیهای نسخه Hugo**](#hugo-version-requirements): نیاز به Hugo v0.146.0+ (نسخه extended) دارد
|
||||
- [**تغییرات پیشوند کلاسهای CSS**](#css-class-prefix-changes): کلاسهای CSS کامپوننت اکنون از پیشوند سازگار `hextra-` استفاده میکنند
|
||||
- [**مدیریت داراییها**](#asset-management-for-katex-and-mermaid): داراییهای KaTeX و Mermaid اکنون در زمان ساخت دانلود میشوند
|
||||
- [**Tailwind CSS v4**](#tailwind-css-v4): کامپایل CSS داخلی اکنون از Tailwind CSS v4.x با پیشوند `hx:` استفاده میکند
|
||||
|
||||
#### نیازمندیهای نسخه Hugo
|
||||
|
||||
**تأثیر**: سایتهایی که از نسخههای قدیمی Hugo استفاده میکنند
|
||||
|
||||
Hextra v0.10.0 به دلیل پذیرش سیستم قالب جدید، نیاز به Hugo v0.146.0 یا بالاتر (نسخه extended) دارد.
|
||||
|
||||
**اقدام مورد نیاز**: قبل از ارتقای Hextra، Hugo را به v0.146.0+ بهروزرسانی کنید
|
||||
|
||||
#### تغییرات پیشوند کلاسهای CSS
|
||||
|
||||
**تأثیر**: سایتهایی با CSS سفارشی که کلاسهای کامپوننت Hextra را هدف قرار میدهند
|
||||
|
||||
Hextra v0.10.0 پیشوند سازگار `hextra-` را برای اکثر کلاسهای CSS کامپوننت معرفی میکند تا قابلیت نگهداری را بهبود بخشد و از تداخل با استایلهای کاربر جلوگیری کند.
|
||||
|
||||
**اقدام مورد نیاز**: اگر CSS سفارشی دارید که کامپوننتهای Hextra را هدف قرار میدهد، نام کلاسهای زیر را بهروزرسانی کنید:
|
||||
|
||||
| حوزه | قبل | بعد |
|
||||
| -------------------- | ---------------------------- | ------------------------------------------------- |
|
||||
| جستجو (ظرف) | `.search-wrapper` | `.hextra-search-wrapper` |
|
||||
| جستجو (ورودی) | `.search-input` | `.hextra-search-input` |
|
||||
| جستجو (نتایج) | `.search-results` | `.hextra-search-results` |
|
||||
| جستجو (عنوان) | `.search-wrapper .title` | `.hextra-search-wrapper .hextra-search-title` |
|
||||
| جستجو (مورد فعال) | `.search-wrapper .active` | `.hextra-search-wrapper .hextra-search-active` |
|
||||
| جستجو (بدون نتیجه) | `.search-wrapper .no-result` | `.hextra-search-wrapper .hextra-search-no-result` |
|
||||
| جستجو (پیشوند) | `.search-wrapper .prefix` | `.hextra-search-wrapper .hextra-search-prefix` |
|
||||
| جستجو (گزیده) | `.search-wrapper .excerpt` | `.hextra-search-wrapper .hextra-search-excerpt` |
|
||||
| جستجو (مطابقت) | `.search-wrapper .match` | `.hextra-search-wrapper .hextra-search-match` |
|
||||
| تارنما محو | `.nav-container-blur` | `.hextra-nav-container-blur` |
|
||||
| منوی همبرگر | `.hamburger-menu` | `.hextra-hamburger-menu` |
|
||||
| تغییر تم | `.theme-toggle` | `.hextra-theme-toggle` |
|
||||
| تغییر زبان | `.language-switcher` | `.hextra-language-switcher` |
|
||||
| ظرف نوار کناری | `.sidebar-container` | `.hextra-sidebar-container` |
|
||||
| مورد فعال نوار کناری | `.sidebar-active-item` | `.hextra-sidebar-active-item` |
|
||||
| نام فایل کد | `.filename` | `.hextra-code-filename` |
|
||||
| آیکون کپی | `.copy-icon` | `.hextra-copy-icon` |
|
||||
| آیکون موفقیت | `.success-icon` | `.hextra-success-icon` |
|
||||
| مراحل | `.steps` | `.hextra-steps` |
|
||||
|
||||
#### مدیریت داراییها برای KaTeX و Mermaid
|
||||
|
||||
**تأثیر**: سایتهایی که از KaTeX یا Mermaid استفاده میکنند
|
||||
|
||||
Hextra v0.10.0 اکنون داراییهای KaTeX و Mermaid را از CDN در زمان ساخت دانلود میکند.
|
||||
|
||||
**چه چیزی تغییر کرده است:**
|
||||
|
||||
- فرآیند ساخت اکنون نیاز به دسترسی به اینترنت برای دانلود این داراییها دارد
|
||||
- دیگر پس از ساخت، فراخوانی CDN خارجی برای این داراییها وجود ندارد
|
||||
|
||||
**اقدام مورد نیاز**:
|
||||
|
||||
- مطمئن شوید که محیط ساخت شما دسترسی به اینترنت برای دانلود داراییها دارد
|
||||
- سایتهای در محیطهای ایزوله ممکن است نیاز به پیشدانلود این داراییها و پیکربندی Hextra برای بارگیری آنها داشته باشند
|
||||
|
||||
#### Tailwind CSS v4
|
||||
|
||||
**تأثیر**: سایتهایی با CSS سفارشی گسترده که کلاسهای Tailwind Hextra `hx-*` را هدف قرار میدهند
|
||||
|
||||
در حالی که Hextra مهاجرت Tailwind CSS v4 را به صورت داخلی مدیریت میکند، سایتهایی با سفارشیسازیهای سنگین ممکن است نیاز به تنظیمات بیشتری داشته باشند.
|
||||
|
||||
**چه چیزی تغییر کرده است:**
|
||||
|
||||
- کامپایل CSS داخلی اکنون از Tailwind CSS v4.x استفاده میکند
|
||||
- کلاسهای ابزار اکنون با پیشوند `hx:` به جای `hx-` هستند
|
||||
|
||||
## مشارکتکنندگان
|
||||
|
||||
این انتشار با مشارکتهای 10 مشارکتکننده جدید ممکن شد:
|
||||
|
||||
- [@oosquare](https://github.com/oosquare) - فونتهای KaTeX، قلابهای رندر تصویر، بهبودهای مدیریت پیوند
|
||||
- [@Zabriskije](https://github.com/Zabriskije) - رفع اسکرول فانتوم
|
||||
- [@miniwater](https://github.com/miniwater) - مرکزسازی پاورقی سفارشی، بهبودهای متن alt تصویر
|
||||
- [@MattDodsonEnglish](https://github.com/MattDodsonEnglish) - کنترلهای نمایهسازی گوگل، مستندات OpenGraph
|
||||
- [@KStocky](https://github.com/KStocky) - ویژگی صفحهبندی معکوس
|
||||
- [@PrintN](https://github.com/PrintN) - اضافه شدن نمایش مستندات
|
||||
- [@hobobandy](https://github.com/hobobandy) - بهبودهای فاصله عنوان
|
||||
- [@dlwocks31](https://github.com/dlwocks31) - بهروزرسانی ترجمه کرهای
|
||||
- [@TwoAnts](https://github.com/TwoAnts) - رفع تغییر تم Giscus
|
||||
- [@ldez](https://github.com/ldez) - بهبودهای جستجو و رفع اشکالات
|
||||
|
||||
با تشکر ویژه از مشارکتکنندگان بازگشتی [@deining](https://github.com/deining) و [@yuri1969](https://github.com/yuri1969) برای حمایت مستمرشان در مستندات، ترجمهها و بهبودهای فنی.
|
||||
|
||||
**تغییرات کامل**: https://github.com/imfing/hextra/compare/v0.9.7...v0.10.0
|
||||
@@ -0,0 +1,247 @@
|
||||
---
|
||||
title: "Hextra v0.10"
|
||||
date: 2025-08-14
|
||||
authors:
|
||||
- name: imfing
|
||||
link: https://github.com/imfing
|
||||
image: https://github.com/imfing.png
|
||||
tags:
|
||||
- Release
|
||||
---
|
||||
|
||||
Hextra v0.10.0 は、新機能、アーキテクチャの刷新、利便性向上を詰め込んだ大きなリリースです。
|
||||
|
||||
<!--more-->
|
||||
|
||||
また、10名の[新規コントリビューター](#contributors)からの貢献と、長らく要望のあった機能の実装も含まれています。
|
||||
|
||||
## アップグレードガイド
|
||||
|
||||
> [!IMPORTANT]
|
||||
> **破壊的変更**: このリリースにはいくつかの破壊的変更が含まれています。アップグレード前にチェックリストと[移行ガイド](#migration-guide)を確認してください。
|
||||
|
||||
v0.10.0 にアップグレードする前に、以下を確認してください:
|
||||
|
||||
- Hugo v0.146.0+ (extended 版) がインストールされていること
|
||||
- カスタムCSSのクラス名変更を確認 ( [CSSクラスプレフィックス変更](#css-class-prefix-changes) と [Tailwind CSS v4](#tailwind-css-v4) を参照)
|
||||
- LaTeX や Mermaid を使用する場合、ビルド環境がアセットダウンロードのためインターネットに接続できること
|
||||
|
||||
準備が整ったら、Hugoモジュールを更新します:
|
||||
|
||||
```bash
|
||||
hugo mod get -u github.com/imfing/hextra@v0.10.0
|
||||
```
|
||||
|
||||
## 新機能
|
||||
|
||||
このリリースの主な新機能は以下の通りです:
|
||||
|
||||
- [**ナビゲーションバーのドロップダウンメニューサポート**](#dropdown-menu-support-in-navbar): 階層型ナビゲーションメニューの作成
|
||||
- [**検索機能の強化**](#enhanced-search-experience): すべての見出しを対象にした精度向上した検索
|
||||
- [**llms.txt サポート**](#llmstxt-support): AI向けサイトアウトラインの生成
|
||||
- [**目次のスクロールハイライト**](#table-of-contents-scroll-highlighting): ページスクロール中の見出し自動ハイライト
|
||||
- [**タブの同期切り替え**](#synchronized-tab-switching): 複数のタブグループ間でのタブ選択の同期
|
||||
- [**ブログ一覧のページネーション**](#blog-list-pagination): ブログ一覧ページへのページネーションコントロール追加
|
||||
- [**MathJax サポート**](#mathjax-support): KaTeXに加えてMathJaxを数式レンダリングエンジンとして選択可能
|
||||
|
||||
### ナビゲーションバーのドロップダウンメニューサポート
|
||||
|
||||
ナビゲーションバーにドロップダウンメニューを作成し、ナビゲーション項目を整理できます。
|
||||
|
||||
```yaml {filename="hugo.yaml"}
|
||||
menu:
|
||||
main:
|
||||
- identifier: products
|
||||
name: "製品"
|
||||
- name: "製品A"
|
||||
parent: products
|
||||
url: "/product-a"
|
||||
- name: "製品B"
|
||||
parent: products
|
||||
url: "/product-b"
|
||||
```
|
||||
|
||||

|
||||
|
||||
### 検索機能の強化
|
||||
|
||||
- **すべての見出しを検索**: ページタイトルだけでなく、すべてのレベルの見出しからコンテンツを検索
|
||||
- **検索結果の精度向上**: タイトル処理とリンク精度の改善
|
||||
- **結果ナビゲーションの修正**: 検索結果が正しいページセクションにリンクするようになりました
|
||||
|
||||
検索機能の強化に貢献してくださった [@ldez](https://github.com/ldez) に感謝します!
|
||||
|
||||

|
||||
|
||||
### llms.txt サポート
|
||||
|
||||
Hextra はサイトの [llms.txt](https://llmstxt.org/) 出力形式をサポートし、AIツールや言語モデルがコンテキストや参照のためにサイトをよりアクセスしやすくします。
|
||||
|
||||
```yaml {filename="hugo.yaml"}
|
||||
outputs:
|
||||
home: [html, llms]
|
||||
```
|
||||
|
||||
これにより、サイトのルートに `llms.txt` ファイルが生成されます。
|
||||
|
||||

|
||||
|
||||
### 目次のスクロールハイライト
|
||||
|
||||
ページをスクロールする際に、目次が現在のセクションを自動的にハイライトするようになり、ナビゲーションがより直感的になりました。
|
||||
|
||||

|
||||
|
||||
### タブの同期切り替え
|
||||
|
||||
同じ項目を持つタブはページ全体で同期されるようになりました。同期が有効な場合、タブを選択すると同じ項目リストを共有するすべてのタブグループが更新されます(選択内容は記憶されます)。
|
||||
|
||||
```yaml {filename="hugo.yaml"}
|
||||
params:
|
||||
page:
|
||||
tabs:
|
||||
sync: true
|
||||
```
|
||||
|
||||
### ブログ一覧のページネーション
|
||||
|
||||
ブログ一覧ページに基本的なページネーションコントロールが追加されました。
|
||||
|
||||
```yaml {filename="hugo.yaml"}
|
||||
params:
|
||||
blog:
|
||||
list:
|
||||
pagerSize: 20 # 1ページあたりの投稿数
|
||||
```
|
||||
|
||||

|
||||
|
||||
### MathJax サポート
|
||||
|
||||
デフォルトのKaTeXサポートに加えて、[MathJax](https://www.mathjax.org/) で数式をレンダリングできるようになりました。ニーズに合ったエンジンを選択できます。
|
||||
|
||||
```yaml {filename="hugo.yaml"}
|
||||
params:
|
||||
math:
|
||||
engine: "mathjax" # デフォルトは "katex"
|
||||
```
|
||||
|
||||
## 技術的改善
|
||||
|
||||
### フレームワークとビルドシステム
|
||||
|
||||
- **Tailwind CSS v4 移行**: [Tailwind CSS v4](https://tailwindcss.com/blog/tailwindcss-v4) への完全移行とカスタマイズサポートの改善
|
||||
- **Hugoテンプレートシステム**: Hugoの[新しいテンプレートシステム](https://gohugo.io/templates/new-templatesystem-overview/) (v0.146.0+) への対応
|
||||
- **数式のサーバーサイドレンダリング**: Hugoネイティブレンダリングを使用した数式レンダリングの改善
|
||||
- **FlexSearch 0.8 アップグレード**: 検索エンジン [FlexSearch](https://github.com/nextapps-de/flexsearch) のアップグレードにより、CJK (中国語、日本語、韓国語) コンテンツのエンコーディング改善と高速化・精度向上
|
||||
- **アセット管理の強化**: KaTeXとMermaidアセットのCDNまたはローカルからの読み込みサポート
|
||||
|
||||
## 利便性の向上
|
||||
|
||||
- **動的ファビコン切り替え**: カラースキーム設定に基づくファビコンの自動更新
|
||||
- **逆順ページネーション**: ページフロントマターで `reversePagination` を設定可能に
|
||||
- **Googleインデックス制御**: Googleのインデックスをブロックする新しいページパラメータ
|
||||
- **幅の処理改善**: CSS変数によるレスポンシブデザイン制御の強化
|
||||
- **スタイリング改善**: Markdownテーブルと水平線のモダンなスタイル
|
||||
|
||||
## バグ修正と安定性
|
||||
|
||||
- **Giscusテーマ同期**: コメントがダーク/ライトモードの切り替えに正しく追従
|
||||
- **検索結果の精度**: 検索結果のリンク問題とタイトルエスケープの修正
|
||||
- **タブ切り替え**: 非同期タブモードでのナビゲーション問題の解決
|
||||
- **ファントムスクロール**: フッター無効時の不要なスクロール動作の修正
|
||||
- **画像アクセシビリティ**: 重複したaltテキストレンダリングの防止
|
||||
- **リンクレンダリング**: 複雑なサイト構造におけるベースURL処理の改善
|
||||
|
||||
---
|
||||
|
||||
## 移行ガイド
|
||||
|
||||
- [**Hugoバージョン要件**](#hugo-version-requirements): Hugo v0.146.0+ (extended版) が必要
|
||||
- [**CSSクラスプレフィックス変更**](#css-class-prefix-changes): コンポーネントCSSクラスに一貫した `hextra-` プレフィックスを採用
|
||||
- [**アセット管理**](#asset-management-for-katex-and-mermaid): KaTeXとMermaidアセットはビルド時にダウンロード
|
||||
- [**Tailwind CSS v4**](#tailwind-css-v4): 内部CSSコンパイルにTailwind CSS v4.xを採用し `hx:` プレフィックスを使用
|
||||
|
||||
#### Hugoバージョン要件
|
||||
|
||||
**影響**: 古いHugoバージョンで動作しているサイト
|
||||
|
||||
Hextra v0.10.0 は新しいテンプレートシステムを採用しているため、Hugo v0.146.0以降 (extended版) が必要です。
|
||||
|
||||
**必要な対応**: Hextraをアップグレードする前にHugoをv0.146.0+に更新
|
||||
|
||||
#### CSSクラスプレフィックス変更
|
||||
|
||||
**影響**: HextraコンポーネントクラスをターゲットにしたカスタムCSSがあるサイト
|
||||
|
||||
Hextra v0.10.0 では、メンテナンス性向上とユーザースタイルとの衝突防止のため、ほとんどのコンポーネントCSSクラスに一貫した `hextra-` プレフィックスを導入しました。
|
||||
|
||||
**必要な対応**: HextraコンポーネントをターゲットにしたカスタムCSSがある場合、以下のクラス名を更新してください:
|
||||
|
||||
| 領域 | 変更前 | 変更後 |
|
||||
| -------------------- | ---------------------------- | ------------------------------------------------- |
|
||||
| 検索 (コンテナ) | `.search-wrapper` | `.hextra-search-wrapper` |
|
||||
| 検索 (入力) | `.search-input` | `.hextra-search-input` |
|
||||
| 検索 (結果) | `.search-results` | `.hextra-search-results` |
|
||||
| 検索 (タイトル) | `.search-wrapper .title` | `.hextra-search-wrapper .hextra-search-title` |
|
||||
| 検索 (アクティブ項目)| `.search-wrapper .active` | `.hextra-search-wrapper .hextra-search-active` |
|
||||
| 検索 (結果なし) | `.search-wrapper .no-result` | `.hextra-search-wrapper .hextra-search-no-result` |
|
||||
| 検索 (プレフィックス)| `.search-wrapper .prefix` | `.hextra-search-wrapper .hextra-search-prefix` |
|
||||
| 検索 (抜粋) | `.search-wrapper .excerpt` | `.hextra-search-wrapper .hextra-search-excerpt` |
|
||||
| 検索 (マッチ) | `.search-wrapper .match` | `.hextra-search-wrapper .hextra-search-match` |
|
||||
| ナビバーブラー | `.nav-container-blur` | `.hextra-nav-container-blur` |
|
||||
| ハンバーガーメニュー | `.hamburger-menu` | `.hextra-hamburger-menu` |
|
||||
| テーマトグル | `.theme-toggle` | `.hextra-theme-toggle` |
|
||||
| 言語スイッチャー | `.language-switcher` | `.hextra-language-switcher` |
|
||||
| サイドバーコンテナ | `.sidebar-container` | `.hextra-sidebar-container` |
|
||||
| サイドバーアクティブ項目 | `.sidebar-active-item` | `.hextra-sidebar-active-item` |
|
||||
| コードファイル名 | `.filename` | `.hextra-code-filename` |
|
||||
| コピーアイコン | `.copy-icon` | `.hextra-copy-icon` |
|
||||
| 成功アイコン | `.success-icon` | `.hextra-success-icon` |
|
||||
| ステップ | `.steps` | `.hextra-steps` |
|
||||
|
||||
#### KaTeXとMermaidのアセット管理
|
||||
|
||||
**影響**: KaTeXまたはMermaidを使用しているサイト
|
||||
|
||||
Hextra v0.10.0 では、KaTeXとMermaidアセットをビルド時にCDNからダウンロードするようになりました。
|
||||
|
||||
**変更点:**
|
||||
|
||||
- これらのアセットをダウンロードするため、ビルドプロセスでインターネットアクセスが必要
|
||||
- ビルド後はこれらのアセットに対する外部CDN呼び出しが不要
|
||||
|
||||
**必要な対応**:
|
||||
|
||||
- アセットをダウンロードするため、ビルド環境がインターネットに接続できることを確認
|
||||
- エアギャップ環境のサイトでは、これらのアセットを事前にダウンロードし、Hextraがそれらを読み込むように設定する必要がある場合があります
|
||||
|
||||
#### Tailwind CSS v4
|
||||
|
||||
**影響**: HextraのTailwindクラス `hx-*` を広範囲にカスタマイズしているサイト
|
||||
|
||||
HextraはTailwind CSS v4移行を内部で処理しますが、高度にカスタマイズされたサイトでは追加の調整が必要な場合があります。
|
||||
|
||||
**変更点:**
|
||||
|
||||
- 内部CSSコンパイルにTailwind CSS v4.xを使用
|
||||
- ユーティリティクラスのプレフィックスが `hx-` から `hx:` に変更
|
||||
|
||||
## コントリビューター
|
||||
|
||||
このリリースは、10名の新規コントリビューターの貢献によって実現されました:
|
||||
|
||||
- [@oosquare](https://github.com/oosquare) - KaTeXフォント、画像レンダーフック、リンク処理の改善
|
||||
- [@Zabriskije](https://github.com/Zabriskije) - ファントムスクロールの修正
|
||||
- [@miniwater](https://github.com/miniwater) - カスタムフッターの中央揃え、画像altテキストの改善
|
||||
- [@MattDodsonEnglish](https://github.com/MattDodsonEnglish) - Googleインデックス制御、OpenGraphドキュメント
|
||||
- [@KStocky](https://github.com/KStocky) - 逆順ページネーション機能
|
||||
- [@PrintN](https://github.com/PrintN) - ドキュメントショーケースの追加
|
||||
- [@hobobandy](https://github.com/hobobandy) - タイトル間隔の改善
|
||||
- [@dlwocks31](https://github.com/dlwocks31) - 韓国語翻訳の更新
|
||||
- [@TwoAnts](https://github.com/TwoAnts) - Giscusテーマ切り替えの修正
|
||||
- [@ldez](https://github.com/ldez) - 検索機能の改善とバグ修正
|
||||
|
||||
継続的なサポート、ドキュメント、翻訳、技術的改善を提供してくださった [@deining](https://github.com/deining) と [@yuri1969](https://github.com/yuri1969) にも感謝します。
|
||||
|
||||
**完全な変更履歴**: https://github.com/imfing/hextra/compare/v0.9.7...v0.10.0
|
||||
@@ -0,0 +1,247 @@
|
||||
---
|
||||
title: "Hextra v0.10"
|
||||
date: 2025-08-14
|
||||
authors:
|
||||
- name: imfing
|
||||
link: https://github.com/imfing
|
||||
image: https://github.com/imfing.png
|
||||
tags:
|
||||
- Release
|
||||
---
|
||||
|
||||
Hextra v0.10.0 is a big release packed with new capabilities, architectural upgrades, and quality-of-life improvements.
|
||||
|
||||
<!--more-->
|
||||
|
||||
It also includes contributions from 10 [new contributors](#contributors) and addresses long-standing community requests.
|
||||
|
||||
## Upgrade Guide
|
||||
|
||||
> [!IMPORTANT]
|
||||
> **Breaking Changes**: This release includes several breaking changes. Please review the checklist and the [Migration Guide](#migration-guide) before upgrading.
|
||||
|
||||
Before upgrading to v0.10.0, ensure that you have:
|
||||
|
||||
- Hugo v0.146.0+ (extended version) installed
|
||||
- Reviewed custom CSS for class name changes (see [CSS Class Prefix Changes](#css-class-prefix-changes) and [Tailwind CSS v4](#tailwind-css-v4))
|
||||
- Verified that build environment has internet access for asset downloads when LaTeX and/or Mermaid is used
|
||||
|
||||
Once ready, update the Hugo module:
|
||||
|
||||
```bash
|
||||
hugo mod get -u github.com/imfing/hextra@v0.10.0
|
||||
```
|
||||
|
||||
## New Features
|
||||
|
||||
Here is a list of notable new features in this release:
|
||||
|
||||
- [**Dropdown Menu Support in Navbar**](#dropdown-menu-support-in-navbar): create hierarchical navigation menus
|
||||
- [**Enhanced Search Experience**](#enhanced-search-experience): improved search across all headings with better accuracy
|
||||
- [**llms.txt Support**](#llmstxt-support): generate AI-friendly site outline
|
||||
- [**Table of Contents Scroll Highlighting**](#table-of-contents-scroll-highlighting): automatic heading highlighting during page scroll
|
||||
- [**Synchronized Tab Switching**](#synchronized-tab-switching): synchronize tab selections across multiple tab groups
|
||||
- [**Blog List Pagination**](#blog-list-pagination): add pagination controls to blog listing pages
|
||||
- [**MathJax Support**](#mathjax-support): alternative math rendering engine alongside KaTeX
|
||||
|
||||
### Dropdown Menu Support in Navbar
|
||||
|
||||
Create dropdown menus in your navigation bar for better navigation items organization.
|
||||
|
||||
```yaml {filename="hugo.yaml"}
|
||||
menu:
|
||||
main:
|
||||
- identifier: products
|
||||
name: "Products"
|
||||
- name: "Product A"
|
||||
parent: products
|
||||
url: "/product-a"
|
||||
- name: "Product B"
|
||||
parent: products
|
||||
url: "/product-b"
|
||||
```
|
||||
|
||||

|
||||
|
||||
### Enhanced Search Experience
|
||||
|
||||
- **Search in all headings**: find content across all heading levels, not just page titles
|
||||
- **Improved result accuracy**: better title handling and linking precision
|
||||
- **Fixed result navigation**: search results now link to the correct page sections
|
||||
|
||||
Huge thanks to [@ldez](https://github.com/ldez) for pushing the search capabilities forward!
|
||||
|
||||

|
||||
|
||||
### llms.txt Support
|
||||
|
||||
Hextra now supports [llms.txt](https://llmstxt.org/) output format for your site, making your site more accessible to AI tools and language models for context and reference.
|
||||
|
||||
```yaml {filename="hugo.yaml"}
|
||||
outputs:
|
||||
home: [html, llms]
|
||||
```
|
||||
|
||||
This will generate an `llms.txt` file at your site's root.
|
||||
|
||||

|
||||
|
||||
### Table of Contents Scroll Highlighting
|
||||
|
||||
The table of contents now automatically highlights the current section as you scroll through the page, making navigation more intuitive.
|
||||
|
||||

|
||||
|
||||
### Synchronized Tab Switching
|
||||
|
||||
Tabs with the same items now synchronize across the page. When sync is enabled, selecting a tab updates all tab groups that share the same items list (and your selection is remembered).
|
||||
|
||||
```yaml {filename="hugo.yaml"}
|
||||
params:
|
||||
page:
|
||||
tabs:
|
||||
sync: true
|
||||
```
|
||||
|
||||
### Blog List Pagination
|
||||
|
||||
Basic pagination controls have been added to blog listing pages.
|
||||
|
||||
```yaml {filename="hugo.yaml"}
|
||||
params:
|
||||
blog:
|
||||
list:
|
||||
pagerSize: 20 # Posts per page
|
||||
```
|
||||
|
||||

|
||||
|
||||
### MathJax Support
|
||||
|
||||
Render mathematical expressions with [MathJax](https://www.mathjax.org/) alongside the default KaTeX support. Choose the engine that best fits your needs.
|
||||
|
||||
```yaml {filename="hugo.yaml"}
|
||||
params:
|
||||
math:
|
||||
engine: "mathjax" # default is "katex"
|
||||
```
|
||||
|
||||
## Technical Improvements
|
||||
|
||||
### Framework and Build System
|
||||
|
||||
- **Tailwind CSS v4 Migration**: complete migration to [Tailwind CSS v4](https://tailwindcss.com/blog/tailwindcss-v4) with improved customization support.
|
||||
- **Hugo Template System**: adapted to Hugo's [new template system](https://gohugo.io/templates/new-templatesystem-overview/) (v0.146.0+) for future compatibility.
|
||||
- **Math Server-Side Rendering**: better handling of math equation rendering using Hugo native rendering by default.
|
||||
- **FlexSearch 0.8 Upgrade**: upgraded search engine [FlexSearch](https://github.com/nextapps-de/flexsearch) for faster, more accurate results with improved CJK (Chinese, Japanese, Korean) content encoding.
|
||||
- **Enhanced Asset Management**: KaTeX and Mermaid assets support loading from CDN or local
|
||||
|
||||
## Quality of Life Improvements
|
||||
|
||||
- **Dynamic favicon switching**: automatic favicon updates based on color scheme preferences
|
||||
- **Reverse pagination**: authors can now set `reversePagination` in page front matter
|
||||
- **Google indexing control**: new page parameter to block Google indexing when needed
|
||||
- **Width handling improvements**: better responsive design controls via CSS variables
|
||||
- **Styling improvements**: modern styles for Markdown table and horizontal line
|
||||
|
||||
## Bug Fixes and Stability
|
||||
|
||||
- **Giscus theme synchronization**: comments now properly follow dark/light mode switches
|
||||
- **Search result accuracy**: fixed linking issues and title escaping in search results
|
||||
- **Tab switching**: resolved navigation issues in non-synced tab mode
|
||||
- **Phantom scrolling**: fixed unwanted scroll behavior when footer is disabled
|
||||
- **Image accessibility**: prevented duplicate alt text rendering
|
||||
- **Link rendering**: improved base URL handling for complex site structures
|
||||
|
||||
---
|
||||
|
||||
## Migration Guide
|
||||
|
||||
- [**Hugo Version Requirements**](#hugo-version-requirements): Requires Hugo v0.146.0+ (extended version)
|
||||
- [**CSS Class Prefix Changes**](#css-class-prefix-changes): Component CSS classes now use consistent `hextra-` prefixing
|
||||
- [**Asset Management**](#asset-management-for-katex-and-mermaid): KaTeX and Mermaid assets now download during build time
|
||||
- [**Tailwind CSS v4**](#tailwind-css-v4): Internal CSS compilation now uses Tailwind CSS v4.x with `hx:` prefix
|
||||
|
||||
#### Hugo Version Requirements
|
||||
|
||||
**Impact**: Sites running older Hugo versions
|
||||
|
||||
Hextra v0.10.0 requires Hugo v0.146.0 or later (extended version) due to the new template system adoption.
|
||||
|
||||
**Action required**: Update Hugo to v0.146.0+ before upgrading Hextra
|
||||
|
||||
#### CSS Class Prefix Changes
|
||||
|
||||
**Impact**: Sites with custom CSS targeting Hextra component classes
|
||||
|
||||
Hextra v0.10.0 introduces consistent `hextra-` prefixing for majority of component CSS classes to improve maintainability and prevent conflicts with user styles.
|
||||
|
||||
**Action required**: If you have custom CSS targeting Hextra components, update the following class names:
|
||||
|
||||
| Area | Before | After |
|
||||
| -------------------- | ---------------------------- | ------------------------------------------------- |
|
||||
| Search (container) | `.search-wrapper` | `.hextra-search-wrapper` |
|
||||
| Search (input) | `.search-input` | `.hextra-search-input` |
|
||||
| Search (results) | `.search-results` | `.hextra-search-results` |
|
||||
| Search (title) | `.search-wrapper .title` | `.hextra-search-wrapper .hextra-search-title` |
|
||||
| Search (active item) | `.search-wrapper .active` | `.hextra-search-wrapper .hextra-search-active` |
|
||||
| Search (no result) | `.search-wrapper .no-result` | `.hextra-search-wrapper .hextra-search-no-result` |
|
||||
| Search (prefix) | `.search-wrapper .prefix` | `.hextra-search-wrapper .hextra-search-prefix` |
|
||||
| Search (excerpt) | `.search-wrapper .excerpt` | `.hextra-search-wrapper .hextra-search-excerpt` |
|
||||
| Search (match) | `.search-wrapper .match` | `.hextra-search-wrapper .hextra-search-match` |
|
||||
| Navbar blur | `.nav-container-blur` | `.hextra-nav-container-blur` |
|
||||
| Hamburger menu | `.hamburger-menu` | `.hextra-hamburger-menu` |
|
||||
| Theme toggle | `.theme-toggle` | `.hextra-theme-toggle` |
|
||||
| Language switcher | `.language-switcher` | `.hextra-language-switcher` |
|
||||
| Sidebar container | `.sidebar-container` | `.hextra-sidebar-container` |
|
||||
| Sidebar active item | `.sidebar-active-item` | `.hextra-sidebar-active-item` |
|
||||
| Code filename | `.filename` | `.hextra-code-filename` |
|
||||
| Copy icon | `.copy-icon` | `.hextra-copy-icon` |
|
||||
| Success icon | `.success-icon` | `.hextra-success-icon` |
|
||||
| Steps | `.steps` | `.hextra-steps` |
|
||||
|
||||
#### Asset Management for KaTeX and Mermaid
|
||||
|
||||
**Impact**: Sites using KaTeX or Mermaid
|
||||
|
||||
Hextra v0.10.0 now downloads KaTeX and Mermaid assets from CDN during build time.
|
||||
|
||||
**What's changed:**
|
||||
|
||||
- Build process now requires internet access to download these assets
|
||||
- No more external CDN calls for these assets after build
|
||||
|
||||
**Action required**:
|
||||
|
||||
- Ensure your build environment has internet access to download assets
|
||||
- Sites in air-gapped environments may need to pre-download these assets and configure Hextra to load them
|
||||
|
||||
#### Tailwind CSS v4
|
||||
|
||||
**Impact**: Sites with extensive custom CSS targeting Hextra Tailwind classes `hx-*`
|
||||
|
||||
While Hextra handles the Tailwind CSS v4 migration internally, sites with heavy customizations may need further adjustments.
|
||||
|
||||
**What's changed:**
|
||||
|
||||
- Internal CSS compilation now uses Tailwind CSS v4.x
|
||||
- Utility classes now prefix with `hx:` rather than `hx-`
|
||||
|
||||
## Contributors
|
||||
|
||||
This release was made possible by contributions from 10 new contributors:
|
||||
|
||||
- [@oosquare](https://github.com/oosquare) - KaTeX fonts, image render hooks, link handling improvements
|
||||
- [@Zabriskije](https://github.com/Zabriskije) - Phantom scroll fix
|
||||
- [@miniwater](https://github.com/miniwater) - Custom footer centering, image alt text improvements
|
||||
- [@MattDodsonEnglish](https://github.com/MattDodsonEnglish) - Google indexing controls, OpenGraph documentation
|
||||
- [@KStocky](https://github.com/KStocky) - Reverse pagination feature
|
||||
- [@PrintN](https://github.com/PrintN) - Documentation showcase additions
|
||||
- [@hobobandy](https://github.com/hobobandy) - Title spacing improvements
|
||||
- [@dlwocks31](https://github.com/dlwocks31) - Korean translation updates
|
||||
- [@TwoAnts](https://github.com/TwoAnts) - Giscus theme switching fix
|
||||
- [@ldez](https://github.com/ldez) - Search improvements and bug fixes
|
||||
|
||||
Additional thanks to returning contributors [@deining](https://github.com/deining) and [@yuri1969](https://github.com/yuri1969) for their continued support with documentation, translations, and technical improvements.
|
||||
|
||||
**Full Changelog**: https://github.com/imfing/hextra/compare/v0.9.7...v0.10.0
|
||||
@@ -0,0 +1,247 @@
|
||||
---
|
||||
title: "Hextra v0.10"
|
||||
date: 2025-08-14
|
||||
authors:
|
||||
- name: imfing
|
||||
link: https://github.com/imfing
|
||||
image: https://github.com/imfing.png
|
||||
tags:
|
||||
- Release
|
||||
---
|
||||
|
||||
Hextra v0.10.0 是一个重大版本更新,包含多项新功能、架构升级和使用体验优化。
|
||||
|
||||
<!--more-->
|
||||
|
||||
本次更新还包含了来自 10 位 [新贡献者](#contributors) 的代码提交,并解决了社区长期期待的功能需求。
|
||||
|
||||
## 升级指南
|
||||
|
||||
> [!IMPORTANT]
|
||||
> **破坏性变更**:此版本包含多项不兼容改动。升级前请仔细阅读检查清单和 [迁移指南](#migration-guide)。
|
||||
|
||||
升级至 v0.10.0 前,请确保:
|
||||
|
||||
- 已安装 Hugo v0.146.0+(扩展版)
|
||||
- 检查自定义 CSS 的类名变更(参见 [CSS 类前缀变更](#css-class-prefix-changes) 和 [Tailwind CSS v4](#tailwind-css-v4))
|
||||
- 确认构建环境可访问互联网以下载 LaTeX 和/或 Mermaid 资源
|
||||
|
||||
准备就绪后,更新 Hugo 模块:
|
||||
|
||||
```bash
|
||||
hugo mod get -u github.com/imfing/hextra@v0.10.0
|
||||
```
|
||||
|
||||
## 新功能
|
||||
|
||||
以下是本版本值得关注的新特性:
|
||||
|
||||
- [**导航栏下拉菜单支持**](#dropdown-menu-support-in-navbar):创建层级导航菜单
|
||||
- [**增强搜索体验**](#enhanced-search-experience):改进全标题搜索精度
|
||||
- [**llms.txt 支持**](#llmstxt-support):生成 AI 友好的站点大纲
|
||||
- [**目录滚动高亮**](#table-of-contents-scroll-highlighting):滚动时自动高亮当前章节
|
||||
- [**同步标签页切换**](#synchronized-tab-switching):跨多组标签页同步选择状态
|
||||
- [**博客列表分页**](#blog-list-pagination):为博客列表添加分页控件
|
||||
- [**MathJax 支持**](#mathjax-support):在 KaTeX 外新增数学公式渲染引擎
|
||||
|
||||
### 导航栏下拉菜单支持
|
||||
|
||||
在导航栏中创建下拉菜单,优化导航项组织方式。
|
||||
|
||||
```yaml {filename="hugo.yaml"}
|
||||
menu:
|
||||
main:
|
||||
- identifier: products
|
||||
name: "产品"
|
||||
- name: "产品A"
|
||||
parent: products
|
||||
url: "/product-a"
|
||||
- name: "产品B"
|
||||
parent: products
|
||||
url: "/product-b"
|
||||
```
|
||||
|
||||

|
||||
|
||||
### 增强搜索体验
|
||||
|
||||
- **全标题搜索**:可搜索所有层级标题内容,不限于页面标题
|
||||
- **提升结果精度**:改进标题处理和链接准确性
|
||||
- **修复结果导航**:搜索结果现在能正确跳转到对应章节
|
||||
|
||||
特别感谢 [@ldez](https://github.com/ldez) 推动搜索功能升级!
|
||||
|
||||

|
||||
|
||||
### llms.txt 支持
|
||||
|
||||
现支持生成 [llms.txt](https://llmstxt.org/) 格式输出,使站点内容更便于 AI 工具和语言模型获取上下文参考。
|
||||
|
||||
```yaml {filename="hugo.yaml"}
|
||||
outputs:
|
||||
home: [html, llms]
|
||||
```
|
||||
|
||||
这将在站点根目录生成 `llms.txt` 文件。
|
||||
|
||||

|
||||
|
||||
### 目录滚动高亮
|
||||
|
||||
滚动页面时,目录会自动高亮当前章节,使导航更加直观。
|
||||
|
||||

|
||||
|
||||
### 同步标签页切换
|
||||
|
||||
相同内容的标签页现在支持跨组同步。启用同步后,选择某个标签会更新所有包含相同项目的标签组(且会记住选择状态)。
|
||||
|
||||
```yaml {filename="hugo.yaml"}
|
||||
params:
|
||||
page:
|
||||
tabs:
|
||||
sync: true
|
||||
```
|
||||
|
||||
### 博客列表分页
|
||||
|
||||
为博客列表页面添加基础分页控件。
|
||||
|
||||
```yaml {filename="hugo.yaml"}
|
||||
params:
|
||||
blog:
|
||||
list:
|
||||
pagerSize: 20 # 每页文章数
|
||||
```
|
||||
|
||||

|
||||
|
||||
### MathJax 支持
|
||||
|
||||
除默认的 KaTeX 外,新增 [MathJax](https://www.mathjax.org/) 数学公式渲染引擎支持,可按需选择。
|
||||
|
||||
```yaml {filename="hugo.yaml"}
|
||||
params:
|
||||
math:
|
||||
engine: "mathjax" # 默认为 "katex"
|
||||
```
|
||||
|
||||
## 技术改进
|
||||
|
||||
### 框架与构建系统
|
||||
|
||||
- **Tailwind CSS v4 迁移**:完整迁移至 [Tailwind CSS v4](https://tailwindcss.com/blog/tailwindcss-v4),提供更好的定制支持
|
||||
- **Hugo 模板系统**:适配 Hugo [新版模板系统](https://gohugo.io/templates/new-templatesystem-overview/)(v0.146.0+)以确保未来兼容性
|
||||
- **数学公式服务端渲染**:默认使用 Hugo 原生渲染改进数学公式处理
|
||||
- **FlexSearch 0.8 升级**:搜索引擎升级至 [FlexSearch](https://github.com/nextapps-de/flexsearch) 0.8,提升 CJK(中日韩)内容编码处理能力
|
||||
- **增强资源管理**:KaTeX 和 Mermaid 资源支持从 CDN 或本地加载
|
||||
|
||||
## 使用体验优化
|
||||
|
||||
- **动态 favicon 切换**:根据色彩偏好自动更新网站图标
|
||||
- **反向分页**:支持通过页面 front matter 设置 `reversePagination`
|
||||
- **Google 索引控制**:新增页面参数控制是否允许 Google 索引
|
||||
- **宽度处理改进**:通过 CSS 变量优化响应式设计控制
|
||||
- **样式改进**:现代化 Markdown 表格和水平线样式
|
||||
|
||||
## 错误修复与稳定性
|
||||
|
||||
- **Giscus 主题同步**:评论模块现在正确跟随暗黑/明亮模式切换
|
||||
- **搜索结果准确性**:修复搜索结果链接和标题转义问题
|
||||
- **标签页切换**:解决非同步模式下的导航问题
|
||||
- **幽灵滚动**:修复禁用页脚时出现的异常滚动行为
|
||||
- **图片可访问性**:避免重复渲染 alt 文本
|
||||
- **链接渲染**:改进复杂站点结构下的基础 URL 处理
|
||||
|
||||
---
|
||||
|
||||
## 迁移指南
|
||||
|
||||
- [**Hugo 版本要求**](#hugo-version-requirements):需 Hugo v0.146.0+(扩展版)
|
||||
- [**CSS 类前缀变更**](#css-class-prefix-changes):组件 CSS 类现统一使用 `hextra-` 前缀
|
||||
- [**资源管理**](#asset-management-for-katex-and-mermaid):KaTeX 和 Mermaid 资源改为构建时下载
|
||||
- [**Tailwind CSS v4**](#tailwind-css-v4):内部 CSS 编译现使用 Tailwind CSS v4.x 并采用 `hx:` 前缀
|
||||
|
||||
#### Hugo 版本要求
|
||||
|
||||
**影响**:使用旧版 Hugo 的站点
|
||||
|
||||
Hextra v0.10.0 因采用新模板系统,要求 Hugo v0.146.0 或更高版本(扩展版)。
|
||||
|
||||
**需执行操作**:升级 Hextra 前先更新 Hugo 至 v0.146.0+
|
||||
|
||||
#### CSS 类前缀变更
|
||||
|
||||
**影响**:自定义 CSS 中引用了 Hextra 组件类的站点
|
||||
|
||||
v0.10.0 为大多数组件 CSS 类引入统一的 `hextra-` 前缀,以提高可维护性并避免与用户样式冲突。
|
||||
|
||||
**需执行操作**:如果自定义 CSS 中引用了 Hextra 组件,请更新以下类名:
|
||||
|
||||
| 区域 | 旧类名 | 新类名 |
|
||||
| -------------------- | -------------------------- | ----------------------------------------------- |
|
||||
| 搜索(容器) | `.search-wrapper` | `.hextra-search-wrapper` |
|
||||
| 搜索(输入框) | `.search-input` | `.hextra-search-input` |
|
||||
| 搜索(结果) | `.search-results` | `.hextra-search-results` |
|
||||
| 搜索(标题) | `.search-wrapper .title` | `.hextra-search-wrapper .hextra-search-title` |
|
||||
| 搜索(活动项) | `.search-wrapper .active` | `.hextra-search-wrapper .hextra-search-active` |
|
||||
| 搜索(无结果) | `.search-wrapper .no-result` | `.hextra-search-wrapper .hextra-search-no-result` |
|
||||
| 搜索(前缀) | `.search-wrapper .prefix` | `.hextra-search-wrapper .hextra-search-prefix` |
|
||||
| 搜索(摘要) | `.search-wrapper .excerpt` | `.hextra-search-wrapper .hextra-search-excerpt` |
|
||||
| 搜索(匹配项) | `.search-wrapper .match` | `.hextra-search-wrapper .hextra-search-match` |
|
||||
| 导航栏模糊效果 | `.nav-container-blur` | `.hextra-nav-container-blur` |
|
||||
| 汉堡菜单 | `.hamburger-menu` | `.hextra-hamburger-menu` |
|
||||
| 主题切换 | `.theme-toggle` | `.hextra-theme-toggle` |
|
||||
| 语言切换器 | `.language-switcher` | `.hextra-language-switcher` |
|
||||
| 侧边栏容器 | `.sidebar-container` | `.hextra-sidebar-container` |
|
||||
| 侧边栏活动项 | `.sidebar-active-item` | `.hextra-sidebar-active-item` |
|
||||
| 代码文件名 | `.filename` | `.hextra-code-filename` |
|
||||
| 复制图标 | `.copy-icon` | `.hextra-copy-icon` |
|
||||
| 成功图标 | `.success-icon` | `.hextra-success-icon` |
|
||||
| 步骤组件 | `.steps` | `.hextra-steps` |
|
||||
|
||||
#### KaTeX 和 Mermaid 资源管理
|
||||
|
||||
**影响**:使用 KaTeX 或 Mermaid 的站点
|
||||
|
||||
v0.10.0 改为在构建时从 CDN 下载 KaTeX 和 Mermaid 资源。
|
||||
|
||||
**变更内容:**
|
||||
|
||||
- 构建过程需要联网下载这些资源
|
||||
- 构建后不再需要外部 CDN 调用
|
||||
|
||||
**需执行操作:**
|
||||
|
||||
- 确保构建环境可访问互联网以下载资源
|
||||
- 隔离环境中的站点需预下载资源并配置 Hextra 加载路径
|
||||
|
||||
#### Tailwind CSS v4
|
||||
|
||||
**影响**:大量自定义 CSS 引用了 `hx-*` 类名的站点
|
||||
|
||||
虽然 Hextra 内部已处理 Tailwind CSS v4 迁移,但深度定制的站点可能需要额外调整。
|
||||
|
||||
**变更内容:**
|
||||
|
||||
- 内部 CSS 编译使用 Tailwind CSS v4.x
|
||||
- 工具类前缀改为 `hx:` 而非 `hx-`
|
||||
|
||||
## 贡献者
|
||||
|
||||
本次发布得益于 10 位新贡献者的代码提交:
|
||||
|
||||
- [@oosquare](https://github.com/oosquare) - KaTeX 字体、图片渲染钩子、链接处理改进
|
||||
- [@Zabriskije](https://github.com/Zabriskije) - 修复幽灵滚动问题
|
||||
- [@miniwater](https://github.com/miniwater) - 自定义页脚居中、图片 alt 文本优化
|
||||
- [@MattDodsonEnglish](https://github.com/MattDodsonEnglish) - Google 索引控制、OpenGraph 文档
|
||||
- [@KStocky](https://github.com/KStocky) - 反向分页功能
|
||||
- [@PrintN](https://github.com/PrintN) - 文档展示增强
|
||||
- [@hobobandy](https://github.com/hobobandy) - 标题间距优化
|
||||
- [@dlwocks31](https://github.com/dlwocks31) - 韩语翻译更新
|
||||
- [@TwoAnts](https://github.com/TwoAnts) - 修复 Giscus 主题切换
|
||||
- [@ldez](https://github.com/ldez) - 搜索功能改进与错误修复
|
||||
|
||||
同时感谢长期贡献者 [@deining](https://github.com/deining) 和 [@yuri1969](https://github.com/yuri1969) 在文档、翻译和技术改进方面的持续支持。
|
||||
|
||||
**完整更新日志**:https://github.com/imfing/hextra/compare/v0.9.7...v0.10.0
|
||||
@@ -0,0 +1,128 @@
|
||||
---
|
||||
title: "Hextra v0.11"
|
||||
date: 2025-08-30
|
||||
authors:
|
||||
- name: imfing
|
||||
link: https://github.com/imfing
|
||||
image: https://github.com/imfing.png
|
||||
tags:
|
||||
- انتشار
|
||||
---
|
||||
|
||||
Hextra v0.11.0 بر صیقل UX و مؤلفههای جدید کاربردی تمرکز دارد: بنر سراسری سایت، کالاوتها و بجهای بهبودیافته، کارتهای غنیتر، یکپارچهسازی تحلیلگرها، و چند بهبود ناوبری. همچنین شامل رفع اشکالات پایداری و بهروزرسانیهای مستندات است.
|
||||
|
||||
<!--more-->
|
||||
|
||||
## راهنمای ارتقا
|
||||
|
||||
برای بیشتر سایتها تغییر شکستآمیزی وجود ندارد. با استفاده از [Hugo Modules](https://gohugo.io/hugo-modules/use-modules/) بهروزرسانی کنید:
|
||||
|
||||
```bash
|
||||
hugo mod get -u github.com/imfing/hextra
|
||||
```
|
||||
|
||||
## نکات برجسته
|
||||
|
||||
- مؤلفه بنر بالایی برای اعلانها
|
||||
- بازطراحی کالاوتها با سبکهای شفافتر
|
||||
- پشتیبانی از تحلیلگرهای Umami و Matomo
|
||||
- شورتکد Asciinema برای ضبطهای ترمینال
|
||||
- گزینهٔ تزئین پیوندهای خارجی
|
||||
- مسیر راهنما برای صفحات تکی (غیرِ مستندات/غیرِ وبلاگ)
|
||||
- بهبودهای نوار ناوبری: مورد پیوند با آیکون و جایگذاری بهتر
|
||||
- سفارشیسازی بهتر بجها و کارتها
|
||||
- کلید تغییر تم از گزینه «System» پشتیبانی میکند
|
||||
|
||||
## ویژگیهای جدید
|
||||
|
||||
### بنر بالایی
|
||||
|
||||
یک بنر سراسری و قابلِ بستن برای اعلانها، لانچها یا پیامهای وضعیت اضافه کنید.
|
||||
|
||||
```yaml {filename="hugo.yaml"}
|
||||
params:
|
||||
banner:
|
||||
key: "announcement"
|
||||
message: Welcome!
|
||||
```
|
||||
|
||||

|
||||
|
||||
### بازطراحی Callout
|
||||
|
||||
[Callout]({{% relref "docs/guide/shortcodes/callout" %}}) برای خوانایی بهتر و تأکید مناسب در تمام تمها بازطراحی شده است.
|
||||
|
||||

|
||||
|
||||
### تحلیلگرها: Umami و Matomo
|
||||
|
||||
پیکربندی داخلی برای فراهمکنندگان تحلیلگر:
|
||||
- [Umami]({{% relref "docs/guide/configuration.md#umami-analytics" %}})
|
||||
- [Matomo]({{% relref "docs/guide/configuration.md#matomo-analytics" %}})
|
||||
|
||||
### شورتکد Asciinema
|
||||
|
||||
با استفاده از [Asciinema](https://www.asciinema.org/) و [شورتکد Asciinema]({{% relref "docs/guide/shortcodes/asciinema.md" %}}) ضبطهای ترمینال را درونگذاری کنید.
|
||||
|
||||
```md
|
||||
{{</* asciinema id="123456" autoplay=true loop=true */>}}
|
||||
```
|
||||
|
||||

|
||||
|
||||
### بهبودهای نوار ناوبری
|
||||
|
||||
- پشتیبانی از آیکون برای موارد پیوند در نوار ناوبری
|
||||
- بهبود موقعیت منو برای هماهنگی با سوییچر زبان و سایر موارد
|
||||
|
||||

|
||||
|
||||
قابل ذکر است، نسخه [0.10.2](https://github.com/imfing/hextra/releases/tag/v0.10.2) امکان افزودن سوییچر زبان و کلید تغییر تم به نوار ناوبری را فراهم میکند.
|
||||
|
||||
### تزئین پیوند خارجی
|
||||
|
||||
بهصورت اختیاری یک تزئین ظریفِ «پیوند خارجی» به پیوندهای خروجی اضافه کنید.
|
||||
|
||||
```yaml {filename="hugo.yaml"}
|
||||
params:
|
||||
externalLinkDecoration: true
|
||||
```
|
||||
|
||||
### فعالسازی مسیر راهنما
|
||||
|
||||
با قرار دادن `breadcrumbs: true` در فرانتمتر، مسیر راهنما را روی صفحات تکی (غیرِ مستندات/وبلاگ) فعال کنید.
|
||||
|
||||
```yaml {filename="content/about.md"}
|
||||
---
|
||||
title: About
|
||||
breadcrumbs: true
|
||||
---
|
||||
```
|
||||
|
||||
### بهبود کارتها و بجها
|
||||
|
||||
- [کارتها]({{% relref "docs/guide/shortcodes/cards.md" %}}): گزینههای جدید `tagIcon` و `tagBorder`.
|
||||
- [بجها]({{% relref "docs/guide/shortcodes/others.md" %}}): رنگها و سبکهای حاشیهٔ جدید.
|
||||
|
||||
## بهبودهای کیفیت زندگی
|
||||
|
||||
- تغییر تم: افزودن گزینه «System»
|
||||

|
||||
- تایپوگرافی: سبکهای بهتر فهرست کار با چکباکس
|
||||

|
||||
- سوییچر زبان: ترتیبدهی بهبود یافته همراه با موارد منوییِ آیکوندار
|
||||
|
||||
## رفع اشکالات
|
||||
|
||||
- Giscus: همگامسازی صحیح تم و زبان
|
||||
- کارتها: رفع رندر بج در حالت RTL
|
||||
- نوار ناوبری: بهبود موقعیت و تعاملات منو
|
||||
|
||||
## مستندات و بومیسازی
|
||||
|
||||
- مستندات: صفحهٔ جدیدی دربارهٔ شورتکدهای Hextra
|
||||
- i18n: افزودن ترجمههای `copyCode` و `system` به `zh-cn`
|
||||
|
||||
---
|
||||
|
||||
**تغییرات کامل**: https://github.com/imfing/hextra/compare/v0.10.2...v0.11.0
|
||||
@@ -0,0 +1,128 @@
|
||||
---
|
||||
title: "Hextra v0.11"
|
||||
date: 2025-08-30
|
||||
authors:
|
||||
- name: imfing
|
||||
link: https://github.com/imfing
|
||||
image: https://github.com/imfing.png
|
||||
tags:
|
||||
- Release
|
||||
---
|
||||
|
||||
Hextra v0.11.0 は、UX の磨き込みと便利な新コンポーネントに注力したリリースです。サイト全体バナー、改良されたコールアウトとバッジ、よりリッチなカード、アナリティクス連携、そしていくつかのナビゲーション改善を含みます。安定性の修正とドキュメント更新も同梱しています。
|
||||
|
||||
<!--more-->
|
||||
|
||||
## アップグレードガイド
|
||||
|
||||
ほとんどのサイトで破壊的変更はありません。[Hugo Modules](https://gohugo.io/hugo-modules/use-modules/) を使って更新してください:
|
||||
|
||||
```bash
|
||||
hugo mod get -u github.com/imfing/hextra
|
||||
```
|
||||
|
||||
## ハイライト
|
||||
|
||||
- お知らせ用のトップバナーコンポーネント
|
||||
- より見やすくなったコールアウトの刷新
|
||||
- Umami と Matomo のアナリティクス対応
|
||||
- 端末録画のための Asciinema ショートコード
|
||||
- 外部リンク装飾オプション
|
||||
- 単一ページ(ドキュメント・ブログ以外)向けのパンくずリスト
|
||||
- ナビバー改善: アイコン付きリンク項目と配置の改善
|
||||
- バッジとカードのカスタマイズ性向上
|
||||
- テーマ切り替えに「System」オプションを追加
|
||||
|
||||
## 新機能
|
||||
|
||||
### トップバナー
|
||||
|
||||
告知やリリース、ステータスメッセージ向けに、サイト全体で表示できる閉じられるバナーを追加します。
|
||||
|
||||
```yaml {filename="hugo.yaml"}
|
||||
params:
|
||||
banner:
|
||||
key: "announcement"
|
||||
message: Welcome!
|
||||
```
|
||||
|
||||

|
||||
|
||||
### コールアウト刷新
|
||||
|
||||
[Callout]({{% relref "docs/guide/shortcodes/callout" %}}) のデザインを刷新し、テーマを問わず可読性と強調表現を向上しました。
|
||||
|
||||

|
||||
|
||||
### アナリティクス: Umami と Matomo
|
||||
|
||||
以下のアナリティクスプロバイダに組み込み設定で対応:
|
||||
- [Umami]({{% relref "docs/guide/configuration.md#umami-analytics" %}})
|
||||
- [Matomo]({{% relref "docs/guide/configuration.md#matomo-analytics" %}})
|
||||
|
||||
### Asciinema ショートコード
|
||||
|
||||
[Asciinema](https://www.asciinema.org/) の端末録画を、新しい [Asciinema ショートコード]({{% relref "docs/guide/shortcodes/asciinema.md" %}}) で埋め込みできます。
|
||||
|
||||
```md
|
||||
{{</* asciinema id="123456" autoplay=true loop=true */>}}
|
||||
```
|
||||
|
||||

|
||||
|
||||
### ナビバーの改善
|
||||
|
||||
- ナビバーのリンク項目でアイコンをサポート
|
||||
- 言語スイッチャー等との兼ね合いを考慮してメニュー配置を最適化
|
||||
|
||||

|
||||
|
||||
特に、[0.10.2](https://github.com/imfing/hextra/releases/tag/v0.10.2) ではナビバーに言語スイッチャーとテーマトグルを追加可能になりました。
|
||||
|
||||
### 外部リンク装飾
|
||||
|
||||
外部リンクに控えめな装飾をオプションで付与できます。
|
||||
|
||||
```yaml {filename="hugo.yaml"}
|
||||
params:
|
||||
externalLinkDecoration: true
|
||||
```
|
||||
|
||||
### パンくずリストの有効化
|
||||
|
||||
フロントマターで `breadcrumbs: true` を設定すると、単一ページ(ドキュメント・ブログ以外)でパンくずリストを有効化できます。
|
||||
|
||||
```yaml {filename="content/about.md"}
|
||||
---
|
||||
title: About
|
||||
breadcrumbs: true
|
||||
---
|
||||
```
|
||||
|
||||
### カードとバッジの改善
|
||||
|
||||
- [カード]({{% relref "docs/guide/shortcodes/cards.md" %}}): 新オプション `tagIcon` と `tagBorder`
|
||||
- [バッジ]({{% relref "docs/guide/shortcodes/others.md" %}}): 新しい色とボーダースタイル
|
||||
|
||||
## 利便性の向上
|
||||
|
||||
- テーマ切り替え: 「System」オプションを追加
|
||||

|
||||
- タイポグラフィ: チェックボックス付きタスクリストのスタイル改善
|
||||

|
||||
- 言語スイッチャー: アイコンメニュー項目との並び順を改善
|
||||
|
||||
## 修正
|
||||
|
||||
- Giscus: テーマと言語の同期を適切に実施
|
||||
- カード: RTL でのバッジ描画を修正
|
||||
- ナビバー: メニュー配置とインタラクションを調整
|
||||
|
||||
## ドキュメントと i18n
|
||||
|
||||
- Docs: Hextra のショートコードをまとめた新ページ
|
||||
- i18n: `zh-cn` に `copyCode` と `system` の翻訳を追加
|
||||
|
||||
---
|
||||
|
||||
**完全な変更履歴**: https://github.com/imfing/hextra/compare/v0.10.2...v0.11.0
|
||||
@@ -0,0 +1,128 @@
|
||||
---
|
||||
title: "Hextra v0.11"
|
||||
date: 2025-08-30
|
||||
authors:
|
||||
- name: imfing
|
||||
link: https://github.com/imfing
|
||||
image: https://github.com/imfing.png
|
||||
tags:
|
||||
- Release
|
||||
---
|
||||
|
||||
Hextra v0.11.0 focuses on UX polish and useful new components: site-wide banner, improved callouts and badges, richer cards, analytics integrations, and several navigation refinements. It also ships stability fixes and documentation updates.
|
||||
|
||||
<!--more-->
|
||||
|
||||
## Upgrade Guide
|
||||
|
||||
No breaking changes are expected for most sites. Update using [Hugo Modules](https://gohugo.io/hugo-modules/use-modules/):
|
||||
|
||||
```bash
|
||||
hugo mod get -u github.com/imfing/hextra
|
||||
```
|
||||
|
||||
## Highlights
|
||||
|
||||
- Top banner component for announcements
|
||||
- Revamped callouts with clearer styles
|
||||
- Umami and Matomo analytics support
|
||||
- Asciinema shortcode for terminal recordings
|
||||
- External link decoration option
|
||||
- Breadcrumbs for single pages (non-docs, non-blogs)
|
||||
- Navbar enhancements: icon link item and improved positions
|
||||
- Improved badges and cards customization
|
||||
- Theme toggle supports "System"
|
||||
|
||||
## New Features
|
||||
|
||||
### Top Banner
|
||||
|
||||
Add a site-wide, dismissible banner for announcements, launches, or status messages.
|
||||
|
||||
```yaml {filename="hugo.yaml"}
|
||||
params:
|
||||
banner:
|
||||
key: "announcement"
|
||||
message: Welcome!
|
||||
```
|
||||
|
||||

|
||||
|
||||
### Callout Revamp
|
||||
|
||||
[Callout]({{% relref "docs/guide/shortcodes/callout" %}}) receive a design refresh for better readability and emphasis across themes.
|
||||
|
||||

|
||||
|
||||
### Analytics: Umami and Matomo
|
||||
|
||||
Built-in configuration for analytics providers:
|
||||
- [Umami]({{% relref "docs/guide/configuration.md#umami-analytics" %}})
|
||||
- [Matomo]({{% relref "docs/guide/configuration.md#matomo-analytics" %}})
|
||||
|
||||
### Asciinema Shortcode
|
||||
|
||||
Embed terminal recordings from [Asciinema](https://www.asciinema.org/) using the new [Asciinema shortcode]({{% relref "docs/guide/shortcodes/asciinema.md" %}}).
|
||||
|
||||
```md
|
||||
{{</* asciinema id="123456" autoplay=true loop=true */>}}
|
||||
```
|
||||
|
||||

|
||||
|
||||
### Navbar Enhancements
|
||||
|
||||
- Support icons for link items in the navbar
|
||||
- Refine menu positions to play nicely with the language switcher and other items
|
||||
|
||||

|
||||
|
||||
Notably, version [0.10.2](https://github.com/imfing/hextra/releases/tag/v0.10.2) enables the addition of language switchers and theme toggles to the navbar.
|
||||
|
||||
### External Link Decoration
|
||||
|
||||
Optionally add a subtle external-link decoration to outbound links.
|
||||
|
||||
```yaml {filename="hugo.yaml"}
|
||||
params:
|
||||
externalLinkDecoration: true
|
||||
```
|
||||
|
||||
### Breadcrumbs Enablement
|
||||
|
||||
Enable breadcrumbs on single pages (non-docs, non-blogs) by setting `breadcrumbs: true` in front matter.
|
||||
|
||||
```yaml {filename="content/about.md"}
|
||||
---
|
||||
title: About
|
||||
breadcrumbs: true
|
||||
---
|
||||
```
|
||||
|
||||
### Cards and Badges Improvements
|
||||
|
||||
- [Cards]({{% relref "docs/guide/shortcodes/cards.md" %}}): new `tagIcon` and `tagBorder` options.
|
||||
- [Badges]({{% relref "docs/guide/shortcodes/others.md" %}}): new colors and border styles.
|
||||
|
||||
## Quality of Life
|
||||
|
||||
- Theme toggle: add "System" option
|
||||

|
||||
- Typography: better task list styles with checkboxes
|
||||

|
||||
- Language switcher: improved ordering with icon menu items
|
||||
|
||||
## Fixes
|
||||
|
||||
- Giscus: sync theme and language properly
|
||||
- Cards: fix badge rendering with RTL
|
||||
- Navbar: refine menu positions and interactions
|
||||
|
||||
## Documentation & i18n
|
||||
|
||||
- Docs: new page covering Hextra shortcodes
|
||||
- i18n: add `copyCode` and `system` translations to `zh-cn`
|
||||
|
||||
---
|
||||
|
||||
**Full Changelog**: https://github.com/imfing/hextra/compare/v0.10.2...v0.11.0
|
||||
@@ -0,0 +1,129 @@
|
||||
---
|
||||
title: "Hextra v0.11"
|
||||
date: 2025-08-30
|
||||
authors:
|
||||
- name: imfing
|
||||
link: https://github.com/imfing
|
||||
image: https://github.com/imfing.png
|
||||
tags:
|
||||
- Release
|
||||
---
|
||||
|
||||
Hextra v0.11.0 专注于打磨使用体验并带来数个实用新组件:站点级顶部横幅、改进的提示框与徽章、更丰富的卡片、分析工具集成,以及多项导航优化。同时包含稳定性修复和文档更新。
|
||||
|
||||
<!--more-->
|
||||
|
||||
## 升级指南
|
||||
|
||||
对大多数站点而言没有破坏性变更。使用 [Hugo Modules](https://gohugo.io/hugo-modules/use-modules/) 更新:
|
||||
|
||||
```bash
|
||||
hugo mod get -u github.com/imfing/hextra
|
||||
```
|
||||
|
||||
## 亮点
|
||||
|
||||
- 用于公告的顶栏横幅组件
|
||||
- 重新设计的提示框,样式更清晰
|
||||
- 支持 Umami 与 Matomo 分析
|
||||
- Asciinema 短代码用于终端录屏
|
||||
- 外链装饰选项
|
||||
- 单页(非文档、非博客)支持面包屑
|
||||
- 导航栏增强:图标链接项与更优布局
|
||||
- 徽章与卡片的自定义能力提升
|
||||
- 主题切换增加「System」选项
|
||||
|
||||
## 新功能
|
||||
|
||||
### 顶部横幅
|
||||
|
||||
为公告、发布或状态消息添加一个站点级、可关闭的横幅。
|
||||
|
||||
```yaml {filename="hugo.yaml"}
|
||||
params:
|
||||
banner:
|
||||
key: "announcement"
|
||||
message: Welcome!
|
||||
```
|
||||
|
||||

|
||||
|
||||
### 提示框重设计
|
||||
|
||||
[Callout]({{% relref "docs/guide/shortcodes/callout" %}}) 获得样式刷新,在各主题下具备更好的可读性与强调效果。
|
||||
|
||||

|
||||
|
||||
### 分析:Umami 与 Matomo
|
||||
|
||||
内置以下分析平台的配置支持:
|
||||
- [Umami]({{% relref "docs/guide/configuration.md#umami-analytics" %}})
|
||||
- [Matomo]({{% relref "docs/guide/configuration.md#matomo-analytics" %}})
|
||||
|
||||
### Asciinema 短代码
|
||||
|
||||
使用全新的 [Asciinema 短代码]({{% relref "docs/guide/shortcodes/asciinema.md" %}}) 嵌入 [Asciinema](https://www.asciinema.org/) 终端录屏。
|
||||
|
||||
```md
|
||||
{{</* asciinema id="123456" autoplay=true loop=true */>}}
|
||||
```
|
||||
|
||||

|
||||
|
||||
### 导航栏增强
|
||||
|
||||
- 支持在导航栏链接项中使用图标
|
||||
- 优化菜单的相对位置,使其与语言切换器等项协同更佳
|
||||
|
||||

|
||||
|
||||
值得一提的是,版本 [0.10.2](https://github.com/imfing/hextra/releases/tag/v0.10.2) 已支持在导航栏添加语言切换器与主题切换。
|
||||
|
||||
### 外链装饰
|
||||
|
||||
可选地为外部链接添加轻量的外链标识装饰。
|
||||
|
||||
```yaml {filename="hugo.yaml"}
|
||||
params:
|
||||
externalLinkDecoration: true
|
||||
```
|
||||
|
||||
### 启用面包屑
|
||||
|
||||
在单页(非文档、非博客)上,通过在 Front Matter 中设置 `breadcrumbs: true` 启用面包屑。
|
||||
|
||||
```yaml {filename="content/about.md"}
|
||||
---
|
||||
title: About
|
||||
breadcrumbs: true
|
||||
---
|
||||
```
|
||||
|
||||
### 卡片与徽章的改进
|
||||
|
||||
- [卡片]({{% relref "docs/guide/shortcodes/cards.md" %}}):新增 `tagIcon` 与 `tagBorder` 选项。
|
||||
- [徽章]({{% relref "docs/guide/shortcodes/others.md" %}}):新增颜色与边框样式。
|
||||
|
||||
## 使用体验优化
|
||||
|
||||
- 主题切换:增加「System」选项
|
||||

|
||||
- 字体排版:改进带复选框的任务列表样式
|
||||

|
||||
- 语言切换器:与图标菜单项的排序更合理
|
||||
|
||||
## 修复
|
||||
|
||||
- Giscus:正确同步主题与语言
|
||||
- 卡片:修复 RTL 场景下的徽章渲染
|
||||
- 导航栏:优化菜单位置与交互
|
||||
|
||||
## 文档与 i18n
|
||||
|
||||
- 文档:新增页面介绍 Hextra 的短代码
|
||||
- i18n:为 `zh-cn` 增加 `copyCode` 与 `system` 翻译
|
||||
|
||||
---
|
||||
|
||||
**完整变更日志**: https://github.com/imfing/hextra/compare/v0.10.2...v0.11.0
|
||||
|
||||
@@ -0,0 +1,218 @@
|
||||
---
|
||||
title: "Hextra v0.12"
|
||||
date: 2026-02-20
|
||||
authors:
|
||||
- name: imfing
|
||||
link: https://github.com/imfing
|
||||
image: https://github.com/imfing.png
|
||||
tags:
|
||||
- انتشار
|
||||
---
|
||||
|
||||
Hextra v0.12.0 مجموعهای غنی از ویژگیهای جدید شامل منوی زمینه صفحه، زوم تصویر، تبهای بازطراحیشده و موارد بیشتر، به همراه بهبودهای جامع دسترسپذیری WCAG 2.2 AA و رفع اشکالات متعدد ارائه میدهد.
|
||||
|
||||
<!--more-->
|
||||
|
||||
## راهنمای ارتقا
|
||||
|
||||
برای بیشتر سایتها تغییر شکستآمیزی وجود ندارد. با استفاده از [Hugo Modules](https://gohugo.io/hugo-modules/use-modules/) بهروزرسانی کنید:
|
||||
|
||||
```bash
|
||||
hugo mod get -u github.com/imfing/hextra
|
||||
```
|
||||
|
||||
## نکات برجسته
|
||||
|
||||
- منوی زمینه صفحه برای کپی/مشاهده سورس Markdown
|
||||
- بازطراحی شورتکد تبها با نامگذاری هر تب و پشتیبانی از آیکون
|
||||
- زوم با کلیک برای تصاویر Markdown
|
||||
- پشتیبانی از تحلیلگر GoatCounter
|
||||
- گزینه مخفیکردن نوار کناری اصلی در دسکتاپ
|
||||
- نمایش آخرین نویسنده ویرایشکننده از طریق GitInfo
|
||||
- گزینه غیرفعالسازی ناوبری قبلی/بعدی
|
||||
- صفحه آرشیو داخلی برای فهرست زمانی نوشتههای وبلاگ
|
||||
- شورتکد و چیدمان واژهنامه
|
||||
- حذف صفحات/بخشها از llms.txt
|
||||
- ترتیب و برچسبهای نوار کناری موبایل همراستا با `menu.main`
|
||||
- عرض محتوای پایدار با پشتیبانی از بازنویسی متغیر CSS
|
||||
- بهبودهای جامع دسترسپذیری WCAG 2.2 AA
|
||||
|
||||
## ویژگیهای جدید
|
||||
|
||||
### منوی زمینه صفحه
|
||||
|
||||

|
||||
|
||||
منوی زمینه صفحه دکمهای کشویی فراهم میکند که با آن میتوانید محتوای صفحه را بهصورت Markdown کپی کنید یا سورس خام Markdown را مشاهده نمایید. با افزایش کاربرانی که مستندات را به ابزارهای هوش مصنوعی مولّد میدهند، دسترسی سریع به Markdown تمیز بسیار مفید است. پیوندهای سفارشی با متغیرهای قالب (`{url}`، `{title}`، `{markdown_url}`) به شما امکان میدهند میانبرهای «از AI بپرس» یا سایر یکپارچهسازیها را مستقیماً در منو ایجاد کنید.
|
||||
|
||||
برای استفاده از قابلیتهای «مشاهده بهصورت Markdown» و `{markdown_url}`، فرمت خروجی Markdown را در پیکربندی سایت فعال کنید:
|
||||
|
||||
```yaml {filename="hugo.yaml"}
|
||||
outputs:
|
||||
page: [html, markdown]
|
||||
section: [html, rss, markdown]
|
||||
```
|
||||
|
||||
سپس منوی زمینه را پیکربندی کنید:
|
||||
|
||||
```yaml {filename="hugo.yaml"}
|
||||
params:
|
||||
page:
|
||||
contextMenu:
|
||||
enable: true
|
||||
links:
|
||||
- name: "Ask AI"
|
||||
url: "https://example.com?content={markdown_url}"
|
||||
icon: "sparkles"
|
||||
```
|
||||
|
||||
### بازطراحی تبها و پشتیبانی از آیکون
|
||||
|
||||
[شورتکد تبها]({{% relref "docs/guide/shortcodes/tabs" %}}) بازطراحی شده است. اکنون میتوان نام تبها را مستقیماً روی هر شورتکد `tab` تنظیم کرد و پارامتر اختیاری `icon` یک آیکون قبل از برچسب تب نمایش میدهد. نحو قبلی همچنان پشتیبانی میشود.
|
||||
|
||||
```md
|
||||
{{</* tabs */>}}
|
||||
{{</* tab name="Photos" icon="photograph" */>}}مدیریت و سازماندهی کتابخانه عکسهای شما.{{</* /tab */>}}
|
||||
{{</* tab name="Music" icon="music-note" */>}}مرور و پخش آهنگهای مورد علاقه شما.{{</* /tab */>}}
|
||||
{{</* tab name="Videos" icon="film" */>}}تماشا و پخش محتوای ویدیویی.{{</* /tab */>}}
|
||||
{{</* /tabs */>}}
|
||||
```
|
||||
|
||||

|
||||
|
||||
### زوم تصویر
|
||||
|
||||
با یک گزینه پیکربندی جدید، زوم با کلیک را روی تصاویر Markdown فعال کنید. این قابلیت از [medium-zoom](https://github.com/francoischalifour/medium-zoom) استفاده میکند.
|
||||
|
||||
```yaml {filename="hugo.yaml"}
|
||||
params:
|
||||
imageZoom:
|
||||
enable: true
|
||||
```
|
||||
|
||||
### تحلیلگر GoatCounter
|
||||
|
||||
پشتیبانی داخلی از تحلیلگر [GoatCounter](https://www.goatcounter.com/) در کنار یکپارچهسازیهای موجود Google Analytics، Umami و Matomo.
|
||||
|
||||
### مخفیکردن نوار کناری اصلی
|
||||
|
||||
یک پارامتر جدید فرانتمتر امکان مخفیکردن نوار کناری اصلی در دسکتاپ را فراهم میکند تا صفحات محتوا عرض کامل داشته باشند.
|
||||
|
||||
```yaml {filename="content/my-page.md"}
|
||||
---
|
||||
title: My Page
|
||||
sidebar:
|
||||
hide: true
|
||||
---
|
||||
```
|
||||
|
||||
### آخرین نویسنده ویرایشکننده
|
||||
|
||||
با استفاده از GitInfo هوگو، آخرین نویسنده کامیت را در کنار تاریخ «آخرین بهروزرسانی» نمایش دهید.
|
||||
|
||||
```yaml {filename="hugo.yaml"}
|
||||
params:
|
||||
displayUpdatedAuthor: true
|
||||
```
|
||||
|
||||

|
||||
|
||||
### غیرفعالسازی ناوبری قبلی/بعدی
|
||||
|
||||
دکمههای ناوبری قبلی/بعدی را در سطح سایت غیرفعال کنید:
|
||||
|
||||
```yaml {filename="hugo.yaml"}
|
||||
params:
|
||||
page:
|
||||
displayPagination: false
|
||||
```
|
||||
|
||||
### حذف از LLMs.txt
|
||||
|
||||
با تنظیم `llms: false` در فرانتمتر، صفحات یا بخشهای کامل را از خروجی `llms.txt` حذف کنید.
|
||||
|
||||
```yaml {filename="content/private-page.md"}
|
||||
---
|
||||
title: "Private Page"
|
||||
llms: false
|
||||
---
|
||||
```
|
||||
|
||||
### صفحه آرشیو
|
||||
|
||||
چیدمان جدید داخلی `archives` نوشتههای وبلاگ را در یک خط زمانی گروهبندیشده بر اساس سال نمایش میدهد و برچسبها بهصورت درونخطی پس از عنوان هر نوشته نشان داده میشوند.
|
||||
|
||||
```yaml {filename="content/archives/_index.md"}
|
||||
---
|
||||
title: Archives
|
||||
layout: archives
|
||||
---
|
||||
```
|
||||
|
||||

|
||||
|
||||
### واژهنامه
|
||||
|
||||
یک [واژهنامه]({{% relref "docs/guide/shortcodes/term" %}}) اصطلاحات سراسری سایت با صفحه فهرست اختصاصی و شورتکد `term` برای تعاریف درونخطی.
|
||||
|
||||
## دسترسپذیری
|
||||
|
||||
بهبودهای جامع دسترسپذیری WCAG 2.2 AA (#924):
|
||||
|
||||
- پیوند رفتن به محتوا و نقشهای نشانهای ARIA در تمام صفحات
|
||||
- ویژگیهای ARIA برای تمام ابزارکهای تعاملی (کلید تغییر تم، تبها، نوار کناری، درخت فایل، منوهای بازشو، جستجو، منوها)
|
||||
- ناوبری صفحهکلیدی برای تبها و کلید تغییر تم (کلیدهای جهتی، Enter، Escape)
|
||||
- پشتیبانی از `prefers-reduced-motion` و سبکهای سراسری `focus-visible`
|
||||
- ۱۵ کلید دسترسپذیری i18n جدید با ترجمه کامل در تمام ۲۱ محلیسازی
|
||||
- جایگزینی تمام رشتههای انگلیسی `aria-label` که بهصورت هاردکد بودند با جستجوی i18n
|
||||
|
||||
## بهبودهای کیفیت زندگی
|
||||
|
||||
- بهبود سبکهای خوانایی جدول
|
||||
- پشتیبانی از ویژگیهای Markdown برای سرتیترها
|
||||
- تشخیص بهتر پیوند فعال برای صفحات فرود بخش چندزبانه
|
||||
- پشتیبانی شورتکد کارت از پارامتر اختیاری `alt` برای تصاویر
|
||||
- پشتیبانی از تصاویر بسته صفحه در ابرداده OpenGraph
|
||||
- عرض محتوا اکنون بهصورت پیشفرض ثابت است، با پشتیبانی از بازنویسی متغیر CSS برای چیدمانهای سفارشی
|
||||
|
||||
## رفع اشکالات
|
||||
|
||||
- جلوگیری از پیشوند پایه دوگانه `relref` در render-link
|
||||
- رفع رندر تبها هنگام تودرتوبودن در مراحل
|
||||
- همراستاسازی ترتیب و برچسبهای نوار کناری موبایل با `menu.main`
|
||||
- رعایت `search.enable` در نوار کناری
|
||||
- رعایت پارامتر صفحه `toc` در منوی بازشو موبایل
|
||||
- بهبود برجستهسازی تطبیق FlexSearch و دستکاری امن DOM
|
||||
- رفع موقعیت زیرعنوان کارت
|
||||
- مدیریت اسلشهای ابتدایی در مسیرهای تصویر OG برای استقرارهای زیرمسیر
|
||||
- رفع بازگرداندن صفحات نتیجه کمتر از حد انتظار توسط FlexSearch
|
||||
- تغییر فایل پیشفرض Umami analytics به `script.js`
|
||||
- رفع جستجوی نویسنده RSS برای Hugo v0.156.0+ (`.Site.Params.Author`)
|
||||
|
||||
## مستندات و بومیسازی
|
||||
|
||||
- افزودن بومیسازی ایتالیایی
|
||||
- پیوند مستندات KaTeX
|
||||
- بهروزرسانی مستندات شورتکد details به نحو angle bracket
|
||||
|
||||
## مشارکتکنندگان
|
||||
|
||||
این انتشار با مشارکت ۱۱ مشارکتکننده جدید ممکن شد:
|
||||
|
||||
- [@ghac101](https://github.com/ghac101) - رفع Umami analytics، غیرفعالسازی ناوبری قبلی/بعدی
|
||||
- [@pmarrapese](https://github.com/pmarrapese) - پشتیبانی از ویژگیهای Markdown برای سرتیترها
|
||||
- [@Bubbler-4](https://github.com/Bubbler-4) - مستندات شورتکد details
|
||||
- [@bloovis](https://github.com/bloovis) - رفع تعداد نتایج FlexSearch
|
||||
- [@AntoninPvr](https://github.com/AntoninPvr) - رفع موقعیت زیرعنوان کارت
|
||||
- [@illia-v](https://github.com/illia-v) - رفع TOC موبایل و کلید تغییر جستجو
|
||||
- [@gallochri](https://github.com/gallochri) - بومیسازی ایتالیایی
|
||||
- [@MatheusFlausino](https://github.com/MatheusFlausino) - حذف از LLMs.txt
|
||||
- [@daniseijo](https://github.com/daniseijo) - قابلیت آخرین نویسنده ویرایشکننده
|
||||
- [@confusedkernel](https://github.com/confusedkernel) - صفحه آرشیو
|
||||
- [@Fenyutanchan](https://github.com/Fenyutanchan) - رفع سازگاری نویسنده RSS با Hugo v0.156.0
|
||||
|
||||
همچنین از مشارکتکنندگان بازگشته [@KStocky](https://github.com/KStocky)، [@ldez](https://github.com/ldez)، [@kowyo](https://github.com/kowyo)، [@torbjornbp](https://github.com/torbjornbp)، [@yuri1969](https://github.com/yuri1969) و [@PrintN](https://github.com/PrintN) بابت مشارکتهای مداومشان سپاسگزاریم.
|
||||
|
||||
---
|
||||
|
||||
**تغییرات کامل**: https://github.com/imfing/hextra/compare/v0.11.1...v0.12.0
|
||||
@@ -0,0 +1,218 @@
|
||||
---
|
||||
title: "Hextra v0.12"
|
||||
date: 2026-02-20
|
||||
authors:
|
||||
- name: imfing
|
||||
link: https://github.com/imfing
|
||||
image: https://github.com/imfing.png
|
||||
tags:
|
||||
- Release
|
||||
---
|
||||
|
||||
Hextra v0.12.0 は、ページコンテキストメニュー、画像ズーム、刷新されたタブ、その他多くの新機能に加え、包括的な WCAG 2.2 AA アクセシビリティ改善と多数のバグ修正を提供します。
|
||||
|
||||
<!--more-->
|
||||
|
||||
## アップグレードガイド
|
||||
|
||||
ほとんどのサイトで破壊的変更はありません。[Hugo Modules](https://gohugo.io/hugo-modules/use-modules/) を使って更新してください:
|
||||
|
||||
```bash
|
||||
hugo mod get -u github.com/imfing/hextra
|
||||
```
|
||||
|
||||
## ハイライト
|
||||
|
||||
- Markdown ソースのコピー・表示ができるページコンテキストメニュー
|
||||
- タブ名指定とアイコンをサポートする刷新されたタブショートコード
|
||||
- Markdown 画像のクリックズーム
|
||||
- GoatCounter アナリティクス対応
|
||||
- デスクトップでメインサイドバーを非表示にするオプション
|
||||
- GitInfo による最終更新者の表示
|
||||
- 前へ/次へナビゲーションの無効化オプション
|
||||
- ブログ記事の年別アーカイブページ
|
||||
- 用語集ショートコードとレイアウト
|
||||
- llms.txt からのページ/セクション除外
|
||||
- モバイルサイドバーの順序とラベルが `menu.main` に準拠
|
||||
- CSS 変数オーバーライドによる安定したコンテンツ幅
|
||||
- 包括的な WCAG 2.2 AA アクセシビリティ改善
|
||||
|
||||
## 新機能
|
||||
|
||||
### ページコンテキストメニュー
|
||||
|
||||

|
||||
|
||||
ページコンテキストメニューはドロップダウンボタンを提供し、ページの内容を Markdown としてコピーしたり、生の Markdown ソースを表示できます。ドキュメントを生成 AI ツールに取り込むユーザーが増える中、クリーンな Markdown への素早いアクセスはますます有用です。テンプレート変数(`{url}`、`{title}`、`{markdown_url}`)を使ったカスタムリンクにより、「AI に質問」ショートカットなどのインテグレーションをメニューに直接組み込めます。
|
||||
|
||||
「Markdown として表示」および `{markdown_url}` 機能を利用するには、サイト設定で Markdown 出力フォーマットを有効にしてください:
|
||||
|
||||
```yaml {filename="hugo.yaml"}
|
||||
outputs:
|
||||
page: [html, markdown]
|
||||
section: [html, rss, markdown]
|
||||
```
|
||||
|
||||
次にコンテキストメニューを設定します:
|
||||
|
||||
```yaml {filename="hugo.yaml"}
|
||||
params:
|
||||
page:
|
||||
contextMenu:
|
||||
enable: true
|
||||
links:
|
||||
- name: "Ask AI"
|
||||
url: "https://example.com?content={markdown_url}"
|
||||
icon: "sparkles"
|
||||
```
|
||||
|
||||
### タブの刷新とアイコン対応
|
||||
|
||||
[タブショートコード]({{% relref "docs/guide/shortcodes/tabs" %}})が刷新されました。各 `tab` ショートコードでタブ名を直接設定でき、オプションの `icon` パラメータでラベルの前にアイコンを表示できます。従来の構文も引き続きサポートされています。
|
||||
|
||||
```md
|
||||
{{</* tabs */>}}
|
||||
{{</* tab name="Photos" icon="photograph" */>}}写真ライブラリを管理・整理します。{{</* /tab */>}}
|
||||
{{</* tab name="Music" icon="music-note" */>}}お気に入りの曲を閲覧・再生します。{{</* /tab */>}}
|
||||
{{</* tab name="Videos" icon="film" */>}}動画コンテンツを視聴・ストリーミングします。{{</* /tab */>}}
|
||||
{{</* /tabs */>}}
|
||||
```
|
||||
|
||||

|
||||
|
||||
### 画像ズーム
|
||||
|
||||
[medium-zoom](https://github.com/francoischalifour/medium-zoom) を利用した新しい設定オプションで、Markdown 画像のクリックズームを有効にできます。
|
||||
|
||||
```yaml {filename="hugo.yaml"}
|
||||
params:
|
||||
imageZoom:
|
||||
enable: true
|
||||
```
|
||||
|
||||
### GoatCounter アナリティクス
|
||||
|
||||
既存の Google Analytics、Umami、Matomo に加え、[GoatCounter](https://www.goatcounter.com/) アナリティクスの組み込みサポートを追加しました。
|
||||
|
||||
### メインサイドバーの非表示
|
||||
|
||||
新しいフロントマターパラメータにより、デスクトップでメインサイドバーを非表示にしてコンテンツを全幅表示できます。
|
||||
|
||||
```yaml {filename="content/my-page.md"}
|
||||
---
|
||||
title: My Page
|
||||
sidebar:
|
||||
hide: true
|
||||
---
|
||||
```
|
||||
|
||||
### 最終更新者の表示
|
||||
|
||||
Hugo の GitInfo を使って、「最終更新日」と合わせて最終コミット者を表示します。
|
||||
|
||||
```yaml {filename="hugo.yaml"}
|
||||
params:
|
||||
displayUpdatedAuthor: true
|
||||
```
|
||||
|
||||

|
||||
|
||||
### 前へ/次へナビゲーションの無効化
|
||||
|
||||
サイト全体で前へ/次へナビゲーションボタンを無効にできます:
|
||||
|
||||
```yaml {filename="hugo.yaml"}
|
||||
params:
|
||||
page:
|
||||
displayPagination: false
|
||||
```
|
||||
|
||||
### LLMs.txt 除外
|
||||
|
||||
フロントマターで `llms: false` を設定すると、個別のページやセクション全体を `llms.txt` 出力から除外できます。
|
||||
|
||||
```yaml {filename="content/private-page.md"}
|
||||
---
|
||||
title: "Private Page"
|
||||
llms: false
|
||||
---
|
||||
```
|
||||
|
||||
### アーカイブページ
|
||||
|
||||
新しい組み込み `archives` レイアウトは、ブログ記事を年ごとにグループ化した時系列タイムラインで表示し、各タイトルの後にタグをインラインで表示します。
|
||||
|
||||
```yaml {filename="content/archives/_index.md"}
|
||||
---
|
||||
title: Archives
|
||||
layout: archives
|
||||
---
|
||||
```
|
||||
|
||||

|
||||
|
||||
### 用語集
|
||||
|
||||
サイト全体の[用語集]({{% relref "docs/guide/shortcodes/term" %}})。専用のリストページとインライン定義用の `term` ショートコードを備えています。
|
||||
|
||||
## アクセシビリティ
|
||||
|
||||
包括的な WCAG 2.2 AA アクセシビリティ改善 (#924):
|
||||
|
||||
- すべてのページに本文へスキップリンクと ARIA ランドマークロール
|
||||
- すべてのインタラクティブウィジェット(テーマトグル、タブ、サイドバー、ファイルツリー、ドロップダウン、検索、メニュー)に ARIA 属性
|
||||
- タブとテーマトグルのキーボードナビゲーション(矢印キー、Enter、Escape)
|
||||
- `prefers-reduced-motion` サポートとグローバル `focus-visible` スタイル
|
||||
- 全 21 ロケールに完全翻訳された 15 個の新しい i18n アクセシビリティキー
|
||||
- ハードコードされた英語 `aria-label` 文字列をすべて i18n ルックアップに置き換え
|
||||
|
||||
## 利便性の向上
|
||||
|
||||
- テーブルの読みやすさ向上のためのスタイル改善
|
||||
- ヘッダーでの Markdown 属性サポート
|
||||
- 多言語セクションランディングページでのアクティブリンク検出の改善
|
||||
- カードショートコードで画像に `alt` パラメータをオプションでサポート
|
||||
- ページバンドル画像が OpenGraph メタデータでサポート
|
||||
- コンテンツ幅がデフォルトで安定し、カスタムレイアウト用の CSS 変数オーバーライドをサポート
|
||||
|
||||
## 修正
|
||||
|
||||
- render-link での `relref` ベースプレフィックスの二重付与を修正
|
||||
- ステップ内にネストされたタブの描画を修正
|
||||
- モバイルサイドバーの順序とラベルを `menu.main` に準拠
|
||||
- サイドバーでの `search.enable` の尊重
|
||||
- モバイルドロップダウンでの `toc` ページパラメータの尊重
|
||||
- FlexSearch のマッチハイライトと安全な DOM 操作の改善
|
||||
- カードのサブタイトル位置の修正
|
||||
- サブパスデプロイメントでの OG 画像パスの先頭スラッシュの処理
|
||||
- FlexSearch が期待より少ない結果ページを返す問題の修正
|
||||
- Umami アナリティクスのデフォルトファイルを `script.js` に変更
|
||||
- Hugo v0.156.0+ での RSS author ルックアップの修正 (`.Site.Params.Author`)
|
||||
|
||||
## ドキュメントと i18n
|
||||
|
||||
- イタリア語ローカリゼーションを追加
|
||||
- KaTeX ドキュメントへのリンクを追加
|
||||
- details ショートコードのドキュメントを angle bracket 構文に更新
|
||||
|
||||
## コントリビューター
|
||||
|
||||
このリリースは 11 名の新しいコントリビューターの貢献により実現しました:
|
||||
|
||||
- [@ghac101](https://github.com/ghac101) - Umami アナリティクスの修正、前へ/次へナビゲーションの無効化
|
||||
- [@pmarrapese](https://github.com/pmarrapese) - ヘッダーの Markdown 属性サポート
|
||||
- [@Bubbler-4](https://github.com/Bubbler-4) - details ショートコードのドキュメント
|
||||
- [@bloovis](https://github.com/bloovis) - FlexSearch の結果件数修正
|
||||
- [@AntoninPvr](https://github.com/AntoninPvr) - カードのサブタイトル位置修正
|
||||
- [@illia-v](https://github.com/illia-v) - モバイル TOC と検索トグルの修正
|
||||
- [@gallochri](https://github.com/gallochri) - イタリア語ローカリゼーション
|
||||
- [@MatheusFlausino](https://github.com/MatheusFlausino) - LLMs.txt 除外
|
||||
- [@daniseijo](https://github.com/daniseijo) - 最終更新者機能
|
||||
- [@confusedkernel](https://github.com/confusedkernel) - アーカイブページ
|
||||
- [@Fenyutanchan](https://github.com/Fenyutanchan) - Hugo v0.156.0 RSS author 互換性修正
|
||||
|
||||
さらに、継続的な貢献をいただいている [@KStocky](https://github.com/KStocky)、[@ldez](https://github.com/ldez)、[@kowyo](https://github.com/kowyo)、[@torbjornbp](https://github.com/torbjornbp)、[@yuri1969](https://github.com/yuri1969)、[@PrintN](https://github.com/PrintN) の各コントリビューターに感謝いたします。
|
||||
|
||||
---
|
||||
|
||||
**完全な変更履歴**: https://github.com/imfing/hextra/compare/v0.11.1...v0.12.0
|
||||
@@ -0,0 +1,218 @@
|
||||
---
|
||||
title: "Hextra v0.12"
|
||||
date: 2026-02-20
|
||||
authors:
|
||||
- name: imfing
|
||||
link: https://github.com/imfing
|
||||
image: https://github.com/imfing.png
|
||||
tags:
|
||||
- Release
|
||||
---
|
||||
|
||||
Hextra v0.12.0 delivers a rich set of new features including page context menus, image zoom, redesigned tabs, and more, plus comprehensive WCAG 2.2 AA accessibility improvements and numerous bug fixes.
|
||||
|
||||
<!--more-->
|
||||
|
||||
## Upgrade Guide
|
||||
|
||||
No breaking changes are expected for most sites. Update using [Hugo Modules](https://gohugo.io/hugo-modules/use-modules/):
|
||||
|
||||
```bash
|
||||
hugo mod get -u github.com/imfing/hextra
|
||||
```
|
||||
|
||||
## Highlights
|
||||
|
||||
- Page context menu for copying/viewing Markdown source
|
||||
- Redesigned tabs shortcode with per-tab naming and icon support
|
||||
- Click-to-zoom for Markdown images
|
||||
- GoatCounter analytics support
|
||||
- Option to hide the main sidebar on desktop
|
||||
- Display last modified author via GitInfo
|
||||
- Option to disable prev/next navigation
|
||||
- Built-in archives page for chronological blog post listings
|
||||
- Term glossary shortcode and layout
|
||||
- Exclude pages/sections from llms.txt
|
||||
- Mobile sidebar ordering and labels aligned with `menu.main`
|
||||
- Stable content width with CSS variable override support
|
||||
- Comprehensive WCAG 2.2 AA accessibility improvements
|
||||
|
||||
## New Features
|
||||
|
||||
### Page Context Menu
|
||||
|
||||

|
||||
|
||||
The page context menu provides a dropdown button that lets you copy the page content as Markdown or view the raw Markdown source. As more users feed documentation into generative AI tools, having quick access to clean Markdown is increasingly useful. Custom links with template variables (`{url}`, `{title}`, `{markdown_url}`) let you wire up "Ask AI" shortcuts or other integrations directly in the menu.
|
||||
|
||||
To use the "View as Markdown" and `{markdown_url}` features, enable the Markdown output format in your site configuration:
|
||||
|
||||
```yaml {filename="hugo.yaml"}
|
||||
outputs:
|
||||
page: [html, markdown]
|
||||
section: [html, rss, markdown]
|
||||
```
|
||||
|
||||
Then configure the context menu:
|
||||
|
||||
```yaml {filename="hugo.yaml"}
|
||||
params:
|
||||
page:
|
||||
contextMenu:
|
||||
enable: true
|
||||
links:
|
||||
- name: "Ask AI"
|
||||
url: "https://example.com?content={markdown_url}"
|
||||
icon: "sparkles"
|
||||
```
|
||||
|
||||
### Tabs Revamp and Icon Support
|
||||
|
||||
The [tabs shortcode]({{% relref "docs/guide/shortcodes/tabs" %}}) has been redesigned. Tab names can now be set directly on each `tab` shortcode, and an optional `icon` parameter displays an icon before the tab label. The previous syntax is still supported.
|
||||
|
||||
```md
|
||||
{{</* tabs */>}}
|
||||
{{</* tab name="Photos" icon="photograph" */>}}Manage and organize your photo library.{{</* /tab */>}}
|
||||
{{</* tab name="Music" icon="music-note" */>}}Browse and play your favorite tracks.{{</* /tab */>}}
|
||||
{{</* tab name="Videos" icon="film" */>}}Watch and stream video content.{{</* /tab */>}}
|
||||
{{</* /tabs */>}}
|
||||
```
|
||||
|
||||

|
||||
|
||||
### Image Zoom
|
||||
|
||||
Enable click-to-zoom on Markdown images with a new configuration option, powered by [medium-zoom](https://github.com/francoischalifour/medium-zoom).
|
||||
|
||||
```yaml {filename="hugo.yaml"}
|
||||
params:
|
||||
imageZoom:
|
||||
enable: true
|
||||
```
|
||||
|
||||
### GoatCounter Analytics
|
||||
|
||||
Built-in support for [GoatCounter](https://www.goatcounter.com/) analytics alongside existing Google Analytics, Umami, and Matomo integrations.
|
||||
|
||||
### Hide Main Sidebar
|
||||
|
||||
A new front matter parameter allows hiding the main sidebar on desktop to give content pages the full width.
|
||||
|
||||
```yaml {filename="content/my-page.md"}
|
||||
---
|
||||
title: My Page
|
||||
sidebar:
|
||||
hide: true
|
||||
---
|
||||
```
|
||||
|
||||
### Last Modified Author
|
||||
|
||||
Display the last commit author alongside the "last updated" date using Hugo's GitInfo.
|
||||
|
||||
```yaml {filename="hugo.yaml"}
|
||||
params:
|
||||
displayUpdatedAuthor: true
|
||||
```
|
||||
|
||||

|
||||
|
||||
### Disable Prev/Next Navigation
|
||||
|
||||
Disable the previous/next navigation buttons site-wide:
|
||||
|
||||
```yaml {filename="hugo.yaml"}
|
||||
params:
|
||||
page:
|
||||
displayPagination: false
|
||||
```
|
||||
|
||||
### LLMs.txt Exclusion
|
||||
|
||||
Exclude individual pages or entire sections from `llms.txt` output by setting `llms: false` in front matter.
|
||||
|
||||
```yaml {filename="content/private-page.md"}
|
||||
---
|
||||
title: "Private Page"
|
||||
llms: false
|
||||
---
|
||||
```
|
||||
|
||||
### Archives Page
|
||||
|
||||
A new built-in `archives` layout displays blog posts in a chronological timeline grouped by year, with tags shown inline after each post title.
|
||||
|
||||
```yaml {filename="content/archives/_index.md"}
|
||||
---
|
||||
title: Archives
|
||||
layout: archives
|
||||
---
|
||||
```
|
||||
|
||||

|
||||
|
||||
### Glossary
|
||||
|
||||
A site-wide terminology [glossary]({{% relref "docs/guide/shortcodes/term" %}}) with a dedicated listing page and a `term` shortcode for inline definitions.
|
||||
|
||||
## Accessibility
|
||||
|
||||
Comprehensive WCAG 2.2 AA accessibility improvements (#924):
|
||||
|
||||
- Skip-to-content link and ARIA landmark roles on all pages
|
||||
- ARIA attributes on all interactive widgets (theme toggle, tabs, sidebar, filetree, dropdowns, search, menus)
|
||||
- Keyboard navigation for tabs and theme toggle (arrow keys, Enter, Escape)
|
||||
- `prefers-reduced-motion` support and global `focus-visible` styles
|
||||
- 15 new i18n accessibility keys with full translations across all 21 locales
|
||||
- Replaced all hardcoded English `aria-label` strings with i18n lookups
|
||||
|
||||
## Quality of Life
|
||||
|
||||
- Improved table readability styles
|
||||
- Markdown attribute support for headers
|
||||
- Better active link detection for multilingual section landing pages
|
||||
- Card shortcode supports optional `alt` parameter for images
|
||||
- Page bundle images supported in OpenGraph metadata
|
||||
- Content width now stays consistent by default, with CSS variable override support for custom layouts
|
||||
|
||||
## Fixes
|
||||
|
||||
- Prevent `relref` double base-prefix in render-link
|
||||
- Fix tabs rendering when nested inside steps
|
||||
- Align mobile sidebar ordering and labels with `menu.main`
|
||||
- Respect `search.enable` in the sidebar
|
||||
- Respect the `toc` page parameter in mobile dropdown
|
||||
- Enhance FlexSearch match highlighting and safe DOM manipulation
|
||||
- Fix card subtitle positioning
|
||||
- Handle leading slashes in OG image paths for subpath deployments
|
||||
- Fix FlexSearch returning fewer than expected result pages
|
||||
- Change default Umami analytics file to `script.js`
|
||||
- Fix RSS author lookup for Hugo v0.156.0+ (`.Site.Params.Author`)
|
||||
|
||||
## Documentation & i18n
|
||||
|
||||
- Add Italian localization
|
||||
- Link KaTeX documentation
|
||||
- Update details shortcode docs to angle bracket syntax
|
||||
|
||||
## Contributors
|
||||
|
||||
This release was made possible by contributions from 11 new contributors:
|
||||
|
||||
- [@ghac101](https://github.com/ghac101) - Umami analytics fix, disable prev/next navigation
|
||||
- [@pmarrapese](https://github.com/pmarrapese) - Markdown attribute support for headers
|
||||
- [@Bubbler-4](https://github.com/Bubbler-4) - Details shortcode documentation
|
||||
- [@bloovis](https://github.com/bloovis) - FlexSearch result count fix
|
||||
- [@AntoninPvr](https://github.com/AntoninPvr) - Card subtitle positioning fix
|
||||
- [@illia-v](https://github.com/illia-v) - Mobile TOC and search toggle fixes
|
||||
- [@gallochri](https://github.com/gallochri) - Italian localization
|
||||
- [@MatheusFlausino](https://github.com/MatheusFlausino) - LLMs.txt exclusion
|
||||
- [@daniseijo](https://github.com/daniseijo) - Last modified author feature
|
||||
- [@confusedkernel](https://github.com/confusedkernel) - Archives page
|
||||
- [@Fenyutanchan](https://github.com/Fenyutanchan) - Hugo v0.156.0 RSS author compatibility fix
|
||||
|
||||
Additional thanks to returning contributors [@KStocky](https://github.com/KStocky), [@ldez](https://github.com/ldez), [@kowyo](https://github.com/kowyo), [@torbjornbp](https://github.com/torbjornbp), [@yuri1969](https://github.com/yuri1969), and [@PrintN](https://github.com/PrintN) for their continued contributions.
|
||||
|
||||
---
|
||||
|
||||
**Full Changelog**: https://github.com/imfing/hextra/compare/v0.11.1...v0.12.0
|
||||
@@ -0,0 +1,218 @@
|
||||
---
|
||||
title: "Hextra v0.12"
|
||||
date: 2026-02-20
|
||||
authors:
|
||||
- name: imfing
|
||||
link: https://github.com/imfing
|
||||
image: https://github.com/imfing.png
|
||||
tags:
|
||||
- Release
|
||||
---
|
||||
|
||||
Hextra v0.12.0 带来了丰富的新功能,包括页面上下文菜单、图片缩放、全新设计的标签页等,同时提供全面的 WCAG 2.2 AA 无障碍改进和大量错误修复。
|
||||
|
||||
<!--more-->
|
||||
|
||||
## 升级指南
|
||||
|
||||
对大多数站点而言没有破坏性变更。使用 [Hugo Modules](https://gohugo.io/hugo-modules/use-modules/) 更新:
|
||||
|
||||
```bash
|
||||
hugo mod get -u github.com/imfing/hextra
|
||||
```
|
||||
|
||||
## 亮点
|
||||
|
||||
- 页面上下文菜单,可复制/查看 Markdown 源码
|
||||
- 全新设计的标签页短代码,支持单独命名和图标
|
||||
- Markdown 图片点击缩放
|
||||
- GoatCounter 分析支持
|
||||
- 桌面端隐藏主侧边栏选项
|
||||
- 通过 GitInfo 显示最后修改作者
|
||||
- 禁用上一篇/下一篇导航选项
|
||||
- 内置归档页面,按时间顺序列出博客文章
|
||||
- 术语表短代码和布局
|
||||
- 从 llms.txt 中排除页面/章节
|
||||
- 移动端侧边栏排序和标签与 `menu.main` 对齐
|
||||
- 通过 CSS 变量覆盖支持稳定的内容宽度
|
||||
- 全面的 WCAG 2.2 AA 无障碍改进
|
||||
|
||||
## 新功能
|
||||
|
||||
### 页面上下文菜单
|
||||
|
||||

|
||||
|
||||
页面上下文菜单提供下拉按钮,可将页面内容复制为 Markdown 或查看原始 Markdown 源码。随着越来越多用户将文档输入生成式 AI 工具,快速获取干净的 Markdown 变得越来越有用。通过模板变量(`{url}`、`{title}`、`{markdown_url}`)添加自定义链接,可以在菜单中直接集成“询问 AI”快捷方式或其他功能。
|
||||
|
||||
要使用“以 Markdown 查看”和 `{markdown_url}` 功能,请在站点配置中启用 Markdown 输出格式:
|
||||
|
||||
```yaml {filename="hugo.yaml"}
|
||||
outputs:
|
||||
page: [html, markdown]
|
||||
section: [html, rss, markdown]
|
||||
```
|
||||
|
||||
然后配置页面上下文菜单:
|
||||
|
||||
```yaml {filename="hugo.yaml"}
|
||||
params:
|
||||
page:
|
||||
contextMenu:
|
||||
enable: true
|
||||
links:
|
||||
- name: "Ask AI"
|
||||
url: "https://example.com?content={markdown_url}"
|
||||
icon: "sparkles"
|
||||
```
|
||||
|
||||
### 标签页重设计与图标支持
|
||||
|
||||
[标签页短代码]({{% relref "docs/guide/shortcodes/tabs" %}})经过重新设计。现在可以直接在每个 `tab` 短代码上设置标签名称,可选的 `icon` 参数可在标签文字前显示图标。之前的语法仍然支持。
|
||||
|
||||
```md
|
||||
{{</* tabs */>}}
|
||||
{{</* tab name="Photos" icon="photograph" */>}}管理和整理您的照片库。{{</* /tab */>}}
|
||||
{{</* tab name="Music" icon="music-note" */>}}浏览和播放您喜爱的曲目。{{</* /tab */>}}
|
||||
{{</* tab name="Videos" icon="film" */>}}观看和串流视频内容。{{</* /tab */>}}
|
||||
{{</* /tabs */>}}
|
||||
```
|
||||
|
||||

|
||||
|
||||
### 图片缩放
|
||||
|
||||
通过新的配置选项,启用 Markdown 图片的点击缩放功能,基于 [medium-zoom](https://github.com/francoischalifour/medium-zoom) 实现。
|
||||
|
||||
```yaml {filename="hugo.yaml"}
|
||||
params:
|
||||
imageZoom:
|
||||
enable: true
|
||||
```
|
||||
|
||||
### GoatCounter 分析
|
||||
|
||||
在现有的 Google Analytics、Umami 和 Matomo 集成之外,新增 [GoatCounter](https://www.goatcounter.com/) 分析的内置支持。
|
||||
|
||||
### 隐藏主侧边栏
|
||||
|
||||
新的 Front Matter 参数允许在桌面端隐藏主侧边栏,使内容页面获得全宽显示。
|
||||
|
||||
```yaml {filename="content/my-page.md"}
|
||||
---
|
||||
title: My Page
|
||||
sidebar:
|
||||
hide: true
|
||||
---
|
||||
```
|
||||
|
||||
### 最后修改作者
|
||||
|
||||
使用 Hugo 的 GitInfo 功能,在"最后更新"日期旁显示最后提交的作者。
|
||||
|
||||
```yaml {filename="hugo.yaml"}
|
||||
params:
|
||||
displayUpdatedAuthor: true
|
||||
```
|
||||
|
||||

|
||||
|
||||
### 禁用上一篇/下一篇导航
|
||||
|
||||
在站点范围内禁用上一篇/下一篇导航按钮:
|
||||
|
||||
```yaml {filename="hugo.yaml"}
|
||||
params:
|
||||
page:
|
||||
displayPagination: false
|
||||
```
|
||||
|
||||
### LLMs.txt 排除
|
||||
|
||||
通过在 Front Matter 中设置 `llms: false`,将单个页面或整个章节从 `llms.txt` 输出中排除。
|
||||
|
||||
```yaml {filename="content/private-page.md"}
|
||||
---
|
||||
title: "Private Page"
|
||||
llms: false
|
||||
---
|
||||
```
|
||||
|
||||
### 归档页面
|
||||
|
||||
新的内置 `archives` 布局按年份分组,以时间线形式展示博客文章,每篇文章标题后内联显示标签。
|
||||
|
||||
```yaml {filename="content/archives/_index.md"}
|
||||
---
|
||||
title: Archives
|
||||
layout: archives
|
||||
---
|
||||
```
|
||||
|
||||

|
||||
|
||||
### 术语表
|
||||
|
||||
站点级[术语表]({{% relref "docs/guide/shortcodes/term" %}}),提供专用列表页面和用于内联定义的 `term` 短代码。
|
||||
|
||||
## 无障碍
|
||||
|
||||
全面的 WCAG 2.2 AA 无障碍改进 (#924):
|
||||
|
||||
- 所有页面添加跳转到内容链接和 ARIA 地标角色
|
||||
- 所有交互组件(主题切换、标签页、侧边栏、文件树、下拉菜单、搜索、菜单)添加 ARIA 属性
|
||||
- 标签页和主题切换的键盘导航(方向键、Enter、Escape)
|
||||
- 支持 `prefers-reduced-motion` 和全局 `focus-visible` 样式
|
||||
- 15 个新的 i18n 无障碍键,在全部 21 个语言环境中提供完整翻译
|
||||
- 将所有硬编码的英文 `aria-label` 字符串替换为 i18n 查找
|
||||
|
||||
## 使用体验优化
|
||||
|
||||
- 改进表格可读性样式
|
||||
- 标题支持 Markdown 属性
|
||||
- 多语言章节着陆页的活动链接检测改进
|
||||
- 卡片短代码支持可选的图片 `alt` 参数
|
||||
- OpenGraph 元数据支持页面资源包图片
|
||||
- 内容宽度默认保持一致,支持通过 CSS 变量覆盖自定义布局
|
||||
|
||||
## 修复
|
||||
|
||||
- 修复 render-link 中 `relref` 基础前缀重复问题
|
||||
- 修复嵌套在步骤中的标签页渲染
|
||||
- 移动端侧边栏排序和标签与 `menu.main` 对齐
|
||||
- 侧边栏中遵循 `search.enable` 设置
|
||||
- 移动端下拉菜单中遵循 `toc` 页面参数
|
||||
- 增强 FlexSearch 匹配高亮和安全的 DOM 操作
|
||||
- 修复卡片副标题定位
|
||||
- 处理子路径部署中 OG 图片路径的前导斜杠
|
||||
- 修复 FlexSearch 返回结果页数少于预期的问题
|
||||
- 将 Umami 分析的默认文件改为 `script.js`
|
||||
- 修复 Hugo v0.156.0+ 的 RSS 作者查找 (`.Site.Params.Author`)
|
||||
|
||||
## 文档与 i18n
|
||||
|
||||
- 添加意大利语本地化
|
||||
- 链接 KaTeX 文档
|
||||
- 将 details 短代码文档更新为尖括号语法
|
||||
|
||||
## 贡献者
|
||||
|
||||
此版本由 11 位新贡献者共同参与完成:
|
||||
|
||||
- [@ghac101](https://github.com/ghac101) - Umami 分析修复、禁用上一篇/下一篇导航
|
||||
- [@pmarrapese](https://github.com/pmarrapese) - 标题 Markdown 属性支持
|
||||
- [@Bubbler-4](https://github.com/Bubbler-4) - details 短代码文档
|
||||
- [@bloovis](https://github.com/bloovis) - FlexSearch 结果计数修复
|
||||
- [@AntoninPvr](https://github.com/AntoninPvr) - 卡片副标题定位修复
|
||||
- [@illia-v](https://github.com/illia-v) - 移动端目录和搜索切换修复
|
||||
- [@gallochri](https://github.com/gallochri) - 意大利语本地化
|
||||
- [@MatheusFlausino](https://github.com/MatheusFlausino) - LLMs.txt 排除
|
||||
- [@daniseijo](https://github.com/daniseijo) - 最后修改作者功能
|
||||
- [@confusedkernel](https://github.com/confusedkernel) - 归档页面
|
||||
- [@Fenyutanchan](https://github.com/Fenyutanchan) - Hugo v0.156.0 RSS 作者兼容性修复
|
||||
|
||||
同时感谢回归贡献者 [@KStocky](https://github.com/KStocky)、[@ldez](https://github.com/ldez)、[@kowyo](https://github.com/kowyo)、[@torbjornbp](https://github.com/torbjornbp)、[@yuri1969](https://github.com/yuri1969) 和 [@PrintN](https://github.com/PrintN) 的持续贡献。
|
||||
|
||||
---
|
||||
|
||||
**完整变更日志**: https://github.com/imfing/hextra/compare/v0.11.1...v0.12.0
|
||||
@@ -0,0 +1,42 @@
|
||||
---
|
||||
linkTitle: "مستندات"
|
||||
title: معرفی
|
||||
---
|
||||
|
||||
👋 سلام! به مستندات Hextra خوش آمدید!
|
||||
|
||||
<!--more-->
|
||||
|
||||
## Hextra چیست؟
|
||||
|
||||
Hextra یک پوسته مدرن، سریع و کامل برای [Hugo][hugo] است که با [Tailwind CSS][tailwind-css] ساخته شده است.
|
||||
این پوسته برای ساخت وبسایتهای زیبا برای مستندات، وبلاگها و وبسایتها طراحی شده و امکاناتی را به صورت پیشفرض ارائه میدهد که انعطاف لازم برای پاسخگویی به نیازهای مختلف را دارد.
|
||||
|
||||
## ویژگیها
|
||||
|
||||
- **طراحی زیبا** - با الهام از Nextra، Hextra از Tailwind CSS استفاده میکند تا طراحی مدرنی ارائه دهد که سایت شما را برجسته میکند.
|
||||
- **چیدمان واکنشگرا و حالت تاریک** - در تمام دستگاهها از موبایل و تبلت تا دسکتاپ عالی به نظر میرسد. حالت تاریک نیز پشتیبانی میشود تا شرایط نوری مختلف را پوشش دهد.
|
||||
- **سریع و سبکوزن** - با قدرت Hugo، یک مولد سایت استاتیک فوقالعاده سریع که در یک فایل باینری واحد قرار دارد، Hextra ردپای کوچکی دارد. برای استفاده از آن نیازی به JavaScript یا Node.js نیست.
|
||||
- **جستجوی تماممتن** - جستجوی تماممتن آفلاین داخلی با قدرت FlexSearch، بدون نیاز به پیکربندی اضافی.
|
||||
- **کامل و آماده استفاده** - عناصر Markdown، برجستهسازی سینتکس، فرمولهای ریاضی LaTeX، نمودارها و Shortcodes برای غنیتر کردن محتوای شما. فهرست مطالب، مسیرهای ناوبری، صفحهبندی، نوار کناری و موارد دیگر همگی به صورت خودکار تولید میشوند.
|
||||
- **چندزبانه و آماده برای سئو** - ساخت سایتهای چندزبانه با حالت چندزبانه Hugo آسان شده است. پشتیبانی پیشفرض برای تگهای سئو، Open Graph و Twitter Cards وجود دارد.
|
||||
- **پشتیبانی از دسترسپذیری** - اجزای تعاملی از نشانهگذاری معنایی، رفتار سازگار با صفحهکلید و بررسیهای خودکار دسترسپذیری استفاده میکنند تا رابط کاربری در گردشکارهای رایج فناوریهای کمکی قابل استفاده بماند.
|
||||
|
||||
## سوال یا بازخورد دارید؟
|
||||
|
||||
{{< callout emoji="❓" >}}
|
||||
Hextra هنوز در حال توسعه فعال است.
|
||||
سوال یا بازخوردی دارید؟ با خیال راحت [یک issue باز کنید](https://github.com/imfing/hextra/issues)!
|
||||
{{< /callout >}}
|
||||
|
||||
## بعدی
|
||||
|
||||
برای شروع، مستقیماً به بخش زیر بروید:
|
||||
|
||||
{{< cards >}}
|
||||
{{< card link="getting-started" title="شروع به کار" icon="document-text" subtitle="یاد بگیرید چگونه با استفاده از Hextra وبسایت بسازید" >}}
|
||||
{{< /cards >}}
|
||||
|
||||
[hugo]: https://gohugo.io/
|
||||
[flex-search]: https://github.com/nextapps-de/flexsearch
|
||||
[tailwind-css]: https://tailwindcss.com/
|
||||
@@ -0,0 +1,41 @@
|
||||
---
|
||||
linkTitle: "ドキュメント"
|
||||
title: はじめに
|
||||
---
|
||||
|
||||
👋 こんにちは!Hextra ドキュメントへようこそ!
|
||||
|
||||
<!--more-->
|
||||
|
||||
## Hextra とは?
|
||||
|
||||
Hextraは、[Tailwind CSS][tailwind-css]を使用して構築された、モダンで高速かつ機能豊富な[Hugo][hugo]テーマです。ドキュメンテーション、ブログ、ウェブサイトのための美しいウェブサイトを構築するために設計されており、さまざまな要件に対応するための機能と柔軟性を提供します。
|
||||
|
||||
## 特徴
|
||||
|
||||
- **美しいデザイン** - Nextra にインスパイアされ、Tailwind CSS を活用したモダンなデザインで、サイトを際立たせます。
|
||||
- **レスポンシブレイアウトとダークモード** - モバイル、タブレット、デスクトップなど、すべてのデバイスで美しく表示されます。また、さまざまな照明条件に対応するため、ダークモードもサポートされています。
|
||||
- **高速で軽量** - 単一のバイナリファイルで提供される超高速な静的サイトジェネレータ Hugo を採用しており、Hextra はフットプリントを最小限に抑えています。JavaScript や Node.js は必要ありません。
|
||||
- **全文検索** - FlexSearch を利用したオフライン全文検索が組み込まれており、追加の設定は不要です。
|
||||
- **バッテリーインクルード** - コンテンツを強化するための Markdown、シンタックスハイライト、LaTeX 数式、ダイアグラム、ショートコード要素が利用可能です。目次、パンくずリスト、ページネーション、サイドバーナビゲーションなどはすべて自動生成されます。
|
||||
- **多言語対応とSEO準備完了** - Hugo の多言語モードを利用して、多言語サイトを簡単に構築できます。SEO タグ、Open Graph、Twitter Cards のサポートも標準で提供されています。
|
||||
- **アクセシビリティ対応** - インタラクティブなコンポーネントは、意味論的なマークアップ、キーボードで使いやすい挙動、自動アクセシビリティチェックを備えており、一般的な支援技術の利用環境でも使いやすさを保ちます。
|
||||
|
||||
## 質問やフィードバック
|
||||
|
||||
{{< callout emoji="❓" >}}
|
||||
Hextra は現在も活発に開発中です。
|
||||
質問やフィードバックがありましたら、[issue を開いて](https://github.com/imfing/hextra/issues)ください!
|
||||
{{< /callout >}}
|
||||
|
||||
## 次に
|
||||
|
||||
以下のセクションから始めましょう:
|
||||
|
||||
{{< cards >}}
|
||||
{{< card link="getting-started" title="はじめに" icon="document-text" subtitle="Hextra を使ってウェブサイトを作成する方法を学ぶ" >}}
|
||||
{{< /cards >}}
|
||||
|
||||
[hugo]: https://gohugo.io/
|
||||
[flex-search]: https://github.com/nextapps-de/flexsearch
|
||||
[tailwind-css]: https://tailwindcss.com/
|
||||
@@ -0,0 +1,42 @@
|
||||
---
|
||||
linkTitle: "Documentation"
|
||||
title: Introduction
|
||||
---
|
||||
|
||||
👋 Hello! Welcome to the Hextra documentation!
|
||||
|
||||
<!--more-->
|
||||
|
||||
## What is Hextra?
|
||||
|
||||
Hextra is a modern, fast and batteries-included [Hugo][hugo] theme built with [Tailwind CSS][tailwind-css].
|
||||
Designed for building beautiful websites for documentation, blogs, and websites, it provides out-of-the-box features and flexibility to meet various requirements.
|
||||
|
||||
## Features
|
||||
|
||||
- **Beautiful Design** - Inspired by Nextra, Hextra utilizes Tailwind CSS to offer a modern design that makes your site look outstanding.
|
||||
- **Responsive Layout and Dark Mode** - It looks great on all devices, from mobile, tablet to desktop. Dark mode is also supported to accommodate various lighting conditions.
|
||||
- **Fast and Lightweight** - Powered by Hugo, a lightning-fast static-site generator housed in a single binary file, Hextra keeps its footprint minimal. No JavaScript or Node.js are needed to use it.
|
||||
- **Full-text Search** - Built-in offline full-text search powered by FlexSearch, no additional configuration required.
|
||||
- **Battery-included** - Markdown, syntax highlighting, LaTeX math formulae, diagrams and Shortcodes elements to enhance your content. Table of contents, breadcrumbs, pagination, sidebar navigation and more are all automatically generated.
|
||||
- **Multi-language and SEO Ready** - Multi-language sites made easy with Hugo's multilingual mode. Out-of-the-box support is included for SEO tags, Open Graph, and Twitter Cards.
|
||||
- **Accessibility Support** - Interactive components use semantic markup, keyboard-friendly behavior, and automated accessibility checks to keep the UI usable across common assistive workflows.
|
||||
|
||||
## Questions or Feedback?
|
||||
|
||||
{{< callout emoji="❓" >}}
|
||||
Hextra is still in active development.
|
||||
Have a question or feedback? Feel free to [open an issue](https://github.com/imfing/hextra/issues)!
|
||||
{{< /callout >}}
|
||||
|
||||
## Next
|
||||
|
||||
Dive right into the following section to get started:
|
||||
|
||||
{{< cards >}}
|
||||
{{< card link="getting-started" title="Getting Started" icon="document-text" subtitle="Learn how to create website using Hextra" >}}
|
||||
{{< /cards >}}
|
||||
|
||||
[hugo]: https://gohugo.io/
|
||||
[flex-search]: https://github.com/nextapps-de/flexsearch
|
||||
[tailwind-css]: https://tailwindcss.com/
|
||||
@@ -0,0 +1,41 @@
|
||||
---
|
||||
linkTitle: "文档"
|
||||
title: 简介
|
||||
---
|
||||
|
||||
👋 你好!欢迎来到 Hextra 文档中心!
|
||||
|
||||
<!--more-->
|
||||
|
||||
## 什么是 Hextra?
|
||||
|
||||
Hextra 是一个基于 [Tailwind CSS][tailwind-css] 构建的现代化、高性能且开箱即用的 [Hugo][hugo] 主题。专为打造文档、博客和网站而设计,它提供丰富的内置功能和灵活配置,满足多样化需求。
|
||||
|
||||
## 核心特性
|
||||
|
||||
- **精美设计** - 灵感源自 Nextra,采用 Tailwind CSS 实现现代美学,让您的站点脱颖而出。
|
||||
- **响应式布局与暗黑模式** - 完美适配移动设备、平板及桌面端,并支持根据环境光线自动切换的暗黑模式。
|
||||
- **极速轻量** - 依托 Hugo 静态网站生成器的单文件二进制架构,无需 JavaScript 或 Node.js 环境即可运行。
|
||||
- **全文搜索** - 内置基于 FlexSearch 的离线全文搜索功能,零配置开箱即用。
|
||||
- **功能完备** - 支持 Markdown 语法高亮、LaTeX 数学公式、图表和 Shortcodes 等丰富内容元素。自动生成目录导航、面包屑、分页及侧边栏等组件。
|
||||
- **多语言与 SEO 友好** - 通过 Hugo 多语言模式轻松构建国际化站点,原生集成 SEO 标签、Open Graph 和 Twitter Cards 支持。
|
||||
- **无障碍支持** - 交互组件使用语义化标记、友好的键盘交互以及自动化无障碍检查,以便在常见辅助技术工作流中保持良好的可用性。
|
||||
|
||||
## 问题或建议?
|
||||
|
||||
{{< callout emoji="❓" >}}
|
||||
Hextra 仍在积极开发中。
|
||||
如有疑问或反馈,欢迎[提交 Issue](https://github.com/imfing/hextra/issues)!
|
||||
{{< /callout >}}
|
||||
|
||||
## 下一步
|
||||
|
||||
立即开始探索:
|
||||
|
||||
{{< cards >}}
|
||||
{{< card link="getting-started" title="快速开始" icon="document-text" subtitle="学习如何使用 Hextra 创建网站" >}}
|
||||
{{< /cards >}}
|
||||
|
||||
[hugo]: https://gohugo.io/
|
||||
[flex-search]: https://github.com/nextapps-de/flexsearch
|
||||
[tailwind-css]: https://tailwindcss.com/
|
||||
@@ -0,0 +1,17 @@
|
||||
---
|
||||
linkTitle: پیشرفته
|
||||
title: مباحث پیشرفته
|
||||
prev: /docs/guide/shortcodes/tabs
|
||||
next: /docs/advanced/multi-language
|
||||
---
|
||||
|
||||
این بخش برخی از مباحث پیشرفته این پوسته را پوشش میدهد.
|
||||
|
||||
<!--more-->
|
||||
|
||||
{{< cards >}}
|
||||
{{< card link="multi-language" title="چندزبانه" icon="translate" >}}
|
||||
{{< card link="customization" title="سفارشیسازی" icon="pencil" >}}
|
||||
{{< card link="comments" title="سیستم نظرات" icon="chat-alt" >}}
|
||||
{{< card link="additional-pages" title="صفحات اضافی" icon="library" >}}
|
||||
{{< /cards >}}
|
||||
@@ -0,0 +1,17 @@
|
||||
---
|
||||
linkTitle: 高度な設定
|
||||
title: 高度なトピック
|
||||
prev: /docs/guide/shortcodes/tabs
|
||||
next: /docs/advanced/multi-language
|
||||
---
|
||||
|
||||
このセクションでは、テーマの高度なトピックについて説明します。
|
||||
|
||||
<!--more-->
|
||||
|
||||
{{< cards >}}
|
||||
{{< card link="multi-language" title="多言語対応" icon="translate" >}}
|
||||
{{< card link="customization" title="カスタマイズ" icon="pencil" >}}
|
||||
{{< card link="comments" title="コメントシステム" icon="chat-alt" >}}
|
||||
{{< card link="additional-pages" title="追加ページ" icon="library" >}}
|
||||
{{< /cards >}}
|
||||
@@ -0,0 +1,17 @@
|
||||
---
|
||||
linkTitle: Advanced
|
||||
title: Advanced Topics
|
||||
prev: /docs/guide/shortcodes/tabs
|
||||
next: /docs/advanced/multi-language
|
||||
---
|
||||
|
||||
This section covers some advanced topics of the theme.
|
||||
|
||||
<!--more-->
|
||||
|
||||
{{< cards >}}
|
||||
{{< card link="multi-language" title="Multi-language" icon="translate" >}}
|
||||
{{< card link="customization" title="Customization" icon="pencil" >}}
|
||||
{{< card link="comments" title="Comments System" icon="chat-alt" >}}
|
||||
{{< card link="additional-pages" title="Additional Pages" icon="library" >}}
|
||||
{{< /cards >}}
|
||||
@@ -0,0 +1,17 @@
|
||||
---
|
||||
linkTitle: 高级
|
||||
title: 高级主题
|
||||
prev: /docs/guide/shortcodes/tabs
|
||||
next: /docs/advanced/multi-language
|
||||
---
|
||||
|
||||
本节涵盖该主题的一些高级内容。
|
||||
|
||||
<!--more-->
|
||||
|
||||
{{< cards >}}
|
||||
{{< card link="multi-language" title="多语言支持" icon="translate" >}}
|
||||
{{< card link="customization" title="自定义配置" icon="pencil" >}}
|
||||
{{< card link="comments" title="评论系统" icon="chat-alt" >}}
|
||||
{{< card link="additional-pages" title="附加页面" icon="library" >}}
|
||||
{{< /cards >}}
|
||||
@@ -0,0 +1,105 @@
|
||||
---
|
||||
title: "صفحات اضافی"
|
||||
weight: 1
|
||||
prev: /docs/advanced
|
||||
aliases:
|
||||
- /docs/advanced/glossary/
|
||||
---
|
||||
|
||||
Hextra چند صفحهٔ اضافی دارد که باید بهصورت جداگانه فعال شوند: واژهنامه و آرشیو.
|
||||
|
||||
<!--more-->
|
||||
|
||||
## واژهنامه
|
||||
|
||||
{{< callout type="info" >}}
|
||||
برای اطلاعات بیشتر دربارهٔ پشتیبانی واژهنامهٔ داخلی Hugo، به [مرجع سریع واژهنامهٔ Hugo](https://gohugo.io/quick-reference/glossary/) مراجعه کنید.
|
||||
{{< /callout >}}
|
||||
|
||||
### فایل دادهٔ منبع
|
||||
|
||||
تعاریف اصطلاحات بهصورت متمرکز در فایل دادهٔ `termbase.yaml` برای هر [زبان پشتیبانیشده](../multi-language/) ذخیره میشوند.
|
||||
|
||||
{{< filetree/container >}}
|
||||
{{< filetree/folder name="data" state="open" >}}
|
||||
{{< filetree/folder name="en" state="open" >}}
|
||||
{{< filetree/file name="termbase.yaml" >}}
|
||||
{{< /filetree/folder >}}
|
||||
{{< filetree/folder name="fr" state="open" >}}
|
||||
{{< filetree/file name="termbase.yaml" >}}
|
||||
{{< /filetree/folder >}}
|
||||
{{< filetree/folder name="ja" state="open" >}}
|
||||
{{< filetree/file name="termbase.yaml" >}}
|
||||
{{< /filetree/folder >}}
|
||||
{{< /filetree/folder >}}
|
||||
{{< /filetree/container >}}
|
||||
|
||||
هر فایل YAML شامل فهرستی از اصطلاحات واژهنامه است. هر ورودی شامل موارد زیر است:
|
||||
|
||||
- `term`: نام کامل مفهوم یا عبارت.
|
||||
- `definition`: توضیح یا شرح مختصر اصطلاح.
|
||||
- `abbr` (اختیاری): مخفف یا سرواژهٔ رایج اصطلاح.
|
||||
|
||||
```yaml {filename="data/fa/termbase.yaml"}
|
||||
- term: seo
|
||||
abbr: SEO
|
||||
definition: "بهینهسازی موتور جستجو – افزایش دیدهشدن یک صفحهٔ وب در نتایج موتورهای جستجو"
|
||||
- term: "سازندهٔ سایت ایستا"
|
||||
definition: "موتورهایی که ورودی متنی را پردازش کرده و صفحات وب ایستا تولید میکنند"
|
||||
```
|
||||
|
||||
### صفحهٔ واژهنامه
|
||||
|
||||
برای رندر شدن صفحهٔ نمایهٔ واژهنامه (که شامل فهرست تمام اصطلاحات تعریفشده بههمراه توضیحات و مخففهای آنهاست)،
|
||||
باید برای هر زبان پشتیبانیشده یک فایل محتوای واژهنامهٔ مخصوص همان زبان تعریف شود.
|
||||
در نام فایل از پسوند کد زبان استفاده کنید؛ برای مثال: `content/glossary/_index.fa.md`.
|
||||
|
||||
```markdown {filename="content/glossary/_index.fa.md"}
|
||||
---
|
||||
title: واژهنامه
|
||||
layout: glossary
|
||||
---
|
||||
```
|
||||
|
||||
یک صفحهٔ نمونه از واژهنامه در [واژهنامه]({{% relref "/glossary" %}}) در دسترس است.
|
||||
|
||||
## آرشیو
|
||||
|
||||
میتوانید برای نوشتههای یک بخش، یک صفحه آرشیو زمانی (گروهبندیشده بر اساس سال) بسازید.
|
||||
|
||||
1. صفحه آرشیو را ایجاد کنید:
|
||||
```yaml {filename="content/archives/_index.md"}
|
||||
---
|
||||
title: Archives
|
||||
layout: archives
|
||||
toc: false
|
||||
---
|
||||
```
|
||||
2. (اختیاری) آن را به منوی بالا اضافه کنید:
|
||||
```yaml {filename="hugo.yaml"}
|
||||
menu:
|
||||
main:
|
||||
- identifier: archives
|
||||
name: Archives
|
||||
pageRef: /archives
|
||||
```
|
||||
3. (اختیاری، چندزبانه) فایلهای آرشیو ترجمهشده با همان layout اضافه کنید، برای مثال:
|
||||
- `content/archives/_index.fa.md`
|
||||
- `content/archives/_index.ja.md`
|
||||
- `content/archives/_index.zh-cn.md`
|
||||
4. (اختیاری) بخش مورد استفاده برای آرشیو را تغییر دهید. مقدار پیشفرض `blog` است.
|
||||
```yaml {filename="hugo.yaml"}
|
||||
params:
|
||||
archives:
|
||||
section: blog
|
||||
```
|
||||
5. (اختیاری) قالب نمایش تاریخ آیتمهای آرشیو را تغییر دهید. مقدار پیشفرض `Jan 02` است.
|
||||
```yaml {filename="hugo.yaml"}
|
||||
params:
|
||||
archives:
|
||||
dateFormat: "Jan 02"
|
||||
```
|
||||
|
||||
پیام حالت خالی از کلید ترجمه `noResultsFound` استفاده میکند.
|
||||
|
||||
یک صفحهٔ نمونه از آرشیو در [آرشیو]({{% relref "/archives" %}}) در دسترس است.
|
||||
@@ -0,0 +1,105 @@
|
||||
---
|
||||
title: "追加ページ"
|
||||
weight: 1
|
||||
prev: /docs/advanced
|
||||
aliases:
|
||||
- /docs/advanced/glossary/
|
||||
---
|
||||
|
||||
Hextra には明示的に有効化する追加ページがあります。用語集とアーカイブです。
|
||||
|
||||
<!--more-->
|
||||
|
||||
## 用語集
|
||||
|
||||
{{< callout type="info" >}}
|
||||
Hugo の用語集サポートの詳細については、[Hugo 用語集クイックリファレンス](https://gohugo.io/quick-reference/glossary/)をご覧ください。
|
||||
{{< /callout >}}
|
||||
|
||||
### データソースファイル
|
||||
|
||||
用語の定義は、各[対応言語](../multi-language/)ごとに `termbase.yaml` データファイルに一元管理されています。
|
||||
|
||||
{{< filetree/container >}}
|
||||
{{< filetree/folder name="data" state="open" >}}
|
||||
{{< filetree/folder name="en" state="open" >}}
|
||||
{{< filetree/file name="termbase.yaml" >}}
|
||||
{{< /filetree/folder >}}
|
||||
{{< filetree/folder name="fr" state="open" >}}
|
||||
{{< filetree/file name="termbase.yaml" >}}
|
||||
{{< /filetree/folder >}}
|
||||
{{< filetree/folder name="ja" state="open" >}}
|
||||
{{< filetree/file name="termbase.yaml" >}}
|
||||
{{< /filetree/folder >}}
|
||||
{{< /filetree/folder >}}
|
||||
{{< /filetree/container >}}
|
||||
|
||||
各 YAML データファイルには、用語の一覧が含まれています。各エントリには以下が含まれます:
|
||||
|
||||
- `term`:概念やフレーズの正式名称。
|
||||
- `definition`:用語の簡潔な説明。
|
||||
- `abbr`(任意):一般的に使用される略語や頭字語。
|
||||
|
||||
```yaml {filename="data/ja/termbase.yaml"}
|
||||
- term: seo
|
||||
abbr: SEO
|
||||
definition: "検索エンジン最適化 — ウェブページの検索エンジンでの可視性を向上させる手法"
|
||||
- term: "静的サイトジェネレーター"
|
||||
definition: "テキスト入力を処理して静的なウェブページを生成するソフトウェアエンジン"
|
||||
```
|
||||
|
||||
### 用語ページ
|
||||
|
||||
定義済みの用語、その説明、および略語を一覧表示するグロッサリーのインデックスページをレンダリングするには、
|
||||
サポートされている各言語ごとに、言語固有のグロッサリー用コンテンツファイルを定義する必要があります。
|
||||
ファイル名には言語コードのサフィックスを使用してください。例: `content/glossary/_index.ja.md`。
|
||||
|
||||
```markdown {filename="content/glossary/_index.ja.md"}
|
||||
---
|
||||
title: 用語集
|
||||
layout: glossary
|
||||
---
|
||||
```
|
||||
|
||||
グロッサリーのサンプルページは [用語集]({{% relref "/glossary" %}}) で確認できます。
|
||||
|
||||
## アーカイブ
|
||||
|
||||
投稿を年ごとにまとめたアーカイブタイムラインページを作成できます。
|
||||
|
||||
1. アーカイブページを作成します:
|
||||
```yaml {filename="content/archives/_index.md"}
|
||||
---
|
||||
title: Archives
|
||||
layout: archives
|
||||
toc: false
|
||||
---
|
||||
```
|
||||
2. (任意)トップメニューに追加します:
|
||||
```yaml {filename="hugo.yaml"}
|
||||
menu:
|
||||
main:
|
||||
- identifier: archives
|
||||
name: Archives
|
||||
pageRef: /archives
|
||||
```
|
||||
3. (任意・多言語)同じ layout を使った翻訳版アーカイブページを追加します。例:
|
||||
- `content/archives/_index.fa.md`
|
||||
- `content/archives/_index.ja.md`
|
||||
- `content/archives/_index.zh-cn.md`
|
||||
4. (任意)アーカイブ対象のセクションを変更します。デフォルトは `blog` です。
|
||||
```yaml {filename="hugo.yaml"}
|
||||
params:
|
||||
archives:
|
||||
section: blog
|
||||
```
|
||||
5. (任意)アーカイブ項目の日付表示形式を変更します。デフォルトは `Jan 02` です。
|
||||
```yaml {filename="hugo.yaml"}
|
||||
params:
|
||||
archives:
|
||||
dateFormat: "Jan 02"
|
||||
```
|
||||
|
||||
空状態メッセージは i18n キー `noResultsFound` を使用します。
|
||||
|
||||
アーカイブのサンプルページは [アーカイブ]({{% relref "/archives" %}}) で確認できます。
|
||||
@@ -0,0 +1,105 @@
|
||||
---
|
||||
title: "Additional Pages"
|
||||
weight: 1
|
||||
prev: /docs/advanced
|
||||
aliases:
|
||||
- /docs/advanced/glossary/
|
||||
---
|
||||
|
||||
Hextra includes additional pages that you can enable explicitly: glossary and archives.
|
||||
|
||||
<!--more-->
|
||||
|
||||
## Glossary
|
||||
|
||||
{{< callout type="info" >}}
|
||||
For more information about Hugo's built-in glossary support, see the [Hugo Glossary Quick Reference](https://gohugo.io/quick-reference/glossary/).
|
||||
{{< /callout >}}
|
||||
|
||||
### Source Data File
|
||||
|
||||
Term definitions are centrally stored in a `termbase.yaml` data file for each [supported language](../multi-language/).
|
||||
|
||||
{{< filetree/container >}}
|
||||
{{< filetree/folder name="data" state="open" >}}
|
||||
{{< filetree/folder name="en" state="open" >}}
|
||||
{{< filetree/file name="termbase.yaml" >}}
|
||||
{{< /filetree/folder >}}
|
||||
{{< filetree/folder name="fr" state="open" >}}
|
||||
{{< filetree/file name="termbase.yaml" >}}
|
||||
{{< /filetree/folder >}}
|
||||
{{< filetree/folder name="ja" state="open" >}}
|
||||
{{< filetree/file name="termbase.yaml" >}}
|
||||
{{< /filetree/folder >}}
|
||||
{{< /filetree/folder >}}
|
||||
{{< /filetree/container >}}
|
||||
|
||||
Each YAML data file contains a list of glossary entries. Every entry includes:
|
||||
|
||||
- `term`: The full name of the concept or phrase.
|
||||
- `definition`: A brief explanation or description of the term.
|
||||
- `abbr` (optional): A commonly used abbreviation or acronym for the term.
|
||||
|
||||
```yaml {filename="data/en/termbase.yaml"}
|
||||
- term: seo
|
||||
abbr: SEO
|
||||
definition: "Search engine optimization – improving the visibility of a web page in search engines"
|
||||
- term: static site generator
|
||||
definition: "Software engines processing text input to generate static web pages"
|
||||
```
|
||||
|
||||
### Glossary Page
|
||||
|
||||
To render the glossary index page (listing all defined terms along with their descriptions and abbreviations),
|
||||
a language-specific glossary content file must be defined for each supported language. Use the language code suffix
|
||||
in the filename, for example `content/glossary/_index.en.md`.
|
||||
|
||||
```markdown {filename="content/glossary/_index.en.md"}
|
||||
---
|
||||
title: Glossary
|
||||
layout: glossary
|
||||
---
|
||||
```
|
||||
|
||||
An example glossary page is available at [Glossary]({{% relref "/glossary" %}}).
|
||||
|
||||
## Archives
|
||||
|
||||
You can create an archive timeline page (grouped by year) for posts in a section.
|
||||
|
||||
1. Create the archive page:
|
||||
```yaml {filename="content/archives/_index.md"}
|
||||
---
|
||||
title: Archives
|
||||
layout: archives
|
||||
toc: false
|
||||
---
|
||||
```
|
||||
2. (Optional) Add it to the top menu:
|
||||
```yaml {filename="hugo.yaml"}
|
||||
menu:
|
||||
main:
|
||||
- identifier: archives
|
||||
name: Archives
|
||||
pageRef: /archives
|
||||
```
|
||||
3. (Optional, multilingual) Add translated archive index pages with the same layout, for example:
|
||||
- `content/archives/_index.fa.md`
|
||||
- `content/archives/_index.ja.md`
|
||||
- `content/archives/_index.zh-cn.md`
|
||||
4. (Optional) Change the content section used for archives. The default is `blog`.
|
||||
```yaml {filename="hugo.yaml"}
|
||||
params:
|
||||
archives:
|
||||
section: blog
|
||||
```
|
||||
5. (Optional) Change the archive item date format. The default is `Jan 02`.
|
||||
```yaml {filename="hugo.yaml"}
|
||||
params:
|
||||
archives:
|
||||
dateFormat: "Jan 02"
|
||||
```
|
||||
|
||||
The empty-state message uses the `noResultsFound` i18n key.
|
||||
|
||||
An example archive page is available at [Archives]({{% relref "/archives" %}}).
|
||||
@@ -0,0 +1,105 @@
|
||||
---
|
||||
title: "附加页面"
|
||||
weight: 1
|
||||
prev: /docs/advanced
|
||||
aliases:
|
||||
- /docs/advanced/glossary/
|
||||
---
|
||||
|
||||
Hextra 提供一些需要单独启用的附加页面:术语表与归档页。
|
||||
|
||||
<!--more-->
|
||||
|
||||
## 术语表
|
||||
|
||||
{{< callout type="info" >}}
|
||||
有关 Hugo 内置术语表支持的更多信息,请参阅 [Hugo 术语表快速参考](https://gohugo.io/quick-reference/glossary/)。
|
||||
{{< /callout >}}
|
||||
|
||||
### 数据源文件
|
||||
|
||||
术语定义集中存储在每种[支持语言](../multi-language/)的 `termbase.yaml` 数据文件中。
|
||||
|
||||
{{< filetree/container >}}
|
||||
{{< filetree/folder name="data" state="open" >}}
|
||||
{{< filetree/folder name="en" state="open" >}}
|
||||
{{< filetree/file name="termbase.yaml" >}}
|
||||
{{< /filetree/folder >}}
|
||||
{{< filetree/folder name="fr" state="open" >}}
|
||||
{{< filetree/file name="termbase.yaml" >}}
|
||||
{{< /filetree/folder >}}
|
||||
{{< filetree/folder name="ja" state="open" >}}
|
||||
{{< filetree/file name="termbase.yaml" >}}
|
||||
{{< /filetree/folder >}}
|
||||
{{< /filetree/folder >}}
|
||||
{{< /filetree/container >}}
|
||||
|
||||
每个 YAML 数据文件包含一组术语条目。每个条目包括:
|
||||
|
||||
- `term`:术语或短语的完整名称。
|
||||
- `definition`:对术语的简要解释或描述。
|
||||
- `abbr`(可选):术语常用的缩写或首字母缩写。
|
||||
|
||||
```yaml {filename="data/zh-cn/termbase.yaml"}
|
||||
- term: seo
|
||||
abbr: SEO
|
||||
definition: "搜索引擎优化——提高网页在搜索引擎中的可见度"
|
||||
- term: "静态网站生成器"
|
||||
definition: "将文本输入处理为静态网页的生成引擎"
|
||||
```
|
||||
|
||||
### 术语页面
|
||||
|
||||
要渲染词汇表索引页面(列出所有已定义的术语及其说明和缩写),
|
||||
必须为每种受支持的语言定义一个对应的语言专用词汇表内容文件。
|
||||
请在文件名中使用语言代码后缀,例如:`content/glossary/_index.zh-cn.md`。
|
||||
|
||||
```markdown {filename="content/glossary/_index.zh-cn.md"}
|
||||
---
|
||||
title: 术语表
|
||||
layout: glossary
|
||||
---
|
||||
```
|
||||
|
||||
示例词汇表页面可在 [术语表]({{% relref "/glossary" %}}) 查看。
|
||||
|
||||
## 归档页
|
||||
|
||||
你可以为某个内容分区的文章创建按年份分组的归档时间线页面。
|
||||
|
||||
1. 创建归档页面:
|
||||
```yaml {filename="content/archives/_index.md"}
|
||||
---
|
||||
title: Archives
|
||||
layout: archives
|
||||
toc: false
|
||||
---
|
||||
```
|
||||
2. (可选)将其添加到顶部菜单:
|
||||
```yaml {filename="hugo.yaml"}
|
||||
menu:
|
||||
main:
|
||||
- identifier: archives
|
||||
name: Archives
|
||||
pageRef: /archives
|
||||
```
|
||||
3. (可选,多语言)添加使用相同 layout 的多语言归档首页,例如:
|
||||
- `content/archives/_index.fa.md`
|
||||
- `content/archives/_index.ja.md`
|
||||
- `content/archives/_index.zh-cn.md`
|
||||
4. (可选)修改归档来源分区。默认值为 `blog`。
|
||||
```yaml {filename="hugo.yaml"}
|
||||
params:
|
||||
archives:
|
||||
section: blog
|
||||
```
|
||||
5. (可选)修改归档条目的日期显示格式。默认值是 `Jan 02`。
|
||||
```yaml {filename="hugo.yaml"}
|
||||
params:
|
||||
archives:
|
||||
dateFormat: "Jan 02"
|
||||
```
|
||||
|
||||
空状态文案使用 i18n 键 `noResultsFound`。
|
||||
|
||||
示例归档页面可在 [归档]({{% relref "/archives" %}}) 查看。
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user