Compare commits

...
101 Commits
Author SHA1 Message Date
riseforever2026 6a1d4a92b8 fuckai 2026-09-20 22:48:54 +08:00
riseforever2026 9336d65c2b Updates 2026-09-19 14:35:12 +08:00
Miyale e000ef2fd4 Update links.md 2026-09-12 22:40:24 +08:00
Miyale 9aae697cf8 更新 链接悬浮特效逻辑 2026-09-12 20:58:09 +08:00
riseforever2026 4378d3b743 修复单个波浪号被识别为删除线的问题 2026-09-12 07:42:22 +08:00
riseforever2026 2e472c4dd4 Update links.md 2026-09-11 22:29:33 +08:00
riseforever2026 68171c238d Update 88x31.gif 2026-09-11 22:27:35 +08:00
riseforever2026 986e0054c7 修改下划线显示逻辑
我真不想写 desc。
2026-09-11 22:14:04 +08:00
riseforever2026 c9f21533b6 Update Masthead.astro 2026-09-11 21:20:41 +08:00
riseforever2026 3565e0f83e Update site.config.ts 2026-09-11 21:11:27 +08:00
riseforever2026 53bd069dd3 Update weekly-9-2.md 2026-09-11 20:13:28 +08:00
riseforever2026 60f9530820 Update weekly-9-2.md 2026-09-11 20:06:05 +08:00
riseforever2026 6a559dddad Update weekly-9-2.md 2026-09-11 18:47:48 +08:00
riseforever2026 8c8e4c507c 删除 鸡脖站 2026-09-11 18:46:14 +08:00
riseforever2026 b64614297b Update about.md 2026-09-06 14:38:20 +08:00
riseforever2026 1a2562932d Delete fuck-lybg.md 2026-09-06 11:31:06 +08:00
riseforever2026 d9beef7ac3 Create fuck-lybg.md 2026-09-06 11:24:51 +08:00
riseforever2026 e0224d6546 修复 关于页面头像元素被异常压缩的 Bug 2026-09-06 09:44:39 +08:00
riseforever2026 739e8c75ba Update weekly-9-1.md 2026-09-06 00:43:31 +08:00
riseforever2026 4219b551d6 Update weekly-9-1.md 2026-09-06 00:40:07 +08:00
riseforever2026 848660bc78 Update weekly-9-1.md 2026-09-06 00:36:50 +08:00
riseforever2026 c56066055c Update weekly-9-1.md 2026-09-06 00:32:18 +08:00
riseforever2026 9f5ed7e5b1 Update weekly-9-1.md 2026-09-06 00:08:40 +08:00
riseforever2026 b20cbe08ba Update weekly-9-1.md 2026-09-06 00:07:24 +08:00
riseforever2026 0e9c3fae07 Update weekly-9-1.md 2026-09-06 00:04:11 +08:00
riseforever2026 c92a4c7478 Create weekly-9-1.md 2026-09-05 23:59:14 +08:00
riseforever2026 197d535d66 Update heartflow.md 2026-09-03 22:32:14 +08:00
riseforever2026 bf39669a3a Create heartflow.md 2026-09-03 22:30:24 +08:00
riseforever2026 7ff54bed6f Update links.md 2026-09-02 12:27:01 +08:00
riseforever2026 8336f527ac Update august.md 2026-08-30 22:07:32 +08:00
riseforever2026 f702ef7210 Update august.md 2026-08-30 20:07:17 +08:00
riseforever2026 10cb33fc1a Delete Untitled.md 2026-08-30 19:48:20 +08:00
riseforever2026 ec6ac63b9f Update Untitled.md 2026-08-30 19:48:09 +08:00
riseforever2026 ffb3c37546 修复tools bug 2026-08-30 19:43:21 +08:00
riseforever2026 10fbbe313f 样式修改
- 为标题元素左侧添加小竖条;
- 修复了左侧栏底部操作按钮没有高亮的问题;
- 修复了引用块字体过大的问题。
2026-08-30 16:18:48 +08:00
riseforever2026 2aa74bc6ab Update links.md 2026-08-30 14:12:11 +08:00
riseforever2026 00a9eb70f9 Update links.md 2026-08-30 12:33:09 +08:00
riseforever2026 22b6a3ef9d search fix 2026-08-29 19:19:04 +08:00
riseforever2026 d9cc2ddf58 Update links.md 2026-08-29 15:04:32 +08:00
riseforever2026 ed8dcecd38 Update links.md 2026-08-29 09:23:14 +08:00
riseforever2026 13803379f0 Update EngagementTabs.astro 2026-08-28 19:42:53 +08:00
riseforever2026 bf027c57f9 Update EngagementTabs.astro 2026-08-28 19:41:11 +08:00
riseforever2026 73f846e978 Update weekly-6-1.md 2026-08-28 19:34:48 +08:00
riseforever2026 6977f97864 Update a-reply-to-a-leter-i-wrote-to-myself-two-years-ago.md 2026-08-28 19:17:26 +08:00
riseforever2026 58a79159f2 Update a-reply-to-a-leter-i-wrote-to-myself-two-years-ago.md 2026-08-28 18:14:12 +08:00
riseforever2026 ad301b9d4f Webmention 增加 Frontmatter 独立控制字段 2026-08-28 09:28:04 +08:00
riseforever2026 c493a0b212 优化互动区样式 2026-08-27 23:39:56 +08:00
riseforever2026 504d5052bd Update Webmentions.astro 2026-08-27 22:39:31 +08:00
riseforever2026 19d38b1ac0 Update Webmentions.astro 2026-08-27 22:21:28 +08:00
riseforever2026 b2982d16ca Update Webmentions.astro 2026-08-27 22:08:37 +08:00
riseforever2026 1207e862d4 Update Webmentions.astro 2026-08-27 21:55:11 +08:00
riseforever2026 a616df9e09 Update Webmentions.astro 2026-08-27 21:45:43 +08:00
riseforever2026 c4400f4b1f Update Webmentions.astro 2026-08-27 21:22:31 +08:00
riseforever2026 46e7e5339d Apply Webmention Function 2026-08-27 21:15:24 +08:00
riseforever2026 0b6ba6efb8 Update august.md 2026-08-27 16:19:37 +08:00
riseforever2026 99d58c61b1 Update ImageLightbox.astro 2026-08-27 16:05:52 +08:00
riseforever2026 2c6319e62a 图片灯箱动画优化
- 为图片灯箱加入了从哪来回哪去的动画
2026-08-27 15:47:16 +08:00
riseforever2026 6e1035d76f Update about.md 2026-08-27 14:05:54 +08:00
riseforever2026 c3fd181286 Update about.md 2026-08-27 09:37:14 +08:00
riseforever2026 987d1c3de2 Update about.md 2026-08-27 08:52:50 +08:00
riseforever2026 59a053bcae Update about.md 2026-08-26 23:48:24 +08:00
riseforever2026 0432ced07f Update about.md 2026-08-26 23:44:14 +08:00
riseforever2026 ff477511b4 Update links.md 2026-08-26 23:16:27 +08:00
riseforever2026 8c7dad5099 Update links.md 2026-08-26 21:07:29 +08:00
riseforever2026 0bfef91748 修复一些逻辑 2026-08-26 17:35:46 +08:00
riseforever2026 2e1f24ee5b Update site.config.ts 2026-08-26 16:51:15 +08:00
riseforever2026 0f267e86e2 Update site.config.ts 2026-08-26 16:45:09 +08:00
riseforever2026 97d272aaf2 Update links.md 2026-08-25 23:18:07 +08:00
riseforever2026 ad0a7a6c7b Update a-reply-to-a-leter-i-wrote-to-myself-two-years-ago.md 2026-08-25 21:34:23 +08:00
riseforever2026 9da0cb51e4 Cover2 2026-08-25 21:20:38 +08:00
riseforever2026 da54228536 Cover 2026-08-25 21:19:30 +08:00
riseforever2026 f18ac0960d Update about.md 2026-08-25 21:15:32 +08:00
riseforever2026 a03965849c Update links.md 2026-08-25 21:06:17 +08:00
riseforever2026 ce34f362be Create a-reply-to-a-leter-i-wrote-to-myself-two-years-ago.md 2026-08-25 20:59:23 +08:00
riseforever2026 069c1e6067 何意味 2026-08-25 11:43:37 +08:00
riseforever2026 8f5edc5521 我不知道我更新了什么 2026-08-25 11:37:33 +08:00
riseforever2026 554c86c792 Update about.md 2026-08-24 17:32:42 +08:00
riseforever2026 6f932720ef Update about.md 2026-08-24 11:38:22 +08:00
riseforever2026 7314bf4714 Update about.md 2026-08-24 11:36:39 +08:00
riseforever2026 7c3835b9c7 Update weekly-8-1.md 2026-08-24 07:44:11 +08:00
riseforever2026 c5a4e0f81c Update links.md 2026-08-23 23:29:15 +08:00
riseforever2026 4cbe927363 Update weekly-8-1.md 2026-08-23 21:55:10 +08:00
riseforever2026 aad0166e0a New Post 2026-08-23 21:52:33 +08:00
riseforever2026 b235be905c Update about.md 2026-08-23 10:27:56 +08:00
riseforever2026 d9343e380f Update about.md 2026-08-23 09:56:03 +08:00
riseforever2026 d7adfb9333 Update about.md 2026-08-23 09:44:53 +08:00
riseforever2026 10d9ad5763 Revert "Update about.md"
This reverts commit 27d91461cf.
2026-08-23 09:44:31 +08:00
riseforever2026 27d91461cf Update about.md 2026-08-23 09:42:39 +08:00
riseforever2026 fab149e514 Update about.md 2026-08-23 09:24:08 +08:00
riseforever2026 df51ba9ff1 Update links.md 2026-08-22 18:11:39 +08:00
riseforever2026 4fea3cf9c5 Merge branch 'main' of src.luming.cool:riseforever2026/Blog 2026-08-22 17:47:10 +08:00
riseforever2026 b8d300d45e 更新 src/content/pages/links.md 2026-08-21 16:14:12 +08:00
riseforever2026 7fe3038ca6 更新 src/content/pages/links.md 2026-08-21 14:54:55 +08:00
RiseForever ec8a724ac2 Update links.md 2026-08-21 14:31:20 +08:00
RiseForever 75939f7e67 Update links.md 2026-08-17 10:31:47 +08:00
RiseForever 1931de34ee Update links.md 2026-08-17 10:27:35 +08:00
RiseForever b06e723ad0 Update 104.md 2026-08-14 16:38:29 +08:00
RiseForever 775aac55e2 Update 104.md 2026-08-14 16:26:50 +08:00
RiseForever 4d1b1573e4 Update links.md 2026-08-14 12:06:44 +08:00
RiseForever b795f698e9 Update links.md 2026-08-14 11:57:40 +08:00
RiseForever c31d8cf832 Update links.md 2026-08-14 11:57:16 +08:00
136 changed files with 2208 additions and 410 deletions
+2
View File
@@ -6,3 +6,5 @@ dist/
.env.*
!.env.example
pnpm-debug.log*
.obsidian/
.pnpm-store/
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 80 KiB

After

Width:  |  Height:  |  Size: 58 KiB

+17 -1
View File
@@ -2,7 +2,7 @@
Mirages 是一个基于 Astro 的静态博客主题,用于发布文章和独立页面。旧版 PHP 文件位于本项目之外,保持不变。
本文档说明 Astro 主题的常用配置、Twikoo 评论和文章 Frontmatter。
本文档说明 Astro 主题的常用配置、Twikoo 评论、WebMention 和文章 Frontmatter。
## 运行项目
@@ -117,6 +117,22 @@ pnpm build
如果页面显示“评论暂时不可用”,依次检查云函数地址是否能从浏览器直接访问、CORS 配置、Twikoo 环境变量和 `envId` 是否包含多余路径或空格。
## WebMention 配置
WebMention 与 Twikoo 并行工作:Twikoo 接收本站评论,WebMention 接收其他网站对文章的回复、提及、点赞和转发。配置入口位于 `src/site.config.ts`:
```ts
webmentions: {
enabled: true,
endpoint: 'https://webmention.example.com',
form: true
},
```
启用后,全站 `<head>` 会声明 `${endpoint}/receive`,文章页从 `${endpoint}/get` 读取当前 canonical URL 的已批准 WebMention。`form` 控制是否在文章底部显示手动发送表单。
仓库在 `deploy/webmention/` 提供了基于 webmentiond、SQLite 和 Docker Compose 的自托管配置。服务器部署、SMTP 登录、反向代理及验证步骤见该目录的 `README.md`。
## 文章 Frontmatter
文章位于 `src/content/posts`,独立页面位于 `src/content/pages`。两者使用相同的字段结构:
+3 -1
View File
@@ -2,6 +2,7 @@ import { defineConfig } from 'astro/config';
import { unified } from '@astrojs/markdown-remark';
import sitemap from '@astrojs/sitemap';
import tailwindcss from '@tailwindcss/vite';
import remarkGfm from 'remark-gfm';
import remarkMath from 'remark-math';
import rehypeKatex from 'rehype-katex';
import shortcodes from './src/lib/shortcodes.ts';
@@ -47,7 +48,8 @@ export default defineConfig({
defaultColor: false
},
processor: unified({
remarkPlugins: [remarkMath, [shortcodes, { githubData, siteUrl: siteConfig.site.url }]],
gfm: false,
remarkPlugins: [[remarkGfm, { singleTilde: false }], remarkMath, [shortcodes, { githubData, siteUrl: siteConfig.site.url }]],
rehypePlugins: [rehypeKatex, noticeShortcode, responsiveTables, [externalLinks, { siteUrl: siteConfig.site.url }]]
})
}
+15
View File
@@ -0,0 +1,15 @@
WEBMENTION_PORT=8080
WEBMENTION_PUBLIC_URL=https://webmention.luming.cool
WEBMENTION_ALLOWED_TARGET_DOMAINS=www.luming.cool,luming.cool
WEBMENTION_ALLOWED_ORIGIN=https://www.luming.cool
WEBMENTION_ADMIN_EMAILS=you@example.com
SERVER_AUTH_JWT_SECRET=replace-with-a-long-random-secret
MAIL_HOST=smtp.example.com
MAIL_PORT=587
MAIL_USER=you@example.com
MAIL_PASSWORD=replace-with-your-smtp-password
MAIL_FROM=you@example.com
MAIL_USE_STARTTLS=true
MAIL_NO_TLS=false
+4
View File
@@ -0,0 +1,4 @@
webmention.luming.cool {
encode zstd gzip
reverse_proxy 127.0.0.1:8080
}
+79
View File
@@ -0,0 +1,79 @@
# WebMention 接收端
本站使用 [webmentiond](https://github.com/zerok/webmentiond) 作为自托管接收端。它负责异步验证来源页面、将结果存入 SQLite,并提供审核后台与公开查询 API。Twikoo 继续作为站内评论系统,两者互不替代。
## 1. 准备域名
将 `webmention.luming.cool` 解析到运行 Docker 的服务器。如果要换成其他域名,同时修改:
- `src/site.config.ts` 中的 `webmentions.endpoint`
- `.env` 中的 `WEBMENTION_PUBLIC_URL`
- Caddy 或 Nginx 的域名
接收端必须使用公网可访问的 HTTPS 地址。
## 2. 配置并启动
在服务器上进入本目录,复制示例环境变量并填写真实值:
```sh
cp .env.example .env
docker compose pull
docker compose up -d
```
Compose 会先用一次性 `webmention-init` 容器将数据卷所有者设为 webmentiond 使用的 UID 1500,然后再启动接收端。若曾使用旧版 Compose,并在日志中看到 `unable to open database file`,可在部署目录执行:
```sh
docker compose stop webmentiond
docker compose run --rm --no-deps --user 0 --entrypoint /bin/sh webmentiond -c 'chown -R 1500:1500 /data'
docker compose up -d webmentiond
```
必须修改以下值:
- `WEBMENTION_ADMIN_EMAILS`:允许登录审核后台的邮箱,可用逗号分隔多个地址。
- `SERVER_AUTH_JWT_SECRET`:长随机字符串,可用 `openssl rand -hex 32` 生成。
- `MAIL_*`:SMTP 地址、账号、密码和发件人。后台使用邮件链接登录,因此 SMTP 不能省略。
SQLite 数据保存在 Docker 卷 `webmention-data`。更新容器不会删除它,仍建议定期备份该卷。
## 3. 配置反向代理
任选 `Caddyfile.example` 或 `nginx.conf.example` 作为反向代理参考。容器只监听服务器本机的 `127.0.0.1:8080`,TLS 由反向代理处理。
部署完成后访问:
```text
https://webmention.luming.cool/ui/
```
输入 `WEBMENTION_ADMIN_EMAILS` 中的邮箱,通过邮件链接登录。收到的 WebMention 验证成功后仍需在这里批准,批准后才会出现在博客文章底部。
## 4. 接口与站点集成
博客构建结果会在 `<head>` 中自动声明:
```html
<link rel="webmention" href="https://webmention.luming.cool/receive">
```
文章页通过以下接口读取当前 canonical URL 已批准的项目:
```text
GET https://webmention.luming.cool/get?target=https://www.luming.cool/posts/example/
```
文章底部也提供发送表单,POST `source` 和 `target` 到 `/receive`。`WEBMENTION_ALLOWED_ORIGIN` 必须与博客的浏览器 Origin 完全一致,否则读取与发送都会被 CORS 拦截。
## 5. 验证
完成接收端和博客部署后:
1. 查看任一文章源码,确认存在 `rel="webmention"`。
2. 打开 `https://webmention.luming.cool/ui/`,确认可以收到登录邮件。
3. 使用 [webmention.rocks](https://webmention.rocks/) 检查接收端标准兼容性。
4. 从一个确实包含本站文章链接的公开页面发送 WebMention。
5. 在管理后台批准后,刷新对应文章,确认它出现在“站外回应”。
`webmentiond` 按完整 target URL 精确查询。发送方若将带 `#fragment` 的链接作为 target,它会被视为与文章 canonical URL 不同的目标;建议发送时使用不带锚点的文章永久链接。
+46
View File
@@ -0,0 +1,46 @@
services:
webmention-init:
image: zerok/webmentiond:latest
user: "0:0"
entrypoint:
- /bin/sh
- -c
command:
- chown -R 1500:1500 /data
volumes:
- webmention-data:/data
restart: "no"
webmentiond:
image: zerok/webmentiond:latest
restart: unless-stopped
depends_on:
webmention-init:
condition: service_completed_successfully
ports:
- "127.0.0.1:${WEBMENTION_PORT:-8080}:8080"
environment:
MAIL_HOST: ${MAIL_HOST}
MAIL_PORT: ${MAIL_PORT}
MAIL_USER: ${MAIL_USER}
MAIL_PASSWORD: ${MAIL_PASSWORD}
MAIL_FROM: ${MAIL_FROM}
MAIL_USE_STARTTLS: ${MAIL_USE_STARTTLS:-true}
MAIL_NO_TLS: ${MAIL_NO_TLS:-false}
SERVER_AUTH_JWT_SECRET: ${SERVER_AUTH_JWT_SECRET}
volumes:
- webmention-data:/data
command:
- --addr
- 0.0.0.0:8080
- --public-url
- ${WEBMENTION_PUBLIC_URL}
- --allowed-target-domains
- ${WEBMENTION_ALLOWED_TARGET_DOMAINS}
- --allowed-origin
- ${WEBMENTION_ALLOWED_ORIGIN}
- --auth-admin-emails
- ${WEBMENTION_ADMIN_EMAILS}
volumes:
webmention-data:
+13
View File
@@ -0,0 +1,13 @@
server {
listen 443 ssl http2;
server_name webmention.luming.cool;
# Keep the existing certificate directives from your server configuration.
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
+1
View File
@@ -22,6 +22,7 @@
"pangu": "^9.1.0",
"photoswipe": "^5.4.4",
"rehype-katex": "^7.0.1",
"remark-gfm": "^4.0.1",
"remark-math": "^6.0.0",
"twikoo": "1.7.15",
"unist-util-visit": "^5.0.0"
+1
View File
@@ -27,6 +27,7 @@
"pangu": "^9.1.0",
"photoswipe": "^5.4.4",
"rehype-katex": "^7.0.1",
"remark-gfm": "^4.0.1",
"remark-math": "^6.0.0",
"twikoo": "1.7.15",
"unist-util-visit": "^5.0.0"
+3
View File
@@ -56,6 +56,9 @@ importers:
rehype-katex:
specifier: ^7.0.1
version: 7.0.1
remark-gfm:
specifier: ^4.0.1
version: 4.0.1
remark-math:
specifier: ^6.0.0
version: 6.0.0
+249
View File
@@ -0,0 +1,249 @@
---
import TwikooComments from '@/components/TwikooComments.astro';
import Webmentions from '@/components/Webmentions.astro';
import { siteConfig } from '@/site.config';
interface Props {
commentsEnabled: boolean;
webmentionEnabled: boolean;
path: string;
target: string;
}
const { commentsEnabled, webmentionEnabled, path, target } = Astro.props;
const showWebmention = webmentionEnabled && siteConfig.webmentions.enabled && Boolean(siteConfig.webmentions.endpoint.trim());
const commentsConfigured = siteConfig.comments.provider === 'twikoo';
const showComments = commentsEnabled && commentsConfigured;
const showTabs = showWebmention && showComments;
---
{(showWebmention || showComments) && <section
class="engagement-shell"
aria-label="文章互动"
data-engagement-tabs={showTabs ? '' : undefined}
data-pagefind-ignore="all"
>
{showTabs ? <div class="engagement-tablist" role="tablist" aria-label="文章互动方式">
<button
class="engagement-tab"
id="engagement-tab-comments"
type="button"
role="tab"
aria-controls="engagement-panel-comments"
aria-selected="true"
data-engagement-tab="comments"
>评论</button>
<button
class="engagement-tab"
id="engagement-tab-webmentions"
type="button"
role="tab"
aria-controls="engagement-panel-webmentions"
aria-selected="false"
tabindex={-1}
data-engagement-tab="webmentions"
>Webmentions</button>
</div> : <h2 class="engagement-title">{showWebmention ? 'Webmention' : '评论'}</h2>}
{showWebmention && <div
class="engagement-panel"
id={showTabs ? 'engagement-panel-webmentions' : undefined}
role={showTabs ? 'tabpanel' : undefined}
aria-labelledby={showTabs ? 'engagement-tab-webmentions' : undefined}
data-engagement-panel={showTabs ? 'webmentions' : undefined}
hidden={showTabs}
>
<Webmentions target={target} />
</div>}
{showComments && <div
class="engagement-panel"
id={showTabs ? 'engagement-panel-comments' : undefined}
role={showTabs ? 'tabpanel' : undefined}
aria-labelledby={showTabs ? 'engagement-tab-comments' : undefined}
data-engagement-panel={showTabs ? 'comments' : undefined}
>
<TwikooComments enabled={commentsEnabled} path={path} />
</div>}
</section>}
<style>
.engagement-shell {
width: min(100%, var(--article-content-width));
margin: 4.375rem auto 0;
border-top: 1px solid var(--color-border);
color: var(--color-text);
font-family: var(--reading-font-family);
font-size: .94rem;
}
.engagement-tablist {
display: flex;
align-items: center;
gap: 1.5rem;
min-height: 3.25rem;
border-bottom: 1px solid var(--color-border);
}
.engagement-title {
margin: 0;
padding: 1.5rem 0 0;
color: var(--color-text);
font-family: var(--reading-font-family);
font-size: 1.5rem;
font-weight: 500;
line-height: 1.4;
}
.engagement-tab {
position: relative;
align-self: stretch;
padding: 0 .125rem;
border: 0;
background: transparent;
color: var(--color-muted);
cursor: pointer;
font-family: inherit;
font-size: .9375rem;
font-weight: 500;
}
.engagement-tab::after {
position: absolute;
right: 0;
bottom: -1px;
left: 0;
height: 2px;
background: var(--color-accent);
content: '';
opacity: 0;
transform: scaleX(.5);
transition: opacity 160ms ease, transform 160ms ease;
}
.engagement-tab:is(:hover, [aria-selected='true']) {
color: var(--color-accent-strong);
}
.engagement-tab[aria-selected='true']::after {
opacity: 1;
transform: scaleX(1);
}
.engagement-tab:focus-visible {
border-radius: var(--radius-sm);
outline: 1px solid var(--color-accent);
outline-offset: 3px;
}
.engagement-panel {
padding-top: 1.5rem;
}
.engagement-panel[hidden] {
display: none;
}
@media (max-width: 37.5rem) {
.engagement-shell {
width: 100%;
margin-top: 3.25rem;
font-size: .9rem;
}
.engagement-tablist {
min-height: 3rem;
}
.engagement-title {
padding-top: 1.25rem;
font-size: 1.375rem;
}
.engagement-panel {
padding-top: 1.25rem;
}
}
</style>
<script>
type EngagementTabName = 'webmentions' | 'comments';
declare global {
interface Window {
__eidolonEngagementTabsBound?: boolean;
}
}
const tabNameFromHash = (): EngagementTabName | null => {
if (window.location.hash === '#comments') return 'comments';
if (window.location.hash === '#webmentions') return 'webmentions';
return null;
};
const activateEngagementTab = (
root: HTMLElement,
name: EngagementTabName,
focus = false
) => {
const tabs = Array.from(root.querySelectorAll<HTMLButtonElement>('[data-engagement-tab]'));
const panels = Array.from(root.querySelectorAll<HTMLElement>('[data-engagement-panel]'));
const activeTab = tabs.find((tab) => tab.dataset.engagementTab === name);
if (!activeTab) return;
for (const tab of tabs) {
const active = tab === activeTab;
tab.setAttribute('aria-selected', String(active));
tab.tabIndex = active ? 0 : -1;
}
for (const panel of panels) {
panel.hidden = panel.dataset.engagementPanel !== name;
}
if (focus) activeTab.focus();
root.dispatchEvent(new CustomEvent('engagement:tab-change', {
bubbles: true,
detail: { tab: name }
}));
};
const bindEngagementTabs = () => {
const root = document.querySelector<HTMLElement>('[data-engagement-tabs]');
if (!root || root.dataset.engagementTabsBound) return;
root.dataset.engagementTabsBound = 'true';
const tabs = Array.from(root.querySelectorAll<HTMLButtonElement>('[data-engagement-tab]'));
const defaultTab = tabs.find((tab) => tab.dataset.engagementTab === 'comments')?.dataset.engagementTab;
const initialTab = tabNameFromHash() ?? (defaultTab as EngagementTabName | undefined);
if (initialTab) activateEngagementTab(root, initialTab);
for (const tab of tabs) {
tab.addEventListener('click', () => {
activateEngagementTab(root, tab.dataset.engagementTab as EngagementTabName);
});
tab.addEventListener('keydown', (event) => {
if (!['ArrowLeft', 'ArrowRight', 'Home', 'End'].includes(event.key)) return;
event.preventDefault();
const currentIndex = tabs.indexOf(tab);
const nextIndex = event.key === 'Home'
? 0
: event.key === 'End'
? tabs.length - 1
: (currentIndex + (event.key === 'ArrowRight' ? 1 : -1) + tabs.length) % tabs.length;
const nextName = tabs[nextIndex]?.dataset.engagementTab as EngagementTabName | undefined;
if (nextName) activateEngagementTab(root, nextName, true);
});
}
};
if (!window.__eidolonEngagementTabsBound) {
window.__eidolonEngagementTabsBound = true;
document.addEventListener('astro:page-load', bindEngagementTabs);
window.addEventListener('hashchange', () => {
const root = document.querySelector<HTMLElement>('[data-engagement-tabs]');
const tab = tabNameFromHash();
if (root && tab) activateEngagementTab(root, tab);
});
}
bindEngagementTabs();
</script>
+148 -2
View File
@@ -24,13 +24,80 @@
const items = images.map((item) => ({
...getSize(item),
src: item.dataset.originalSrc || item.currentSrc || item.src,
alt: item.alt
msrc: item.currentSrc || item.src,
alt: item.alt,
element: item
}));
lightboxPromise ??= import('photoswipe/lightbox').then(({ default: PhotoSwipeLightbox }) => {
const lightbox = new PhotoSwipeLightbox({
pswpModule: () => import('photoswipe'),
bgClickAction: 'close'
bgClickAction: 'close',
wheelToZoom: true,
allowPanToNext: true,
pinchToClose: true,
showHideAnimationType: 'zoom',
showAnimationDuration: 360,
hideAnimationDuration: 300,
easing: 'cubic-bezier(0.22, 1, 0.36, 1)',
paddingFn: (viewportSize) => ({
top: 16,
right: 16,
bottom: viewportSize.x < 640 ? 78 : 92,
left: 16
})
});
lightbox.on('uiRegister', () => {
lightbox.pswp?.ui?.registerElement({
name: 'thumbnails',
className: 'pswp__thumbnails',
appendTo: 'root',
order: 20,
onInit: (element, pswp) => {
element.setAttribute('role', 'toolbar');
element.setAttribute('aria-label', '图片预览');
const buttons = Array.from({ length: pswp.getNumItems() }, (_, itemIndex) => {
const item = pswp.getItemData(itemIndex);
const button = document.createElement('button');
const thumbnail = document.createElement('img');
const label = item.alt ? `查看图片:${item.alt}` : `查看第 ${itemIndex + 1} 张图片`;
button.type = 'button';
button.className = 'pswp__thumbnail';
button.title = label;
button.setAttribute('aria-label', label);
button.addEventListener('click', () => pswp.goTo(itemIndex));
thumbnail.src = item.msrc || item.src || '';
thumbnail.alt = '';
thumbnail.draggable = false;
button.append(thumbnail);
element.append(button);
return button;
});
const updateCurrentThumbnail = () => {
buttons.forEach((button, itemIndex) => {
const isCurrent = itemIndex === pswp.currIndex;
button.classList.toggle('is-current', isCurrent);
if (isCurrent) {
button.setAttribute('aria-current', 'true');
element.scrollTo({
behavior: matchMedia('(prefers-reduced-motion: reduce)').matches ? 'auto' : 'smooth',
left: button.offsetLeft - (element.clientWidth - button.clientWidth) / 2
});
} else {
button.removeAttribute('aria-current');
}
});
};
pswp.on('change', updateCurrentThumbnail);
updateCurrentThumbnail();
}
});
});
lightbox.init();
return lightbox;
@@ -85,4 +152,83 @@
<style is:global>
.prose img.lightbox-image { cursor: zoom-in; }
.prose img.lightbox-image:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 4px; }
.pswp__thumbnails {
position: absolute;
z-index: 10;
right: 64px;
bottom: 12px;
left: 64px;
display: flex;
gap: 8px;
align-items: center;
width: max-content;
max-width: calc(100% - 128px);
height: 64px;
margin-inline: auto;
padding: 6px;
overflow-x: auto;
overscroll-behavior-x: contain;
scrollbar-width: none;
touch-action: pan-x;
}
.pswp__thumbnails::-webkit-scrollbar { display: none; }
.pswp__thumbnail {
flex: 0 0 64px;
width: 64px;
height: 52px;
padding: 2px;
overflow: hidden;
cursor: pointer;
background: rgb(20 20 20 / 72%);
border: 2px solid transparent;
border-radius: 4px;
opacity: .58;
transition: border-color 160ms ease, opacity 160ms ease, transform 160ms ease;
}
.pswp__thumbnail:hover { opacity: .88; }
.pswp__thumbnail.is-current {
border-color: #fff;
opacity: 1;
transform: translateY(-2px);
}
.pswp__thumbnail:focus-visible {
outline: 2px solid var(--color-accent);
outline-offset: 2px;
}
.pswp__thumbnail img {
display: block;
width: 100%;
height: 100%;
object-fit: cover;
border-radius: 2px;
}
@media (max-width: 639px) {
.pswp__thumbnails {
right: 8px;
bottom: 8px;
left: 8px;
gap: 6px;
max-width: calc(100% - 16px);
height: 56px;
padding: 5px;
}
.pswp__thumbnail {
flex-basis: 54px;
width: 54px;
height: 44px;
}
}
@media (prefers-reduced-motion: reduce) {
.pswp__thumbnail { transition: none; }
}
</style>
+11 -8
View File
@@ -22,19 +22,21 @@ interface Props {
textTone?: BannerTextTone;
}
const { article, banner, about = false } = Astro.props;
const { article, banner, about = false, textTone: toneOverride } = Astro.props;
const enabled = Boolean(about || article || banner || siteConfig.banner.enabled);
const image = banner ? banner.image : article?.image ?? (about ? undefined : siteConfig.banner.image);
const title = about ? siteConfig.site.author.name : (banner?.title ?? article?.title ?? siteConfig.banner.title);
const subtitle = banner?.subtitle ?? siteConfig.banner.subtitle;
const position = banner?.position ?? siteConfig.banner.position;
const textTone = toneOverride ?? banner?.textTone ?? article?.textTone ?? siteConfig.banner.textTone ?? 'auto';
---
{enabled && <section
class="relative top-0 flex min-h-50 items-center justify-center overflow-hidden bg-raised pt-16 text-center text-foreground md:pt-16"
class:list={['relative top-0 flex min-h-50 items-center justify-center overflow-hidden bg-raised pt-16 text-center text-foreground md:pt-16', { 'about-masthead': about }]}
style={`background-position: ${position}; --mobile-height: ${siteConfig.banner.mobileHeightVh}vh; --desktop-height: ${siteConfig.banner.desktopHeightVh}vh; --overlay: ${siteConfig.banner.overlay}`}
data-banner-image={image || undefined}
data-banner-tone={image ? 'light' : undefined}
data-banner-tone={image ? (textTone === 'auto' ? 'light' : textTone) : undefined}
data-banner-tone-mode={image ? textTone : undefined}
aria-labelledby="masthead-title"
data-pagefind-ignore="all"
data-banner
@@ -47,7 +49,7 @@ const position = banner?.position ?? siteConfig.banner.position;
{image && <div class="absolute inset-0 z-[1]" style={`background-color: rgb(0 0 0 / ${siteConfig.banner.overlay})`} aria-hidden="true"></div>}
<div class="relative z-10 flex w-[calc(100%-1.75rem)] flex-col items-center justify-center">
{about && <img
class:list={['mb-5 size-[7rem] rounded-full border-4 border-white/85 object-cover shadow-lg md:size-[9.375rem]', { 'about-avatar': siteConfig.site.author.rotateAvatar }]}
class:list={['mb-5 size-[7rem] shrink-0 rounded-full border-4 border-white/85 object-cover shadow-lg md:size-[9.375rem]', { 'about-avatar': siteConfig.site.author.rotateAvatar }]}
src={siteConfig.site.author.avatar}
alt={`${siteConfig.site.author.name} 的头像`}
width="150"
@@ -55,7 +57,7 @@ const position = banner?.position ?? siteConfig.banner.position;
loading="eager"
fetchpriority="high"
/>}
<h1 class="m-0 text-[2rem] leading-tight font-light tracking-[0] md:text-[2.5rem]" id="masthead-title">{title}</h1>
<h1 class:list={['m-0 text-[2rem] leading-tight font-light tracking-[0] md:text-[2.5rem]', { 'shrink-0': about }]} id="masthead-title">{title}</h1>
{article ? <p class="masthead-meta mt-3 mb-0 flex flex-wrap items-center justify-center gap-x-2 gap-y-1 text-[0.9375rem] md:text-base">
<span class="masthead-date"><span>{article.date.year}</span><strong>年</strong><span>{article.date.month}</span><strong>月</strong><span>{article.date.day}</span><strong>日</strong></span>
{article.categories.length > 0 && <span class="masthead-separator" aria-hidden="true">·</span>}
@@ -67,9 +69,9 @@ const position = banner?.position ?? siteConfig.banner.position;
</div>
</section>}
{enabled && image && <script>
{enabled && image && textTone === 'auto' && <script>
const updateBannerTone = () => {
const masthead = document.querySelector<HTMLElement>('[data-banner][data-banner-image]');
const masthead = document.querySelector<HTMLElement>("[data-banner][data-banner-image][data-banner-tone-mode='auto']");
const imageUrl = masthead?.dataset.bannerImage;
if (!masthead || !imageUrl) return;
@@ -107,6 +109,7 @@ const position = banner?.position ?? siteConfig.banner.position;
<style>
section { height: var(--mobile-height); }
.about-masthead { min-height: 15rem; }
:global(:root[data-font='serif']) section h1 { font-weight: 700; }
section[data-banner-image][data-banner-tone='dark'] h1,
section[data-banner-image][data-banner-tone='dark'] p,
@@ -124,6 +127,6 @@ const position = banner?.position ?? siteConfig.banner.position;
.masthead-category { font-family: var(--mirages-font-ui); }
.about-avatar { transform: rotate(0deg); transition: transform 0.5s cubic-bezier(0.33, 1, 0.68, 1); }
.about-avatar:hover { transform: rotate(-32deg); }
@media (min-width: 48rem) { section { height: var(--desktop-height); } }
@media (min-width: 48rem) { section { height: var(--desktop-height); } .about-masthead { min-height: 18rem; } }
@media (prefers-reduced-motion: reduce) { .about-avatar { transition: none; transform: none; } .about-avatar:hover { transform: none; } }
</style>
+12 -2
View File
@@ -78,8 +78,8 @@ const { overlay = false } = Astro.props;
{sidebarToolbarItems.map((item) => (
<div class="static flex items-center" data-toolbar-item={item.type} data-toolbar-name={item.name}>
{item.type === 'settings' && <ThemeSwitcher placement="up" />}
{item.type === 'link' && <a class="grid size-[2.5rem] shrink-0 place-items-center text-foreground no-underline hover:bg-raised" href={item.href} target={item.external ? '_blank' : undefined} rel={item.external ? 'noreferrer' : undefined} aria-label={item.name} title={item.name}><ToolbarIcon icon={item.icon} /><span class="sr-only">{item.name}</span></a>}
{item.type === 'rss' && <button class="relative grid size-[2.5rem] shrink-0 cursor-pointer place-items-center border-0 bg-transparent p-0 text-foreground hover:bg-raised" type="button" aria-label={item.name} title={item.name} data-rss-copy data-rss-url={item.href}><span class="grid place-items-center leading-none" data-rss-default-icon><ToolbarIcon icon={item.icon} /></span><Check class="hidden" aria-hidden="true" size="1em" data-rss-success-icon /><span class="pointer-events-none absolute bottom-[calc(100%+0.5rem)] left-1/2 hidden -translate-x-1/2 whitespace-nowrap rounded-[4px] bg-foreground px-2 py-1 text-xs text-page shadow-mirages" role="status" data-rss-feedback>已复制</span><span class="sr-only">{item.name}</span></button>}
{item.type === 'link' && <a class="grid size-[2.5rem] shrink-0 place-items-center rounded-[4px] text-foreground no-underline transition-colors duration-150 hover:bg-mirages-accent/10 hover:text-mirages-accent" href={item.href} target={item.external ? '_blank' : undefined} rel={item.external ? 'noreferrer' : undefined} aria-label={item.name} title={item.name}><ToolbarIcon icon={item.icon} /><span class="sr-only">{item.name}</span></a>}
{item.type === 'rss' && <button class="relative grid size-[2.5rem] shrink-0 cursor-pointer place-items-center rounded-[4px] border-0 bg-transparent p-0 text-foreground transition-colors duration-150 hover:bg-mirages-accent/10 hover:text-mirages-accent" type="button" aria-label={item.name} title={item.name} data-rss-copy data-rss-url={item.href}><span class="grid place-items-center leading-none" data-rss-default-icon><ToolbarIcon icon={item.icon} /></span><Check class="hidden" aria-hidden="true" size="1em" data-rss-success-icon /><span class="pointer-events-none absolute bottom-[calc(100%+0.5rem)] left-1/2 hidden -translate-x-1/2 whitespace-nowrap rounded-[4px] bg-foreground px-2 py-1 text-xs text-page shadow-mirages" role="status" data-rss-feedback>已复制</span><span class="sr-only">{item.name}</span></button>}
</div>
))}
</div>
@@ -176,6 +176,16 @@ const { overlay = false } = Astro.props;
background: color-mix(in srgb, currentColor 16%, transparent);
}
[data-sidebar-toolbar] [data-toolbar-item] > details > summary {
border-radius: var(--radius-sm);
transition: background-color var(--transition-fast), color var(--transition-fast);
}
[data-sidebar-toolbar] [data-toolbar-item] > details > summary:is(:hover, :focus-visible) {
background-color: color-mix(in srgb, var(--color-accent) 10%, transparent);
color: var(--color-accent);
}
.navbar-over-banner [data-navbar-tools] .navbar-search-container > .search-form {
border-color: color-mix(in srgb, var(--color-text) 50%, transparent);
background: color-mix(in srgb, var(--color-bg) 92%, transparent);
+1 -1
View File
@@ -65,7 +65,7 @@ const placeholder = siteConfig.search.provider === 'pagefind' ? siteConfig.searc
.navbar-search-container > .search-form {
transform-origin: right center;
scale: 0 1;
transition: scale 200ms ease-out, opacity 200ms ease-out;
transition: scale 200ms cubic-bezier(0, 0.55, 0.45, 1), opacity 200ms cubic-bezier(0, 0.55, 0.45, 1);
}
.search-form input[type='search']::-webkit-search-cancel-button {
+8 -1
View File
@@ -1,5 +1,6 @@
---
import { siteConfig } from '@/site.config';
import { getWebmentionEndpoint } from '@/lib/webmentions';
interface Props {
title?: string;
@@ -7,6 +8,7 @@ interface Props {
image?: string;
type?: 'website' | 'article';
noindex?: boolean;
webmention?: boolean;
}
const {
@@ -14,16 +16,21 @@ const {
description = siteConfig.site.description,
image,
type = 'website',
noindex = false
noindex = false,
webmention = false
} = Astro.props;
const pageTitle = title ? `${title} - ${siteConfig.site.title}` : siteConfig.site.title;
const canonical = new URL(Astro.url.pathname, siteConfig.site.url);
const imageUrl = image ? new URL(image, siteConfig.site.url) : undefined;
const webmentionEndpoint = webmention && siteConfig.webmentions.enabled && siteConfig.webmentions.endpoint.trim()
? getWebmentionEndpoint(siteConfig.webmentions.endpoint, 'receive')
: undefined;
---
<title>{pageTitle}</title>
<meta name="description" content={description} />
<link rel="canonical" href={canonical} />
{webmentionEndpoint && <link rel="webmention" href={webmentionEndpoint} />}
<meta property="og:type" content={type} />
<meta property="og:title" content={pageTitle} />
<meta property="og:description" content={description} />
+3
View File
@@ -39,6 +39,8 @@
const initCurrentComments = () => {
const root = document.querySelector('#twikoo-comments');
if (!(root instanceof HTMLElement) || root.dataset.twikooBound) return;
const panel = root.closest('[data-engagement-panel]');
if (panel instanceof HTMLElement && panel.hidden) return;
let config;
try {
config = JSON.parse(root.dataset.twikooConfig ?? '{}');
@@ -62,6 +64,7 @@
initCurrentComments();
document.addEventListener('astro:page-load', initCurrentComments);
document.addEventListener('engagement:tab-change', initCurrentComments);
document.addEventListener('astro:before-swap', () => {
document.querySelector('#twikoo-comments')?.replaceChildren();
});
+6 -7
View File
@@ -12,12 +12,12 @@ const config = comments.provider === 'twikoo' && comments.envId.trim() ? {
} : null;
---
{enabled && config && <section class="comments-shell" id="comments" aria-labelledby="comments-title">
<h2 id="comments-title">评论</h2>
<h2 class="sr-only" id="comments-title">评论</h2>
<div id="twikoo-comments" data-twikoo-config={JSON.stringify(config)} data-twikoo-state="idle"></div>
</section>}
{enabled && !config && <section class="comments-shell comments-preview" id="comments" aria-labelledby="comments-title" data-pagefind-ignore="all">
<h2 id="comments-title">评论</h2>
<h2 class="sr-only" id="comments-title">评论</h2>
<div class="twikoo-preview" aria-label="Twikoo 评论预览">
<p class="twikoo-preview-status">Twikoo 尚未配置</p>
<div class="twikoo-preview-fields" aria-hidden="true">
@@ -30,9 +30,8 @@ const config = comments.provider === 'twikoo' && comments.envId.trim() ? {
</section>}
<style is:global>
#comments { width: min(100%, var(--article-content-width)); margin: 4.375rem auto 0; }
#comments > h2 { margin: 0 0 1.5rem; padding-top: 1.375rem; border-top: 1px solid var(--color-border); color: var(--color-accent-strong); font-family: var(--reading-font-family); font-size: 1.5625rem; font-weight: 500; }
#twikoo-comments, #comments > #twikoo { color: var(--color-text); font-size: .94rem; }
#comments { width: 100%; margin: 0; font-family: var(--reading-font-family); }
#twikoo-comments, #comments > #twikoo { color: var(--color-text); font-family: var(--reading-font-family); font-size: .94rem; }
#twikoo-comments .tk-comments-title, #comments > #twikoo .tk-comments-title { margin: 0 0 18px; color: var(--color-text); font-family: var(--font-serif); font-size: 1.1rem; font-weight: 600; }
#twikoo-comments .tk-comment, #comments > #twikoo .tk-comment { padding: 1.375rem 0; border-bottom: 1px solid var(--color-border); }
#twikoo-comments .tk-content, #twikoo-comments .tk-comment-content, #comments > #twikoo .tk-content, #comments > #twikoo .tk-comment-content { margin-top: .5rem; color: var(--color-text); line-height: 1.75; overflow-wrap: anywhere; }
@@ -94,7 +93,7 @@ const config = comments.provider === 'twikoo' && comments.envId.trim() ? {
#comments > #twikoo .tk-submit-action-icon { color: var(--color-muted) !important; }
#comments > #twikoo .OwO-logo { color: var(--color-muted) !important; }
#comments > #twikoo .OwO-body { border: 1px solid var(--color-border) !important; border-radius: var(--radius-sm) !important; background: var(--color-surface) !important; color: var(--color-text) !important; box-shadow: var(--shadow-soft) !important; }
#comments > #twikoo .tk-send { min-width: 7rem !important; height: 2.25rem !important; border: 0 !important; border-radius: var(--radius-sm) !important; background: var(--color-accent) !important; color: var(--color-accent-contrast) !important; font-weight: 500 !important; }
#comments > #twikoo .tk-send { min-width: 7rem !important; height: 2.25rem !important; border: 0 !important; border-radius: var(--radius-sm) !important; background: var(--color-accent) !important; color: var(--color-accent-contrast) !important; font-family: var(--reading-font-family) !important; font-size: .875rem !important; font-weight: 500 !important; }
#comments > #twikoo .tk-send.is-disabled { opacity: .55 !important; }
#comments > #twikoo .tk-preview { border: 1px solid var(--color-border) !important; border-radius: var(--radius-sm) !important; background: transparent !important; color: var(--color-muted) !important; }
#comments > #twikoo .tk-comments-container { margin-top: 3rem !important; }
@@ -169,5 +168,5 @@ const config = comments.provider === 'twikoo' && comments.envId.trim() ? {
#comments > #twikoo .tk-replies .tk-comment > .tk-avatar { flex-basis: 1.75rem !important; width: 1.75rem !important; height: 1.75rem !important; margin-right: .5rem !important; }
#comments > #twikoo .OwO .OwO-body { right: 0 !important; left: auto !important; width: min(18rem, 100vw - 2rem) !important; }
}
@media (max-width: 37.5rem) { #comments { margin-top: 3.25rem; } #twikoo-comments .tk-avatar, #twikoo-comments .tk-comment-avatar { width: 1.875rem; height: 1.875rem; } }
@media (max-width: 37.5rem) { #twikoo-comments .tk-avatar, #twikoo-comments .tk-comment-avatar { width: 1.875rem; height: 1.875rem; } }
</style>
+844
View File
@@ -0,0 +1,844 @@
---
import { getWebmentionEndpoint } from '@/lib/webmentions';
import { siteConfig } from '@/site.config';
interface Props {
target?: string;
}
const { target = new URL(Astro.url.pathname, siteConfig.site.url).href } = Astro.props;
const config = siteConfig.webmentions;
const endpoint = config.endpoint.trim();
const receiveEndpoint = endpoint ? getWebmentionEndpoint(endpoint, 'receive') : '';
const getEndpoint = endpoint ? getWebmentionEndpoint(endpoint, 'get') : '';
---
{config.enabled && endpoint && <section
class="webmentions-shell"
id="webmentions"
aria-labelledby="webmentions-title"
data-webmentions-root
data-get-endpoint={getEndpoint}
data-receive-endpoint={receiveEndpoint}
data-target={target}
data-site-origin={new URL(siteConfig.site.url).origin}
data-pagefind-ignore="all"
>
<h2 class="sr-only" id="webmentions-title">Webmention</h2>
<div class="webmentions-loading" data-webmentions-loading role="status" aria-label="正在读取 Webmention">
<svg class="webmentions-loading-spinner" viewBox="25 25 50 50" aria-hidden="true">
<circle class="webmentions-loading-path" cx="50" cy="50" r="20" fill="none"></circle>
</svg>
<span>Loading...</span>
</div>
<p class="webmentions-status" data-webmentions-status role="status" hidden></p>
<div class="webmentions-reactions" data-webmentions-reactions hidden>
<div data-webmentions-reaction-group="like" hidden>
<h3><span data-webmentions-like-count>0</span> 人喜欢</h3>
<div class="webmentions-reaction-list" data-webmentions-like-list></div>
</div>
<div data-webmentions-reaction-group="repost" hidden>
<h3><span data-webmentions-repost-count>0</span> 次转发</h3>
<div class="webmentions-reaction-list" data-webmentions-repost-list></div>
</div>
</div>
<div class="webmentions-discussion" data-webmentions-discussion hidden>
<h3><span data-webmentions-discussion-count>0</span> 条回应与提及</h3>
<ol data-webmentions-list></ol>
</div>
{config.form && <form class="webmention-form" action={receiveEndpoint} method="post" data-webmention-form>
<label for="webmention-source">发送 Webmention</label>
<div class="webmention-form-row">
<input id="webmention-source" name="source" type="url" inputmode="url" autocomplete="url" placeholder="https://example.com/your-post" required />
<input name="target" type="hidden" value={target} />
<button type="submit">发送</button>
</div>
<p class="webmention-form-status" data-webmention-form-status role="status" aria-live="polite"></p>
</form>}
</section>}
<style>
.webmentions-shell {
font-family: var(--reading-font-family);
font-size: .94rem;
}
.webmentions-status,
.webmention-form-status {
color: var(--color-muted);
font-size: .86rem;
}
.webmentions-loading {
display: flex;
min-height: 5rem;
align-items: center;
justify-content: center;
gap: .625rem;
color: var(--color-muted);
font-size: .86rem;
}
.webmentions-loading[hidden] {
display: none;
}
.webmentions-loading-spinner {
width: 2.625rem;
height: 2.625rem;
animation: webmentions-loading-rotate 2s linear infinite;
}
.webmentions-loading-path {
animation: webmentions-loading-dash 1.5s ease-in-out infinite;
stroke: var(--color-accent);
stroke-dasharray: 90, 150;
stroke-dashoffset: 0;
stroke-linecap: round;
stroke-width: 2;
}
.webmentions-status {
margin: 0;
padding-block: .25rem 1rem;
}
@keyframes webmentions-loading-rotate {
to { transform: rotate(360deg); }
}
@keyframes webmentions-loading-dash {
0% { stroke-dasharray: 1, 200; stroke-dashoffset: 0; }
50% { stroke-dasharray: 90, 150; stroke-dashoffset: -40px; }
100% { stroke-dasharray: 90, 150; stroke-dashoffset: -120px; }
}
@media (prefers-reduced-motion: reduce) {
.webmentions-loading-spinner,
.webmentions-loading-path {
animation-duration: 3s;
}
}
.webmentions-reactions {
display: flex;
flex-wrap: wrap;
gap: 1.25rem 2.5rem;
margin-bottom: 2rem;
}
.webmentions-reactions h3,
.webmentions-discussion h3 {
margin: 0 0 .75rem;
color: var(--color-text);
font-family: var(--reading-font-family);
font-size: .9375rem;
font-weight: 500;
}
.webmentions-reaction-list {
display: flex;
flex-wrap: wrap;
gap: .45rem;
}
:global(.webmention-reaction) {
display: grid;
width: 2.25rem;
height: 2.125rem;
place-items: center;
overflow: hidden;
border: 1px solid var(--color-border);
border-radius: 50%;
background: var(--color-code);
color: var(--color-muted);
font-family: var(--mirages-font-ui);
font-size: .75rem;
font-weight: 600;
text-decoration: none;
}
:global(.webmention-site-icon) {
position: relative;
display: grid;
width: 100%;
height: 100%;
place-items: center;
overflow: hidden;
border-radius: inherit;
}
:global(.webmention-site-icon img),
:global(.webmention-icon-fallback) {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
}
:global(.webmention-site-icon img) {
z-index: 1;
padding: .3rem;
border-radius: inherit;
background: var(--color-surface);
object-fit: contain;
opacity: 0;
}
:global(.webmention-site-icon[data-icon-loaded='true'] img) {
opacity: 1;
}
:global(.webmention-icon-fallback) {
display: grid;
place-items: center;
}
:global(.webmention-reaction:hover) {
border-color: var(--color-accent);
color: var(--color-accent-strong);
}
.webmentions-discussion ol {
margin: 0;
padding: 0;
list-style: none;
}
:global(.webmention-item) {
display: grid;
grid-template-columns: 2.25rem minmax(0, 1fr);
gap: .75rem;
padding: 1.25rem 0;
border-top: 1px solid var(--color-border);
}
:global(.webmention-avatar) {
display: grid;
width: 2.25rem;
height: 2.25rem;
place-items: center;
border-radius: 50%;
background: var(--color-code);
color: var(--color-muted);
font-family: var(--mirages-font-ui);
font-size: .75rem;
font-weight: 600;
}
:global(.webmention-meta) {
display: flex;
flex-wrap: wrap;
align-items: baseline;
gap: .25rem .65rem;
min-width: 0;
}
:global(.webmention-author) {
color: var(--color-text);
font-size: .8125rem;
font-weight: 500;
overflow-wrap: anywhere;
}
:global(.webmention-host) {
color: var(--color-muted);
font-size: .75rem;
overflow-wrap: anywhere;
}
:global(.webmention-date),
:global(.webmention-kind) {
color: var(--color-muted);
font-size: .75rem;
}
:global(.webmention-content) {
margin: .5rem 0 0;
color: var(--color-text);
font-size: .9375rem;
line-height: 1.65;
overflow-wrap: anywhere;
white-space: pre-wrap;
}
:global(.webmention-source-link) {
display: inline-block;
margin-top: .45rem;
color: var(--color-accent);
font-size: .78rem;
}
.webmention-form {
margin-top: 2rem;
padding-top: 1.25rem;
border-top: 1px solid var(--color-border);
}
.webmention-form > label {
display: block;
margin-bottom: .5rem;
color: var(--color-muted);
font-size: .8rem;
}
.webmention-form-row {
display: flex;
gap: .625rem;
}
.webmention-form input[type='url'] {
min-width: 0;
flex: 1 1 auto;
height: 2.125rem;
padding: .438rem .525rem;
border: 1px solid var(--color-border);
border-radius: var(--radius-sm);
background: var(--color-surface);
color: var(--color-text);
font-family: inherit;
font-size: .8125rem;
box-shadow: none;
}
.webmention-form input[type='url']:focus {
border-color: var(--color-accent);
outline: none;
}
.webmention-form button {
display: inline-flex;
flex: 0 0 auto;
align-items: center;
justify-content: center;
min-width: 7rem;
height: 2.25rem;
padding: 0 .875rem;
border: 0;
border-radius: var(--radius-sm);
background: var(--color-accent);
color: var(--color-accent-contrast);
cursor: pointer;
font-family: inherit;
font-size: .875rem;
font-weight: 500;
}
.webmention-form button:disabled {
cursor: wait;
opacity: .6;
}
.webmention-form-status {
min-height: 1.5em;
margin: .4rem 0 0;
}
@media (max-width: 37.5rem) {
.webmentions-shell {
font-size: .9rem;
}
.webmention-form-row {
align-items: stretch;
flex-direction: column;
}
.webmention-form button {
align-self: flex-end;
min-width: 5.5rem;
}
}
</style>
<script>
type WebmentionRecord = {
id: string;
source: string;
hostname: string;
createdAt: string;
title: string;
content: string;
author: string;
siteName: string;
favicons: string[];
type: string;
};
type WebmentionClientState = {
bound?: boolean;
controller?: AbortController;
metadataCache?: Map<string, Promise<SourceMetadata | null>>;
observer?: IntersectionObserver;
};
type SourceMetadata = {
title: string;
siteName: string;
favicon: string;
};
declare global {
interface Window {
__miragesWebmentions?: WebmentionClientState;
}
}
const state = window.__miragesWebmentions ??= {};
const metadataCache = state.metadataCache ??= new Map<string, Promise<SourceMetadata | null>>();
const getString = (record: Record<string, unknown>, key: string) => {
const value = record[key];
return typeof value === 'string' ? value.trim() : '';
};
const safeSource = (value: string) => {
try {
const url = new URL(value);
return url.protocol === 'http:' || url.protocol === 'https:' ? url : null;
} catch {
return null;
}
};
const safeAsset = (value: string, base: URL) => {
if (!value) return '';
try {
const url = new URL(value, base);
return url.protocol === 'http:' || url.protocol === 'https:' ? url.href : '';
} catch {
return '';
}
};
const plainText = (value: string) => {
if (!value) return '';
const parsed = new DOMParser().parseFromString(value, 'text/html');
return (parsed.body.textContent ?? '').replace(/\s+/g, ' ').trim().slice(0, 1200);
};
const objectValue = (value: unknown) => (
value && typeof value === 'object' && !Array.isArray(value)
? value as Record<string, unknown>
: null
);
const normalizeMention = (value: unknown): WebmentionRecord | null => {
if (!value || typeof value !== 'object' || Array.isArray(value)) return null;
const record = value as Record<string, unknown>;
const source = safeSource(getString(record, 'source'));
if (!source) return null;
const author = plainText(getString(record, 'author_name'));
const siteName = plainText(getString(record, 'site_name'))
|| plainText(getString(record, 'site_title'))
|| author
|| source.hostname;
const favicon = safeAsset(
getString(record, 'favicon') || getString(record, 'site_icon') || getString(record, 'icon'),
source
);
const favicons = Array.from(new Set([
favicon,
`https://favicon.im/${encodeURIComponent(source.hostname)}?larger=true`
].filter(Boolean)));
return {
id: getString(record, 'id'),
source: source.href,
hostname: source.hostname,
createdAt: getString(record, 'created_at'),
title: plainText(getString(record, 'title')),
content: plainText(getString(record, 'content')),
author: author || source.hostname,
siteName,
favicons,
type: getString(record, 'type').toLowerCase()
};
};
const kindOf = (mention: WebmentionRecord) => {
if (mention.type.includes('like')) return 'like';
if (mention.type.includes('repost') || mention.type.includes('share')) return 'repost';
if (mention.type.includes('reply')) return 'reply';
return 'mention';
};
const kindLabel = (kind: ReturnType<typeof kindOf>) => ({
like: '喜欢',
repost: '转发',
reply: '回应',
mention: '提及'
})[kind];
const initialFor = (name: string) => Array.from(name.trim())[0]?.toLocaleUpperCase() ?? '@';
const displayTitle = (mention: WebmentionRecord) => mention.title || mention.siteName || mention.hostname;
const sourceSlug = (source: URL) => {
const segments = source.pathname.split('/').filter(Boolean);
const segment = segments.at(-1) ?? '';
try {
return decodeURIComponent(segment).replace(/\.(?:html?|php)$/i, '');
} catch {
return segment.replace(/\.(?:html?|php)$/i, '');
}
};
const isSlugTitle = (title: string, source: URL) => {
const normalized = (value: string) => value
.trim()
.toLocaleLowerCase()
.replace(/[\s_-]+/g, '-');
return Boolean(title) && normalized(title) === normalized(sourceSlug(source));
};
const parseSourceDocument = (html: string, base: URL): SourceMetadata => {
const sourceDocument = new DOMParser().parseFromString(html, 'text/html');
const metaContent = (selector: string) => (
sourceDocument.querySelector<HTMLMetaElement>(selector)?.content ?? ''
);
const faviconHref = sourceDocument.querySelector<HTMLLinkElement>(
'link[rel~="icon"], link[rel="shortcut icon"]'
)?.getAttribute('href') ?? '';
return {
title: plainText(metaContent('meta[property="og:title"]') || sourceDocument.title),
siteName: plainText(metaContent('meta[property="og:site_name"]')),
favicon: safeAsset(faviconHref, base)
};
};
const fetchSourceDocument = async (mention: WebmentionRecord, requestUrl = mention.source) => {
const controller = new AbortController();
const timeout = window.setTimeout(() => controller.abort(), 8000);
try {
const response = await fetch(requestUrl, {
headers: { Accept: 'text/html,application/xhtml+xml' },
signal: controller.signal
});
if (!response.ok) return null;
const contentType = response.headers.get('content-type') ?? '';
if (!contentType.toLowerCase().includes('text/html')) return null;
return parseSourceDocument(await response.text(), new URL(mention.source));
} catch {
return null;
} finally {
window.clearTimeout(timeout);
}
};
const fetchMicrolinkMetadata = async (mention: WebmentionRecord) => {
const source = new URL(mention.source);
const url = new URL('https://api.microlink.io/');
url.searchParams.set('url', mention.source);
const controller = new AbortController();
const timeout = window.setTimeout(() => controller.abort(), 8000);
try {
const response = await fetch(url, {
headers: { Accept: 'application/json' },
signal: controller.signal
});
if (!response.ok) return null;
const payload = objectValue(await response.json());
const data = objectValue(payload?.data);
if (!data) return null;
const title = plainText(typeof data.title === 'string' ? data.title : '');
return {
title: isSlugTitle(title, source) ? '' : title,
siteName: plainText(typeof data.publisher === 'string' ? data.publisher : ''),
favicon: ''
};
} catch {
return null;
} finally {
window.clearTimeout(timeout);
}
};
const sourceMetadata = (mention: WebmentionRecord, siteOrigin: string) => {
const sourceOrigin = new URL(mention.source).origin;
const canFetchDirectly = sourceOrigin === window.location.origin || sourceOrigin === siteOrigin;
const cacheKey = `${canFetchDirectly ? 'direct' : 'external'}:${mention.source}`;
const cached = metadataCache.get(cacheKey);
if (cached) return cached;
const directUrl = sourceOrigin === siteOrigin
? new URL(`${new URL(mention.source).pathname}${new URL(mention.source).search}`, window.location.origin).href
: mention.source;
const request = canFetchDirectly
? fetchSourceDocument(mention, directUrl).then((metadata) => metadata ?? fetchMicrolinkMetadata(mention))
: fetchMicrolinkMetadata(mention);
metadataCache.set(cacheKey, request);
return request;
};
const enrichMention = async (mention: WebmentionRecord, siteOrigin: string) => {
const metadata = await sourceMetadata(mention, siteOrigin);
if (!metadata) return mention;
return {
...mention,
title: mention.title || metadata.title,
siteName: metadata.siteName || mention.siteName,
favicons: Array.from(new Set([metadata.favicon, ...mention.favicons].filter(Boolean)))
};
};
const sourceLink = (mention: WebmentionRecord, className: string) => {
const link = document.createElement('a');
link.className = className;
link.href = mention.source;
link.target = '_blank';
link.rel = 'nofollow ugc noopener noreferrer';
return link;
};
const createSiteIcon = (mention: WebmentionRecord, className: string) => {
const wrapper = document.createElement('span');
wrapper.className = className;
wrapper.setAttribute('aria-hidden', 'true');
const fallback = document.createElement('span');
fallback.className = 'webmention-icon-fallback';
fallback.textContent = initialFor(mention.siteName || mention.hostname);
const image = document.createElement('img');
image.alt = '';
image.loading = 'lazy';
image.decoding = 'async';
image.referrerPolicy = 'no-referrer';
image.addEventListener('load', () => {
wrapper.dataset.iconLoaded = 'true';
});
let faviconIndex = 0;
image.addEventListener('error', () => {
faviconIndex += 1;
const nextFavicon = mention.favicons[faviconIndex];
if (nextFavicon) {
image.src = nextFavicon;
return;
}
image.remove();
});
wrapper.append(fallback);
const firstFavicon = mention.favicons[0];
if (firstFavicon) {
image.src = firstFavicon;
wrapper.append(image);
}
return wrapper;
};
const renderReaction = (mention: WebmentionRecord) => {
const link = sourceLink(mention, 'webmention-reaction');
const title = displayTitle(mention);
link.append(createSiteIcon(mention, 'webmention-site-icon'));
link.title = `${title} (${mention.hostname})`;
link.setAttribute('aria-label', `${title}:${kindLabel(kindOf(mention))}`);
return link;
};
const renderDiscussion = (mention: WebmentionRecord) => {
const kind = kindOf(mention);
const item = document.createElement('li');
item.className = 'webmention-item';
const avatar = createSiteIcon(mention, 'webmention-avatar webmention-site-icon');
const body = document.createElement('div');
const meta = document.createElement('div');
meta.className = 'webmention-meta';
const author = sourceLink(mention, 'webmention-author');
author.textContent = displayTitle(mention);
meta.append(author);
if (displayTitle(mention) !== mention.hostname) {
const host = document.createElement('span');
host.className = 'webmention-host';
host.textContent = mention.hostname;
meta.append(host);
}
if (mention.createdAt) {
const date = new Date(mention.createdAt);
if (!Number.isNaN(date.getTime())) {
const time = document.createElement('time');
time.className = 'webmention-date';
time.dateTime = date.toISOString();
time.textContent = new Intl.DateTimeFormat('zh-CN', { dateStyle: 'medium' }).format(date);
meta.append(time);
}
}
const type = document.createElement('span');
type.className = 'webmention-kind';
type.textContent = kindLabel(kind);
meta.append(type);
body.append(meta);
const text = mention.content;
if (text) {
const content = document.createElement('p');
content.className = 'webmention-content';
content.textContent = text;
body.append(content);
}
const source = sourceLink(mention, 'webmention-source-link');
source.textContent = '查看来源';
body.append(source);
item.append(avatar, body);
return item;
};
const renderMentions = (root: HTMLElement, mentions: WebmentionRecord[]) => {
const loading = root.querySelector<HTMLElement>('[data-webmentions-loading]');
const status = root.querySelector<HTMLElement>('[data-webmentions-status]');
const likeGroup = root.querySelector<HTMLElement>('[data-webmentions-reaction-group="like"]');
const repostGroup = root.querySelector<HTMLElement>('[data-webmentions-reaction-group="repost"]');
const reactions = root.querySelector<HTMLElement>('[data-webmentions-reactions]');
const discussion = root.querySelector<HTMLElement>('[data-webmentions-discussion]');
const likeList = root.querySelector<HTMLElement>('[data-webmentions-like-list]');
const repostList = root.querySelector<HTMLElement>('[data-webmentions-repost-list]');
const list = root.querySelector<HTMLOListElement>('[data-webmentions-list]');
if (!loading || !status || !likeGroup || !repostGroup || !reactions || !discussion || !likeList || !repostList || !list) return;
const likes = mentions.filter((mention) => kindOf(mention) === 'like');
const reposts = mentions.filter((mention) => kindOf(mention) === 'repost');
const discussions = mentions.filter((mention) => !['like', 'repost'].includes(kindOf(mention)));
likeList.replaceChildren(...likes.map(renderReaction));
repostList.replaceChildren(...reposts.map(renderReaction));
list.replaceChildren(...discussions.map(renderDiscussion));
const likeCount = root.querySelector<HTMLElement>('[data-webmentions-like-count]');
const repostCount = root.querySelector<HTMLElement>('[data-webmentions-repost-count]');
const discussionCount = root.querySelector<HTMLElement>('[data-webmentions-discussion-count]');
if (likeCount) likeCount.textContent = String(likes.length);
if (repostCount) repostCount.textContent = String(reposts.length);
if (discussionCount) discussionCount.textContent = String(discussions.length);
likeGroup.hidden = likes.length === 0;
repostGroup.hidden = reposts.length === 0;
reactions.hidden = likes.length + reposts.length === 0;
discussion.hidden = discussions.length === 0;
loading.hidden = true;
status.textContent = mentions.length ? '' : '暂时还没有站外回应。';
status.hidden = mentions.length > 0;
};
const fetchWebmentions = (root: HTMLElement) => {
if (root.dataset.webmentionsLoaded) return;
root.dataset.webmentionsLoaded = 'true';
const loading = root.querySelector<HTMLElement>('[data-webmentions-loading]');
const status = root.querySelector<HTMLElement>('[data-webmentions-status]');
const getEndpoint = root.dataset.getEndpoint;
const target = root.dataset.target;
const siteOrigin = root.dataset.siteOrigin;
if (!loading || !status || !getEndpoint || !target || !siteOrigin) return;
state.controller?.abort();
const controller = new AbortController();
state.controller = controller;
const url = new URL(getEndpoint);
url.searchParams.set('target', target);
fetch(url, { headers: { Accept: 'application/json' }, signal: controller.signal })
.then((response) => {
if (!response.ok) throw new Error(`HTTP ${response.status}`);
return response.json();
})
.then((data: unknown) => {
if (!root.isConnected) return;
const mentions = Array.isArray(data)
? data.map(normalizeMention).filter((mention): mention is WebmentionRecord => mention !== null)
: [];
renderMentions(root, mentions);
if (!mentions.length) return;
void Promise.all(mentions.map((mention) => enrichMention(mention, siteOrigin))).then((enriched) => {
if (root.isConnected) renderMentions(root, enriched);
});
})
.catch(() => {
if (controller.signal.aborted || !root.isConnected) return;
loading.hidden = true;
status.textContent = '站外回应暂时无法读取。';
status.hidden = false;
});
};
const loadCurrentWebmentions = () => {
const root = document.querySelector<HTMLElement>('[data-webmentions-root]');
if (!root || root.dataset.webmentionsBound) return;
root.dataset.webmentionsBound = 'true';
state.observer?.disconnect();
if (!('IntersectionObserver' in window)) {
fetchWebmentions(root);
return;
}
state.observer = new IntersectionObserver((entries, observer) => {
if (!entries.some((entry) => entry.isIntersecting)) return;
observer.disconnect();
fetchWebmentions(root);
}, { rootMargin: '400px 0px' });
state.observer.observe(root);
};
const submitWebmention = (form: HTMLFormElement) => {
const status = form.querySelector<HTMLElement>('[data-webmention-form-status]');
const button = form.querySelector<HTMLButtonElement>('button[type="submit"]');
if (!status || !button) return;
button.disabled = true;
status.textContent = '正在发送...';
const body = new URLSearchParams();
for (const [name, value] of new FormData(form)) {
if (typeof value === 'string') body.append(name, value);
}
fetch(form.action, {
method: 'POST',
body,
// webmentiond currently requires this Content-Type without a charset suffix.
headers: {
Accept: 'application/json',
'Content-Type': 'application/x-www-form-urlencoded'
}
}).then(async (response) => {
if (!response.ok) {
const message = plainText(await response.text());
throw new Error(message || `HTTP ${response.status}`);
}
status.textContent = '已收到,验证通过并经审核后会显示在这里。';
const source = form.elements.namedItem('source');
if (source instanceof HTMLInputElement) source.value = '';
}).catch((error: unknown) => {
const message = error instanceof Error ? error.message : '';
status.textContent = message ? `发送失败:${message}` : '发送失败,请稍后重试。';
}).finally(() => {
button.disabled = false;
});
};
if (!state.bound) {
state.bound = true;
document.addEventListener('submit', (event) => {
const form = event.target;
if (!(form instanceof HTMLFormElement) || !form.matches('[data-webmention-form]')) return;
event.preventDefault();
submitWebmention(form);
});
document.addEventListener('astro:page-load', loadCurrentWebmentions);
document.addEventListener('astro:before-swap', () => {
state.observer?.disconnect();
state.controller?.abort();
});
}
loadCurrentWebmentions();
</script>
+1
View File
@@ -20,6 +20,7 @@ const baseSchema = z.object({
z.object({ enabled: z.boolean().default(true), position: z.enum(['left', 'right']).default('right') })
]).default(true),
comments: z.boolean().default(false),
webmention: z.boolean().default(false),
math: z.boolean().default(false),
mermaid: z.boolean().default(false)
});
+44 -70
View File
@@ -1,23 +1,29 @@
---
cover: "https://image.luming.cool/i/2026/07/26/6a6628967fe03.webp"
cover: "https://image.luming.cool/i/2026/08/25/6a8d95c4195c9.webp"
title: "关于"
pubDate: "2026-07-22T01:28:00.000Z"
updatedDate: "2026-07-27T05:26:00.000Z"
categories:
tags:
slug: "about"
comments: false
---
## 关于⌈我⌋
我是 RiseForever,生于河南。
我是 RiseForever,真名路明,生于河南,高二。
准高二了。喜欢开发软件、科技数码。是一名 Xiaomi Vela 快应用开发者。
我很幸福。
性格偏多疑敏感,善于察觉身边人的微小情绪。平时喜欢独处,不喜欢与任何人一起逛街、看电影,因为我感觉受到束缚。
### 听歌
如果你想知道我是一个怎样的人,请随便翻翻[我的文章](/archives),里面写的比我说的更清楚。
华晨宇、邓紫棋,他们绝大部分的歌我都循环了 100+ 遍,完全能熟练地唱出来。
这里列几首我喜欢的,欢迎品鉴:
- 华晨宇[《七重人格》](https://music1.luming.cool/share/BkxO252JGi)
- 华晨宇[《飞行模式》](https://music1.luming.cool/share/qg7ZPAcoCU)
- 华晨宇[《双截棍》](https://music1.luming.cool/share/E7PBSMJxBm)
- 邓紫棋[《受难曲》](https://music1.luming.cool/share/od6toNgdDS)
- 邓紫棋[《夜的尽头》](https://music1.luming.cool/share/lH8r5ulv3m)
### 联系
@@ -25,10 +31,16 @@ comments: false
GitHub:[virelyx258](https://github.com/virelyx258)
请不要试图添加我的即时通讯账户。无论有什么想探讨的,随时欢迎电邮交流。
云仓:[riseforever2026](https://src.luming.cool/riseforever2026)
X:[luming_cool](https://x.com/luming_cool)
**请不要添加我的国内即时通讯账户。** 无论有什么想探讨的,随时欢迎电邮交流。
### 使用的工具
[collapse title = "工具列表"]
[tools title = "设计"]
[Canva](https://www.canva.cn)+(https://image.luming.cool/i/2026/08/07/6a75ba231df9b.webp)/(图像设计)
[即时设计](https://js.design)+(https://image.luming.cool/i/2026/08/07/6a75c0b9bbf29.webp)/(UI 设计)
@@ -54,24 +66,30 @@ GitHub:[virelyx258](https://github.com/virelyx258)
[Debian 13](https://www.debian.org/index.zh-cn.html)+(https://image.luming.cool/i/2026/08/07/6a75c2db6a6e9.webp)/(备用系统)
[/tools]
[/collapse]
## 关于⌈这个网站⌋
严格来说,这个网站的建立时间是在 2024 年 10 月。因为我在那时开始转型记录生活。
有些话我没法对任何人说,于是就在这里写下。
### 站名
因为我的真名是路明,所以就给博客取名“路明笔记”。
### 域名
起初用的是 riseforever.cn,因为初中时我很想要一个有美好寓意的域名,想了很多,结果只有这个域名可注册。于是我选了它,网名也跟着取成了“RiseForever”。
起初用的是 riseforever.cn。当时想要有个美好寓意,想了很多,只有这个域名可用。于是匆匆注册,网名也跟着取成了“RiseForever”。
初三时,我觉得 riseforever.cn 太长了,且 .CN 当时仍不支持隐私保护,便想着换个域名。当时朋友买了一个“mnb.cool”,让我看到了 .cool 这个后缀。过了几天,我在学校灵机一动——用自己的名字拼写“luming”做前缀,使用“.cool”后缀,这样搭配在视觉上非常和谐。
初三时,我觉得 riseforever.cn 太长了,且 .CN 当时仍不支持免费隐私保护,便起了换域名的念头。当时朋友买了一个“mnb.cool”,让我看到了 .cool 这个后缀。过了几天,我在学校灵机一动——用自己的名字拼写“luming”做前缀,使用“.cool”后缀,这样搭配在视觉上非常和谐,双拼也很好记。
那周周末,我回家一搜 luming.cool ——未注册,于是赶紧注册了它。
| 注册商 | 帝思普(腾讯云) |
| -------------: | :------------------------------------------------------------------------------------------------------------- |
| 首次购入价格 | ¥48 |
| 续费价格 | ¥65 |
| 续费价格 | ¥105(原 ¥65) |
| 域名年龄 | ![域名年龄徽章](https://yisi.yun/api/badge/domain-age/luming.cool?theme=blue&lang=zh&size=medium&mode=light) |
[collapse title="riseforever.cn 信息"]
@@ -84,7 +102,7 @@ GitHub:[virelyx258](https://github.com/virelyx258)
[/collapse]
目前保持着 riseforever.cn 和 luming.cool 双域名持有,每年续费大约需要¥103。
目前保持着 riseforever.cn 和 luming.cool 双域名持有,每年续费大约需要¥143。
### 服务器
@@ -99,68 +117,16 @@ GitHub:[virelyx258](https://github.com/virelyx258)
| 硬盘 | 30GB SSD |
| 带宽 | 100 Mbps(峰值) |
[collapse title="2026 年 1 月 - 6 月"]
7iNet 香港特惠秒杀机,¥9.9/月,炸夸响。后因其性能太过诡异而被更换。
| CPU | 2H E5-2698 v4 |
| -----: | :-------------------------------------- |
| 内存 | 2G |
| 硬盘 | 40GB SSD(写入 43MB/s,读取 156MB/s) |
| 带宽 | 10 Mbps(不限流量) |
[/collapse]
[collapse title="2026 年以前"]
腾讯云新加坡服务器,¥99/年,买了两年,参加活动又送了三个月。后因 IP 线路更换导致延迟过高而被更换。
| CPU | 2H Platinum 8255C |
| -----: | :--------------------------------------- |
| 内存 | 2G |
| 硬盘 | 50GB SSD(写入 338MB/s,读取 6.2GB/s) |
| 带宽 | 30 Mbps(月限流 1TB) |
[/collapse]
### CDN
使用[毅融盾](https://rcdn.hydun.com/)进行图床加速。
毅融盾是融合了网宿与白山 CDN 资源的企业级 CDN,针对未备案域名进行特调,提供卓越的中国大陆访问速度。且没有三六九等的套餐配置,仅按流量计费,出售的是流量包。
毅融盾是我所在公司的产品,内部团队可免费使用,不限流量。如果你是外部用户,也可以通过[赞助计划](https://blog.hydun.com/9.html)免费获取 CDN 服务。
### 主题
使用我与 AI 协作制作的 Astro 主题 Eidolon。
[点我跳转开源仓库](https://src.luming.cool/riseforever2026/Eidolon)
它极大程度上复刻了 Typecho 主题 Mirages 的风格和功能,又在此基础上使用了更先进的 TailWind CSS,使得站点响应速度更加优秀。
~~因为 Mirages 是一款付费主题,如果贸然开源会影响到原主题的销售,且本站主题仍处于开发状态,所以本主题暂不开源。~~
仔细想想,发现我们其实不是同一个赛道。我做的是 Astro 主题,受众是 Astro 用户,不耽误 Typecho 主题的销售。况且,并不是所有 Typecho 用户都能无感切换到静态博客。
所以,本主题准备开源。
[collapse title="在此之前"]
使用 [Mirages](https://get233.com/archives/mirages-intro.html),一款阅读体验优秀的单栏 Typecho 主题。
我是在[白熊阿丸的小屋](https://blog.bxaw.name)首次体验这款主题,发现它支持用户手动切换衬线/非衬线字体、字体大小,这能使不同口味的用户都获得最适合自己的阅读体验。并且,这款主题在我的 MacBook Pro 2013 上表现得非常流畅。
于是在 2026 年 4 月,我选择购入并使用它。
[/collapse]
### 使用的第三方服务
使用 [WeAvatar](https://weavatar.com/) 作为评论区头像系统。
使用 [LUM ALBUM](https://image.luming.cool) 作为图床。(~~这也算第三方服务嘛~~)
### 备案
### 备案 & 墙
本站永远都不会考虑备案。
经过实测,本站在江苏部分地区会被劫持到反诈 IP,无法正常访问。这不是你的问题,也不是我的问题。
## 关于⌈我的作品⌋
[tools title = "Xiaomi Vela 快应用"]
@@ -181,8 +147,16 @@ GitHub:[virelyx258](https://github.com/virelyx258)
[/tools]
[tools title = "参与/发起的项目"]
[固件修改计划](https://qm.qq.com/q/C2hFEcdv5S)+(https://image.luming.cool/i/2026/08/23/6a8a4b00047f4.webp)/(小米可穿戴设备固件修改)
[Route2N](https://www.route2n.online)+(https://image.luming.cool/i/2026/08/23/6a8a4b361dde9.webp)/(AI API 中转站)
[/tools]
## 关于⌈版权协议⌋
如果没有特殊说明,本站文章都是原创,基于 [CC-BY-NC-ND 4.0](https://creativecommons.org/licenses/by-nc-nd/4.0/deed.zh-hans) 协议公开。
如果没有特殊说明,本站文章都是原创,基于 [CC-BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh-hans) 协议公开。
转载请注明原文链接。[协议](https://creativecommons.org/licenses/by-nc-nd/4.0/deed.zh-hans)原则上不允许对本站文章的再混合、转换、或者二次创作。如果有必要二创,请邮件沟通。
转载/演绎请注明原文链接。
+27 -17
View File
@@ -2,7 +2,7 @@
title: "友人"
description: "友谊地久天长"
pubDate: "2026-07-22T01:28:00.000Z"
cover: "https://image.luming.cool/i/2026/07/26/6a662e5c66130.webp"
cover: "https://image.luming.cool/i/2026/08/25/6a8d95c50c750.webp"
slug: "links"
---
@@ -20,11 +20,17 @@ slug: "links"
[小改学习志](https://www.haoyu233.com/)+(https://weavatar.com/avatar/14e584196d31262ea144ab4d75d4c083?s=200)/(行到水穷处,坐看云起时。)
[老陈爱刷机](https://blog.chenyuxia.com/)+(https://image.luming.cool/i/2026/06/21/6a37fdaf9c4c7.webp)/(你可以在这里找到一些好玩的东西。)
[懋和道人](https://blog.dao.js.cn/)+(https://weavatar.com/avatar/37d41e2b550633a30f5d41de61c1aa92?s=400&r=G&d=mp&ver=1754413756)/(李懋和,俗名李栋梁。书法、国画爱好者,互联网安全与前端建设者。)
[lcrworld's blog](https://lcrworld.xyz)+(https://lcrworld.xyz/default-avatar.jpeg)/(lcrworld的个人博客,分享文章,记录日常)
[UpXuu](https://upxuu.com)+(https://image.luming.cool/i/2026/08/17/6a82721a3b068.webp)/(逐光而上。)
[KFACBT](https://blog.gytxtx.top/)+(https://image.luming.cool/i/2026/06/22/6a3957de12346.webp)/(主要分享一些技术文章,偶尔也会发一些日常。)
[往日信笺](https://www.xingmail.cn/)+(https://image.luming.cool/i/2026/06/22/6a39570f5a1b6.webp)/(一个Xing分享自己的故事的地方)
[Horean's Blog](https://blog.hxrch.top)+(https://image.luming.cool/i/2026/06/21/6a37f998e92c8.webp)/(Spread the knowledge wisely & widely.)
[Horean's Blog](https://blog.hhut.me/)+(https://image.luming.cool/i/2026/06/21/6a37f998e92c8.webp)/(Spread the knowledge wisely & widely.)
[小岚的杂物间](https://www.guirlan.de/)+(https://weavatar.com/avatar/172530293dcfb25d871a72ccb39b21c2?s=200)/(这里储存着各种稀奇古怪事物~)
@@ -40,13 +46,19 @@ slug: "links"
[Pinpe 的云端](https://pinpe.top/)+(https://image.luming.cool/i/2026/06/22/6a39568f421dd.webp)/(一片属于自己的云朵。)
[朝朝听雨](https://rainzt.cn/)+(https://rainzt.cn/zzty.png)/(物物而不物于物,念念而不念于念。)
[蒋音象](https://jiangyx.org/)+(https://image.luming.cool/i/2026/07/11/6a51235da5835.webp)/(以文会友,以友辅仁。)
[摸鱼小窝](https://moyu.plus/)+(https://moyu.plus/logo.webp)/(代码路上雾茫茫。)
[摸鱼小窝](https://blog.aistu.cn)+(https://blog.aistu.cn/logo.webp)/(代码路上雾茫茫。)
[岚汐の小窝](https://blog.lanxis.top/)+(https://pic.lingqi.vip/logo11.jpg)/(一个兽兽的小树屋~)
[没吃饱的天镜镜](https://blog.8765777.xyz/)+(https://blogr2.8765777.xyz/assets/my/7590A261E0E39A642ABF4873E89EAFF9.jpg)/(诺贝尔奖关注者,文学奖读者)
[睿朗的秘密基地](https://blog.iamcrl.cn/)+(https://iamcrl.cn/avatar.jpg)/(Ruilang's Blog)
[拥抱日出的小屋](https://blog.byside.top)+(https://blog.byside.top/upload/logo.jpg)/(拥抱日出,也拥抱生活)
[岚汐の小窝](https://blog.lanxis.top/)+(https://blog.lanxis.top/upload/b_b0e5eb025faadac07cf07f007348155b.jpg)/(一个兽兽的小树屋~)
[睿朗的小窝](https://notes.iamcrl.cn/)+(https://iamcrl.cn/avatar.jpg)/(Ruilang's Blog)
[云晓晨](https://blog.kaiqi.wang)+(https://www.kaiqi.wang/favicon.ico)/(未来路远,勿忘初心。)
@@ -58,32 +70,30 @@ slug: "links"
[蘇 SU](https://suus.me)+(https://weavatar.com/avatar/5b986063afb0ee2d78abd40defe3aec607d812b372093008646e137f61023869?sha256=1&d=mp&s=500)/在数字的海洋中,寻找属于自己的星辰。)
[松種小窝](https://pineseed.cn/)+(https://image.luming.cool/i/2026/06/21/6a37fa0dc1945.webp)/(花开又花落,时节暗中迁。)
## 技术类博主
[新锐博客](https://blog.xrbk.cn/)+(https://blog.xrbk.cn/favicon.png)/(记录学习与分享资源。)
[RubbishZ](https://rubbishz.com/)+(https://image.luming.cool/i/2026/08/26/6a8ee3a108b7b.webp)/(实力非凡的 Vela 快应用创作者。)
[老陈爱刷机](https://blog.chenyuxia.com/)+(https://image.luming.cool/i/2026/06/21/6a37fdaf9c4c7.webp)/(抖音博主,10 后技术大蛇。)
[Tony's Blog](https://blog.iamsjy.com/)+(https://weavatar.com/avatar/05133c94d51c8003519bd17e55ddcd33)/(一个萌新的博客。)
[10 科技说](https://www.tech10.cn/)+(https://image.luming.cool/i/2026/08/06/6a74af0519e25.webp)/(10科技说的个人主页。)
[新锐博客](https://blog.xrbk.cn/)+(https://blog.xrbk.cn/favicon.png)/(记录学习与分享资源。)
[米雅乐](https://blog.miyale.cc/)+(https://image.luming.cool/i/2026/07/23/6a619b7273d45.webp)/(Coder & Designer.)
[LR.C](https://bbslrc.vxni.ink/)+(https://image.luming.cool/i/2026/06/21/6a37ede8eaad4.webp)/(一位 Xiaomi Vela 快应用开发者。)
[LR.C](https://bbslrc.vxni.ink/)+(https://image.luming.cool/i/2026/06/21/6a37ede8eaad4.webp)/(一位 Xiaomi Vela 快应用创作者。)
[小景](https://jingyuan-zheng.github.io/zh/)+(https://image.luming.cool/i/2026/07/23/6a62284fa496c.webp)/(随心分享有趣的技术、开源项目与生活记录。)
[Rain](https://rainzt.cn/)+(https://rainzt.cn/zzty.png)/(物物而不物于物,念念而不念于念)
[XXY の博客](https://blog.xuxiny.top)+(https://q1.qlogo.cn/headimg_dl?dst_uin=3429924750&spec=5)/(爱折腾,爱分享。)
[圆周率](https://www.yuanzj.top)+(https://image.luming.cool/i/2026/06/21/6a37fa3752ea4.webp)/(My Blog!)
[MC_Kero blog](https://blog.mckero.com/)+(https://img.cdn1.vip/i/68f3418995084_1760772489.png)/(依稀当年泪目干。)
[Levi](https://leviqin.top/)+(https://image.luming.cool/i/2026/06/22/6a3957bedea05.webp)/(一个有意思的Blog,工作记录,日常分享,欢迎访问。)
[KFACBT](https://blog.gytxtx.top/)+(https://image.luming.cool/i/2026/06/22/6a3957de12346.webp)/(主要分享一些技术文章,偶尔也会发一些日常。)
[重生云](https://xiaochopin.github.io/)+(https://weavatar.com/avatar/a10109bb266cc4eebc8d7992a4977a0c?s=200)/(明月装饰了你的窗,你装饰了别人的梦。)
[Echo](https://www.liveout.cn/)+(https://image.luming.cool/i/2026/07/23/6a619b08ec4ad.webp)/(Life is code. I will debug it.)
@@ -94,6 +104,6 @@ slug: "links"
欢迎与我交换 88x31 按钮。第一个是本站按钮。若要交换,请先在贵站放置本站按钮,然后电邮联系我进行交换。
<div style="display: inline-block; width: 88px;"><a href="https://www.luming.cool"><img src="https://image.luming.cool/i/2026/07/21/6a5f455105140.gif" alt="路明笔记" style="width: 100%; height: auto; display: block;"></a></div>
<div style="display: inline-block; width: 88px;"><a href="https://www.luming.cool"><img src="https://www.luming.cool/88x31.gif" alt="路明笔记" style="width: 100%; height: auto; display: block;"></a></div>
<div style="display: inline-block; width: 88px;"><a href="https://blog.bxaw.name/" target="_blank"><img src="https://img.bxaw.name/hotlink-ok/logo/bxaw-88x31.gif" alt="白熊阿丸" style="width: 100%; height: auto; display: block;"></a></div>
<div style="display: inline-block; width: 88px;"><a href="https://blog.verdant.ee/" target="_blank"><img src="https://image.luming.cool/i/2026/08/02/6a6f6164bd5b6.gif" alt="映屿" style="width: 100%; height: auto; display: block;"></a></div>
+5 -12
View File
@@ -8,11 +8,10 @@ categories:
tags:
- "Windows"
comments: true
webmention: true
---
<!-- wp:heading -->
<h2 class="wp-block-heading">前言</h2>
<!-- /wp:heading -->
## 前言
<!-- wp:paragraph -->
<p>大家好,我是路明。在文章开始之前,我想先问大家一个问题:在座的各位有多少是使用Windows11的呢?</p>
@@ -56,9 +55,7 @@ comments: true
<figure class="wp-block-image aligncenter size-full is-resized"><img src="https://luming-website.chgskj.cn/luming-notes/2024/01/20240113083009056354.webp" /></figure>
<!-- /wp:image -->
<!-- wp:heading -->
<h2 class="wp-block-heading">简要介绍</h2>
<!-- /wp:heading -->
## 简要介绍
<!-- wp:paragraph -->
<p>Tiny11是一个在国外拥有很好口碑的Windows11镜像,它在系统组件方面做了极大的精简,使其在安装后占用C盘空间≤9GB(原版≥20GB)。</p>
@@ -72,9 +69,7 @@ comments: true
<p>据说,Tiny11的最低硬件要求是2GB的RAM+8GB的ROM,可以说是让任何计算机都能安装体验Windows11了。</p>
<!-- /wp:paragraph -->
<!-- wp:heading -->
<h2 class="wp-block-heading">系统功能</h2>
<!-- /wp:heading -->
## 系统功能
<!-- wp:paragraph -->
<p>Tiny11和Windows11基本相同,删除了原版Windows11的诸多非核心组件(包括Microsoft Edge,但可以在Microsoft Store下载回来),但保留了Microsoft Store,方便用户下载其它Microsoft应用。</p>
@@ -134,9 +129,7 @@ comments: true
<p>如果你只是想要一个精简版系统,也可以下载Tiny11并安装。</p>
<!-- /wp:paragraph -->
<!-- wp:heading -->
<h2 class="wp-block-heading">下载地址(来自异次元)</h2>
<!-- /wp:heading -->
## 下载地址(来自异次元)
<!-- wp:paragraph -->
<p>阿里云盘:<a href="https://www.aliyundrive.com/s/JeDiTyWoHcV" target="_blank" rel="noreferrer noopener" data-type="URL" data-id="https://www.aliyundrive.com/s/JeDiTyWoHcV">https://www.aliyundrive.com/s/JeDiTyWoHcV</a></p>
+4 -3
View File
@@ -8,11 +8,12 @@ categories:
tags:
- "优化"
comments: true
webmention: true
---
<h2>前言</h2>
## 前言
大家好,我是路明。想必大家都用过Microsoft Edge吧,现在的Microsoft Edge的新标签页和侧边栏几乎处处都是广告。接下来小编教大家如何快速优化自己的Microsoft Edge。
<h2>优化</h2>
## 优化
先来看看优化前的Microsoft Edge。
<div class="wp-block-image">
<figure class="aligncenter size-large">
@@ -49,5 +50,5 @@ comments: true
<figure class="wp-block-image size-large">
<div class="fancybox-wrapper" data-fancybox="post-images"><img src="https://luming-website.chgskj.cn/luming-notes/2024/01/20240113084209312200.webp" /></div></figure>
今天的这个小技巧你学会了吗?
<h2>结束语</h2>
## 结束语
本期文章就到这里啦,我是路明,我们下期再见。
+6 -5
View File
@@ -7,11 +7,12 @@ categories:
- "生活"
tags: []
comments: true
webmention: true
---
<h2>前言</h2>
## 前言
大家好,我是路明。看到本文的标题,你可能会疑惑:Synaptics不是和笔记本电脑触摸板有关的吗?怎么变成蠕虫病毒了?接下来就由我来给大家科普下何为Synaptics蠕虫病毒以及如何正确预防。
<h2>简介</h2>
## 简介
Synaptics原为一种触控板驱动程序,但是也有一种与其同名的Synaptics,它是一种新型木马病毒,这种病毒具有很强的传播性,可以通过Excel宏来实现,也可以通过修改exe程序数据段来实现。
<img src="https://luming-website.chgskj.cn/luming-notes/2024/01/20240113085420532284.webp" />
@@ -19,7 +20,7 @@ Synaptics原为一种触控板驱动程序,但是也有一种与其同名的Sy
当用户的exe程序感染Synaptics后,其首先会将自身复制到程序所在目录中,再将原程序的内容复制到自身资源段内,再复制程序图标,当用户运行被感染的文件时,Synaptics会自动释放名为“._cache_Filename.exe”的可执行文件并运行,不会影响到原程序的功能,使得用户很难直接发现Synaptics的感染。感染Synaptics后,它会通过注册表写入开机启动项,并且在后台时时刻刻消耗你的CPU,监听用户的USB设备,当用户插入USB设备后,Synaptics会立刻感染USB设备内的*.exe和*.xlsx文件,并通过写入Autorun.inf的方法来实现当用户双击USB设备时自动运行。
当用户的xlsx表格感染Synaptics后,会读取并复制xlsx文件内容,接着会与病毒文件中的资源段.xlsm合并为新的*.xlsm文件,最后替换正常文件。xlsm资源会自动启用所有宏,当用户打开文档时,无需确认就会自动执行宏。
<h2 id="header-id-2" class="wp-block-heading">如何辨别</h2>
## 如何辨别
辨别Synaptics也是一件不算很难的事。大家只需进入操作系统中的“文件夹选项”,将“隐藏受保护的操作系统文件”取消选中,并将“显示隐藏的文件、文件夹和驱动器”选中,点击“确定”即可。
接下来,进入“桌面”、“我的文档”、“下载”这三个文件夹,在里面寻找一些被隐藏的开头前缀为“._cache_”的可执行文件以及表格文件,如果没有,就右键空白处→显示→超大图标,这时候,被感染的文件就很容易露出鸡脚了(喜)。
@@ -29,9 +30,9 @@ Synaptics原为一种触控板驱动程序,但是也有一种与其同名的Sy
如果有小伙伴要问了:我的“桌面”、“我的文档”、“下载”文件夹内并没有exe文件怎么办?
小编:……没事,你进入C:\ProgramData\Synaptics目录,看里面有没有Synaptics.exe,如果有的话就是了,没有的话就不是了。。
<h2>解毒</h2>
## 解毒
这里我来给大家分享一个由吾爱破解大佬开发的Synaptics文件恢复工具,可以进行全盘扫描并恢复。
下载链接:<a href="https://loverain.lanzoul.com/iFrtr12qamre" target="_blank" rel="noreferrer noopener">https://loverain.lanzoul.com/iFrtr12qamre</a>
<h2>结束语</h2>
## 结束语
本期文章就到这里啦,我是路明,我们下期再见!
+4 -3
View File
@@ -7,13 +7,14 @@ categories:
- "生活"
tags:
comments: true
webmention: true
---
<h2>前言</h2>
## 前言
大家好,我是路明。上周,我的U盘莫名出现了问题,原本的文件系统为exFAT,在Windows中突然变成了FAT32,并且名称变成了全无规律的乱码文本,打开后是一堆乱码的文件夹及文件,创建日期有的是1980年,有的是2089年,并且无法打开。
我尝试了许多数据恢复的方法(包括但不限于7-Data数据恢复、Windows自带扫描坏扇区等),均无作用,最后利用DiskGenius成功找回丢失分区并完美挽救文件,接下来就由我来教大家如何利用DiskGenius解决。
<h2>解决方法</h2>
## 解决方法
首先,需要准备好一个DiskGenius专业版(破解版可以使用专业版功能即可,无需购买),打开它。
<img src="https://luming-website.chgskj.cn/luming-notes/2024/01/20240113090852938747.webp" />
@@ -45,7 +46,7 @@ comments: true
恢复时间取决于文件体积,恢复完成后可将U盘格式化继续使用。
<img src="https://luming-website.chgskj.cn/luming-notes/2024/01/20240113091959003921.webp" />
<h2>结束语</h2>
## 结束语
本期文章就到这里啦,我是路明,我们下期再见!
&nbsp;
+6 -5
View File
@@ -7,21 +7,22 @@ categories:
- "科技"
tags:
comments: true
webmention: true
---
<h2>前言</h2>
## 前言
大家好,我是路明。本期文章由我来向大家介绍一下Notepad--这款软件。
<h2>何为Notepad++</h2>
## 何为Notepad++
Notepad++是一款比较流行的记事本工具,其具有轻量的特点,非常适合做轻量文本工作。
但是Notepad++的作者是一名不折不扣的台独分子,曾经多次在官网内发表涉政言论,并打算在未来的Notepad++版本中加入恶意代码。
<h2>何为Notepad--</h2>
## 何为Notepad--
它是一款由中国人使用C++编写的文本编辑器,可以兼容Windows/Linux/macOS全平台。其目标是替换掉Notepad++,注重于在国产操作系统&amp;macOS上发展。
对比Notepad++,Notepad--可以跨平台,这使得更多领域的用户能够享受到轻量级的文本编辑服务。
<img src="https://luming-website.chgskj.cn/luming-notes/2024/01/20240113093027830423.webp" />
<h2>下载地址</h2>
## 下载地址
[c-downbtn type="123" url="https://www.123pan.com/s/Y5Nvjv-NzH8d.html" pwd=""]123云盘下载[/c-downbtn]
<h2>结束语</h2>
## 结束语
本期文章就到这里啦,我是路明,我们下期再见!
+20 -19
View File
@@ -8,14 +8,15 @@ categories:
tags:
- "WordPress"
comments: true
webmention: true
---
<h2>前言</h2>
## 前言
大家好,我是路明。本期文章,我想和大家聊聊Puock主题的美化方法。
Puock主题是一款基于WordPress开发的高颜值的自适应主题,支持白天与黑夜模式、无刷新加载等功能。本文将尽可能详尽地对Puock主题美化步骤进行介绍。
本文涉及的一切操作均以<a href="https://loneliness.chgskj.cn/" target="_blank" rel="noopener">沙雕笔记</a>为演示,特此感谢网友沙雕搞电脑的贡献!(沙雕笔记,原名Loneliness博客,采用Puock主题,后续变更为了Argon主题。)
<h2>准备工作</h2>
## 准备工作
你<strong>需要准备</strong>的有:
<ul>
<li>一个安装了WordPress<strong>6.2.2</strong>及<strong>更新版本</strong>,且能够<strong>正常访问主页和后台</strong>的网站</li>
@@ -23,10 +24,10 @@ Puock主题是一款基于WordPress开发的高颜值的自适应主题,支持
<li>一台可以正常使用的<strong>Windows/Linux PC</strong>或<strong>Mac</strong>(<s>哪怕是<strong>树莓派</strong>都行</s>)</li>
<li>一颗热爱折腾的心</li>
</ul>
<h2>开始操作</h2>
<h3>登录到网站后台</h3>
## 开始操作
### 登录到网站后台
在浏览器地址框内输入<code>https://你的网站地址/wp-admin/</code> ,回车进入,输入您的管理员账号和密码,登录即可。
<h3>安装Puock主题包</h3>
### 安装Puock主题包
登录后台后,在左侧栏菜单中找到“外观”按钮,将鼠标停留在上方,点击悬浮菜单中的“主题”按钮(移动端只需点击外观→主题即可)。在主题页面中点击“安装主题”→“上传主题”,选择下载好的主题包文件,上传并安装即可。
<img src="https://luming-website.chgskj.cn/luming-notes/2024/01/20240113112820066696.webp" />
@@ -36,7 +37,7 @@ Puock主题是一款基于WordPress开发的高颜值的自适应主题,支持
安装可能会花费一些时间,耐心等待即可。直到提示安装完毕后,点击“立即启用”即可启用Puock主题。
启用Puock主题后,我们可以在网站后台左侧栏靠下部分找到“Puock主题配置”选项卡,这是<strong>Puock主题</strong>的控制面板,后续所用到的大多数功能会在此调试。
<h3 id="header-id-5" class="wp-block-heading">菜单栏标题美化</h3>
### 菜单栏标题美化
Puock主题内置了部分<a href="http://fontawesome.p2hp.com/faicons.html" target="_blank" rel="noreferrer noopener" data-type="URL" data-id="http://fontawesome.p2hp.com/faicons.html">Font Awesome</a>图标库,因此我们可以直接在菜单栏中调用该图标库进行美化(如下方代码)。
<pre class="corepress-code-pre"><code>&lt;i class="fa fa-home" aria-hidden="true"&gt;&lt;/i&gt; 首页</code></pre>
进入网站后台→“外观”选项卡→“菜单”选项卡,选择显示在导航栏的菜单(主要菜单),如该博主的博客所示,有许许多多菜单项(如图)
@@ -60,7 +61,7 @@ Puock主题内置了部分<a href="http://fontawesome.p2hp.com/faicons.html" tar
美化完成后,您的博客菜单应该就能实现以下效果(如图):
<img src="https://luming-website.chgskj.cn/luming-notes/2024/01/20240113113630282994.webp" />
<h3 id="header-id-6" class="wp-block-heading">自定义您的Cravatar头像</h3>
### 自定义您的Cravatar头像
WordPress通常会使用Gravatar中您邮箱账户的头像作为您的头像,但是在中国大陆地区无法访问Gravatar,因此国内志愿者制作了Gravatar的镜像网站——Cravatar,而您可以进入<a href="https://www.cravatar.cn/" target="_blank" rel="noreferrer noopener" data-type="URL" data-id="https://gravatar.cn/">Cravatar官网</a>来修改您的头像。
但是如何更改WordPress的默认头像地址为Cravatar呢?这时就需要一款插件来解决这个难题了——它就是<a href="https://www.lovestu.com/wpopt.html" target="_blank" rel="noopener">WPOPT</a>。
@@ -70,13 +71,13 @@ WordPress通常会使用Gravatar中您邮箱账户的头像作为您的头像,
<img src="https://luming-website.chgskj.cn/luming-notes/2024/01/20240113114101442552.webp" />
如图,在“优化加速”栏目中,点击“gravatar.cn”即可。(此处作者估计是标错了,这个选项实际是通往cravatar.cn的)。
<h3 id="header-id-7" class="wp-block-heading">侧边栏加入Puock自带小组件</h3>
### 侧边栏加入Puock自带小组件
Puock其实自带了一些小组件,如“作者信息”、“搜索框”、“一言一句话”、“热门文章”、“最新文章”、“读者墙”等。
进入网站后台→“外观”选项卡→“小工具”选项卡(如图)即可对不同位置的侧边栏小组件进行添加和管理。
<img src="https://luming-website.chgskj.cn/luming-notes/2024/01/20240113114223842623.webp" />
<h4 id="header-id-8" class="wp-block-heading">作者信息</h4>
#### 作者信息
在一个位置中(如“通用 - 侧边栏”)空白处点击加号,会弹出选择小组件的窗口。点击“浏览全部”按钮,下翻在“小工具”一栏中即可看到“Puock主题 关于博主”小组件,点击它,即可添加到该区域。
接下来可以对博主信息进行一些修改。(如图)
@@ -96,11 +97,11 @@ Puock其实自带了一些小组件,如“作者信息”、“搜索框”、
简单修改后效果如下
<img src="https://luming-website.chgskj.cn/luming-notes/2024/01/20240113114322767193.webp" />
<h4 id="header-id-9" class="wp-block-heading">其它小组件</h4>
#### 其它小组件
其它诸如“一言一句话”、“搜索框”、“热门文章”、“最新文章”等的小组件,只需要修改图标即可,其它可根据个人喜好进行修改。
<h3 id="header-id-10" class="wp-block-heading">侧边栏加入扩展小组件</h3>
### 侧边栏加入扩展小组件
[c-alert type="success"]本栏目部分内容摘录自https://www.zibll.com/forum-post/8927.html,,若侵犯了您的权益请联系博主进行删除![/c-alert]
<h4 id="header-id-11" class="wp-block-heading">简单的小模块</h4>
#### 简单的小模块
该方法可以实现一个简单的按钮跳转链接效果,如以下所示。
<img src="https://luming-website.chgskj.cn/luming-notes/2024/01/20240113114605756906.webp" />
@@ -114,7 +115,7 @@ Puock其实自带了一些小组件,如“作者信息”、“搜索框”、
.ads{display:block; padding:40px 15px; text-align:center; color:#fff!important; background:#ff5719; background-image:-webkit-linear-gradient(135deg,#bbafe7,#5368d9); background-image:linear-gradient(135deg,#bbafe7,#5368d9)}.ads h4{margin:0; font-size:22px; font-weight:bold}.ads h5{margin:10px 0 0; font-size:14px; font-weight:bold}.ads.ads-btn{margin-top:20px; font-weight:bold}.ads.ads-btn:hover{color:#ff5719}.ads-btn{display:inline-block; font-weight:normal; margin-top:10px; color:#666; text-align:center; vertical-align:top; user-select:none; border:none; padding:0 36px; line-height:38px; font-size:14px; border-radius:10px; outline:0; -webkit-transition:all 0.3s ease-in-out; -moz-transition:all 0.3s ease-in-out; transition:all 0.3s ease-in-out}.ads-btn:hover,.btn:focus,.btn.focus{outline:0; text-decoration:none}.ads-btn:active,.btn.active{outline:0; box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.ads-btn-outline{line-height:36px; color:#fff; background-color:transparent; border:1px solid#fff}.ads-btn-outline:hover,.btn-outline:focus,.btn-outline.focus{color:#343a3c; background-color:#fff}
&lt;/style&gt;</code></pre>
[c-alert type="warning"]内容仅供参考,具体组件标题和跳转到的地址可自行修改。[/c-alert]
<h4 id="header-id-14" class="wp-block-heading">跑马灯滚动公告栏</h4>
#### 跑马灯滚动公告栏
该方法可以实现一个彩色跑马灯滚动公告栏效果,如以下所示。
<img src="https://luming-website.chgskj.cn/luming-notes/2024/01/20240113114707332210.webp" />
@@ -129,9 +130,9 @@ Puock其实自带了一些小组件,如“作者信息”、“搜索框”、
&lt;b id="nr"&gt;欢迎来到XX博客&lt;/b&gt; &lt;/marquee&gt;
&lt;/div&gt;</code></pre>
[c-alert type="warning"]内容仅供参考,具体公告内容可自行修改。[/c-alert]
<h3 id="header-id-15" class="wp-block-heading">界面简单美化</h3>
### 界面简单美化
[c-alert type="success"]本栏目内容摘录自<a href="https://blognas.hwb0307.com/linux/docker/744" target="_blank" rel="noopener">Bensz</a>及<a href="https://www.zibll.com/forum-post/8927.html" target="_blank" rel="noopener">Zibll社区</a>,若侵犯了您的权益请联系博主进行删除![/c-alert]
<h4 id="header-id-16" class="wp-block-heading">鼠标移动特效-影相随</h4>
#### 鼠标移动特效-影相随
依次进入控制台→外观→主题文件编辑器,在右方文件列表中找到“主题页脚(footer.php)”,点击打开,在该文件内容的最后一个&lt;/body&gt;前插入以下代码即可。
<pre class="corepress-code-pre"><code>&lt;!--鼠标样式:两个同心圆,大圆追小圆--&gt;
&lt;style type="text/css"&gt;
@@ -144,7 +145,7 @@ Puock其实自带了一些小组件,如“作者信息”、“搜索框”、
&lt;script src="https://cdn.jsdelivr.net/gh/huangwb8/bloghelper@latest/js/cursor_01.js"&gt;&lt;/script&gt;
&lt;!--鼠标样式结束--&gt;</code></pre>
修改完毕后,保存主题配置文件即可。
<h4 id="header-id-17" class="wp-block-heading">界面圆角化</h4>
#### 界面圆角化
依次进入Puock主题配置→脚本及样式→头部自定义全局CSS样式,在框内输入以下代码
<pre class="corepress-code-pre"><code>.p-block,.widget,.input-group {border-radius: 20px;}
.widget-puock-author .header {
@@ -156,13 +157,13 @@ border-top-right-radius: 20px;
.wight{filter: blur(1px);
} </code></pre>
接着,保存配置文件,您的网站就由小圆角风格转变为大圆角风格了。
<h4 id="header-id-18" class="wp-block-heading">头像呼吸光环和鼠标悬停旋转放大</h4>
#### 头像呼吸光环和鼠标悬停旋转放大
依次进入Puock主题配置→脚本及样式→头部自定义全局CSS样式,在框内输入以下代码
<pre class="corepress-code-pre"><code>/*头像呼吸光环和鼠标悬停旋转放大开始*/
.avatar{border-radius: 50%; animation: light 4s ease-in-out infinite; transition: 0.5s;}.avatar:hover{transform: scale(1.15) rotate(720deg);}@keyframes light{0%{box-shadow: 0 0 4px #f00;} 25%{box-shadow: 0 0 16px #0f0;} 50%{box-shadow: 0 0 4px #00f;} 75%{box-shadow: 0 0 16px #0f0;} 100%{box-shadow: 0 0 4px #f00;}}
/*头像呼吸光环和鼠标悬停旋转放大结束*/</code></pre>
接着,保存配置文件,若您的侧边栏添加了“作者信息”模块,则您的头像会被添加呼吸光环效果,并且当鼠标悬停时,您的头像会旋转并放大;鼠标移走时,您的头像会反方向旋转并复原。
<h4 id="header-id-19" class="wp-block-heading">底部备案号等信息美化</h4>
#### 底部备案号等信息美化
依次进入Puock主题配置→脚本及样式→底部页脚信息,在框内输入以下代码
<pre class="corepress-code-pre"><code>&lt;style&gt;
/* 核心样式 */
@@ -256,5 +257,5 @@ background-color: #99a5cd !important;
&lt;/span&gt;
&lt;br&gt;</code></pre>
内容可根据自身情况进行修改。修改完毕后,保存配置文件即可。
<h2>结束语</h2>
## 结束语
本期文章就到这里啦,我是路明,我们下期再见!
+8 -7
View File
@@ -9,11 +9,12 @@ tags:
- "Windows"
- "优化"
comments: true
webmention: true
---
<h2>前言</h2>
## 前言
大家好,我是路明。这篇文章,我们来聊聊Windows电脑提升运行效率的方法。
<h2>情景引入</h2>
## 情景引入
小A是一名在校大学生,一日,他在实体店购买了一台4核心8线程、8GB内存的笔记本电脑。
他在实体店体验展示机的时候,发现展示机充分展示出了其卓越的性能,但是当他把实体机带回家后,发现卡得和老爷机一样,和自己在实体店体验过的机子完全不是一个样子。
@@ -21,7 +22,7 @@ comments: true
他开始在网上下载各种硬件配置检测工具,试图揭开这家“黑心商家”的虚伪面具,但奇怪的是,经过小A的苦苦检测,依然没有发现任何只因脚,这台电脑的配置和售出时标出的配置一模一样,丝毫没有作假的痕迹。
小A很苦恼,认为自己真是个foolish
<h2>计算机为什么会在使用过程中逐渐卡顿?</h2>
## 计算机为什么会在使用过程中逐渐卡顿?
计算机在使用过程中会逐渐变卡顿,这属于正常现象。常见的造成此结果的原因有以下几个:
<ul>
<li>长期未清理系统缓存</li>
@@ -35,8 +36,8 @@ comments: true
<li>机器操作系统未进行正确的设置</li>
</ul>
接下来,小编将针对这些问题给出一系列对应解决方案。
<h2>解决方案</h2>
<h3>改变对CPU核心数的设定</h3>
## 解决方案
### 改变对CPU核心数的设定
首先,在电脑正常运行时,同时按下Windows徽标键(简称为“Win键”)+字母R键(简称为“R键”),调出运行窗口
<img class="alignnone" src="https://luming-website.chgskj.cn/luming-notes/2023/12/20231231080850537488.webp" width="349" height="204" />
@@ -48,7 +49,7 @@ comments: true
在此处,可以看到处理器个数及最大内存被限制了,我们只需将两选项都更改为最大值即可。
但是,上述这种情况出现的概率微乎其微,可能不会帮到大家太多,所以我们看下一种方法。
<h3>开启卓越性能模式</h3>
### 开启卓越性能模式
懂计算机的小伙伴应该都知道,在电脑的控制面板→电源选项内,有着不同种类的电源选项。有平衡、省电、高性能模式。但是,对于追求性能的小伙伴,这些模式肯定是不能满足自己的。其实,在Windows中还有一种“卓越性能”模式,可以最大化发挥电脑的硬件性能。接下来我们就来打开它。
首先,以管理员身份运行命令提示符(“cmd.exe”)
@@ -66,5 +67,5 @@ comments: true
直接点击启用它,就可以享受电脑的卓越性能了。
<img src="https://luming-website.chgskj.cn/luming-notes/2023/12/20231231082138541843.webp" />
<h2>小结</h2>
## 小结
本期文章主要介绍了优化电脑运行性能的各种方法。这期文章就到这里了,我是路明,我们下期再见。
+1
View File
@@ -7,6 +7,7 @@ categories:
- "生活"
tags:
comments: true
webmention: true
---
大家好,我是路明。
+1
View File
@@ -11,6 +11,7 @@ tags:
- "电子课程表"
- "软件"
comments: true
webmention: true
---
2023 年 12 月 24 日,“峄校智表” 项目进行了 KB1024 的更新进程。
+8 -7
View File
@@ -7,11 +7,12 @@ categories:
- "科技"
tags:
comments: true
webmention: true
---
<h2>前言</h2>
## 前言
大家好,我是路明。这期文章我想和大家浅谈一下 在Windows下,批处理文件中%0|%0命令的意义。
<h2>%0|%0运行的效果</h2>
## %0|%0运行的效果
提起%0|%0运行后的效果,相比懂点电脑的小伙伴都会或多或少地在网络上发现过诸如“只有5个字符就能卡爆你的电脑!快拿来整蛊你的朋友!”之类的文章,那么它的效果可想而知了:
[zd-plane title="虚拟场景"]你双击点开了内容为%0|%0的批处理文件
@@ -35,7 +36,7 @@ comments: true
2.趁着电脑还没有卡死,注销电脑[/zd-plane]
如果上述方法都没有解决的话,那就只能关机喽§(* ̄▽ ̄*)§
<h2>原理</h2>
## 原理
好了,不小心扯了那么多,接下来和大家分享一下这个批处理文件的原理。
首先,%0   在批处理文件中代表<span style="color: #ff0000;"><strong>批处理文件本身</strong></span>,即如果运行%0,命令行会再次运行这个批处理文件。
@@ -47,9 +48,9 @@ comments: true
<strong>执行这个批处理文件本身,如果执行失败,那么依然执行这个批处理文件本身。</strong>
可以把整个过程理解为图形化编程中的<span style="color: #ff0000;"><strong>永远循环</strong></span>,即永远执行这个批处理文件本身,永不停止。
<h2>同理程序分享</h2>
## 同理程序分享
在Windows命令行(cmd)中,有一些代码可以同样实现类似于%0|%0的效果。
<h3>程序1</h3>
### 程序1
<pre class="corepress-code-pre"><code>start cmd
%0</code></pre>
分析:根据代码可直观地看到,第一行代码中“start”是“启动”的意思,“cmd”即Windows中的命令行主程序(cmd.exe)。“%0”则为前文中提到的,重复再执行一遍该批处理文件。
@@ -57,7 +58,7 @@ comments: true
当批处理文件再次执行自身的时候,依然会再次运行自身,达成无限循环的效果。
不过,该方法的效果直观可见,运行后,屏幕上会<strong><span style="color: #ff0000;">快速出现一堆命令行窗口</span></strong>,同样会造成卡慢,死机的效果,当然也是可以通过前文提到的解决方法来解决的。
<h3>程序2</h3>
### 程序2
<pre class="corepress-code-pre"><code>:start
start cmd
goto start</code></pre>
@@ -69,5 +70,5 @@ goto start</code></pre>
<li><code>start cmd</code> - 这行命令尝试启动一个新的命令提示符窗口。但是,实际上这里有一个小错误。<code>start</code>是一个命令,后面应该直接跟参数(这里是<code>cmd</code>),而不是应该有空格。正确的写法应该是<code>start cmd</code>。</li>
<li><code>goto start</code> - 这是一个跳转命令。它会将脚本的控制权跳转到名为“start”的标签处,从而形成一个无限循环。这意味着一旦脚本开始执行,它会不断地启动新的命令提示符窗口,直到用户手动停止脚本的执行。<code></code></li>
</ol>
<h2>结束语</h2>
## 结束语
本期文章的分享就到这里了,我是路明,我们下期文章再见!
+5 -4
View File
@@ -8,11 +8,12 @@ categories:
tags:
- "WordPress"
comments: true
webmention: true
---
<h2>前言</h2>
## 前言
大家好,我是路明。这篇文章,我们来聊聊如何给自己的博客引用FontAwesome图标库。
<h2>用途</h2>
## 用途
图标库是用来装饰博客元素的一种渠道,而FontAwesome图标库则是一款比较成熟的图标库,拥有的图标数量很多,能够满足绝大部分用户的需求。
要在WordPress博客中引用FontAwesome图标库,前提条件是您的WordPress主题内置了图标库,否则引用图标库是无效的。常见的具有FontAwesome图表库的主题有:Argon、CorePress(标准版)、Puock等。
@@ -26,7 +27,7 @@ comments: true
<img src="https://luming-website.chgskj.cn/luming-notes/2024/01/20240114001246210644.webp" />
可以非常直观地发现,加入图标后的菜单项显得更加灵动且自然,使访客可以更直观地理解菜单项的内容。那么如何引用图标库呢?
<h2>引用</h2>
## 引用
使用<code>&lt;i class="fa fa-图标名称" aria-hidden="true"&gt;&lt;/i&gt;</code> 即可引用。例如我要引用<img src="https://luming-website.chgskj.cn/luming-notes/2024/01/20240114001857355129.webp" />这个图标,则需要输入<code>&lt;i class="fa fa-home" aria-hidden="true"&gt;&lt;/i&gt;</code> 这段代码。
<img src="https://luming-website.chgskj.cn/luming-notes/2024/01/20240114001951163460.webp" />
@@ -34,5 +35,5 @@ comments: true
若要在博客的菜单项内引用图标库,只需要在项目标题前加入对应的图标代码即可。
要快速地查阅FontAwesome图标内容,可前往<a href="https://fontawesome.p2hp.com/" target="_blank" rel="noopener">FontAwesome中文网</a>查询并自行添加。
<h2>结束语</h2>
## 结束语
本期文章就到这里啦,我是路明,我们下期再见!
+4 -3
View File
@@ -9,11 +9,12 @@ tags:
- "Windows"
- "优化"
comments: true
webmention: true
---
<h3>前言</h3>
### 前言
众所不周知,蓝屏工作室在2022年11月开发出了蓝屏工具箱的第一个版本。其中很多功能都是在凑数,但是里面有个“清理系统缓存”脚本是工作室成员共同研发出来的,并且效果十分优秀。今天在翻文件的时候无意间发现了,就拿出来给大家分享一下。
<h3>代码</h3>
### 代码
<pre class="corepress-code-pre"><code>@echo off
echo ■■■■■■■创峄信息科技■■■■■■■
echo ■■本脚本由创峄信息科技提供技术支持■■
@@ -75,5 +76,5 @@ echo ■■■您可以继续翻看清理记录,或退出■■
echo ■■■■■■■创峄信息科技■■■■■■■
pause
exit</code></pre>
<h3> 食用方法</h3>
### 食用方法
将以上代码复制,并在Windows系统下新建一个文本文档,打开后将代码粘贴进去,再将该文本文档的后缀名更改为.bat,最后右键以管理员身份运行即可。
+7 -6
View File
@@ -7,15 +7,16 @@ categories:
- "生活"
tags:
comments: true
webmention: true
---
<h3>前言</h3>
### 前言
大家好,我是路明。今天,我们一起来用C++来解决一个数学问题。
<h3>问题</h3>
### 问题
问题如下:
<img class="aligncenter" src="https://luming-website.chgskj.cn/luming-notes/2024/01/20240130082746169560.webp" />
<h3>初步解决</h3>
### 初步解决
由题可知,题目要求用户输入圆的半径至程序,接下来在程序内部进行运算,最后输出圆的直径、周长和面积。
根据圆的计算公式,可知:
@@ -25,7 +26,7 @@ s=πr²d</code></pre>
有了这些公式,解决这个问题也就易如反掌了。
&nbsp;
<h3>代码编写</h3>
### 代码编写
在本程序中,需要用到C++中<code>iostream</code> 、<code>iomanip</code> 、<code>cstdio</code> 等头文件,因此我们在程序头部输入以下代码:
<pre class="corepress-code-pre"><code>#include&lt;iostream&gt;
#include&lt;iomanip&gt;
@@ -67,9 +68,9 @@ printf()命令的参数是用“,”分隔开的。其中第一个参数代表
%0.4f的意思是保留四位小数后输出。
在程序的末尾,请一定不要忘记编写<code>return 0;</code> !
<h3>调试运行程序</h3>
### 调试运行程序
[video width="1366" height="768" webm="http://virelyx.com/wp-content/uploads/2024/01/20240130092216116744.webm"][/video]
<h3>源代码</h3>
### 源代码
<pre class="corepress-code-pre"><code>#include &lt;iostream&gt;
#include&lt;iomanip&gt;
#include&lt;cstdio&gt;
+5 -4
View File
@@ -10,19 +10,20 @@ tags:
- "蓝屏"
- "软件"
comments: true
webmention: true
---
就在刚刚,2024年的大年初一,我们蓝屏工具箱开发团队正式且自豪地向大家宣布:蓝屏工具箱4.0的正式版本,今天,发布了!今天,请允许我以蓝屏工具箱开发团队的身份来向大家介绍蓝屏工具箱这款软件。
<h3>蓝屏工具箱是什么?</h3>
### 蓝屏工具箱是什么?
<section>蓝屏工具箱是蓝屏科技在2022年11月立项的一款系统工具箱软件,在2022年12月开始开发并推出第一个正式版本。在蓝屏工具箱的一开始,我们并没有做什么创新方面的元素,软件UI非常复古原始,并且没有绚丽多彩的图标。或许唯一能够引人注目一点的就是它那尚未完善的账号系统了。</section><section><img class="aligncenter" src="https://image.luming.cool/i/2026/05/10/69fff0888db49.webp" />从2023年4月开始,我们开始从0开始打磨蓝屏工具箱4.0的每一处功能。从实时响应的账户系统,到实时更新的公告系统。由于给我们的开发时间不多,因此我们只能延长开发周期。</section><section>在开发蓝屏工具箱4.0的时候看见友商一个接一个发布新版本的时候,虽然内心有着些许的浮躁,但是发现友商产品越来越大的体积,功能越来越臃肿后,我们决定做点什么...</section><section>2023年12月,蓝屏工具箱4.0的账户、头像、图片公告等功能均已完善。</section><section>2024年2月,我们奋起直追,完成了蓝屏工具箱4.0的核心功能——“插件应用市场”。顾名思义,这是一个人人平等的应用社区。在这里,用户可以申请成为开发者,申请成功后可通过应用上传页上传自己制作的插件,或者也可以上传别人开发的一些小应用。上传的应用需要运维人员的审核,审核通过后就会出现在应用列表中,供其他用户下载使用。</section><section>在“插件应用市场”的加持下,蓝屏工具箱的功能得到了史无前例的强大,这也使蓝屏工具箱4.0的体积占用也得到了缩减,从先前3.0版本的90MB,到如今4.0版本的5MB,我们也花了十足的功夫为它“瘦身”。</section>
<h3>蓝屏工具箱的主要功能</h3>
### 蓝屏工具箱的主要功能
<section>首先,双击打开蓝屏工具箱主程序,会弹出登录窗口。输入您的账号及密码后点击“快速登录”即可登入蓝屏工具箱。如果您未接入互联网,您也可以点击登录按钮旁边的“离线模式”进入离线模式。</section><section>登录后,会加在主界面。由于x86程序的内存读写特性,这个过程通常需要5秒钟左右。</section><section>程序在刚刚安装完时,您的插件库内是没有内置任何插件的,您可以从插件应用市场来下载充实您的插件库。当然,当您未接入互联网,亦或是您希望体验一些未上传到应用商店的非官方插件,您也可以使用插件库中的“导入插件”来充盈您的插件库。</section><section>在聊天室界面,您可以与其他和您一样使用蓝屏工具箱4.0的用户一起畅谈人生。当文字已不能表达您的丰富情感时,您也可以选择使用聊天室的“发送图片”功能。当您因不可抗力因素错过某些消息时,也无需慌张。您可以使用“查看聊天记录”功能,从服务器获取最新的聊天记录文件并解析。</section><section>聊天室禁止发送不良信息,我们的后台运维人员有权且有能力通过消息直接封禁违规者的账号。</section><section>在设置界面,您可以修改自己账号的昵称、账号、密码、头像等,同时也可以记下自己的ID,以便预防自己忘记密码。同时,您可以修改窗口的样式:方角、圆角,任您灵活切换。</section><section>最后,蓝屏工具箱内置了更新系统,您可以在设置→关于界面→检查更新 来检查更新并全自动安装更新。</section>
<h3>展望蓝屏工具箱的未来</h3>
### 展望蓝屏工具箱的未来
<section>在未来,我们还有许多Flags,比如:</section>
<ul class="list-paddingleft-1">
<li>做出开发者激励计划</li>
<li>做出一些蓝屏币兑换奖品的功能,让蓝屏币发挥作用。</li>
</ul>
<section>总而言之,蓝屏工具箱的路道阻且长,我们将会沉下心来,以工匠精神打造更加优质的产品。</section><section>蓝屏工具箱是一款完全基于易语言编写的软件,我们希望通过自己的微薄之力让中文编程发挥一些光和热。</section>
<h3>获取蓝屏工具箱</h3>
### 获取蓝屏工具箱
<section>蓝屏工具箱官网:<a href="https://tools.chgskj.cn" target="_blank" rel="noopener">https://tools.chgskj.cn</a></section><section>大家可以扫描下方的二维码加入蓝屏工具箱用户群,体验全新的蓝屏工具箱4.0</section><section><img class="aligncenter" src="https://image.luming.cool/i/2026/05/10/69fff08a6e1be.webp" /></section>
+11 -10
View File
@@ -8,15 +8,16 @@ categories:
tags:
- "安卓"
comments: true
webmention: true
---
<h2>前言</h2>
## 前言
大家好,万年不更的冤种路明又和大家见面了。
本期文章我们来说说如何用一支词典笔来丰富自己的校园生活(<del>顺利进厂</del>)(bushi)
[c-alert type="warning"]本文中所出现的所有图片均为路明亲手绘制,仅供参考![/c-alert]
<h2>准备工作</h2>
## 准备工作
<blockquote>要实现本文所提及的一切内容,你需要准备以下材料
To implement everything mentioned in this article, you need to prepare the following materials.</blockquote>
@@ -25,7 +26,7 @@ To implement everything mentioned in this article, you need to prepare the follo
<li>一根USB<span style="color: #ff0000;">*数据线</span></li>
<li>一台运行<span style="color: #ff0000;">*Windows操作系统</span>的台式机/笔记本电脑/Mac</li>
</ul>
<h3>FAQ</h3>
### FAQ
<span style="color: #ff0000;">*安卓系统</span>:词典笔(点读笔)务必搭载Android®操作系统,否则无法实现本文中的任何效果。可在购买时咨询客服。
<span style="color: #ff0000;">*非品牌类</span>:词典笔(点读笔)在选购时请您刻意避开品牌点读笔,因为品牌点读笔对防破解方面做的非常成熟,不利于破解操作。一般杂牌词典笔价格在50~150元人民币之间。
@@ -33,9 +34,9 @@ To implement everything mentioned in this article, you need to prepare the follo
<span style="color: #ff0000;">*数据线</span>:一根可以连接词典笔(点读笔)和电脑并进行数据传输的USB线。
<span style="color: #ff0000;">*Windows操作系统</span>:若您拥有丰富的ADB经验,则您也可以选用Linux&amp;macOS。
<h2>核心破解</h2>
## 核心破解
<blockquote>由于不同点读笔有不同的破解分支,所以路明在这里给大家提供两种思路供大家参考。</blockquote>
<h3>JXW思路</h3>
### JXW思路
<blockquote>有些点读笔(词典笔)使用的是JXW服务内核,因此直接可以利用JXW服务进行破解。</blockquote>
首先进入点读笔(词典笔)的<code>“关于本机”</code> 页面(下图仅供参考)
@@ -44,7 +45,7 @@ To implement everything mentioned in this article, you need to prepare the follo
连续点击三下<code>“SN号”</code> ,再点击一下<code>“软件版本”</code>  ,此时会弹出窗口提示输入密码,在窗口中设法输入<code>“jxwkj888”</code> 并确认,即可进入系统原生设置。
进入系统原生设置后,即可通过开发者选项打开<code>USB调试</code> 功能,连接电脑进行愉快地玩机吧!
<h3>通用思路</h3>
### 通用思路
由于绝大多数点读笔(词典笔)使用的都是联发科(MediaTek)处理器,因此我们可以利用系统工厂测试中的MTK Logger运行Shell脚本来进入系统原生设置。
第一步仍和JXW思路相同,先进入点读笔(词典笔)的“关于本机”界面(下图仅供参考)
@@ -74,9 +75,9 @@ To implement everything mentioned in this article, you need to prepare the follo
点击确定,即可进入安卓原生设置。
同JXW思路一样,在安卓原生设置中您可以开启<code>USB调试</code> 选项来尽情玩机了。
<h2>玩机软件</h2>
## 玩机软件
<blockquote>在进行核心破解之后,我们就可以在点读笔(词典笔)上自由地安装软件了。接下来路明会分情况来和大家分享一些点读笔应用。</blockquote>
<h3>适用于32位处理器</h3>
### 适用于32位处理器
<blockquote>对于32位处理器的点读笔(词典笔),我们可以用来玩玩一些小游戏以及装一些别的软件。
*注意:32位软件在64位点读笔(词典笔)上也可以正常使用。</blockquote>
@@ -92,12 +93,12 @@ To implement everything mentioned in this article, you need to prepare the follo
<span style="color: #ff0000;">*酷狗概念版</span>:新版本酷狗概念版安装至点读笔(词典笔)上后可能会出现播放页载入时闪退的问题。
<span style="color: #ff0000;">*豌豆荚</span>:豌豆荚在部分小屏点读笔的使用过程中可能会出现应用界面无法正常操作的问题。
<h3>适用于64位处理器</h3>
### 适用于64位处理器
<blockquote>对于64位处理器的点读笔(词典笔)支持的功能就更多了,你可以在你的点读笔(词典笔)上面安装近乎市面上所有的软件。</blockquote>
Wear应用库:<a href="https://vincent8623.lanzouw.com/b00zti91i" target="_blank" rel="noopener">点我进入</a>
进入后可以下载里面的任意安装包,下载完成后直接安装即可。
<h2>结束语</h2>
## 结束语
本期文章到这里就结束了,再提一嘴:路明不建议在正常学习中把玩破解后的词典笔(点读笔),毕竟这类产品生来就是辅助学习使用的,不要因为它耽误自己的学业噢~
祝大家学业有成~
+1
View File
@@ -12,6 +12,7 @@ tags:
- "蓝屏"
- "课表"
comments: true
webmention: true
---
经考虑,我们决定停运峄校智表软件。
+15 -14
View File
@@ -10,11 +10,12 @@ tags:
- "易语言"
- "软件"
comments: true
webmention: true
---
<h2>前言</h2>
## 前言
大家好,我是路明。本期文章我要向大家推荐一款功能强大且实用的系统工具箱——蓝屏工具箱。
<h2>软件简介</h2>
## 软件简介
蓝屏工具箱是由创峄信息科技基于开发的一款适用于Windows的工具箱软件,官网<a href="https://tools.chgskj.cn" target="_blank" rel="noopener">tools.chgskj.cn</a>
您可以在此处高速下载蓝屏工具箱:<a href="https://www.123pan.com/s/v1krVv-9Te03.html" target="_blank" rel="noopener">https://www.123pan.com/s/v1krVv-9Te03.html</a>
@@ -22,9 +23,9 @@ comments: true
<img class="aligncenter" src="https://image.luming.cool/i/2026/05/10/69fff20a78ba8.png" />
通过官网,我们可以看到这款软件处处透出了年轻活力的气息。点击“最新版下载”按钮,即可下载蓝屏工具箱的最新版本安装包。
<h2>界面一览&amp;功能介绍</h2>
## 界面一览&功能介绍
蓝屏工具箱的最新版本号是4.5.4 KB0512,相比较于官网给出的参考图,最新版本对界面做出了很多改动。
<h3>登录注册界面</h3>
### 登录注册界面
首次启动软件,会进入登录注册界面。
<img class="aligncenter" src="https://image.luming.cool/i/2026/05/10/69fff20b24d6a.png" />
@@ -32,19 +33,19 @@ comments: true
<img src="https://image.luming.cool/i/2026/05/10/69fff20c6ecc8.png" />
新用户初次使用蓝屏工具箱需要手动注册一个新账号,注册完之后即可使用账号密码登录工具箱。
<h3>主界面</h3>
### 主界面
进入主界面,可以看到时钟、天气、签到、公告、资讯、随机应用模块按部就班地在窗口内整齐排列,如下图。
<img class="aligncenter" src="https://image.luming.cool/i/2026/05/10/69fff20dbaaaf.png" />
点击签到,我们会发现蓝屏币新增了2个。蓝屏币是蓝屏工具箱的内部“货币”,目前的用途是高速下载插件。
<h3>全屏时钟</h3>
### 全屏时钟
在主界面时钟的右下角有一个“全屏”图标按钮,点击它即可进入一个纯黑背景的时钟,如下图。
<img class="aligncenter" src="https://image.luming.cool/i/2026/05/10/69fff20e5bc44.png" />
路明觉得这个时钟非常适合学校考试时进行使用,相比那些广告繁多的时钟显示网站,蓝屏工具箱中的无广告时钟真的是一个不错的选择。
<h3>资讯界面</h3>
### 资讯界面
“资讯”功能是蓝屏工具箱推出的更加系统化的公告方案。当蓝屏工具箱及创峄信息科技有新的动态消息时,会第一时间将消息以文章的方式推送至工具箱内。
在首页会默认推送最新的两篇资讯,若要查看完整资讯,则需手动点击左侧栏的“资讯”按钮(如下图)。
@@ -54,7 +55,7 @@ comments: true
点击文章右侧的“查看文章”按钮即可查看文章内容(如下图)。
<img class="aligncenter" src="https://image.luming.cool/i/2026/05/10/69fff21162e0c.png" />
<h3>聊天室功能</h3>
### 聊天室功能
蓝屏工具箱为了方便用户与开发者之间的直接交流,所以在软件内提供了聊天室功能(如图)。
<img class="aligncenter" src="https://image.luming.cool/i/2026/05/10/69fff21211e57.png" />
@@ -62,7 +63,7 @@ comments: true
在聊天室内可以发送文字、图片消息。同时,点击“查看聊天记录”按钮,即可查看聊天室中的全部聊天记录。
[c-alert type="warning"]若聊天记录数量过多,可能会导致工具箱运行缓慢或内存溢出闪退,这属于正常现象,重启工具箱即可。[/c-alert]
<h3>应用市场</h3>
### 应用市场
要说到蓝屏工具箱的核心重磅功能,那就当属应用市场了。蓝屏工具箱打破了本地集成插件的常规思路,采用了云端存储的应用仓库,由用户自行选配下载,把蓝屏工具箱打造成属于自己的瑞士军刀。
点击左侧栏的“商店”按钮,即可进入应用商店主界面(如图)。
@@ -94,7 +95,7 @@ comments: true
<img class="aligncenter" src="https://image.luming.cool/i/2026/05/10/69fff21531fc8.png" />
上传了应用之后,运维人员会对上传的插件进行审核。审核通过后,开发者的应用就会出现在应用商店内。若审核不通过,系统会向您发送邮件。通常应用审核工作会在上传后3个工作日内结束,若长期未响应,您可以联系admin@chgskj.cn进行解决。
<h3>功能列表</h3>
### 功能列表
在用户下载了应用之后,在哪里查看已下载的应用呢?
答案当然是功能列表啦!
@@ -102,7 +103,7 @@ comments: true
蓝屏工具箱为用户准备了功能强大的本地应用管理器。在这个列表内,您可以启动已下载的应用、将应用快捷方式添加到桌面、卸载应用以及打开应用目录。
<img class="aligncenter" src="https://image.luming.cool/i/2026/05/10/69fff215dbc48.png" />
<h3>设置</h3>
### 设置
若要对软件功能及账号信息进行编辑,您可以前往蓝屏工具箱的设置模块。
点击左侧栏的“设置”按钮,即可进入设置(如图)。
@@ -122,7 +123,7 @@ comments: true
『捐助我们』:蓝屏工具箱是免费软件,依靠捐助的资金来进行运维。不捐助不影响您使用本软件的全部功能,捐助是为了我们更好地为您提供服务。
『关于软件』:在此界面可以查看蓝屏工具箱的版本号信息和更新日志,并且可以快速地检查更新。
<h2>系统兼容性</h2>
## 系统兼容性
功能介绍就暂时告一段落了。接下来小编和大家一起来看看蓝屏工具箱对操作系统的兼容性。
蓝屏工具箱理论上支持Windows7 7600及以上的全部Windows版本。但是由于Windows8系列对于MDI客户窗口的不兼容性,所以蓝屏工具箱4.5.4 KB0512及以前的版本都不支持Windows8系列操作系统,如果强制使用会导致软件停止运行。
@@ -130,13 +131,13 @@ comments: true
但是值得一提的是蓝屏工具箱开发团队已经掌握了兼容Windows8系列的方案,并且预估会在未来不久发布全新的版本,该版本将支持Windows8系列。
由于蓝屏工具箱客户端内部使用Excel作为数据库读写载体,调用了libxl.dll,然而该dll文件不支持在XP系统下运行,所以很遗憾,蓝屏工具箱不支持且不会支持WindowsXP系列操作系统。对于使用XP系统的蓝屏工具箱用户,我们建议您升级到Windows7再使用蓝屏工具箱。
<h2>软件生态</h2>
## 软件生态
蓝屏工具箱拥有丰富的软件生态。虽然它是Windows系统工具箱,但开发团队正在努力基于Wine制作蓝屏工具箱的Linux版本。若您对蓝屏工具箱感兴趣,您可以加入蓝屏工具箱客户群。
<img class="aligncenter" src="https://image.luming.cool/i/2026/05/10/69fff08a6e1be.webp" />
同时,蓝屏工具箱在<a href="https://blog.chgskj.cn/" target="_blank" rel="noopener">夏雨社区</a>也有专属的圈子,<a href="https://blog.chgskj.cn/forum/354.html" target="_blank" rel="noopener">点我即可进入圈子讨论</a>。
<h2>总结</h2>
## 总结
总的来说,蓝屏工具箱由年轻人开发,积极维护,界面精美,功能强大,值得大家下载使用。
今天的分享就到这里啦,我是路明,我们下期再见。
@@ -8,6 +8,7 @@ categories:
tags:
- "易语言"
comments: true
webmention: true
---
## 前言
+1
View File
@@ -7,6 +7,7 @@ categories:
tags:
- "校园"
comments: true
webmention: true
---
## 前言
+1
View File
@@ -7,6 +7,7 @@ categories:
tags:
- "校园"
comments: true
webmention: true
---
## 总述
@@ -8,6 +8,7 @@ categories:
tags:
- "问卷"
comments: true
webmention: true
---
## 前言
+1
View File
@@ -8,6 +8,7 @@ categories:
tags:
- "校园"
comments: true
webmention: true
---
本周四晚活动课,我像往常一样打着乒乓球。在接近尾声时,一群小学生吃完饭,排着整齐的队列回班。这时,他们班的班主任老师跑了过来,说了声:”让我试试呗”。
+1
View File
@@ -8,6 +8,7 @@ categories:
tags:
- "校园"
comments: true
webmention: true
---
## 前言
+1
View File
@@ -8,6 +8,7 @@ categories:
tags:
- "考试"
comments: true
webmention: true
---
## 前言
+1
View File
@@ -8,6 +8,7 @@ categories:
tags:
- "研学"
comments: true
webmention: true
---
## 前言
+1
View File
@@ -9,6 +9,7 @@ tags:
- "游戏"
- "睡眠"
comments: true
webmention: true
---
## 前言
+1
View File
@@ -8,6 +8,7 @@ categories:
tags:
- "校园"
comments: true
webmention: true
---
## 前言
+1
View File
@@ -9,6 +9,7 @@ tags:
- "校园"
- "考试"
comments: true
webmention: true
---
## 前言
+1
View File
@@ -9,6 +9,7 @@ tags:
- "校园"
- "考试"
comments: true
webmention: true
---
## 前言
@@ -7,6 +7,7 @@ categories:
- "公告"
tags:
comments: true
webmention: true
---
真快,仿佛上一秒还在写2024年元旦文章,现在都已经开始写2025的了。
-129
View File
@@ -1,129 +0,0 @@
---
cover: "https://image.luming.cool/i/2026/07/26/6a662e5c66130.webp"
title: "友人"
pubDate: "2025-01-24T01:26:00.000Z"
updatedDate: "2026-07-28T04:03:48.000Z"
categories:
tags:
comments: true
---
## 提交友链
目前仅接受邮箱申请。请先在贵站添加本站友链,随后将贵站信息按以下格式发送到
hi [at] riseforever.cn
```json
[博客名称](博客网址)+(博客Logo)
```
[collapse title="我站信息"]
```plaintext
站点名称:路明笔记
站长昵称:Riseforever 或 路明
站点链接:https://luming.cool
站点简介:不慌张,不绝望,不狂妄,不投降。
站点头像:https://cn.cravatar.com/avatar/302380667bdaf4e1390800e62494d4af?s=500&r=X
或 站点Logo:https://image.luming.cool/i/2026/05/10/6a001b4129893.png
(可根据自身情况选用Logo或头像)
站长邮箱:hi[at]riseforever.cn(请手动将`[at]`替换为`@`)
```
[/collapse]
友链按照互动频率排序。
---
## 单向链接
[白熊阿丸的小屋](https://blog.bxaw.name)+(https://image.luming.cool/i/2026/07/23/6a619a9ad3e61.webp)
[Vei Blog](https://blog.veitzn.top/)+(https://image.luming.cool/i/2026/06/22/6a3956faa910d.webp)
[莫比乌斯](https://mobius.blog/)+(https://image.luming.cool/i/2026/07/25/6a648121695fc.webp)
## 生活类博主
[悦绮录](https://i.duckxu.com/)+(https://image.luming.cool/i/2026/06/22/6a39572c9ef57.webp)
[小改学习志](https://www.haoyu233.com/)+(https://weavatar.com/avatar/14e584196d31262ea144ab4d75d4c083?s=200)
[老陈爱刷机](https://blog.chenyuxia.com/)+(https://image.luming.cool/i/2026/06/21/6a37fdaf9c4c7.webp)
[往日信笺](https://www.xingmail.cn/)+(https://image.luming.cool/i/2026/06/22/6a39570f5a1b6.webp)
[Horean&#39;s Blog](https://blog.hxrch.top)+(https://image.luming.cool/i/2026/06/21/6a37f998e92c8.webp)
[小岚的杂物间](https://www.guirlan.de/)+(https://weavatar.com/avatar/172530293dcfb25d871a72ccb39b21c2?s=200)
[阿锋的小宇宙](https://blog.feng.pub/)+(https://blog.feng.pub/static/logo/avatar.jpg)
[希记](https://note.moxiify.cn/)+(https://q1.qlogo.cn/g?b=qq&nk=3188468169&s=640)
[Fmkli](https://lli.moe)+(https://image.luming.cool/i/2026/06/21/6a37f9efaef09.webp)
[伏枥之间](https://www.leehenry.top)+(https://image.luming.cool/i/2026/06/22/6a39577800675.webp)
[合荒小站](https://hehuang.site)+(https://image.luming.cool/i/2026/07/18/6a5b17d83080c.webp)
[Pinpe 的云端](https://pinpe.top/)+(https://image.luming.cool/i/2026/06/22/6a39568f421dd.webp)
[蒋音象](https://jiangyx.org/)+(https://image.luming.cool/i/2026/07/11/6a51235da5835.webp)
[摸鱼小窝](https://blog.aistu.cn)+(https://blog.aistu.cn/logo.webp)
[云晓晨](https://blog.kaiqi.wang)+(https://www.kaiqi.wang/favicon.ico)
[柳橙睿](https://www.liuchengrui.cn/)+(https://image.luming.cool/i/2026/06/22/6a395765069a2.webp)
[CC米饭的小世界](https://world.ccrice.com/)+(https://weavatar.com/avatar/39bab898a41e6fa8d7357abd9c283bb7?s=200)
[makotowu](https://makotowu.cnstlapy.cn/)+(https://image.luming.cool/i/2026/06/22/6a3956cf92ebd.webp)
[蘇 SU](https://suus.me)+(https://weavatar.com/avatar/5b986063afb0ee2d78abd40defe3aec607d812b372093008646e137f61023869?sha256=1&d=mp&s=500)
[松種小窝](https://pineseed.cn/)+(https://image.luming.cool/i/2026/06/21/6a37fa0dc1945.webp)
## 技术类博主
[新锐博客](https://blog.xrbk.cn/)+(https://blog.xrbk.cn/favicon.png)
[米雅乐](https://www.miyale.cc/)+(https://image.luming.cool/i/2026/07/23/6a619b7273d45.webp)
[LR.C](https://bbslrc.vxni.ink/)+(https://image.luming.cool/i/2026/06/21/6a37ede8eaad4.webp)
[小景](https://jingyuan-zheng.github.io/zh/)+(https://image.luming.cool/i/2026/07/23/6a62284fa496c.webp)
[XXY の博客](https://blog.xuxiny.top)+(https://q1.qlogo.cn/headimg_dl?dst_uin=3429924750&spec=5)
[圆周率](https://www.yuanzj.top)+(https://image.luming.cool/i/2026/06/21/6a37fa3752ea4.webp)
[MC_Kero blog](https://blog.mckero.com/)+(https://img.cdn1.vip/i/68f3418995084_1760772489.png)
[Levi](https://leviqin.top/)+(https://image.luming.cool/i/2026/06/22/6a3957bedea05.webp)
[KFACBT](https://blog.gytxtx.top/)+(https://image.luming.cool/i/2026/06/22/6a3957de12346.webp)
[重生云](https://xiaochopin.github.io/)+(https://weavatar.com/avatar/a10109bb266cc4eebc8d7992a4977a0c?s=200)
[Echo](https://www.liveout.cn/)+(https://image.luming.cool/i/2026/07/23/6a619b08ec4ad.webp)
[Bensz](https://blognas.hwb0307.com/)+(https://blognas.hwb0307.com/logo.jpg)
## 失联
以下为单删友链 / 网站无法正常访问的博主。
[collapse title="已失联的博主"]
[Limitz_](https://limitz.top)+(https://q1.qlogo.cn/g?b=qq&nk=66870019&s=100)
[/collapse]
## 88x31
欢迎与我交换 88x31 按钮。第一个是本站按钮。若要交换,请先在贵站放置本站按钮,然后电邮联系我进行交换。
<div style="display: inline-block; width: 88px;"><a href="https://www.luming.cool"><img src="https://image.luming.cool/i/2026/07/21/6a5f455105140.gif" alt="路明笔记" style="width: 100%; height: auto; display: block;"></a></div>
<div style="display: inline-block; width: 88px;"><a href="https://blog.bxaw.name/" target="_blank"><img src="https://img.bxaw.name/hotlink-ok/logo/bxaw-88x31.gif" alt="白熊阿丸" style="width: 100%; height: auto; display: block;"></a></div>
<div style="display: inline-block; width: 88px;"><a href="https://blog.verdant.ee/" target="_blank"><img src="https://www.glowisle.me/88x31.gif" alt="映屿" style="width: 100%; height: auto; display: block;"></a></div>
+1
View File
@@ -7,6 +7,7 @@ categories:
- "生活"
tags:
comments: true
webmention: true
---
很抱歉我拖更了这么久,最近发生的事情很多很多。
@@ -8,6 +8,7 @@ categories:
tags:
- "WordPress"
comments: true
webmention: true
---
> 人非圣贤,孰能无过。我也是一名学习人,难免会犯错误。如果本文有任何不恰当的地方/您有更优的方法,请您在本篇文章的评论区留言,我将第一时间采纳。谢谢您!
@@ -9,6 +9,7 @@ tags:
- "Python"
- "易语言"
comments: true
webmention: true
---
## 前言
@@ -8,6 +8,7 @@ categories:
tags:
- "WordPress"
comments: true
webmention: true
---
5日下午,我在使用Follow给我自己的网站认证。但就在验证这一关里,它频频报错:
@@ -9,6 +9,7 @@ tags:
- "Python"
- "易语言"
comments: true
webmention: true
---
如你所见,RStatus视奸系统现已在Github平台开源,基于Apache 2.0协议。
@@ -8,6 +8,7 @@ categories:
tags:
- "WordPress"
comments: true
webmention: true
---
## 事发
+1
View File
@@ -8,6 +8,7 @@ categories:
tags:
- "网站"
comments: true
webmention: true
---
## 前言
+1
View File
@@ -10,6 +10,7 @@ tags:
- "手表"
- "校园"
comments: true
webmention: true
---
## 前言
@@ -10,6 +10,7 @@ tags:
- "生活"
- "读书"
comments: true
webmention: true
---
## 前言
@@ -7,6 +7,7 @@ categories:
tags:
- "校园"
comments: true
webmention: true
---
## 前言
@@ -8,6 +8,7 @@ categories:
tags:
- "手表"
comments: true
webmention: true
---
## 前言
+1
View File
@@ -7,6 +7,7 @@ categories:
- "生活"
tags:
comments: true
webmention: true
---
What can i say ?
+1
View File
@@ -8,6 +8,7 @@ categories:
tags:
- "校园"
comments: true
webmention: true
---
## 前言
+1
View File
@@ -9,6 +9,7 @@ tags:
- "校园"
- "考试"
comments: true
webmention: true
---
## 前言
+1
View File
@@ -8,6 +8,7 @@ categories:
tags:
- "考试"
comments: true
webmention: true
---
本篇周记日期范围:04/20-4/30(两周一起写)。
+1
View File
@@ -10,6 +10,7 @@ tags:
- "校园"
- "考试"
comments: true
webmention: true
---
这篇文章写于2025年5月23日,距离河南省中招考试还有29天。
+1
View File
@@ -9,6 +9,7 @@ tags:
- "易语言"
- "校园"
comments: true
webmention: true
---
今天是 2025 年 5 月 31 日,端午节。朋友们,你们吃粽子了吗?
@@ -7,6 +7,7 @@ categories:
- "公告"
tags:
comments: true
webmention: true
---
今日中考。祝愿所有的考生都能考上自己的第一志愿,金榜题名!
+4 -1
View File
@@ -8,6 +8,7 @@ categories:
tags:
- "校园"
comments: true
webmention: true
---
各位朋友,晚上好。欢迎收看Riseforever在25年6月的第一篇周记。
@@ -82,7 +83,9 @@ comments: true
## 毕业前的留念
沾同学的福,我借到了一台华强北手表,可以拍照的那种。在这周内,我留下了若干张照片。时间真快,转眼间距离中考只剩15天,真正的在校时间也只剩下10天。我在学校拍了一些照片,分享出来和大家一起纪念我的初中。
沾同学的福,~~我借到了一台华强北手表,可以拍照的那种。~~在这周内,我留下了若干张照片。时间真快,转眼间距离中考只剩15天,真正的在校时间也只剩下10天。我在学校拍了一些照片,分享出来和大家一起纪念我的初中。
(2026 年 8 月补档:骗你的,下面的图片都是我用自己带的手机拍的,说成华强北手表只是怕被同学看到举报🤣)
拍照技术有点菜,勿喷。
@@ -9,6 +9,7 @@ tags:
- "开发"
- "易语言"
comments: true
webmention: true
---
## 前言
@@ -10,6 +10,7 @@ tags:
- "生活"
- "软件"
comments: true
webmention: true
---
## 前言
@@ -8,6 +8,7 @@ categories:
tags:
- "人生大事"
comments: true
webmention: true
---
朋友们,好久不见。转眼间,洛阳市中考已经结束了,我已经是一名准高中生了。中考结束,怅然若失,让我把最近的经历讲给你听。
@@ -8,6 +8,7 @@ categories:
tags:
- "人生大事"
comments: true
webmention: true
---
## 前言(摘要)
@@ -8,6 +8,7 @@ categories:
tags:
- "问卷"
comments: true
webmention: true
---
朋友们,上午好。
@@ -9,6 +9,7 @@ tags:
- "Vela"
- "开发"
comments: true
webmention: true
---
## 前言
@@ -3,6 +3,7 @@ cover: "https://image.luming.cool/i/2026/05/10/69fff3ce09f1d.webp"
title: "暑期 · 军训总结"
pubDate: "2025-08-27T13:53:00.000Z"
updatedDate: "2026-07-24T02:51:20.000Z"
toc: true
categories:
- "生活"
tags:
@@ -10,6 +11,7 @@ tags:
- "生活"
- "软件"
comments: true
webmention: true
---
<!-- wp:audio {"id":1153} -->
@@ -32,9 +34,7 @@ comments: true
<p>关键词:<code>Vela开发初体验</code>、<code>军训七天</code>、<code>和平精英</code>、<code>新鼠标</code>、<code>暑期总结</code>。</p>
<!-- /wp:paragraph -->
<!-- wp:heading -->
<h2 class="wp-block-heading">Vela开发初体验</h2>
<!-- /wp:heading -->
## Vela开发初体验
<!-- wp:paragraph -->
<p>不知道Vela是什么的同学请先<a href="https://iot.mi.com/vela/quickapp/zh/guide/" data-type="link" data-id="https://iot.mi.com/vela/quickapp/zh/guide/" target="_blank" rel="noreferrer noopener">移步这里</a></p>
@@ -78,17 +78,13 @@ comments: true
<!-- /wp:paragraph --></blockquote>
<!-- /wp:quote -->
<!-- wp:heading -->
<h2 class="wp-block-heading">军训七天</h2>
<!-- /wp:heading -->
## 军训七天
<!-- wp:paragraph -->
<p>8月19日 ~ 8月26日,我们前往学校报了到,并进行了为期七天的军训。这七天把我压抑得,我快要爆发了。</p>
<!-- /wp:paragraph -->
<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">新环境</h3>
<!-- /wp:heading -->
### 新环境
<!-- wp:paragraph -->
<p>8月19日上午,我在父母陪同下前往学校进行军训报到。进入新宿舍,一种熟悉又陌生的气息扑面而来:熟悉是因为它具备着与我初中宿舍相同的设施:柜子、水龙头和浴室;陌生,则是因为宿舍里有着五张陌生的面孔。</p>
@@ -106,9 +102,7 @@ comments: true
<p>剩余的几天,我在宿舍生活得还不错,每晚都能准时睡着,睡眠时间也保持在8小时左右。空调制冷效果一天比一天好,内机设定温度由一开始的16℃逐渐变为了20℃、22℃、26℃……我仍记得,倒数第二天晚上,空调开26℃,冻得我即使用被子捂住全身也仍能感受到寒意。当然,可能也有天气的原因——我们从第三天军训开始下大雨,后续几天保持阴天。</p>
<!-- /wp:paragraph -->
<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">军训服</h3>
<!-- /wp:heading -->
### 军训服
<!-- wp:paragraph -->
<p>学校军训,使用的服装是学校组织统一购买的的军训服,五十块钱。讲真,衣服穿上身的那一刻,我觉得这辈子买过最亏的物品就是军训服——上半身就是劣质化纤,下半身的布料甚至会刺激我的腿。</p>
@@ -132,9 +126,7 @@ comments: true
<p>这身衣服在功能上不透气、不舒适,在外观上也不符合军队标准,完全可以说是一笔智商税了。</p>
<!-- /wp:paragraph -->
<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">宿舍</h3>
<!-- /wp:heading -->
### 宿舍
<!-- wp:paragraph -->
<p>这算是我对这所学校唯二极度不满的地方。首先,以军训期间的作息规定为例:每天晚上 21:40 必须躺在床上,不能坐或站。每天宿管会逮出来一些 21:40 以后还未躺在床上的人。</p>
@@ -162,9 +154,7 @@ comments: true
<p>说人话,就是“无论如何我都要给你挑出点毛病来”。鸡蛋里挑骨头,为了打压学生而打压学生,真做作!</p>
<!-- /wp:paragraph -->
<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">课外书</h3>
<!-- /wp:heading -->
### 课外书
<!-- wp:paragraph -->
<p>军训倒数第二天的下午,班里自习课上。</p>
@@ -196,9 +186,7 @@ comments: true
<p>我他妈才高一,不是高三高考生!为了升学率去限制学生阅读课外读物,妄图通过这种方法来让学生花更多时间投入学习,真是可笑。现在我终于理解了这学校之前为什么那么多跳的了。</p>
<!-- /wp:paragraph -->
<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">感触</h3>
<!-- /wp:heading -->
### 感触
<!-- wp:paragraph -->
<p>军训期间,我确确实实提前预习了一部分课本,因为实在是太无聊了。读到语文课本时,我感到了一种莫名的似曾相识。里面的大多数课文都是我在小学或初中遇到过的,有种见到阔别已久的老朋友的熟悉,但是一想到它是我高中三年要作为正式课程学习的内容,又有一种莫名的失落和恐惧。</p>
@@ -260,9 +248,7 @@ comments: true
<p>这差不多也是一次蜕变,我感受到了父母以前对我的溺爱</p>
<!-- /wp:paragraph -->
<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">内卷</h3>
<!-- /wp:heading -->
### 内卷
<!-- wp:paragraph -->
<p>没想到,这所学校的同学们比我想象中的要“卷”得多。</p>
@@ -288,9 +274,7 @@ comments: true
<p>其余时间,比如早上七点整,同学们用完早餐,纷纷走向操场,等待教官要求集合。这段时间里,班主任要求我们必须“带上语文诗词小页子背诵”。每天晚自习要“抽查背诵”,如果抽查不合格,就到教室后面一直站着,直到会背为止。</p>
<!-- /wp:paragraph -->
<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">军训结束前的心情</h3>
<!-- /wp:heading -->
### 军训结束前的心情
<!-- wp:paragraph -->
<p>之所以单独划分一个板块来写,是因为这种心情太深刻了。</p>
@@ -312,9 +296,7 @@ comments: true
<p>看到这里,你可能会问我为什么会对“暴虐”自己七天的教官有如此正面的评价。我想说,相比于其他班的教官,他爱吹牛b,幽默风趣,总是能逗我们笑;他不吝啬以身试法买饮料奖励我们,并说“哪怕掏空我的钱包”;他总把我们班拉出去与别的班“比赛”,扬言“一定要把‘七班最强’这个名声打好”。</p>
<!-- /wp:paragraph -->
<!-- wp:heading -->
<h2 class="wp-block-heading">和平精英</h2>
<!-- /wp:heading -->
## 和平精英
<!-- wp:paragraph -->
<p>这估计是每逢假期不得不提的一个话题。废话不多说,上时间统计。</p>
@@ -332,9 +314,7 @@ comments: true
<p>期间有几天,我那在上班的堂姐主动找我玩和平,我便陪着她一块玩,那几天的我,很快乐。</p>
<!-- /wp:paragraph -->
<!-- wp:heading -->
<h2 class="wp-block-heading">新鼠标</h2>
<!-- /wp:heading -->
## 新鼠标
<!-- wp:paragraph -->
<p>军训七天回家之后,发现自己服役了一年多的杂牌鼠标滚轮暴毙了。才放了七天,滚轮就出现了上下滑动乱跳的情况。</p>
@@ -364,9 +344,7 @@ comments: true
<p>鼠标个头挺大,握起来有点质感。惊喜的是它在这个价位居然给了肩键。当然,可能是我没用过带肩键的鼠标,不知道价格情况。(笑)</p>
<!-- /wp:paragraph -->
<!-- wp:heading -->
<h2 class="wp-block-heading">总结</h2>
<!-- /wp:heading -->
## 总结
<!-- wp:paragraph -->
<p>这个暑假,我做了比较多的事情:</p>
@@ -10,6 +10,7 @@ tags:
- "系统"
- "软件"
comments: true
webmention: true
---
晚上好,朋友们。今天下午三点半,我准时蹲守,观看了小米澎湃OS3的发布会。看完之后,我心血来潮,因为我突然感到了小米做系统的认真和负责。所以,我撰写了本篇文章,希望能帮助大家理解,小米澎湃OS 3,究竟更新了什么。
+1
View File
@@ -8,6 +8,7 @@ categories:
tags:
- "校园"
comments: true
webmention: true
---
## 前言
+1
View File
@@ -8,6 +8,7 @@ categories:
tags:
- "校园"
comments: true
webmention: true
---
## 前言
+1
View File
@@ -8,6 +8,7 @@ tags:
- "校园"
comments: true
math: true
webmention: true
---
本周关键词:`驳校报强制投稿`、`驳离谱校规`、`《731》`、`想象中的小米手环10Pro+`、`好题分享`、`一体机声卡炸了`、`博客更新`。
@@ -7,6 +7,7 @@ categories:
tags:
- "公告"
comments: true
webmention: true
---
## 更换说明
@@ -8,6 +8,7 @@ tags:
- "生活"
- "考试"
comments: true
webmention: true
---
真快,心还停留在得知中考成绩时的失落,现实中我已在高中经历了两次月考。第二次月考成绩出来之后,我想抱抱以前的自己。
@@ -8,6 +8,7 @@ tags:
- "学校"
- "议论"
comments: true
webmention: true
---
> 鸡蛋碰不过石头,本文事例非本人经历,没有针对任何学校,若对号入座,那你就是对的。
@@ -7,6 +7,7 @@ categories:
tags:
- "生活"
comments: true
webmention: true
---
## 标签
+1
View File
@@ -9,6 +9,7 @@ tags:
- "校园"
- "疾病"
comments: true
webmention: true
---
忽然发现“周记”栏目好久没有更新了,那我就来写一篇水一下。
@@ -9,6 +9,7 @@ tags:
- "小米"
- "手表"
comments: true
webmention: true
---
上周日返校途中,我在 AstroBox 上面刷着软件库,恰巧刷到了一位大佬编写的 Vela 第三方网易云音乐客户端。这是 Vela 圈出现的第三个自制客户端了。我使用的上一款客户端 [OMusic](https://www.bandbbs.cn/resources/4324/updates) 十分完美,但用久了之后,想尝试一些新的界面和功能。所以我便抱着试一试的态度下载了这个软件。
@@ -8,6 +8,7 @@ tags:
- "建站"
- "问卷"
comments: true
webmention: true
---
今天逛各大博客收录平台的时候,无意看到一位博友回答了一份问卷——《[独立博客自省问卷 15 题](https://yayu.net/4626.html)》。点进问卷链接,读了一遍问卷内容,发现这些问题都直戳内心,部分问题让我汗颜无地。
@@ -7,6 +7,7 @@ categories:
tags:
- "开发"
comments: true
webmention: true
---
## 前言
@@ -7,6 +7,7 @@ categories:
tags:
- "公告"
comments: true
webmention: true
---
最近天气越来越冷了,我看着蓝色的头像和博客配色,总觉得不应季了。
@@ -9,6 +9,7 @@ tags:
- "开源"
- "软件"
comments: true
webmention: true
---
## 前言
@@ -8,6 +8,7 @@ tags:
- "TicWatch"
- "手表"
comments: true
webmention: true
---
上周,我在闲鱼上斥巨资 ¥190 淘到了一台 TicWatch Pro3,因为我需要一块能够满足我在校通讯需求的手表。
@@ -7,6 +7,7 @@ categories:
tags:
- "年度总结"
comments: true
webmention: true
---
写完之后回来看看,忽然发现这篇文章没什么意义,只是把 2025 年发过的文章理了一遍。
@@ -8,6 +8,7 @@ tags:
- "一体机"
- "重装系统"
comments: true
webmention: true
---
上周,我给我班一体机重装了 Windows11 企业版 LTSC,原想着会像我给初中时的一体机重装一样简单,但我还是防不胜防——踩雷了。
@@ -8,6 +8,7 @@ tags:
- "REDMI Watch 5"
- "手表"
comments: true
webmention: true
---
## 写在前面
@@ -8,6 +8,7 @@ tags:
- "网页"
- "设计"
comments: true
webmention: true
---
我们班有一个传统——每周班会课上,老师会允许量化积分排名前五的同学随机抽取一项奖励。

Some files were not shown because too many files have changed in this diff Show More