<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>陽升之谷</title><description>Kai&apos;s Blog</description><link>https://kyki.moe/</link><language>zh_CN</language><item><title>在fnOS上通过Docker代理系统自带qBittorrent的WebUI（c3556e4）</title><link>https://kyki.moe/posts/docker-install-for-fnos-qbit-proxy/</link><guid isPermaLink="true">https://kyki.moe/posts/docker-install-for-fnos-qbit-proxy/</guid><pubDate>Mon, 26 Jan 2026 01:49:53 GMT</pubDate><content:encoded>&lt;p&gt;&lt;strong&gt;开年第一篇文章，新年快乐～&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;前言&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://docs.pbh-btn.com&quot;&gt;PeerBanHelper&lt;/a&gt;，通过WebUI与qBittorrent通讯。通过系统自带的资源监控不难注意到，飞牛OS系统自带的下载器后后端由qBittorrent和Aria2支撑，进程名称为&lt;code&gt;trim-qbittorrent&lt;/code&gt;和&lt;code&gt;trim-aria2c&lt;/code&gt;。但是飞牛OS没有提供系统自带qBittorrent的原生WebUI接口，&lt;a href=&quot;https://github.com/xxxuuu/fnos-qb-proxy&quot;&gt;xxxuuu/fnos-qb-proxy&lt;/a&gt;提供了一个Go语言代理WebUI的客户端，但是没有Docker部署。&lt;/p&gt;
&lt;p&gt;让我这个Docker小白来试试。&lt;/p&gt;
&lt;p&gt;&lt;em&gt;本文其实就是&lt;a href=&quot;https://github.com/Kainichy/fnos-qb-proxy/blob/main/Docker-Install.md&quot;&gt;Kainichy/fnos-qb-proxy/Docker-Install.md&lt;/a&gt;加几句话哈，水一篇文章美滋滋。已经PR给&lt;a href=&quot;https://github.com/xxxuuu/fnos-qb-proxy&quot;&gt;xxxuuu/fnos-qb-proxy&lt;/a&gt;了，应该不久就能在那里看见。&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;获取所需文件&lt;/h2&gt;
&lt;p&gt;到&lt;a href=&quot;https://github.com/xxxuuu/fnos-qb-proxy/releases&quot;&gt;xxxuuu/fnos-qb-proxy: Releases&lt;/a&gt;获取&lt;code&gt;fnos-qb-proxy_linux-amd64&lt;/code&gt;，到&lt;a href=&quot;https://github.com/Kainichy/fnos-qb-proxy&quot;&gt;Kainichy/fnos-qb-proxy&lt;/a&gt;获取相应的&lt;code&gt;Dockerfile&lt;/code&gt;和&lt;code&gt;docker-compose.yml&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;然后进行一些配置，如下。配置过程中将多次用到查找与替换的功能，建议使用支持相应功能的编辑器而非手动替换，以免出错。此外，除非您清楚地知道您在做什么，否则不建议修改其他位置的内容。&lt;/p&gt;
&lt;h2&gt;修改Dockerfile&lt;/h2&gt;
&lt;p&gt;请将如下字段中的&lt;code&gt;fnos-qb-proxy_linux-amd64&lt;/code&gt;改为您下载的可执行文件的文件名：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;COPY fnos-qb-proxy_linux-amd64 /usr/local/bin/fnos-qb-proxy
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;修改docker-compose.yml&lt;/h2&gt;
&lt;p&gt;如果您需要自定义代理容器在宿主机上暴露的端口号（效果相当于上文中通过&lt;code&gt;--port&lt;/code&gt;参数传入的端口号），请修改如下字段中引号左边的&lt;code&gt;7777&lt;/code&gt;为您所需要的端口号：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    ports:
      - &quot;7777:8086&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果您需要自定义qBittorrent WebUI的访问密码（效果相当于上文中通过&lt;code&gt;-p&lt;/code&gt;或&lt;code&gt;--password&lt;/code&gt;参数传入的密码），请修改如下字段中的&lt;code&gt;fnosnb&lt;/code&gt;为您所需要的密码，注意，此处请勿将密码修改为非ASCII字符，否则qBittorrent的WebUI将错误转译密码导致登录失败：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    environment:
      - PASSWORD=fnosnb
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;⚠️ 只要您的用户名不是&lt;code&gt;Kainichy&lt;/code&gt;，您必须将以下内容中的&lt;code&gt;Kainichy&lt;/code&gt;替换为您的用户名：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    volumes:
      - /home/Kainichy/qbt.sock:/home/Kainichy/qbt.sock
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后开始构建并启动，如下。&lt;/p&gt;
&lt;h2&gt;构建镜像，启动容器&lt;/h2&gt;
&lt;p&gt;有两种方法完成这件事。&lt;/p&gt;
&lt;h3&gt;SSH&lt;/h3&gt;
&lt;p&gt;SSH访问您的主机，然后在含有&lt;code&gt;Dockerfile&lt;/code&gt;、&lt;code&gt;docker-compose.yml&lt;/code&gt;以及可执行文件的目录下执行&lt;code&gt;docker compose up -d&lt;/code&gt;。&lt;/p&gt;
&lt;h3&gt;fnOS WebUI / 飞牛OS网页版&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;创建一个目录，并将&lt;code&gt;Dockerfile&lt;/code&gt;以及可执行文件通过您喜爱的方式上传到您的飞牛，注意此时不要上传&lt;code&gt;docker-compose.yml&lt;/code&gt;，否则可能会出现错误。并且请注意，目录需要上传到一个您接下来操作的账户能够访问的目录下。&lt;/li&gt;
&lt;li&gt;登录您的飞牛OS网页版，进入Docker应用，在边栏中选择Compose，选择&lt;code&gt;新建项目&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;填写&lt;code&gt;项目名称&lt;/code&gt;，选择第一步中上传的文件夹，此时在对话框中上传&lt;code&gt;docker-compose.yml&lt;/code&gt;，或者复制并粘贴&lt;code&gt;docker-compose.yml&lt;/code&gt;的全部内容，注意不要打乱格式。&lt;/li&gt;
&lt;li&gt;选择&lt;code&gt;确定&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;此时您的容器应该正常运行，并且您将会在&lt;code&gt;7777&lt;/code&gt;或您指定的端口号上访问飞牛自带的&lt;code&gt;trim-qbittorrent&lt;/code&gt;的WebUI。&lt;/p&gt;
&lt;h2&gt;确保下载中心服务在Docker服务之前启动&lt;/h2&gt;
&lt;p&gt;我们注意到在fnOS中，Docker服务可能在下载中心启动之前完成启动，导致&lt;code&gt;~/qbt.sock&lt;/code&gt;被Docker意外占用，进而导致下载中心携带的的qBittorrent进程无法正常启动。因此，我们需要确保下载中心服务在Docker服务之前启动，具体方法为如下。&lt;/p&gt;
&lt;p&gt;在终端/SSH中运行&lt;code&gt;sudo systemctl edit docker.service&lt;/code&gt;，默认情况下，这将打开一个由Nano编辑器承载的&lt;code&gt;/etc/systemd/system/docker.service.d/override.conf&lt;/code&gt;编辑窗口，此时在&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;### Anything between here and the comment below will become the new contents of the file
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;（从1开始数，通常位于第2行）&lt;/p&gt;
&lt;p&gt;以及&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;### Lines below this comment will be discarded
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;（通常位于第6行）&lt;/p&gt;
&lt;p&gt;这两行注释（通常显示为蓝色）之间添加如下内容：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[Unit]
After=dlcenter.service
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;确保前几行看起来像是：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;### Editing /etc/systemd/system/docker.service.d/override.conf
### Anything between here and the comment below will become the new contents of the file

[Unit]
After=dlcenter.service

### Lines below this comment will be discarded

### /etc/systemd/system/docker.service
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这将使&lt;code&gt;dlcenter.service&lt;/code&gt;（fnOS的下载中心服务，亦负责启动自带的qBittorrent）在&lt;code&gt;docker.service&lt;/code&gt;之前运行。&lt;/p&gt;
&lt;p&gt;最后，运行&lt;code&gt;sudo systemctl daemon-reload&lt;/code&gt;来使得这些修改生效。&lt;/p&gt;
&lt;p&gt;撒花🎉。如果是像我一样要通过Docker运行并接入&lt;a href=&quot;https://docs.pbh-btn.com&quot;&gt;PeerBanHelper&lt;/a&gt;，还可以通过&lt;code&gt;docker inspect {Container}&lt;/code&gt;来获取Docker提供的容器DNS名称，解决容器间访问时的IP变换问题。&lt;/p&gt;
&lt;p&gt;更好的BitTorrent网络环境，这何尝不是一种TECH OTAKUS SAVE THE WORLD呢。&lt;/p&gt;
</content:encoded></item><item><title>电子邮件的退信 / Apple Support，很棒——如果你只问电池健康</title><link>https://kyki.moe/posts/email-bouncing-and-dear-apple-support/</link><guid isPermaLink="true">https://kyki.moe/posts/email-bouncing-and-dear-apple-support/</guid><pubDate>Wed, 27 Aug 2025 22:41:00 GMT</pubDate><content:encoded>&lt;p&gt;叠个薄薄的甲。熟悉我的读者（虽然可能不多）应该都知道，我是老「果吹」了。我不是想抱怨，只是想说说这次和Apple的对话。&lt;/p&gt;
&lt;p&gt;让我们从这个折磨我的问题开始。&lt;/p&gt;
&lt;h2&gt;“退回给发件人的未送达邮件”&lt;/h2&gt;
&lt;p&gt;要讲清楚这个问题，我们就从电子邮件的传递开始吧。&lt;/p&gt;
&lt;h3&gt;电子邮件的「发」与「收」&lt;/h3&gt;
&lt;p&gt;一封电子邮件从发件人按下「发送」，到出现在收件人的收件箱中，从不只是「发送」和「接收」那么简单。但，让我们把这个并不简单地流程，简单地讲一讲。&lt;/p&gt;
&lt;p&gt;发件人在发件客户端按下「发送」时，信件先被交给了发信服务器。对于使用不同邮件服务的用户，他们的发信服务器也会不一样。
接着，这封信按照约定的协议，投递进收件人的收信服务器。
最后，收件人打开自己的邮箱客户端时，客户端从服务器取出信件，把它呈现给用户。&lt;/p&gt;
&lt;p&gt;这一来一往，或许只花了几秒钟。可这封信背后，其实经过了两个客户端、两个服务器的接力合作。&lt;/p&gt;
&lt;p&gt;比如说，我在Mac上用Mail.app通过iCloud Mail，给一位使用Outlook邮件服务和客户端的Android用户发邮件。邮件会先从我的Mac送到iCloud的发信服务器，再投递到Outlook的收信服务器，最后被对方的Outlook客户端拉取下来。就这样，一封邮件完成了它的旅程。&lt;/p&gt;
&lt;h3&gt;电子邮件的「退回」&lt;/h3&gt;
&lt;p&gt;就像现实中的信件有时会被退回，电子邮件同样有各种各样的退信情形。我们也可以简单地分为「发件服务器退信」和「收件服务器退信」，并简要地举几个例子。&lt;/p&gt;
&lt;p&gt;发件服务器退信：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;发件频率过高&lt;/li&gt;
&lt;li&gt;邮件体积过大&lt;/li&gt;
&lt;li&gt;邮件被识别为垃圾邮件&lt;/li&gt;
&lt;li&gt;发件人标识配置错误或鉴权不通过&lt;/li&gt;
&lt;li&gt;收件服务器不存在或不可及：例如，向&lt;code&gt;@blackhole.kyki.moe&lt;/code&gt;发送邮件&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;收件服务器退信：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;收件人邮箱已满&lt;/li&gt;
&lt;li&gt;发信服务器身份验证失败&lt;/li&gt;
&lt;li&gt;邮件被拦截列表或安全策略拒收&lt;/li&gt;
&lt;li&gt;查无此人：例如向&lt;code&gt;alice@kyki.moe&lt;/code&gt;发送邮件&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;两个属于AS714 APPLE-ENGINEERING的、遭拒的IP地址&lt;/h3&gt;
&lt;p&gt;如果去查询一下&lt;code&gt;57.103.66.120&lt;/code&gt;和&lt;code&gt;57.103.64.119&lt;/code&gt;这两个IP地址，很容易就能得知，它们目前的归属都是&lt;a href=&quot;https://radar.cloudflare.com/as714&quot;&gt;AS714 APPLE-ENGINEERING&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;你可能已经猜到了，这两个IP地址肯定跟iCloud Mail有关。是的，它们是iCloud的众多发信服务器IP之二。但单独拿出来讲，它们有什么特别的呢？
&lt;strong&gt;这两个IP在向Microsoft的收信服务器传输信件时，会遭到拒绝。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;于是发件人会在几秒到几分钟后，在自己的收件箱里看到一封名为「Undelivered Mail Returned to Sender」的退信报告，说&lt;code&gt;hotmail-com.olc.protection.outlook.com&lt;/code&gt;回复了错误代码&lt;a href=&quot;https://learn.microsoft.com/en-us/troubleshoot/exchange/email-delivery/ndr/fix-error-code-550-5-7-1-in-exchange-online&quot;&gt;550 5.7.1&lt;/a&gt;，并且反馈发件服务器在相应的拦截列表（S3150）上。&lt;/p&gt;
&lt;p&gt;如果这时负责发送我邮件的发信服务器是我自建的，例如我在云服务厂商处租赁了一台（虚拟）服务器，并在该服务器上运行着我的发信服务，那我便可以轻松地找到云服务厂商，要求更换一个新的IP地址，或者要求云服务厂商联系Microsoft协商将该IP地址从拦截名单上移除，但……我的发信服务器是iCloud Mail的啊，所以……&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;好戏开始，我算是踢到钢板啦！&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;解决问题的尝试，以及本文的正题——与Apple支持的沟通尝试&lt;/h2&gt;
&lt;h3&gt;“如果你仍需要协助”&lt;/h3&gt;
&lt;p&gt;在&lt;a href=&quot;https://support.apple.com/zh-cn/102322&quot;&gt;与 iCloud 邮件有关的邮件管理员信息 - 官方 Apple 支持 (中国)&lt;/a&gt;这篇Apple支持主题中，“如果你仍需要协助”章节，我们会看到这样一段描述：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;如果你已遵循我们的最佳做法，并已查阅邮件日志来了解更多信息，但仍无法诊断和解决传送问题，那么你可以发送电子邮件到 &lt;a href=&quot;mailto:icloudadmin@apple.com&quot;&gt;icloudadmin@apple.com&lt;/a&gt; 并提供以下所有信息，以便联系我们的邮件管理员团队&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;这个地址并不是为iCloud Mail的用户准备的，而是为那些试图向iCloud Mail用户发送邮件但遇到障碍的邮件管理员准备的，但按常理来讲，既然声明的抬头是「我们的邮件管理员团队」，那就……应该不会只管收信，不管发信吧？所以我还是向&lt;a href=&quot;mailto:icloudadmin@apple.com&quot;&gt;icloudadmin@apple.com&lt;/a&gt;发了一封邮件，反馈部分发信服务器IP被Outlook收信服务器拦截的问题，结果……石沉大海。&lt;/p&gt;
&lt;p&gt;数日后，我又看到同一章节的末尾还有一句&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;如果你不是系统管理员，并且需要 iCloud 邮件方面的协助，请&lt;a href=&quot;https://getsupport.apple.com/?caller=kbase&quot;&gt;联系 Apple 支持&lt;/a&gt;。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;于是便有了和Apple支持的沟通尝试。&lt;/p&gt;
&lt;h3&gt;案例0165：邮件发送失败&lt;/h3&gt;
&lt;p&gt;说实话，这并不是我第一次和Apple支持沟通。反而，事实上，作为一个数年的Apple老用户，我联系Apple支持的次数并不少。
或许是因为自己的技术不断精进，越到后来，越感觉和Apple支持沟通的过程中，反而自己更像是那个专业人士。&lt;/p&gt;
&lt;p&gt;所以我已经很久很久没有联系过Apple支持，说真的，每次一想到“明知他们完全帮助不到我，又抱着一丝丝希望联系上他们，最后又失望而归”的老生常谈……我下一次还联系Apple支持的可能性就又下降一点。每一次都保不齐是我最后一次联系Apple支持的尝试。
只是这一次我尤其火大。&lt;/p&gt;
&lt;p&gt;按照惯例，能不打电话的时候，绝不打电话，我先是选择线上对谈，然后得知需要打电话，把案例提升给Senior Advisor（高级顾问）……好吧，习惯了，虽然在我的感官上他们的Senior Advisor也没有“高级”到哪里去。&lt;/p&gt;
&lt;p&gt;电话接通后，高级顾问简要问了几个问题，然后打开了我的屏幕共享，然后不出我所料，又是那两个Apple支持的万能雷区——预览版软件和虚拟专用网络，被拿出来作为拒绝将这个案例发送给Engineering Team（工程师团队）的理由。&lt;/p&gt;
&lt;p&gt;这并非我第一次因为类似的原因被Apple支持拒绝提供帮助，我也清楚在&lt;a href=&quot;https://beta.apple.com/agreements/apple-beta-software-agreement-ea1846.pdf&quot;&gt;Apple Beta Software Agreement&lt;/a&gt;也写道：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;During Your participation in the Beta Program or in a particular seed, Apple is not obligated to provide You with any maintenance, technical or other support for the Apple Software.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;但是需要注意的是，结合全文，我本人（或许是水平有限）也完全不能得出这一段“No Support and Maintenance”条款适用于「并非预览版的服务」。也就是说，我不认为这个协议摘掉了Apple为我订阅的服务提供支持的义务。&lt;/p&gt;
&lt;p&gt;之前一些界限比较模糊，不太好确定是软件还是服务的问题，我一次次被拒绝，基本上是合理的，我也从来没有微辞。&lt;/p&gt;
&lt;p&gt;这一次的体验实在是过于糟糕，过于不合乎逻辑和理性。我并不想，也没有必要，向一个顾问解释电子邮件系统究竟是怎么运作的。但我已经强调我脱离预览版软件环境（例如，使用iCloud.com网页版）之后仍然有这样的问题，我已经尽全力试图让其理解，为什么这不是一个「软件」问题，而是一个服务器端的问题。
我甚至说，我现在并不使用任何Apple设备和软件，这样就没有任何预览版软件了，我在一台Windows 11 PC上使用Google Chrome访问iCloud.com网页版发送邮件，遇到这样的问题了，现在可以为我提供技术支持，把案例提交给Engineering Team了吗？&lt;/p&gt;
&lt;p&gt;还是遭到拒绝。&lt;/p&gt;
&lt;p&gt;我被拒绝这么多次，第一次这么恼火。这就像是我去一家精酿酒馆想买一些酒，有时会遇到打酒的机器泵出液体不畅的问题，我和店员说“是不是向负责人反馈一下”，然后店员以我来买酒时开的汽车经过改装为由拒绝听取我的意见……&lt;/p&gt;
&lt;p&gt;Excuse me???&lt;/p&gt;
&lt;p&gt;我理解如果鸡毛蒜皮的小问题，甚至是用户使用不当造成的错误，都报告到工程师团队，必然引起不必要的麻烦。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;但能不能不要一看到用户在使用预览版软件，就像收到惊吓的乌龟缩在壳里一样只会重复念叨让用户刷机？&lt;/strong&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;我喜欢Apple的产品是真的，我讨厌Apple支持的水平和态度也是真的。&lt;/p&gt;
&lt;p&gt;祝大家都用得开心，用得稳定，永远不需要联系Apple支持那是最好。&lt;/p&gt;
&lt;p&gt;如果遇到了Apple支持不能解决的问题和糟心事……这里我给自己打一个小广告，欢迎&lt;a href=&quot;https://www.zhihu.com/consult/people/1089280608508768256&quot;&gt;来知乎找我付费咨询&lt;/a&gt;～&lt;/p&gt;
</content:encoded></item><item><title>家庭影院杂谈和小明V1 Ultra使用体验</title><link>https://kyki.moe/posts/home-theater-and-xming-v1-ultra/</link><guid isPermaLink="true">https://kyki.moe/posts/home-theater-and-xming-v1-ultra/</guid><pubDate>Wed, 05 Mar 2025 12:59:16 GMT</pubDate><content:encoded>&lt;p&gt;&lt;em&gt;如果你正在&lt;a href=&quot;https://kyki.moe/&quot;&gt;陽升之谷&lt;/a&gt;阅读本文，文中所有商品链接均已去除推广标记，如有需要查看请放心点击。&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;梦开始的配置&lt;/h2&gt;
&lt;p&gt;从最开始的一套雏形到今天，我的家庭影院总算是让我完整地规划好了。让我来简单地聊聊一些心得和体验。流水账式写法致歉。&lt;/p&gt;
&lt;p&gt;我最开始的配置如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.mi.com/redmiprojector/specs?product_id=1224200049&quot;&gt;Redmi投影仪 Pro&lt;/a&gt;，二手，2024年中入手价约¥850&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://support.apple.com/en-us/111839&quot;&gt;Apple TV 4K (3rd generation)&lt;/a&gt;，64GB Wi-Fi版，原销售地区美国，全新，2024年中入手价约¥950&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://support.apple.com/en-us/111994&quot;&gt;Apple HomePod (1st generation)&lt;/a&gt;，国行特殊SKU，二手，2021年底入手价约¥1200&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;我很难想象当时的我脑子抽什么风，什么都没调研无脑选了粗粮家的东西~~（难道是爱？）~~。
促使我真正开始研究投影仪各项参数的因素是Redmi投影仪 Pro非常蛋疼的1080P分辨率，以及只有30Hz的刷新率。直至我打算换机器的时候我都一直还没有注意到投影仪还有亮度这个重要参数。
开始在网上真正开始找一台优秀的千元投影仪的时候，我才在人们的讨论中幡然醒悟——原来我之前白天拉窗帘也看不清楚的投影画面并不是什么特别正常的现象，150ANSI流明简直是低了又低。我是笨蛋。&lt;/p&gt;
&lt;h2&gt;这么暗，换个投影仪罢（恼）&lt;/h2&gt;
&lt;h3&gt;看看LCD技术&lt;/h3&gt;
&lt;p&gt;看到非常高性价比的两台机器是&lt;a href=&quot;https://www.haqu.com/k1pro/parameterK1Pro.html&quot;&gt;哈趣K1 Pro&lt;/a&gt;和&lt;a href=&quot;https://www.formovie.cn/detail/q2%20pro&quot;&gt;小明Q2 Pro&lt;/a&gt;。截至发稿这两台机器在我看来仍然非常有竞争里，在一个¥1000以下价位里。所以我在这里稍微聊一聊我光靠纸面参数得到的见解。&lt;/p&gt;
&lt;p&gt;亮度方面，哈趣K1 Pro在标准模式下 60寸投影画面实测亮度为330.88lm左右（&lt;a href=&quot;https://www.zhihu.com/tardis/zm/art/591707464&quot;&gt;来源：知乎 @投影卡卡&lt;/a&gt;），小明Q2 Pro 100寸投影画面实测亮度为241.37lm左右（&lt;a href=&quot;https://www.zhihu.com/tardis/zm/art/583826869&quot;&gt;来源：知乎 @投影卡卡&lt;/a&gt;）。但这两个数据并不公平，因为投影画面的大小并不一样。100&quot;对角线，16:9的画面大小约2.7429m²；而60&quot;对角线，16:9的画面大小约为0.9768m²。所以把哈趣K1 Pro的作者误差值去掉，再乘以$2.7429/0.9768=2.8080$，再把作者误差加回去，我们可以得到$(330.88-50)*2.8080+50=838.71104$。宇宙安全声明：我是纯纯半桶水晃荡晃荡，这一段里的算法找ChatGPT聊出来的，如有误还请纠正～&lt;/p&gt;
&lt;p&gt;其他参数我直接列个表格，如下。其他参数基本一样的，不表。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;哈趣K1 Pro&lt;/th&gt;
&lt;th&gt;小明Q2 Pro&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;USB&lt;/td&gt;
&lt;td&gt;未标注版本号&lt;/td&gt;
&lt;td&gt;USB3.0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;以太网&lt;/td&gt;
&lt;td&gt;一个RJ45，速率未知&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dolby Atmos&lt;/td&gt;
&lt;td&gt;未标注&lt;/td&gt;
&lt;td&gt;可解码可播放&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;扬声器&lt;/td&gt;
&lt;td&gt;2*5W&lt;/td&gt;
&lt;td&gt;2*3W&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OS&lt;/td&gt;
&lt;td&gt;当贝OS&lt;/td&gt;
&lt;td&gt;FengOS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MEMC&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;原生服务接入&lt;/td&gt;
&lt;td&gt;腾讯START云游戏&lt;/td&gt;
&lt;td&gt;小米米家&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;关于FengOS的一些体验我会在下面有关小明V1 Ultra的内容里聊到。别的不表了，因为我是云用户（不是）。&lt;/p&gt;
&lt;h3&gt;又看了看DLP技术，下单了&lt;/h3&gt;
&lt;p&gt;最后因为市场原因两台都没买。于是想着体验一下DLP技术好了，去海鲜市场淘了一个坚果J6s，战争成色，2025年初入手价约¥450。遇到了好多不满，如下。&lt;/p&gt;
&lt;p&gt;战争成色让我不爽的：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;DMD上微镜坏了俩。边缘两个白点，不过不是显示区域内，这点问题不大。&lt;/li&gt;
&lt;li&gt;棱镜烧黄了一块。大概半个显示区域全是黄澄澄的。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;机器本身让我不爽的：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;完全不支持HDMI CEC。每次开机都得拿两个遥控器，关机也是。&lt;/li&gt;
&lt;li&gt;色彩管理非常非常差。尤其红色，Apple Music图标的颜色看起来像纪梵希的小羊皮306（宇宙安全声明：我是不懂美妆的技术宅，现场去橙色购物软件搜了一个很相似的颜色而已）。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;DLP技术让我不爽的：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;彩虹纹。肉眼几乎不可见，但需要扫码或者屏摄分享时影响很大。&lt;/li&gt;
&lt;li&gt;散斑。稍微近一点很容易看到。周末跑到极米家看了一下也很明显……有种4K抖成1080P的美，没错是高抖低。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;LCD永不为奴？小明V1 Ultra主观体验报告&lt;/h2&gt;
&lt;p&gt;截至发稿，最后我的做法是加预算上了小明V1 Ultra。另外还买了又一个HomePod，组成立体声，所以配置变成了这样：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://detail.tmall.com/item.htm?id=773966085342&quot;&gt;小明V1 Ultra&lt;/a&gt;，全新，2025年初入手价约¥1800&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://support.apple.com/en-us/111839&quot;&gt;Apple TV 4K (3rd generation)&lt;/a&gt;，还是那台～&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://support.apple.com/en-us/111994&quot;&gt;Apple HomePod (1st generation)&lt;/a&gt;，原来那台，以及另一台：国行，二手，2025年初入手价约¥950&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;顺便提一嘴，所有国产投影仪厂商似乎对于产品命名这一块都有点让人摸不着头脑。小明「V1」的迭代产品叫&lt;a href=&quot;https://detail.tmall.com/item.htm?id=885335645516&quot;&gt;New V1&lt;/a&gt;，那再迭代一次呢？「New New V1」吗？不仅小明，包括哈趣在内的一众厂商都喜欢New来New去的，让我想起了Linus（LTT那位）的New New Vault了。嗨，这我没意见，整活而已，而且内部NAS他想怎么命名也不至于混淆它的观众。问题是他们的旗舰店里还有一款&lt;a href=&quot;https://detail.tmall.com/item.htm?id=761665905363&quot;&gt;小明V1&lt;/a&gt;，他们的店铺主页上打着「新品」的徽记。结果点开是「V1」而不是「New V1」。这边私以为还是把这个迭代产品叫做「V2」甚至是「V1（第二代）」比较合适呢
。
下面来从几个方面聊聊这台机器，从一个个人用户的视角，以及大家都聊过的东西我就不再聊了，接下来的我希望给到我的读者一些不一样的内容。&lt;/p&gt;
&lt;h3&gt;音响&lt;/h3&gt;
&lt;p&gt;即使是手持HomePods Stereo的我，拿到这台机器的时候也被它的音箱震撼到了。或许是太久没见过一个优秀的内置音响？并不是高音或者低音有多么强悍，也不是人声解析力有多高，2*6W的规格，没标大小的音腔，能给到的也就是这么点了。单论这几个项目肯定是连单个的HomePod都打不过的。真正震撼到我的是它的声场。真的是相当相当开阔了，比放在床头的HomePod厉害不少。听的是&lt;a href=&quot;https://music.apple.com/cn/album/main-titles/1608610102?i=1608610104&quot;&gt;Severance的Main Titles&lt;/a&gt;（顺便安利一下Apple TV+原创剧集《人生切割术》Severance，截至发稿，第二季正在连载）。不过我在想把HomePod顶在头顶上是不是也会有这么好的效果🤔。&lt;/p&gt;
&lt;h3&gt;MEMC&lt;/h3&gt;
&lt;p&gt;没用过MEMC的可能没感觉，这属于用过了就回不去的技术。我个人更喜欢看起来fps更高的画面，即使MEMC的加入导致一些场合可能不那么符合原著，我仍然非常喜欢这些画面。&lt;/p&gt;
&lt;h3&gt;700CVIA亮度&lt;/h3&gt;
&lt;p&gt;是的，这个亮度甚至被他们自家的新机New V1（现在知道上面为啥要提这个命名了吧）吊打。New V1的亮度是950CVIA了。不过似乎可以理解。像素多了之后透光性能当然地会下降，以及新设备估计也有光源上的新突破。但是700CVIA也完全够我在夜晚或者是白天的窗帘背后看内容了。观看SDR内容，我并不觉得有什么大问题。&lt;/p&gt;
&lt;h3&gt;自带云台&lt;/h3&gt;
&lt;p&gt;虽然只有一个范围为5～15°的俯仰轴，但是对于我来说还是完全足够了。前面说过我的安置位置要求我的投影仪必须倾斜放置，但是这个单轴云台又弥补了这一点。不过市面上大部分有云台的投影仪应该都是单轴的？航向轴基本上都是靠直接转动底座完成的了。横滚轴的话……真的要调投影仪的横滚轴吗？&lt;/p&gt;
&lt;h3&gt;吵死了，而且很费电&lt;/h3&gt;
&lt;p&gt;真的是很吵。官宣噪音小于30dB，我没有分贝仪，不敢说这个数值对不对，但是真的挺吵的。所有HomePods Stereo用户建议把音量从静音向上按3下。&lt;/p&gt;
&lt;p&gt;整机功耗更是来到了惊人的120W左右，这还是我音响完全没有工作的情况下。&lt;/p&gt;
&lt;h3&gt;不支持HDMI ARC/eARC，CEC支持不完善&lt;/h3&gt;
&lt;p&gt;是的，Apple TV+HomePod还想再加一个PlayStation然后爽用HomePod打游戏的用户请慎买。&lt;/p&gt;
&lt;p&gt;是的，CEC只能电视控盒子，反过来不行。&lt;/p&gt;
&lt;h3&gt;服务很好&lt;/h3&gt;
&lt;p&gt;我在峰米服务微信公众号提了一下这个CEC单向的问题……没想到还有电话跟进。虽然那个给我回电的客服啥也不懂，但是我大概听出来了意思就是不打算适配😅。&lt;/p&gt;
&lt;h3&gt;FengOS&lt;/h3&gt;
&lt;p&gt;出厂系统版本号我忘了😅，不过我也用了一段时间的出厂版本，然后才升级到最新版本的。变化主要有以下几点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;FengOS自己的桌面没了，直接变成银河奇异果。
这一点我还挺喜欢的。作为一个投影仪本体不联网的外接播放用户，比起之前FengOS断网界面的亮色背景，银河奇异果断网界面的深色背景让我感觉更舒服。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;宣传页吹的的「AIPQ画质增强」删掉了。
感知不强……？这个功能挺鸡肋的，我的肉眼看不出开和不开的区别。我猜无非是自动的亮度、对比度、饱和度、锐化调节。甚至删掉之前除了对比一下效果我根本就没开这功能。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;「蓝牙音箱模式」从实验室功能变成了正式功能。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;启动速度有了比较显著的提升。
之前的启动是：风扇开转 - FengOS启动画面 - HDMI连接中。
现在是：风扇开转 - HDMI连接中。
而且这不是仅仅删了一屏而时间没变，启动时间确实缩短了。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;新增连接峰米小程序快捷入口。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;以及一些我认为可圈可点的地方有：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;墙面颜色自适应。
如果家里的墙颜色并不是纯白色，甚至如果家里的墙是白色，但是白得不够标准，这个功能还是能够体现出一些区别的。经过Apple TV的色彩平衡和这个墙面颜色自适应修正之后纯粹对比iPhone的屏幕，我认为投影画面的颜色准确度可以说相当高了。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;米家/小明同学（小爱同学）原生接入。
小明的生产厂商峰米科技是光峰科技和小米联合投资的子公司，于是理所当然地有了接入米家生态的能力。原来的Redmi上面有一个我用着非常舒服的功能就是米家原生接入。在我看剧的时候告诉我“电饭煲烹饪完成”确实是我觉得很有用的功能，虽然这个功能目前由我的Apple Watch负责，我仍然认为原生的米家接入非常适合小米生态用户。而且小明系列产品，以及峰米系列产品，其性价比在我看来确实高过小米的自有品牌小米和Redmi。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;我确实不理解那些把自己电视上的语音助手接入深度求索大模型当作卖点的厂商到底在想什么。所以呢？我可以方便地在电视上用语音助手和大模型沟通？如果接入的是别的模型，可能还有读屏之类的功能值得使用，但是深度求索-V3和深度求索-R1这两个模型根本就没有多模态支持……看起来完全就是蹭热度的行为了吧。&lt;/p&gt;
&lt;p&gt;FengOS出彩的地方其实不多，但没有广告，没有杂七杂八没用的功能，我认为这才是一个电视OS该有的样子。&lt;/p&gt;
&lt;h3&gt;LCD永不为奴！&lt;/h3&gt;
&lt;p&gt;这台投影仪确实非常特别，作为我在购物平台上看到的唯一一台LCD原生4K投影仪，它确实非常特别。不需要DLP和抖DMD来显示4K，不会有白点，不会有彩虹纹，更不会有散斑。即使对比度、亮度以及色彩都比DLP要差一些，可能不足以弄出很好的HDR效果，我还是喊：LCD永不为奴！&lt;/p&gt;
&lt;p&gt;所有DLP投影仪厂商在宣传页上几乎都会大肆宣称自己的色彩、亮度、对比度好于单LCD投影，并且把单LCD称为“行业正逐渐淘汰的技术”。实际上DLP除了确实在色彩上显著优于单LCD投影，其他指标并不是必然好于单LCD。例如，让我们对比我在淘宝直接按销量降序得到排名第一的DLP投影仪&lt;a href=&quot;https://detail.tmall.com/item.htm?&amp;amp;id=839454266449&quot;&gt;极米Z6X第五代&lt;/a&gt;，以及同样方式得到排名第一的单LCD投影仪&lt;a href=&quot;https://detail.tmall.com/item.htm?id=842003412798&quot;&gt;小明Q5 Pro&lt;/a&gt;，这两者的一些参数，如下。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;极米Z6X第五代&lt;/th&gt;
&lt;th&gt;小明Q5 Pro&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;亮度/CVIA流明&lt;/td&gt;
&lt;td&gt;500&lt;/td&gt;
&lt;td&gt;600&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;色域&lt;/td&gt;
&lt;td&gt;121% Rec.709&lt;/td&gt;
&lt;td&gt;确实是“根本不敢讲色彩”&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;对比度&lt;/td&gt;
&lt;td&gt;未展示&lt;/td&gt;
&lt;td&gt;2000:1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;售价（无补贴）&lt;/td&gt;
&lt;td&gt;¥1771&lt;/td&gt;
&lt;td&gt;¥1299&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;不否认高端产品上的DLP规格也会显著高于低端产品，但是直接硬吹一切DLP，硬踩一切单LCD的宣传确实可以斟酌一下是不是有点夸张。&lt;/p&gt;
&lt;p&gt;在购置DLP投影仪的时候，做过一些研究的人会考虑到DMD芯片尺寸这个参数。但非常奇怪的是，在横向对比DLP投影仪和单LCD投影仪的时候却几乎没有人思考过这个问题。好像在单LCD投影仪上这个参数就不存在了似的。&lt;/p&gt;
&lt;p&gt;除了像素点的个数，芯片的尺寸在这两种投影仪里也都起着非常重要的作用。DLP投影仪中的DMD芯片的典型尺寸在0.2&quot;到1.38&quot;不等。而单LCD投影仪里的LCD面板动不动就好几英寸。投影仪通常离光屏/投影面的距离并不近，很多时候都能达到3～4m，芯片/面板的尺寸在此时便开始显得尤其重要。&lt;/p&gt;
&lt;p&gt;周末去店里看~~（白嫖）~~了&lt;a href=&quot;https://detail.tmall.com/item.htm?id=822005701320&quot;&gt;极米RS 10 Plus&lt;/a&gt;，上来就问芯片尺寸，店员一看就知道我不是过来买的，保不齐是过来找茬来了，没多说话。说是0.47&quot;的DMD，投影距离大约2m，观看距离在1m的时候就能明显看出一些散斑了，还是在抗散斑功能启用的情况下。&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;说完了，体验也记录得差不多了。希望能对你有所帮助～&lt;/p&gt;
</content:encoded></item><item><title>Bug+1: 时间机器无法完成备份</title><link>https://kyki.moe/posts/bug-time-machine-inaccessible-files/</link><guid isPermaLink="true">https://kyki.moe/posts/bug-time-machine-inaccessible-files/</guid><pubDate>Sun, 03 Nov 2024 23:28:47 GMT</pubDate><content:encoded>&lt;p&gt;&lt;em&gt;这个主题的代码字体里的u长得好像v，请注意辨别。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;是收到了这样的错误：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Time Machine couldn&apos;t complete the backup to ((Target))&lt;br /&gt;
Time Machine did not finish backing up because some files were unavailable. Backups will resume when your Mac is unlocked.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;然后查询Log（使用&lt;a href=&quot;https://eclecticlight.co/mints-a-multifunction-utility/&quot;&gt;Mints&lt;/a&gt;），可以抓到这段错误代码：&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Backup failed: BACKUP_DELAYED_UNFINISHED_PROTECTED_FILES (104)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;通过搜索引擎找到有帮助的答案是：&lt;a href=&quot;https://apple.stackexchange.com/questions/433761/time-machine-shows-no-backup-after-backing-up&quot;&gt;https://apple.stackexchange.com/questions/433761/time-machine-shows-no-backup-after-backing-up&lt;/a&gt;。依照其中的指示，可以通过下面的命令获得更详细的日志：&lt;/p&gt;
&lt;p&gt;&lt;code&gt;log show --style syslog --last 30m  --predicate &apos;senderImagePath contains[cd] &quot;TimeMachine&quot;&apos; --info --debug&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;获取日志之后，在其中查找形如下面内容的日志条目：&lt;/p&gt;
&lt;p&gt;&lt;code&gt;localhost backupd[256]: (TimeMachine) [com.apple.TimeMachine:EventCollection] Adding event for inaccessible protected file ((Path)) | EventDatabase.swift:569&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;其中&lt;code&gt;((Path))&lt;/code&gt;就是Time Machine无法访问从而导致上述104错误的文件。&lt;/p&gt;
&lt;p&gt;继续根据上述答案文章中的指示，我们可以通过如下命令排除所有无法访问的文件，从而正常完成备份：&lt;/p&gt;
&lt;p&gt;&lt;code&gt;sudo tmutil addexclusion -p ((Path))&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;但是，我们也可以试图修复文件的访问权限，从而避免备份缺斤短两。实践中可以得知，Time Machine的访问权限是和当前用户相同的。所以做法也很简单，就是&lt;code&gt;chown&lt;/code&gt;+&lt;code&gt;chmod&lt;/code&gt;大法：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo chown -R ((Username)):staff ((Path))
chmod -R u+r ((Path))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如此便可放行当前用户对异常文件的访问了。并且这么操作还可以避免对异常文件的排除，让备份更加完整。&lt;/p&gt;
&lt;p&gt;Make Time Machine Great Again!&lt;/p&gt;
&lt;h2&gt;后记&lt;/h2&gt;
&lt;p&gt;遇到这个问题并不是毫无来头。我也是在从Time Machine恢复了Mac之后，再备份时出现的这个问题。&lt;/p&gt;
&lt;p&gt;可以认为从Time Machine恢复Mac会导致部分文件的所有和访问权限出现问题。因为Time Machine在备份失败时报的错误就是部分文件不可用，所以期间我也多次使用CleanMyMac X的&lt;code&gt;Repair Disk Permissions&lt;/code&gt;和&lt;code&gt;Time Machine Snapshot Thinning&lt;/code&gt;功能试图解决，但结果显然是毫无效果。&lt;/p&gt;
&lt;p&gt;希望能够帮到你。&lt;/p&gt;
</content:encoded></item><item><title>通过VS Code历史记录恢复误删文件</title><link>https://kyki.moe/posts/thank-you-vscode-for-saving-my-file/</link><guid isPermaLink="true">https://kyki.moe/posts/thank-you-vscode-for-saving-my-file/</guid><pubDate>Wed, 01 May 2024 03:22:58 GMT</pubDate><content:encoded>&lt;p&gt;如果你误删了，并且试图恢复一个曾经用Visual Studio Code保存过的文件，按下&lt;code&gt;⌘ + ⇧ + P&lt;/code&gt;（对于Windows：&lt;code&gt;Ctrl + Shift + P&lt;/code&gt;）呼出主命令面板，输入并运行&lt;code&gt;Local History: Find Entry to Restore&lt;/code&gt;命令，即可浏览和查找VS Code为你保存的文件历史记录。&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;是的，我要连发两篇文章。&lt;/p&gt;
&lt;p&gt;看到这个标题，而且两篇文章挨这么近，就很难不想象是不是发生了一些事情（汗）。要知道，在笔者，本站站长，陽楷锴，写完上一篇文章（&lt;a href=&quot;/posts/encounter-email-spoofing-and-more&quot;&gt;邂逅电邮假冒和其承载的钓鱼网站&lt;/a&gt;）之后，不知道脑子抽什么风，就想着要更新一下主题。于是很快啊，啪的一下就打开了GitHub，然后&lt;a href=&quot;https://github.com/saicaca/fuwari&quot;&gt;saicaca/fuwari&lt;/a&gt;最新Zip直接就下载下来，Safari直接就自动解压，然后往项目文件夹里直接就复制，粘贴，全部替换。&lt;/p&gt;
&lt;p&gt;没错，直接就复制，粘贴，全部替换，一气呵成。有的时候我自己都佩服我自己的动作居然这么行云流水。我打开VS Code，打算用它提供的图形化Git看一下我的自定义修改啥的，得兼顾主题更新和自定义内容啊，而且Astro框架和主题高度同构，我的文章源文件还得从Git恢复回来呢。于是，发现，其中没有显示Deleted状态下红色文件名的&lt;code&gt;encounter-email-spoofing-and-more.md&lt;/code&gt;。我怕了，于是转念一想，当时「一气呵成」的时候好像忘了……把上篇文章的源文件stage到Git里，更没有commit，更没有push到GitHub。&lt;/p&gt;
&lt;p&gt;我开始上网搜索Mac恢复文件的办法，因为我在废纸篓里根本没看到这个文件。看到好几个数据恢复软件，但是一上来就要我许可证，我感觉不太靠谱，就像骗子公司生产的骗子产品，比上篇文章里的诈骗邮件还像骗子，毕竟是装都不装了直接要钱～&lt;/p&gt;
&lt;p&gt;根本不敢用那些数据恢复软件之下，我打开了Time Machine。发现我没有连接备份盘的情况下，Time Machine不会创建任何快照。上一次连接是两天前啊……自然是找不到这个该死的&lt;code&gt;encounter-email-spoofing-and-more.md&lt;/code&gt;了。&lt;/p&gt;
&lt;p&gt;重新写的心都有了，想想花了两三个小时写的，有这时间不如去打点游戏，或是睡点觉……想放弃的时候，想起来VS Code在我刚刚前往它的图形化Git功能的时候还打开着那个该死的&lt;code&gt;encounter-email-spoofing-and-more.md&lt;/code&gt;，虽然它好像当时显示着找不到该文件和一个令人害怕的红色叉叉。我觉得这是我最后一线希望了，翻着一个又一个菜单，我仍然没能找到相关入口，心越来越慌了。&lt;/p&gt;
&lt;p&gt;最后呢？我重写了吗？没有。去Bing查了一下VS Code到底有没有恢复文件的功能，结果还真的给我找到了：&lt;a href=&quot;https://zhuanlan.zhihu.com/p/672076216&quot;&gt;vscode 恢复被删除的文件 - 知乎&lt;/a&gt;。我跟看到救星一样又跑到VS Code里，一套&lt;code&gt;⌘ + ⇧ + P&lt;/code&gt;然后&lt;code&gt;Local History: Find Entry to Restore&lt;/code&gt;，像刚才全部替换的时候一样一气呵成，终于，我找到了这个文件。谢天谢地，直接恢复到覆盖前的版本，找回了我几个小时的心血。&lt;/p&gt;
&lt;p&gt;呜呜呜，再也不嫌弃VS Code体积大了，也再也不乱删它的缓存了，说不定哪天就……哎，真的都是泪。&lt;/p&gt;
&lt;p&gt;Visual Studio Code，听我说谢谢你。&lt;/p&gt;
&lt;p&gt;Astro，听我说，我也谢谢你。&lt;/p&gt;
</content:encoded></item><item><title>邂逅电邮假冒和其承载的钓鱼网站</title><link>https://kyki.moe/posts/encounter-email-spoofing-and-more/</link><guid isPermaLink="true">https://kyki.moe/posts/encounter-email-spoofing-and-more/</guid><pubDate>Wed, 01 May 2024 00:52:42 GMT</pubDate><content:encoded>&lt;h2&gt;背景&lt;/h2&gt;
&lt;p&gt;最近新入手一个域名。对其用途有清晰的设想，但是设想中的相关项目还远远达不到可以启动的地步……遂先行注册该域名并在项目启动前长期持有。
&lt;s&gt;无论如何这个新域名都是我年轻时候宏伟梦想的象征了。&lt;/s&gt;&lt;/p&gt;
&lt;h2&gt;接连不断的RUA报告&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;本文所称「电子邮件假冒」是指Email Spoofing（&lt;a href=&quot;https://en.wikipedia.org/wiki/Email_spoofing&quot;&gt;Wikipedia&lt;/a&gt;）。由于我实在不知道这东西的正式中文名称是什么，于是先用Cloudflare的翻译「电子邮件假冒」（出处：&lt;a href=&quot;https://www.cloudflare.com/zh-cn/learning/email-security/what-is-email-spoofing/&quot;&gt;什么是电子邮件假冒？&lt;/a&gt;）称呼之。&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;自从我于2024-04-10注册下这个域名，并且配置好大部分保护性措施（包括DMARC、SPF、DKIM记录等）起，截至撰稿时（2024-05-01凌晨），12封由于违反DMARC规则的RUA报告（Aggregate Report）邮件抵达了我的邮箱……平均两天就有一封多。&lt;/p&gt;
&lt;p&gt;根据Cloudflare DMARC Management给出的报告，可以得到以下结论：&lt;/p&gt;
&lt;p&gt;按来源分类：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;AS4134（No.31,Jin-rong Street）：8封&lt;/li&gt;
&lt;li&gt;AS9929（CHINA UNICOM Industrial Internet Backbone）：4封&lt;/li&gt;
&lt;li&gt;AS56046（China Mobile Communications Corporation）：1封&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;按去向分类：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;google.com：6封&lt;/li&gt;
&lt;li&gt;docomo.co.jp：4封&lt;/li&gt;
&lt;li&gt;GMO Internet Group Inc.：1封&lt;/li&gt;
&lt;li&gt;kddi.com：1封&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;很显然，所有违规邮件都来自同一个地区，而去向则都与发件服务器所在地区不同。&lt;/p&gt;
&lt;p&gt;由于这些收件服务器都没有向我发送RUF报告（Forensic Report），所以我并没有办法搞清楚这个域名究竟被用作了什么邮件的发件人。
我相当烦恼，但更多细节在一封特别的邮件中被清楚地展示在我面前。&lt;/p&gt;
&lt;h2&gt;特别的邮件：退信&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;This is the mail system at host mail.chun2.ne.jp.
I&apos;m sorry to have to inform you that your message could not be delivered to one or more recipients. It&apos;s attached below.
For further assistance, please send mail to postmaster.
If you do so, please include this problem report. You can delete your own text from the attached returned message.
The mail system&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;我收到了一封以上面引用块中的文本为开头的电子邮件。大胆推测应该是收件服务器检测到DMARC违规，但没有按照记录中的要求发送RUA或是RUF报告给规定位置，而直接发送了未送达通知到原发件地址。此时，由于我为我的域名设置了MX记录，自然地，这封未送达通知就到了我的收件箱里。&lt;/p&gt;
&lt;p&gt;为什么说这封邮件特别？首先因为它不是规范的RUA或是RUF报告，而更重要的是，这个独特的收件服务器（mail.chun2.ne.jp），在未送达通知中附上了邮件原文。这也是我称之为「退信」的原因。&lt;/p&gt;
&lt;p&gt;于是乎我得以窥探某些人用这个域名所发邮件的内容的一角。&lt;/p&gt;
&lt;p&gt;首先仍然是来源和去向。该邮件来自位于AS4837（CHINA UNICOM China169 Backbone）的一台发件服务器，去向为po.chun2.ne.jp。接着，下面是邮件内容：&lt;/p&gt;
&lt;p&gt;&amp;lt;details&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;summary&amp;gt;Apple机器翻译&amp;lt;/summary&amp;gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;发件人：MasterCard
标题：万事达卡:非法使用嫌疑的安全检查。
正文：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;感谢您使用【Mastercard】。这次，因为有想确认是否是本人使用的交易，所以非常抱歉，限制了部分卡的使用，并联系了您。
因此，请在以下页面访问后，配合确认卡的使用情况。给您添麻烦和担心，非常抱歉。请您多多谅解。如果没有回答的话，卡的使用限制可能会持续，请提前知悉。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://clck.ru/3ALtcH&quot;&gt;▼确认使用情况请看这里&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;非常抱歉给您带来不便和担心，请您多多谅解。&lt;/p&gt;
&lt;p&gt;发行人
Mastercard
东京都涩谷区樱丘町26-1 Cerulean Tower 16楼&lt;/p&gt;
&lt;p&gt;所有用户均被视为已批准并同意本网站客户的隐私使用条款。
©1994-2024 Mastercard. Mastercard作为机会均等的雇主进行企业活动。&lt;/p&gt;
&lt;p&gt;卡丢失、被盗、紧急情况下的账户信息访问等，365天24小时，无论是国内还是海外，都接受万事达卡会员的咨询。https://www.mastercard.us/content/dam/mccom/global/documents/global-services-phone-numbers.pdf&lt;/p&gt;
&lt;p&gt;可以搜索包括无接触结算和手机结算在内的信用卡、借记卡、预付万事达卡的加盟店和最近的ATM机。&lt;/p&gt;
&lt;p&gt;https://www.mastercard.co.jp/ja-jp/personal/get-support/mastercard-nearby.html&lt;/p&gt;
&lt;p&gt;发行人
Mastercard
东京都涩谷区樱丘町26-1 Cerulean Tower 16楼&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/blockquote&gt;
&lt;p&gt;&amp;lt;/details&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;details&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;summary&amp;gt;日语原文&amp;lt;/summary&amp;gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;发件人：MasterCard
标题：MasterCardカード:不正使用疑惑のセキュリティチェック
正文：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;【Mastercard】利用いただき、ありがとうございます。このたび、ご本人様のご利 用かどうかを確 認させていただきたいお取 引がありましたので、誠に勝手ながら、カードのご利 用を一部制 限させていただき、ご連 絡させていただきました。
つきましては、以下ヘアクセスの上、カードのご利 用確 認にご協力をお願い致します。お客様にはご 迷 惑、ご心配をお掛けし、誠に申し訳ございません。何卒ご理解いただきたくお願い申しあげます。ご回答をいただけない場合、カードのご利 用制 限が継続されることもございますので、予めご了承下さい。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://clck.ru/3ALtcH&quot;&gt;▼ご利用確認はこちら&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;ご不便とご心配をおかけしまして誠に申し訳ございませんが、何とぞご理 解 賜りたくお願い申しあげます。&lt;/p&gt;
&lt;p&gt;発行者
Mastercard
東京都渋谷区桜丘町26-1 セルリアンタワー16階&lt;/p&gt;
&lt;p&gt;すべてのユーザーは、このWebサイトの顧客のプライバシー利用規約を承認および同意したものと見なされます。
©1994-2024 Mastercard. Mastercardは、機会均等雇用主として企業活動を行っています。&lt;/p&gt;
&lt;p&gt;カードの紛失・盗難、緊急時のアカウント情報へのアクセスなど、365日24時間、国内からでも海外からでも、Mastercard会員様よりのお問い合わせを受け付けています。https://www.mastercard.us/content/dam/mccom/global/documents/global-services-phone-numbers.pdf&lt;/p&gt;
&lt;p&gt;コンタクトレス決済やモバイル決済を含むクレジット、デビット、プリペイド Mastercardのご利用いただける加盟店や最寄りのATMを検索をいただけます。&lt;/p&gt;
&lt;p&gt;https://www.mastercard.co.jp/ja-jp/personal/get-support/mastercard-nearby.html&lt;/p&gt;
&lt;p&gt;発行者
Mastercard
東京都渋谷区桜丘町26-1 セルリアンタワー16階&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/blockquote&gt;
&lt;p&gt;&amp;lt;/details&amp;gt;&lt;/p&gt;
&lt;p&gt;日语我看不懂一点，所以只能用机器翻译，见谅。好在这不影响对这封邮件的分析。可以看出，这是一封诈骗邮件，谎称收件人的Mastercard卡片被限制，需要在线恢复卡片功能。另外也不难看出写这封邮件的人水平其实不怎么样，连Mastercard这个名字的大小写都没搞清楚，发件人和标题都错写成了“MasterCard”。&lt;/p&gt;
&lt;p&gt;其中给出的“确认使用情况”链接是&lt;a href=&quot;https://clck.ru/3ALtcH&quot;&gt;https://clck.ru/3ALtcH&lt;/a&gt;。访问该站点的主页并进行一些简单的查询就很容易发现这是Yandex的短链接服务，攻击者应该是通过该短链接服务来隐藏真实URL以逃过邮件安全系统的检测。
该链接最终会跳转到&lt;a href=&quot;http://vmu178.com/?index=205&quot;&gt;http://vmu178.com/?index=205&lt;/a&gt;。忽略令人诟病的明文HTTP协议，该网站的反侦查意识还是有一点的。如果直接访问，会看到无内容的白屏页面。此时需要一个日本IP来显示该页面的内容。&lt;/p&gt;
&lt;p&gt;至此，我们就能发现该页面的真面目：骗取银行卡信息（卡号、持卡人姓名和其他信息、有效期、CVV等）的钓鱼页面。从而我的域名在被我注册前都被用于做些什么事情也可见一斑。&lt;/p&gt;
&lt;h2&gt;怎么办？&lt;/h2&gt;
&lt;p&gt;作为域名所有者，我已经设置了有效的SPF、DKIM和DMARC记录以有效阻止这些恶意邮件真正抵达收件人邮箱。按照我的现行DMARC规则，所有无法通过SPF或DKIM验证的发件服务器发送的邮件都会在发送违规报告到指定位置后被丢弃。&lt;/p&gt;
&lt;p&gt;是的，某些人仍然可以宣称自己的邮件来自我的域名，这是电子邮件运作的基本原理。但是他们能做的也就只有宣称而已。&lt;/p&gt;
&lt;h2&gt;后记&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;/posts/thank-you-vscode-for-saving-my-file&quot;&gt;VS Code，听我说，谢谢你。&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>关于这些年自建网站的一切</title><link>https://kyki.moe/posts/everything-about-blogging/</link><guid isPermaLink="true">https://kyki.moe/posts/everything-about-blogging/</guid><pubDate>Sat, 20 Apr 2024 22:53:07 GMT</pubDate><content:encoded>&lt;h2&gt;是的，我删掉了很多文章&lt;/h2&gt;
&lt;p&gt;主要是因为看起来过于……腻歪，就好像我为了建站而建站。虽然事实上我确实是通过这段时间的网站建设学到了很多东西，也可以说就是为了建站而建站吧。
另外就是觉得那些文章写得还是有点太水了，或者说过于稚嫩，不是很想继续展示在外面。就像是……黑历史一样。
倒是删掉的都是关于自建网站的内容，总感觉直接丢弃颇有浪费之意，于是便有了这篇文章以及这个标题。&lt;/p&gt;
&lt;h2&gt;关于域名&lt;/h2&gt;
&lt;p&gt;撰稿时，本站使用的域名已经是第二个了。
至于为什么弃用了原来的域名，只能说少不更事选了非常中二的而且现在的我相当不喜欢的一款，哎。
如果关注了本站很久的话应该知道有更换域名的事情，当时我设置了307 - Temporary Redirect来提示访客，现在已经停止重定向，原来的域名也已经在出售中。但是估计真的知道这件事而且不在我交际圈里的人并不存在。无论如何，我并不希望原先的域名出现在任何地方，或是被互联网记住。如果真的知道本站原来的域名，而又恰巧看到原来的域名在任何公开的位置出现，请按照&lt;a href=&quot;/about&quot;&gt;关于&lt;/a&gt;中的邮箱地址联系我，十分感谢。如果是在非公开的位置记录下了本站原来的域名，还请进行更改。&lt;/p&gt;
&lt;h2&gt;关于渲染引擎：&lt;a href=&quot;//hexo.io&quot;&gt;Hexo&lt;/a&gt;和&lt;a href=&quot;//astro.build&quot;&gt;Astro&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;心路&lt;/h3&gt;
&lt;p&gt;从一开始我使用的是Hexo这款“快速、简洁且高效的博客框架”，至于原因，是因为入门时看到了大量有关Hexo的入门教程，这也反映出Hexo社区大、文档完整，在博客框架界的口碑也相当不错。&lt;/p&gt;
&lt;p&gt;期间一直使用的主题是&lt;a href=&quot;https://github.com/iblh/hexo-theme-material&quot;&gt;Material&lt;/a&gt;。
因为从一开始其实是一个Android用户。大概是在&lt;a href=&quot;/posts/Win-to-macOS&quot;&gt;在从Windows转移到macOS后，如何不那么别扭&lt;/a&gt;这篇文章发布前后买了台Mac，然后才慢慢进入了苹果生态。Android用户的话，就很喜欢Google的那套Material Design，而且这个主题当时就排在&lt;a href=&quot;https://hexo.io/themes/&quot;&gt;Hexo官网的主题页面&lt;/a&gt;很前面的位置。遇到这个主题也是一种缘分吧。&lt;/p&gt;
&lt;p&gt;期间因为自己的折腾心就加了各种各样的魔改在主题里，可以去我的fork看一看：&lt;a href=&quot;https://github.com/Kainichy/hexo-theme-material&quot;&gt;https://github.com/Kainichy/hexo-theme-material&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;后来因为看久了有点审美疲劳，再加上Google自己都把Material Design从尖锐的矩形风格迭代成圆润的样式，再加上访问速度真的有点堪忧，再加上……忘了。就由于这些各种各样的原因，我一直盘算着换个主题。悄悄说：本来还打算一年一换的。后来发现自己好像还是有点太忙了，于是一直搁置着换主题的事情。&lt;/p&gt;
&lt;p&gt;一直到2024年4月12日，想到每次Cloudflare Web Analytics给我发摘要邮件都会飙红的指标，我下定决心换一个主题。&lt;/p&gt;
&lt;p&gt;本来打算用Sukka大佬的&lt;a href=&quot;https://github.com/SukkaW/hexo-theme-suka&quot;&gt;Suka&lt;/a&gt;，然后因为有点太简约又想去换个新的，兜兜转转，最后看到了&lt;a href=&quot;https://github.com/saicaca/hexo-theme-vivia&quot;&gt;Vivia&lt;/a&gt;。这个主题好啊，简约又符合当代各个科技厂商都倾向的圆润的大方向，结果一打开就是醒目的：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[!NOTE]
This project is no longer actively maintained. If you are interested in this theme, it is recommended to use &lt;a href=&quot;https://github.com/saicaca/fuwari&quot;&gt;the new Astro version&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;本项目已不再活跃维护，若对本主题感兴趣，建议使用&lt;a href=&quot;https://github.com/saicaca/fuwari&quot;&gt;新的 Astro 版本&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;于是我就自然而然地用了“&lt;a href=&quot;https://github.com/saicaca/fuwari&quot;&gt;新的 Astro 版本&lt;/a&gt;”。后来就是各种各样的迁移忙活了我两个周末，再后来就是你现在看到的这样啦。&lt;/p&gt;
&lt;h3&gt;为什么是Astro&lt;/h3&gt;
&lt;p&gt;对于我来说，Astro引擎加上Fuwari主题的好处还是相当明显的：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;访问速度明显加快&lt;/li&gt;
&lt;li&gt;&lt;s&gt;暂时&lt;/s&gt;缓解审美疲劳&lt;/li&gt;
&lt;li&gt;又能学到新东西了&lt;/li&gt;
&lt;li&gt;Cloudflare Pages自带构建模版：以前用Hexo由于我技术力不够Cloudflare Pages老报错，非得回退到老版本的Pages构建环境才行&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;而其缺点也不少：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;主题与引擎同构，欲更换主题比Hexo麻烦得多，此外主题的更新也成了问题&lt;/li&gt;
&lt;li&gt;对于一些主题来说，可供自定义的选项貌似过少，例如像我使用的Fuwari，如果需要修改文章的路径将是一个大工程&lt;/li&gt;
&lt;li&gt;使用很多插件都相当不方便，例如&lt;a href=&quot;https://docs.astro.build/en/guides/integrations-guide/sitemap/&quot;&gt;@astrojs/sitemap&lt;/a&gt;和&lt;a href=&quot;https://docs.astro.build/en/guides/rss/&quot;&gt;@astrojs/rss&lt;/a&gt;。比起Hexo需要配置的地方多得多&lt;/li&gt;
&lt;li&gt;项目文件夹过于复杂&lt;/li&gt;
&lt;li&gt;社群小，教程少，文档不成熟&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;但麻烦是一时，流畅是长期问题。于是最后权衡之下我留在了Astro。&lt;/p&gt;
&lt;h2&gt;关于静态博客托管服务：&lt;a href=&quot;https://pages.github.com&quot;&gt;GitHub Pages&lt;/a&gt;、&lt;a href=&quot;https://www.netlify.com/&quot;&gt;Netlify&lt;/a&gt;、&lt;a href=&quot;https://vercel.com/&quot;&gt;Vercel&lt;/a&gt;和&lt;a href=&quot;https://pages.cloudflare.com/&quot;&gt;Cloudflare Pages&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;心路&lt;/h3&gt;
&lt;p&gt;一开始还是因为大量教程选择了老牌的GitHub Pages。后来还是因为大量教程尝试了Netlify，试图搭建CMS并失败。后来又因为大量教程尝试了Vercel。最后是Cloudflare Pages最特别，给我发了推广邮件我就去试用了。&lt;/p&gt;
&lt;h3&gt;为什么是Cloudflare Pages&lt;/h3&gt;
&lt;p&gt;最后是因为我用它当权威DNS和CDN而一直用了下去。就是这么简单。颇有种「肥水不流外人田」的美。
其实真要说的话也完全有道理的，能省下很多Cloudflare的CDN回源的时间，从中间环节加快了访问速度。
而且他们碳中和啊。&lt;/p&gt;
&lt;h3&gt;各家服务的客观对比&lt;/h3&gt;
&lt;p&gt;以前对比优缺点，现在对比可用性，哈哈。针对的环境很明确的，不过多赘述。&lt;/p&gt;
&lt;p&gt;GitHub Pages：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;控制台（GitHub主站）连通性不佳&lt;/li&gt;
&lt;li&gt;默认域名连通性不佳&lt;/li&gt;
&lt;li&gt;自定义域名连通性正常，速度一般&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Netlify：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;控制台连通性不佳&lt;/li&gt;
&lt;li&gt;默认域名连通性不佳&lt;/li&gt;
&lt;li&gt;自定义域名连通性正常，速度一般&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Vercel：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;控制台连通性不佳&lt;/li&gt;
&lt;li&gt;默认域名连通性不佳&lt;/li&gt;
&lt;li&gt;自定义域名连通性正常，速度较慢&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Cloudflare Pages：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;控制台连通性正常&lt;/li&gt;
&lt;li&gt;默认域名连通性正常，速度一般&lt;/li&gt;
&lt;li&gt;自定义域名连通性正常，速度一般&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;下面是摘录的一些有关各平台主要功能限制的对比。但是我觉得大部分时候没有必要在意平台限制的，因为基本达不到。&lt;/p&gt;
&lt;p&gt;&amp;lt;details&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;summary&amp;gt;我觉得没有必要的对比&amp;lt;/summary&amp;gt;&lt;/p&gt;
&lt;p&gt;GitHub Pages：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;自定义域名：一个。&lt;/li&gt;
&lt;li&gt;限制：
&lt;ul&gt;
&lt;li&gt;（Git仓库）单个文件大于50MB将受到警告。&lt;/li&gt;
&lt;li&gt;（Git仓库）单个文件大于100MB无法上传。&lt;/li&gt;
&lt;li&gt;（Git仓库）项目总大小「强烈建议」少于5GB。&lt;/li&gt;
&lt;li&gt;每小时可构建10次，每次不超过10min。&lt;/li&gt;
&lt;li&gt;每月流量100GB。
详情可见：https://docs.github.com/en/pages/getting-started-with-github-pages/about-github-pages#guidelines-for-using-github-pages&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Netlify：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;自定义域名：多个。&lt;/li&gt;
&lt;li&gt;限制：
对于每个账户：
&lt;ul&gt;
&lt;li&gt;同时只能构建一个站点。&lt;/li&gt;
&lt;li&gt;每月流量100GB。&lt;/li&gt;
&lt;li&gt;每月构建时间300分钟。
详情可见：https://www.netlify.com/pricing&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Cloudflare Pages：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;自定义域名：100个；&lt;/li&gt;
&lt;li&gt;限制：
&lt;ul&gt;
&lt;li&gt;每月构可构建500次，每次不超过20min。&lt;/li&gt;
&lt;li&gt;文件数量最多20,000个。&lt;/li&gt;
&lt;li&gt;单个文件大小不得超过25MiB。
详情可见：https://developers.cloudflare.com/pages/platform/limits&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Vercel：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;自定义域名：50个。&lt;/li&gt;
&lt;li&gt;限制：
&lt;ul&gt;
&lt;li&gt;每日可构建100次，但每小时不超过32次。每次不超过45min。每月总计不超过100h。&lt;/li&gt;
&lt;li&gt;单个Git仓库支持连接3个Vercel项目。&lt;/li&gt;
&lt;li&gt;每月带宽100次。
详情可见：https://vercel.com/docs/platform/limits&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;lt;/details&amp;gt;&lt;/p&gt;
&lt;p&gt;只能说希望大环境好一点。&lt;/p&gt;
&lt;h2&gt;写在最后&lt;/h2&gt;
&lt;p&gt;很感谢你能看完这篇文章，因为几乎没什么营养，就是一些无用的记录。虽然好像我的大多数文章都是这样。那么就先写到这里，期待接下来在Astro的驱动下我能有更好的写作体验，你能有更好的浏览体验。当然前提是我有心情和时间更新（）。&lt;/p&gt;
&lt;p&gt;此致
顺颂时祺。&lt;/p&gt;
</content:encoded></item><item><title>通过Apple快捷指令更新Cloudflare Gateway绑定IP</title><link>https://kyki.moe/posts/update-cloudflare-gateway-ip-shortcuts/</link><guid isPermaLink="true">https://kyki.moe/posts/update-cloudflare-gateway-ip-shortcuts/</guid><pubDate>Thu, 02 Jun 2022 21:13:20 GMT</pubDate><content:encoded>&lt;h2&gt;TL;DR&lt;/h2&gt;
&lt;p&gt;获取Cloudflare Account ID、包含Account.Zero Trust:Edit权限的Cloudflare API Token、Location的ID后，使用此快捷指令即可更新Cloudflare Gateway绑定IP：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;https://www.icloud.com/shortcuts/8e625a57927b4079a4a682aab430d6aa&lt;/li&gt;
&lt;li&gt;https://kyki.moe/posts/update-Cloudflare-Gateway-IP-shortcuts/Update%20Cloudflare%20Gateway%20IP.shortcut&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;两个链接内容一致，站内链接权当备份。&lt;/p&gt;
&lt;p&gt;根本没&lt;s&gt;仔细&lt;/s&gt;测试过Apple的Shortcuts Setup能不能用的问题。根据我对Apple的认知，很可能会遇到变量导入的问题，尤其是涉及到有两个字符串需要转换为布尔值。如果遇到相关问题，建议直接把你的内容硬编码到快捷指令里，然后给我留个评论，谢谢～&lt;/p&gt;
&lt;p&gt;（我相信都用着Cloudflare Zero Trust而且还能找到这里来的人应该不差这点能力的，吧。）;-）&lt;/p&gt;
&lt;h2&gt;背景&amp;amp;介绍&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;//www.cloudflare.com/zh-cn/products/zero-trust/gateway&quot;&gt;Cloudflare Gateway&lt;/a&gt;是一款运行于DNS层或HTTP层的安全网关。其具有不错的可自定义程度。在基于DNS使用时，其提供IPv4/IPv6 :53 UDP、DoT、DoH几种接入方式。&lt;/p&gt;
&lt;p&gt;在通过IPv4 :53 UDP接入其DNS服务时，由于IPv4地址非常稀缺，每个人分配到的接入点都将是一个相同的Anycast IP地址。因此需要在Cloudflare登记客户端IP地址以进行个性化配置。&lt;/p&gt;
&lt;p&gt;很不幸，Cloudflare没有提供DDNS支持，而我的路由器又不支持DoT、DoH，更糟糕的是，我的ISP到现在都没有提供IPv6互联网……所以很长一段时间我都只能手动进行IP地址更新。&lt;/p&gt;
&lt;p&gt;直到最近我突发奇想，决定通过Cloudflare API对Cloudflare Gateway绑定IP进行定期更新。&lt;/p&gt;
&lt;h2&gt;前提&amp;amp;准备&lt;/h2&gt;
&lt;h3&gt;Cloudflare API Token&lt;/h3&gt;
&lt;p&gt;首先，为了使用Cloudflare API，我们需要一个至少包含Account.Zero Trust:Edit权限的Cloudflare API Token。可以在&lt;a href=&quot;https://dash.cloudflare.com/profile/api-tokens&quot;&gt;https://dash.cloudflare.com/profile/api-tokens&lt;/a&gt;进行生成。&lt;/p&gt;
&lt;h3&gt;Cloudflare Account ID&lt;/h3&gt;
&lt;p&gt;打开&lt;a href=&quot;https://dash.teams.cloudflare.com&quot;&gt;Cloudflare Zero Trust仪表板&lt;/a&gt;，登入账户后，在页面的URL中应该可以非常方便地看到你的Account ID，不做过多赘述。&lt;/p&gt;
&lt;h3&gt;Gateway Location信息&lt;/h3&gt;
&lt;p&gt;生成符合条件的API Token之后，我们需要获取Gateway中对应Location的ID。这一步有两种获取方法。&lt;/p&gt;
&lt;h4&gt;通过网页仪表板获取&lt;/h4&gt;
&lt;p&gt;打开&lt;a href=&quot;https://dash.teams.cloudflare.com&quot;&gt;Cloudflare Zero Trust仪表板&lt;/a&gt;，登入账户后，在边栏选择&lt;code&gt;Gateway &amp;gt; Locations&lt;/code&gt;，并选择或新建一个想要使用的位置，对其进行至少一次编辑（如名称、ECS支持、是否为默认等）。此时你需要记录该Location的名称。&lt;/p&gt;
&lt;p&gt;然后在边栏中转到&lt;code&gt;Logs &amp;gt; Admin&lt;/code&gt;，查看对应的&lt;code&gt;Update location&lt;/code&gt;事件，在log的json中寻找关键字为&lt;code&gt;id&lt;/code&gt;的字符串。注意不是&lt;code&gt;account_id&lt;/code&gt;，也不是&lt;code&gt;network&lt;/code&gt;关键字下的&lt;code&gt;id&lt;/code&gt;。&lt;/p&gt;
&lt;h4&gt;通过API获取&lt;/h4&gt;
&lt;p&gt;执行&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;GET https://api.cloudflare.com/client/v4/accounts/:identifier/gateway/locations
    Header: Authorization: Bearer :token
    Header: Content-Type: application/json
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;即可获得你所有可用的Gateway Locations。在返回的json中寻找关键字为&lt;code&gt;id&lt;/code&gt;以及&lt;code&gt;name&lt;/code&gt;的字符串。如果你使用curl，则可以执行：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;curl -X GET &quot;https://api.cloudflare.com/client/v4/accounts/:identifier/gateway/locations&quot; \
     -H &quot;Authorization: Bearer :token&quot; \
     -H &quot;Content-Type: application/json&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这一步中的&lt;code&gt;:identifier&lt;/code&gt;是指你的Cloudflare Account ID，&lt;code&gt;:token&lt;/code&gt;是指你的API Token，下文同样。注意在替换为你的个人内容时不要保留&lt;code&gt;:&lt;/code&gt;，例如，如果你的Account ID是&lt;code&gt;example123456&lt;/code&gt;，你应该使用&lt;code&gt;https://api.cloudflare.com/client/v4/accounts/example123456/gateway/locations&lt;/code&gt;而非&lt;code&gt;https://api.cloudflare.com/client/v4/accounts/:example123456/gateway/locations&lt;/code&gt;。&lt;/p&gt;
&lt;h2&gt;编写快捷指令&lt;/h2&gt;
&lt;p&gt;这一步建议在macOS中进行，因为iOS上的快捷指令对HTTP请求的配置界面很奇怪。我用着并不是很明白。如果你没有macOS设备，可以使用前文中已编写完毕的快捷指令~~，或者硬着头皮上~~。&lt;/p&gt;
&lt;p&gt;由于作者使用的是英文版操作系统，可能一些翻译不是非常准确，敬请谅解。&lt;/p&gt;
&lt;p&gt;主要流程为：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;获取当前IP地址：外部，IPv4

获取URL内容：
    https://api.cloudflare.com/client/v4/accounts/:identifier/gateway/locations/:uuid
    方法为PUT
    Header：
        Content-Type: application/json
        Authorization: Bearer :token
    请求正文格式为json，包含：
        networks，类型为数组/阵列（Array），包含：
            一个字典（Dictionary），包含：
                network，类型为字符串/文本（Text），值为:ip/32
        name，类型为字符串，值为:name
        client_default，类型为布尔（Boolean），值为:client_default
        ecs_support，类型为布尔，值为:ecs_support
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;此处&lt;code&gt;:identifier&lt;/code&gt;和&lt;code&gt;:token&lt;/code&gt;的定义与上文（#通过API获取）一致，不再赘述。&lt;code&gt;:uuid&lt;/code&gt;指需要更新的Location ID。&lt;code&gt;:ip&lt;/code&gt;指你在快捷指令的第一步中获取的外部IPv4地址。&lt;code&gt;:name&lt;/code&gt;指你希望将此Location重命名为的名称。若不欲重命名，填写为原来的名称即可。&lt;code&gt;:client_default&lt;/code&gt;指你是否希望此Location成为默认选项（目前我尚不知道此选项的作用）。注意，如果你希望将此项目的值设为&lt;code&gt;False&lt;/code&gt;，你需要保证你有一个另外的Location作为默认值，否则其值必须为&lt;code&gt;True&lt;/code&gt;。&lt;code&gt;:ecs_support&lt;/code&gt;指你是否希望此Location的DNS服务启用ECS，建议设为&lt;code&gt;True&lt;/code&gt;来提高性能。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://api.cloudflare.com/#zero-trust-gateway-locations-update-zero-trust-gateway-location&quot;&gt;Cloudflare API Documentation&lt;/a&gt;给出的样例请求正文格式为：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{&quot;name&quot;:&quot;Austin Office Location&quot;,&quot;networks&quot;:[&quot;192.0.2.1&quot;],&quot;client_default&quot;:&quot;false&quot;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这是不对的。如果按照此方式进行请求，我们将得到一个错误，消息为&lt;code&gt;json: cannot unmarshal string into Go struct field LocationRequest.networks of type api.NetworkRecordJSON&lt;/code&gt;以及&lt;code&gt;json: cannot unmarshal string into Go struct field LocationRequest.client_default of type bool&lt;/code&gt;。我不知道Cloudflare为什么会在一个示例里出现两处错误。正确的样例请求正文格式应为：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{&quot;name&quot;:&quot;Austin Office Location&quot;,&quot;networks&quot;:[{&quot;network&quot;: &quot;192.0.2.1/24&quot;}],&quot;client_default&quot;:false}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;此处我也遇到了问题。搜索后参考了&lt;a href=&quot;https://community.cloudflare.com/t/create-update-teams-location-documentation-error/324335&quot;&gt;Cloudflare Community里的一篇文章&lt;/a&gt;解决了问题。十分感谢。&lt;/p&gt;
&lt;p&gt;至此，可以直接通过Apple平台上的快捷指令完成对Cloudflare Gateway绑定IP的更新了。后话就是建议添加自动化获得更加体验了。&lt;/p&gt;
</content:encoded></item><item><title>Face ID全新戴口罩识别功能测速</title><link>https://kyki.moe/posts/face-id-with-mask/</link><guid isPermaLink="true">https://kyki.moe/posts/face-id-with-mask/</guid><pubDate>Fri, 28 Jan 2022 14:04:43 GMT</pubDate><content:encoded>&lt;p&gt;题图来自&lt;a href=&quot;https://www.macrumors.com/2021/02/01/ios-14-5-unlock-iphone-with-apple-watch/&quot;&gt;MacRumors&lt;/a&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;本文章有视频版本，欢迎观看：
&amp;lt;iframe src=&quot;//player.bilibili.com/player.html?aid=978589854&amp;amp;bvid=BV1444y1p7qN&amp;amp;cid=494729663&amp;amp;page=1&amp;amp;high_quality=1&amp;amp;danmaku=1&quot; allowfullscreen=&quot;allowfullscreen&quot; width=&quot;100%&quot; height=&quot;500&quot; scrolling=&quot;no&quot; frameborder=&quot;0&quot; sandbox=&quot;allow-top-navigation allow-same-origin allow-forms allow-scripts&quot;&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Apple在北京时间今日凌晨发布了iOS 15.4的第一个开发者预览版。其中包含一个很亮眼的新功能：Face ID可以识别佩戴口罩的脸了。
不同于之前iOS 14.5中发布的通过Apple Watch解锁，之前的功能受信号环境干扰较大。而这次的功能并不需要你拥有Apple Watch。也就是说，iPhone终于可以依靠自身的Face ID组件来识别被口罩覆盖的面部了。&lt;/p&gt;
&lt;p&gt;除开安全性，我们最关心的便是解锁速度。那么让我来测试一下戴口買与不載口置时Face ID识别速度区别有多大。&lt;/p&gt;
&lt;h2&gt;测试方法：&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;通过Mac上的QuickTime来录制iPhone的屏幕&lt;/li&gt;
&lt;li&gt;将录制的视频导入Final Cut Pro&lt;/li&gt;
&lt;li&gt;对Face ID动画的帧数进行计数&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;不戴口罩与戴口罩的情況分别测试。
为了计数方便，我在将视频导入Final Cut Pro时选择的帧率为60fps，实际视频帧率低于该值。
动画的起始与结束帧均计算在内。&lt;/p&gt;
&lt;h2&gt;测试条件：&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;设备型号为iPhone 12&lt;/li&gt;
&lt;li&gt;作者始终佩戴同一副眼镜&lt;/li&gt;
&lt;li&gt;自然光源始终从作者的右侧照入&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;以下是测试结果：&lt;/h2&gt;
&lt;p&gt;首先是不戴口罩的情况：&lt;/p&gt;
&lt;p&gt;可以看到动画起始帧为6:30。
&lt;img src=&quot;https://pic4.zhimg.com/80/v2-48b8329e859ebf8462a87fa6c01b9754.png&quot; alt=&quot;Full Face Beginning&quot; /&gt;
动画结束帧为7:1。
&lt;img src=&quot;https://pic4.zhimg.com/80/v2-d72ac67f5a88cb3e5548c10f2a8bff44.png&quot; alt=&quot;Full Face End&quot; /&gt;&lt;/p&gt;
&lt;p&gt;共计有32帧。原视频帧率为53.241fps。计算得Face ID不戴口罩情况下识别时间约为601ms。&lt;/p&gt;
&lt;p&gt;然后是佩戴口罩，触发iOS新功能的情况：&lt;/p&gt;
&lt;p&gt;动画起始帧为7:28。
&lt;img src=&quot;https://pic4.zhimg.com/80/v2-ccd3399c8fd2a5981a1e60f12874d47f.png&quot; alt=&quot;Mask On Beginning&quot; /&gt;
动画结束帧为8:20。
&lt;img src=&quot;https://pic4.zhimg.com/80/v2-ae50b10687561021c518fa7d474377b3.png&quot; alt=&quot;Mask On End&quot; /&gt;&lt;/p&gt;
&lt;p&gt;共计有53帧。原视频帧率为56.06fps。计算得Face ID佩戴口罩情況下识别时间约为945ms。&lt;/p&gt;
&lt;h2&gt;复盘一下：&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;不戴口罩识别用时约601ms&lt;/li&gt;
&lt;li&gt;佩戴口罩识别用时约945ms&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;慢了大约57.24%。总体主观感觉，能感觉到慢了，但不多。&lt;/p&gt;
</content:encoded></item><item><title>App+1: 带壳截图工具capXDR</title><link>https://kyki.moe/posts/app-capxdr/</link><guid isPermaLink="true">https://kyki.moe/posts/app-capxdr/</guid><pubDate>Sat, 09 Jan 2021 17:55:36 GMT</pubDate><content:encoded>&lt;p&gt;截图，对于大部分用户来说都是非常常用的一个操作，对于一些科技行业的文字工作者或许使用得更是无比频繁。&lt;/p&gt;
&lt;p&gt;我们也常常想要生成像设备厂商宣传页面上那样的带有设备外型的截图，像这样的：
&lt;img src=&quot;https://pic4.zhimg.com/80/v2-33e0c7af9074d62b00bfeb1d34f5bbaf.jpg&quot; alt=&quot;MacBook Pro 16 inch&quot; /&gt;&lt;/p&gt;
&lt;p&gt;对于移动设备已经有了一些App来为我们进行后期处理，比如Snapmod。
那么在桌面端有没有办法做出这么漂亮的图片而不打开专业的图片处理工具呢？&lt;/p&gt;
&lt;p&gt;少数派给出了使用截图神器ShareX的方案：&lt;a href=&quot;https://sspai.com/post/64354&quot;&gt;一日一技 | 使用 ShareX 快速为截图套壳 - 少数派&lt;/a&gt;
然而看起来实在是太麻烦了。还涉及到抠图、配置文件修改之类的操作实在是难以操作。&lt;/p&gt;
&lt;p&gt;所以我希望介绍一款能够轻松完成截图加壳处理的App：capXDR。
这是一个民间大佬开发的macOS App。目前只有Intel版本，M1用户也可以通过Rosetta运行。
看一下设置菜单好了：
&lt;img src=&quot;https://pic4.zhimg.com/80/v2-210a45c6385e7b18306e4c0d0c02df96.png&quot; alt=&quot;capXDR设置菜单&quot; /&gt;
作者画了不少机壳模版了，可以通过导入的方式选择。&lt;/p&gt;
&lt;p&gt;下载地址：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;App本体：https://cdn.jsdelivr.net/lihaoyun6/capXDR-plugins/app/capXDR.dmg&lt;/li&gt;
&lt;li&gt;插件列表：https://github.com/lihaoyun6/capXDR-plugins/blob/master/thumbs/textlist.md&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;项目repo地址：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;GitHub：https://github.com/lihaoyun6/capXDR-plugins&lt;/li&gt;
&lt;li&gt;Gitee：https://gitee.com/lihaoyun/capXDR-plugins&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>关于隐私</title><link>https://kyki.moe/posts/privacy/</link><guid isPermaLink="true">https://kyki.moe/posts/privacy/</guid><pubDate>Sat, 19 Dec 2020 23:05:50 GMT</pubDate><content:encoded>&lt;p&gt;你或许想不到，一个静态博客居然会有隐私说明。
为什么是说明而不是条款呢？因为如果你看到了这里，你已经把我的小破站看得很深入了……可以说使用即同意吧。&lt;/p&gt;
&lt;p&gt;你的数据将被通过以下方式收集：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Cloudflare Web Analytics的JavaScript所得数据：https://static.cloudflareinsights.com/beacon.min.js；&lt;/li&gt;
&lt;li&gt;Cloudflare CDN与客户端的连接数据；&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;简要地说明一下你被收集的数据：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;你访问本站使用的的User-Agent字符串（用于分析你使用的浏览器、设备类型和操作系统）；&lt;/li&gt;
&lt;li&gt;你访问本站的哪个子域名；&lt;/li&gt;
&lt;li&gt;你从什么网站跳转到本站；&lt;/li&gt;
&lt;li&gt;你访问本站的哪些目录/页面；&lt;/li&gt;
&lt;li&gt;你的IP地址（用于了解你所在的国家/地区和模糊的访客识别）；&lt;/li&gt;
&lt;li&gt;你使用的HTTP版本和TLS版本；&lt;/li&gt;
&lt;li&gt;你在本站停留的时间以及进行的操作（包括但不限于鼠标滚动、光标移动、鼠标点击）。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;你被收集的数据会被如何使用：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;我不会对你的数据做任何处理，仅供我个人参考；&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;当然，如果你不愿意被收集如此详细的数据，完全可以直接屏蔽前文提到的URL来防止采集你数据的JavaScript脚本被执行。如果你不希望你的IP地址被收集，当然也可以直接通过Tor或代理来访问本站。这里没有任何&lt;s&gt;恶心的&lt;/s&gt;类似BlockAdBlock之类的限制。&lt;/p&gt;
</content:encoded></item><item><title>来点音乐</title><link>https://kyki.moe/posts/music/</link><guid isPermaLink="true">https://kyki.moe/posts/music/</guid><pubDate>Sat, 12 Dec 2020 11:45:15 GMT</pubDate><content:encoded>&lt;p&gt;这个页面是用来分享一些我喜欢的音乐的。由于我使用的是Apple Music，如果你并不使用的话，可能这个页面对你来说并不是非常方便。无论如何，你都可以选择阅读我的播放列表。&lt;/p&gt;
&lt;p&gt;所有内容在Apple Music US店面提供。&lt;/p&gt;
&lt;h2&gt;我的Apple Music个人资料&lt;/h2&gt;
&lt;p&gt;关注&lt;a href=&quot;https://music.apple.com/profile/RiverYkb&quot;&gt;我的Apple Music&lt;/a&gt;，更方便地收听我喜欢的音乐。&lt;/p&gt;
&lt;h2&gt;只有一个的播放列表&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://music.apple.com/cn/playlist/test-audio/pl.u-Ymb09K0HPNd8YmA&quot;&gt;Test Audio&lt;/a&gt;
收集了一些我认为比较能够体现设备音频素质的音乐，且不同的曲目有不同的特点。得益于Apple Music Hi-Res Lossless的高音质，如果你有DAC等设备，这将是非常不错的选择。另外，建议你在不同的乐曲中分别选段播放，播放整个列表将耗费非常多时间。&lt;/p&gt;
&lt;h2&gt;Apple Music自动生成：电台&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://music.apple.com/cn/station/kai-yangs-station/ra.u-444d854e19f7a42a1abb70ff757aa95f&quot;&gt;Kai Yang&apos;s Station&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://music.apple.com/cn/station/discovery-station/ra.q-GAI6IDQ0NGQ4NTRlMTlmN2E0MmExYWJiNzBmZjc1N2FhOTVm&quot;&gt;Kai Yang&apos;s Discovery Station&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Apple Music自动生成：播放列表&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://music.apple.com/cn/playlist/new-music-mix/pl.pm-d5779e520ff52d7f92a16adeffe1e54a&quot;&gt;New Music Mix - 音乐新发现&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://music.apple.com/cn/playlist/favourites-mix/pl.pm-d5779e520ff52d7f10a18ba22bf28b77&quot;&gt;Favourites Mix - 最爱精选&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://music.apple.com/cn/playlist/get-up-mix/pl.pm-d5779e520ff52d7fe0af400db5e3b8f3&quot;&gt;Get Up! Mix - 能量充电&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://music.apple.com/cn/playlist/chill-mix/pl.pm-d5779e520ff52d7f67ef78f781437c5b&quot;&gt;Chill Mix - 放松歌单&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Apple Music自动生成：Replay播放列表&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://music.apple.com/cn/playlist/replay-2023/pl.rp-GjjDsvPbJzwR&quot;&gt;Replay 2023&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://music.apple.com/cn/playlist/replay-2022/pl.rp-DbbMcLG4ZN5a&quot;&gt;Replay 2022&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://music.apple.com/cn/playlist/replay-2021/pl.rp-0AA5clnpj4PL&quot;&gt;Replay 2021&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://music.apple.com/cn/playlist/replay-2020/pl.rp-755pcRLOMn2b&quot;&gt;Replay 2020&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://music.apple.com/cn/playlist/replay-2019/pl.rp-8AAwfX1ZAvMY&quot;&gt;Replay 2019&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://music.apple.com/cn/playlist/replay-2018/pl.rp-P44YCYREzAeX&quot;&gt;Replay 2018&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;生成你的Replay播放列表：&lt;a href=&quot;https://replay.music.apple.com&quot;&gt;REPLAY&lt;/a&gt;。打开后登录你的Apple ID然后Get Replay Mix就好。&lt;/p&gt;
&lt;p&gt;格式为：&lt;code&gt;歌手 - 曲目&lt;/code&gt;，以换行符分隔。你可以通过任何你偏好的服务使用它们。&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;希望能满足你的耳朵。&lt;/p&gt;
</content:encoded></item><item><title>Bug+1: 用终端commit GitHub远程仓库时用户识别错误</title><link>https://kyki.moe/posts/bug-github-commits-error-user/</link><guid isPermaLink="true">https://kyki.moe/posts/bug-github-commits-error-user/</guid><pubDate>Sat, 24 Oct 2020 00:08:29 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;这是一篇比较水的文章。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;闲着没事去&lt;a href=&quot;https://github.com/SkyYkb/SkyYkb.github.io&quot;&gt;本博客所在的GitHub repo&lt;/a&gt;看了看，结果发现一堆其他人的commit。
&lt;img src=&quot;https://pic4.zhimg.com/80/v2-17e1714026535889e6dedfa10131f363_1440w.png&quot; alt=&quot;本repo的commit历史页面&quot; /&gt;&lt;/p&gt;
&lt;p&gt;遂点开commit详情查看内容，发现确实是我提交的东西。。。
这我就很奇怪了，于是打开那个人的首页，发现并没有看到有在我的repo里有过任何提交。。。
&lt;img src=&quot;https://pic4.zhimg.com/80/v2-630fc7f96e31ee26182c8d7dc9225531_1440w.png&quot; alt=&quot;神秘人物的GitHub首页&quot; /&gt;&lt;/p&gt;
&lt;p&gt;难道这是个bug？&lt;/p&gt;
&lt;p&gt;于是乎我去联系了GitHub Support，发现是我在复制GitHub提供的no-reply邮箱地址的时候少了一位，结果出现了这样的问题。&lt;/p&gt;
&lt;p&gt;但是我很好奇的是，为什么会出现这样的问题，因为我只是填错了邮箱地址，但是我的GitHub Personal Access Token是正确的。也就是说，我用一个不存在的邮箱地址，以及SkyYkb的Token，就能把commit放到别人的名义下面去，虽然并不会在别人的首页显示。&lt;/p&gt;
&lt;p&gt;仿佛看到了什么危险的东西啊。。。&lt;/p&gt;
&lt;h2&gt;解决方案&lt;/h2&gt;
&lt;p&gt;经过一番Google，发现一个&lt;a href=&quot;https://gist.github.com/adefrutoscasado/6573392a5fa916b95529458aba79a73f&quot;&gt;Gist&lt;/a&gt;提供了解决方案：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git rebase -i HEAD~&amp;lt;number of commits&amp;gt; -x &quot;git commit --amend --author &apos;Author Name &amp;lt;author.name@mail.com&amp;gt;&apos; --no-edit&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;但是缺点是会导致在GitHub上显示出的commit时间是你执行之后的时间。
但无论如何作者变回来了。
但是在GitHub的边栏仍然会留有那个神秘人物的名字。
&lt;img src=&quot;https://pic4.zhimg.com/80/v2-b38d808fb1c20aacd1b4e833b8f73a8d_1440w.png&quot; alt=&quot;边栏上的Contributors&quot; /&gt;&lt;/p&gt;
&lt;p&gt;这个时候就直接找&lt;a href=&quot;https://support.github.com&quot;&gt;GitHub Support&lt;/a&gt;说明情况就可以了。或者稍微等一等也可以。&lt;/p&gt;
</content:encoded></item><item><title>我们为什么需要HTTP/3</title><link>https://kyki.moe/posts/why-http3/</link><guid isPermaLink="true">https://kyki.moe/posts/why-http3/</guid><pubDate>Sat, 17 Oct 2020 22:09:08 GMT</pubDate><content:encoded>&lt;h2&gt;什么是&lt;a href=&quot;https://zh.wikipedia.org/wiki/HTTP/3&quot;&gt;HTTP/3&lt;/a&gt;？&lt;/h2&gt;
&lt;p&gt;继&lt;a href=&quot;https://zh.wikipedia.org/wiki/%E8%B6%85%E6%96%87%E6%9C%AC%E4%BC%A0%E8%BE%93%E5%8D%8F%E8%AE%AE#%E7%89%88%E6%9C%AC#HTTP/1.1&quot;&gt;HTTP/1.1&lt;/a&gt;和&lt;a href=&quot;https://zh.wikipedia.org/wiki/HTTP/2&quot;&gt;HTTP/2&lt;/a&gt;之后的全新版本HTTP协议。&lt;/p&gt;
&lt;p&gt;HTTP/3协议废除了TCP协议，改用&lt;a href=&quot;https://zh.wikipedia.org/wiki/QUIC&quot;&gt;QUIC&lt;/a&gt;。全名叫&lt;strong&gt;Q&lt;/strong&gt;uick &lt;strong&gt;U&lt;/strong&gt;DP &lt;strong&gt;I&lt;/strong&gt;nternet &lt;strong&gt;C&lt;/strong&gt;onnection，读作“quick”，~~一听就知道很快嘛。~~从名字我们不难看出，这是个基于&lt;a href=&quot;https://zh.wikipedia.org/wiki/%E7%94%A8%E6%88%B7%E6%95%B0%E6%8D%AE%E6%8A%A5%E5%8D%8F%E8%AE%AE&quot;&gt;UDP&lt;/a&gt;的协议。大佬们就是用这个80年代协议加上个传输安全，成了QUIC。&lt;/p&gt;
&lt;p&gt;再说说QUIC的前身gQUIC。其实早在Chrome 55的时候Google就已经实现了gQUIC协议，然后添加了一个Chrome flag，而且现在还存在，使用Chrome的读者可以到&lt;a&gt;chrome://flags/#enable-quic&lt;/a&gt;进行考古。但是gQUIC也不同于QUIC，它只能用于发送HTTP流量，而QUIC除了应用在了HTTP/3，还可以用于发送DNS、SSH、Telnet之类的流量。完全取代UDP应该问题不大。&lt;/p&gt;
&lt;p&gt;在2015年，Google把QUIC提交到了&lt;a href=&quot;https://zh.wikipedia.org/wiki/IETF&quot;&gt;IETF&lt;/a&gt;，然后整出来一个叫HTTP-over-QUIC的东西，又后来改了个名字，称为HTTP/3。&lt;/p&gt;
&lt;h2&gt;HTTP/2是怎么运作的？&lt;/h2&gt;
&lt;p&gt;要说新技术，肯定要把老技术拿出来说一说。&lt;/p&gt;
&lt;p&gt;HTTP/2以及之前所有版本的HTTP协议，都是基于&lt;a href=&quot;https://zh.wikipedia.org/wiki/%E4%BC%A0%E8%BE%93%E6%8E%A7%E5%88%B6%E5%8D%8F%E8%AE%AE&quot;&gt;TCP&lt;/a&gt;协议构建的。在你的设备与服务器开始安全的（经过&lt;a href=&quot;https://zh.wikipedia.org/wiki/TLS&quot;&gt;TLS&lt;/a&gt;加密的）交换你想要的数据之前，他们首先需要建立连接，然后进行三次握手，你的设备就能确定服务器的身份，然后开始传输加密的数据。（这里假设你不想要握手时候证书之类的数据，当然除了应用程序也没什么人会想要这个）&lt;/p&gt;
&lt;h2&gt;那它有什么不同？好在哪里？&lt;/h2&gt;
&lt;p&gt;&lt;s&gt;唯一的不同，是处处都不同。&lt;/s&gt;（老苹果了）&lt;/p&gt;
&lt;p&gt;从一开始你可能就要想了，UDP不是上世纪80年代的&lt;s&gt;比站长还老的&lt;/s&gt;东西了吗？怎么还翻出来炒冷饭呢？我们知道，DNS协议就是基于UDP实现的，一大原因就是因为它的速度。就算服务器远在灯塔国，一个基于UDP的DNS请求去回一趟（注意是去了又回来）都只用100+ms。&lt;/p&gt;
&lt;p&gt;于是从上文不难得出答案，那就是快，因为不需要建立连接，原先的TLS三次握手被简化为一次。同时还具有很好的兼容性，HTTP/3在QUIC的基础上仍然支持了传统的TLS三次握手。&lt;/p&gt;
&lt;p&gt;同时，不需要建立连接还带来了新的好处，就是免中断。在TCP连接建立好之后，如果你的网络环境在传输过程中发生了改变，如你突然连接上了虚拟专用网络，又或者是你从无线局域网跑到了蜂窝移动数据，通常你就需要重新建立连接来传输完整的数据。在Chromium浏览器中，这体现为“ERR_NETWORK_CHANGED”的报错。于是你就需要刷新页面重新加载了。&lt;/p&gt;
&lt;p&gt;但QUIC不需要，他只管发数据包，反正没有连接。但是这里又有一个转折了：如果你的网络环境发生了改变，你的公网IP势必会发生变化，这样如果服务器还往原来的地方发数据包，你岂不是收不到了？这个时候，你的设备往往只需要朝服务器再发一个数据包，包含了刚开始握手时给的唯一ID，并且要求服务器更改传输地址就可以了。&lt;/p&gt;
&lt;p&gt;并且不同于TCP完全由操作系统实现，QUIC通过应用程序层面实现的方式不需要理会系统的优化程度，只管自己实现就好。&lt;/p&gt;
&lt;p&gt;综上，我能看到的最舒服和最迫切的应用前景就是DNS了。传统的UDP DNS太不安全，轻松劫持，DoT、DoH三次握手太慢，DNSSec又不是大多域名都启用，所以DNS这块应用HTTP/3可以说是完美解决大部分问题。&lt;/p&gt;
&lt;h2&gt;那它难道没有缺点？&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Every coin has 2 sides.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;它肯定是有缺点的。但其实都不是它本身的缺点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;浏览器目前对HTTP/3的支持尚不完善，Chrome、Edge、Firefox都是只有每夜构建版才支持。（前两者的叫Canary，最后者的叫Nightly）甚至还需要加flag或者config。Curl甚至还得自己编译。&lt;/li&gt;
&lt;li&gt;由于NAT设备优化的问题，可能会使丢包率高于原先的TCP连接。&lt;/li&gt;
&lt;li&gt;有些NAT设备会重写UDP报文的header，然后当场爆炸。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;完。&lt;/p&gt;
</content:encoded></item><item><title>在从Windows转移到macOS后，如何不那么别扭</title><link>https://kyki.moe/posts/win-to-macos/</link><guid isPermaLink="true">https://kyki.moe/posts/win-to-macos/</guid><pubDate>Sun, 10 May 2020 12:24:37 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;经历相关：从Windows转移到macOS约半年时间。
本文基于从Windows 10 1909切换到macOS Catalina撰写。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;你当然可以通过直接安装Windows来解决使用习惯的问题，但是那样就失去了Mac的灵魂，也会导致性能、优化弱鸡。
所以我推荐通过安装第三方软件解决问题。
要解决麻烦，首先要知道区别在哪里。在我体验macOS之后，有比较强烈的缺失感的有：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;窗口贴边吸附&lt;/li&gt;
&lt;li&gt;剪贴板历史记录&lt;/li&gt;
&lt;li&gt;一个「比较好」的压缩软件&lt;/li&gt;
&lt;li&gt;NTFS读写&lt;/li&gt;
&lt;li&gt;开始菜单&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;于是本文将分为四个部分推荐软件。&lt;/p&gt;
&lt;h2&gt;1. 窗口贴边吸附&lt;/h2&gt;
&lt;p&gt;一说到这个，肯定会有人提到Magnet。
但我不推荐它。因为它在App Store要¥12才能使用。
&lt;img src=&quot;https://pic1.zhimg.com/80/v2-cc0b0cade4175dc9105bd619fdd45f54_1440w.jpg&quot; alt=&quot;Magnet on the Mac App Store&quot; /&gt;
这就非常之难受：难道Windows自带的功能我macOS要用第三方软件不说，还得付钱？
所以我发现了这样一款挺不错的软件：&lt;strong&gt;Rectangle&lt;/strong&gt;
这个软件支持好多种窗口位置，看图：
&lt;img src=&quot;https://pic2.zhimg.com/80/v2-c5653017debc38f81f8fd2469ac49e21_1440w.jpg&quot; alt=&quot;Rectangle main&quot; /&gt;
并且每一个都支持自定义快捷方式：
&lt;img src=&quot;/posts/Win-to-macOS/rec-shortcuts.webp&quot; alt=&quot;Rectangle shortcuts&quot; /&gt;
支持鼠标拖拽贴边隐藏。体验下来基本可以做到Windows用户不别扭、直觉操作的水平。
下载地址：https://github.com/rxhanson/Rectangle/releases/latest&lt;/p&gt;
&lt;h2&gt;2. 剪贴板历史记录&lt;/h2&gt;
&lt;p&gt;Windows 10某个版本中，加入了一个功能，叫做剪贴板历史记录：
&lt;img src=&quot;/posts/Win-to-macOS/Win-clipboard.webp&quot; alt=&quot;Windows Clipboard&quot; /&gt;
这个功能非常人性化、方便啊，只需要按下Windows徽标键+V就能呼出剪贴板历史记录，双击直接粘贴，就不用跑来跑去。用过这个功能的人应该都是深有体会。
其实macOS也有这样的第三方软件，叫CopyLess 2。
&lt;img src=&quot;https://pic4.zhimg.com/80/v2-f699ddab57177462caf65cd9994f2faf_1440w.jpg&quot; alt=&quot;CopyLess 2&quot; /&gt;
主界面整体而言比Windows更修长，并且还多了复制来源的软件。在安装助理程序之后，还能支持双击直接粘贴到当前激活的编辑框。
那Pro版本有啥功能呢？&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;iCloud同步&lt;/li&gt;
&lt;li&gt;最多保留1000个粘贴条目&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;其实我觉得性价比并不高。因为我到现在也还没碰到免费版的条目数量限制……
并且还有Windows没有的特色功能：连串拷贝&amp;amp;粘贴。你可以通过CopyLess来不断复制，然后一并粘贴到一个编辑框中。
&lt;img src=&quot;https://pic1.zhimg.com/80/v2-319d8ee95f8fad0499a844c4e7f9f080_1440w.jpg&quot; alt=&quot;CopyLess 2 in the MAS&quot; /&gt;
下载地址：&lt;a href=&quot;https://apps.apple.com/cn/app/copyless-2/id993841014&quot;&gt;CopyLess 2&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;3. 一个「比较好」的压缩软件&lt;/h2&gt;
&lt;p&gt;Windows下面，有一个非常好用的软件Bandizip。它当然也有macOS版本，不过并不是免费的，似乎费用还挺高。
这里推荐eZip。功能不赘述了，基本与Bandizip齐平。并且支持在压缩时忽略macOS系统临时文件，对Windows用户更友好。
下载地址：&lt;a href=&quot;https://ezip.awehunt.com/?locale=zh-CN&quot;&gt;eZip - 专为 macOS 而设计的压缩软件！&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;4. NTFS读写&lt;/h2&gt;
&lt;p&gt;这里也有几款非常有名的软件，如Paragon、Tuxera之类的软件。但是它们都收费，都收费！
这里推荐Mounty这款体积非常非常小的插件：
&lt;img src=&quot;https://pic2.zhimg.com/80/v2-44314c53f96265cafb1c7779aa7029c1_1440w.png&quot; alt=&quot;Mounty size&quot; /&gt;
完全免费，随用随开。它并没有图形界面，启动后只会在菜单栏显示一个小图标：
&lt;img src=&quot;https://pic4.zhimg.com/80/v2-e550d14c4c0fed40b2d0421d6e0d56ff_1440w.jpg&quot; alt=&quot;Mounty main&quot; /&gt;
然后就可以实现NTFS读写了。非常方便。
安装方法：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Homebrew安装：
&lt;code&gt;brew cask install mounty&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;dmg直接安装：
https://mounty.app/releases/Mounty.dmg&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;5. 开始菜单&lt;/h2&gt;
&lt;p&gt;其实macOS并不是没有开始菜单，只是拆分到了几处：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;位于左上角Apple Logo的电源菜单&lt;/li&gt;
&lt;li&gt;Launchpad&lt;/li&gt;
&lt;li&gt;访达边栏的目录快捷方式&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;然而有没有办法可以合在一起呢？
很遗憾，没有。但是可以稍微曲线救国一下。因为大多数Windows用户打开开始菜单就是奔着应用程序去的，所以我们可以设置一个触发角（系统偏好设置》桌面&amp;amp;屏幕保护程序》屏幕保护程序》触发角），在左下角的地方直接呼出Launchpad。
&lt;img src=&quot;https://pic2.zhimg.com/80/v2-1114f80f109ea8fc10a0a5f5375e88d9_1440w.jpg&quot; alt=&quot;Hot Corner&quot; /&gt;
这样当你鼠标移动到屏幕左下角的时候，就会弹出Launchpad。也算是曲线救国。&lt;/p&gt;
&lt;p&gt;结尾。&lt;/p&gt;
</content:encoded></item><item><title>Include Video in the Posts</title><link>https://kyki.moe/posts/video/</link><guid isPermaLink="true">https://kyki.moe/posts/video/</guid><description>This post demonstrates how to include embedded video in a blog post.</description><pubDate>Mon, 01 Jan 2001 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Just copy the embed code from YouTube or other platforms, and paste it in the markdown file.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;---
title: Include Video in the Post
published: 2023-10-19
// ...
---

&amp;lt;iframe width=&quot;100%&quot; height=&quot;468&quot; src=&quot;https://www.youtube.com/embed/5gIf0_xpFPI?si=N1WTorLKL0uwLsU_&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allowfullscreen&amp;gt;&amp;lt;/iframe&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;YouTube&lt;/h2&gt;
&lt;p&gt;&amp;lt;iframe width=&quot;100%&quot; height=&quot;468&quot; src=&quot;https://www.youtube.com/embed/5gIf0_xpFPI?si=N1WTorLKL0uwLsU_&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; allowfullscreen&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/p&gt;
&lt;h2&gt;Bilibili&lt;/h2&gt;
&lt;p&gt;&amp;lt;iframe width=&quot;100%&quot; height=&quot;468&quot; src=&quot;//player.bilibili.com/player.html?bvid=BV1fK4y1s7Qf&amp;amp;p=1&quot; scrolling=&quot;no&quot; border=&quot;0&quot; frameborder=&quot;no&quot; framespacing=&quot;0&quot; allowfullscreen=&quot;true&quot;&amp;gt; &amp;lt;/iframe&amp;gt;&lt;/p&gt;
</content:encoded></item><item><title>Simple Guides for Fuwari</title><link>https://kyki.moe/posts/guide/</link><guid isPermaLink="true">https://kyki.moe/posts/guide/</guid><description>How to use this blog template.</description><pubDate>Mon, 01 Jan 2001 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;Cover image source: &lt;a href=&quot;https://image.civitai.com/xG1nkqKTMzGDvpLrqFT7WA/208fc754-890d-4adb-9753-2c963332675d/width=2048/01651-1456859105-(colour_1.5),girl,_Blue,yellow,green,cyan,purple,red,pink,_best,8k,UHD,masterpiece,male%20focus,%201boy,gloves,%20ponytail,%20long%20hair,.jpeg&quot;&gt;Source&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This blog template is built with &lt;a href=&quot;https://astro.build/&quot;&gt;Astro&lt;/a&gt;. For the things that are not mentioned in this guide, you may find the answers in the &lt;a href=&quot;https://docs.astro.build/&quot;&gt;Astro Docs&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Front-matter of Posts&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;---
title: My First Blog Post
published: 2023-09-09
description: This is the first post of my new Astro blog.
image: ./cover.jpg
tags: [Foo, Bar]
category: Front-end
draft: false
---
&lt;/code&gt;&lt;/pre&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Attribute&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;title&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The title of the post.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;published&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The date the post was published.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;description&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;A short description of the post. Displayed on index page.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;image&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The cover image path of the post.&amp;lt;br/&amp;gt;1. Start with &lt;code&gt;http://&lt;/code&gt; or &lt;code&gt;https://&lt;/code&gt;: Use web image&amp;lt;br/&amp;gt;2. Start with &lt;code&gt;/&lt;/code&gt;: For image in &lt;code&gt;public&lt;/code&gt; dir&amp;lt;br/&amp;gt;3. With none of the prefixes: Relative to the markdown file&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;tags&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The tags of the post.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;category&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The category of the post.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;draft&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;If this post is still a draft, which won&apos;t be displayed.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;Where to Place the Post Files&lt;/h2&gt;
&lt;p&gt;Your post files should be placed in &lt;code&gt;src/content/posts/&lt;/code&gt; directory. You can also create sub-directories to better organize your posts and assets.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;src/content/posts/
├── post-1.md
└── post-2/
    ├── cover.png
    └── index.md
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Markdown Extended Features</title><link>https://kyki.moe/posts/markdown-extended/</link><guid isPermaLink="true">https://kyki.moe/posts/markdown-extended/</guid><description>Read more about Markdown features in Fuwari</description><pubDate>Mon, 01 Jan 2001 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;GitHub repository cards&lt;/h2&gt;
&lt;p&gt;You can add dynamic cards that link to GitHub repositories, on page load, the repository information is pulled from the GitHub API.&lt;/p&gt;
&lt;p&gt;::github{repo=&quot;Fabrizz/MMM-OnSpotify&quot;}&lt;/p&gt;
&lt;p&gt;Create a GitHub repository card with the code &lt;code&gt;::github{repo=&quot;&amp;lt;owner&amp;gt;/&amp;lt;repo&amp;gt;&quot;}&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;::github{repo=&quot;saicaca/fuwari&quot;}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Admonitions&lt;/h2&gt;
&lt;p&gt;Following types of admonitions are supported: &lt;code&gt;note&lt;/code&gt; &lt;code&gt;tip&lt;/code&gt; &lt;code&gt;important&lt;/code&gt; &lt;code&gt;warning&lt;/code&gt; &lt;code&gt;caution&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;:::note
Highlights information that users should take into account, even when skimming.
:::&lt;/p&gt;
&lt;p&gt;:::tip
Optional information to help a user be more successful.
:::&lt;/p&gt;
&lt;p&gt;:::important
Crucial information necessary for users to succeed.
:::&lt;/p&gt;
&lt;p&gt;:::warning
Critical content demanding immediate user attention due to potential risks.
:::&lt;/p&gt;
&lt;p&gt;:::caution
Negative potential consequences of an action.
:::&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;:::note
Highlights information that users should take into account, even when skimming.
:::

:::tip
Optional information to help a user be more successful.
:::
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The title of the admonition can be customized.&lt;/p&gt;
&lt;p&gt;:::note[MY CUSTOM TITLE]
This is a note with a custom title.
:::&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;:::note[MY CUSTOM TITLE]
This is a note with a custom title.
:::
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;[!TIP]
&lt;a href=&quot;https://github.com/orgs/community/discussions/16925&quot;&gt;The GitHub syntax&lt;/a&gt; is also supported.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; [!NOTE]
&amp;gt; The GitHub syntax is also supported.

&amp;gt; [!TIP]
&amp;gt; The GitHub syntax is also supported.
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Markdown Example</title><link>https://kyki.moe/posts/markdown/</link><guid isPermaLink="true">https://kyki.moe/posts/markdown/</guid><description>A simple example of a Markdown blog post.</description><pubDate>Mon, 01 Jan 2001 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;An h1 header&lt;/h1&gt;
&lt;p&gt;Paragraphs are separated by a blank line.&lt;/p&gt;
&lt;p&gt;2nd paragraph. &lt;em&gt;Italic&lt;/em&gt;, &lt;strong&gt;bold&lt;/strong&gt;, and &lt;code&gt;monospace&lt;/code&gt;. Itemized lists
look like:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;this one&lt;/li&gt;
&lt;li&gt;that one&lt;/li&gt;
&lt;li&gt;the other one&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Note that --- not considering the asterisk --- the actual text
content starts at 4-columns in.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Block quotes are
written like so.&lt;/p&gt;
&lt;p&gt;They can span multiple paragraphs,
if you like.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Use 3 dashes for an em-dash. Use 2 dashes for ranges (ex., &quot;it&apos;s all
in chapters 12--14&quot;). Three dots ... will be converted to an ellipsis.
Unicode is supported. ☺&lt;/p&gt;
&lt;h2&gt;An h2 header&lt;/h2&gt;
&lt;p&gt;Here&apos;s a numbered list:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;first item&lt;/li&gt;
&lt;li&gt;second item&lt;/li&gt;
&lt;li&gt;third item&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Note again how the actual text starts at 4 columns in (4 characters
from the left side). Here&apos;s a code sample:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# Let me re-iterate ...
for i in 1 .. 10 { do-something(i) }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As you probably guessed, indented 4 spaces. By the way, instead of
indenting the block, you can use delimited blocks, if you like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;define foobar() {
    print &quot;Welcome to flavor country!&quot;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;(which makes copying &amp;amp; pasting easier). You can optionally mark the
delimited block for Pandoc to syntax highlight it:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import time
# Quick, count to ten!
for i in range(10):
    # (but not *too* quick)
    time.sleep(0.5)
    print i
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;An h3 header&lt;/h3&gt;
&lt;p&gt;Now a nested list:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;First, get these ingredients:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;carrots&lt;/li&gt;
&lt;li&gt;celery&lt;/li&gt;
&lt;li&gt;lentils&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Boil some water.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Dump everything in the pot and follow
this algorithm:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; find wooden spoon
 uncover pot
 stir
 cover pot
 balance wooden spoon precariously on pot handle
 wait 10 minutes
 goto first step (or shut off burner when done)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Do not bump wooden spoon or it will fall.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Notice again how text always lines up on 4-space indents (including
that last line which continues item 3 above).&lt;/p&gt;
&lt;p&gt;Here&apos;s a link to &lt;a href=&quot;http://foo.bar&quot;&gt;a website&lt;/a&gt;, to a &lt;a href=&quot;local-doc.html&quot;&gt;local
doc&lt;/a&gt;, and to a &lt;a href=&quot;#an-h2-header&quot;&gt;section heading in the current
doc&lt;/a&gt;. Here&apos;s a footnote [^1].&lt;/p&gt;
&lt;p&gt;[^1]: Footnote text goes here.&lt;/p&gt;
&lt;p&gt;Tables can look like this:&lt;/p&gt;
&lt;p&gt;size material color&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;9 leather brown
10 hemp canvas natural
11 glass transparent&lt;/p&gt;
&lt;p&gt;Table: Shoes, their sizes, and what they&apos;re made of&lt;/p&gt;
&lt;p&gt;(The above is the caption for the table.) Pandoc also supports
multi-line tables:&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;keyword text&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;red Sunsets, apples, and
other red or reddish
things.&lt;/p&gt;
&lt;p&gt;green Leaves, grass, frogs
and other things it&apos;s
not easy being.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;A horizontal rule follows.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Here&apos;s a definition list:&lt;/p&gt;
&lt;p&gt;apples
: Good for making applesauce.
oranges
: Citrus!
tomatoes
: There&apos;s no &quot;e&quot; in tomatoe.&lt;/p&gt;
&lt;p&gt;Again, text is indented 4 spaces. (Put a blank line between each
term/definition pair to spread things out more.)&lt;/p&gt;
&lt;p&gt;Here&apos;s a &quot;line block&quot;:&lt;/p&gt;
&lt;p&gt;| Line one
| Line too
| Line tree&lt;/p&gt;
&lt;p&gt;and images can be specified like so:&lt;/p&gt;
&lt;p&gt;Inline math equations go in like so: $\omega = d\phi / dt$. Display
math should get its own line and be put in in double-dollarsigns:&lt;/p&gt;
&lt;p&gt;$$I = \int \rho R^{2} dV$$&lt;/p&gt;
&lt;p&gt;$$
\begin{equation*}
\pi
=3.1415926535
;8979323846;2643383279;5028841971;6939937510;5820974944
;5923078164;0628620899;8628034825;3421170679;\ldots
\end{equation*}
$$&lt;/p&gt;
&lt;p&gt;And note that you can backslash-escape any punctuation characters
which you wish to be displayed literally, ex.: `foo`, *bar*, etc.&lt;/p&gt;
</content:encoded></item><item><title>Expressive Code Example</title><link>https://kyki.moe/posts/expressive-code/</link><guid isPermaLink="true">https://kyki.moe/posts/expressive-code/</guid><description>How code blocks look in Markdown using Expressive Code.</description><pubDate>Mon, 01 Jan 2001 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Here, we&apos;ll explore how code blocks look using &lt;a href=&quot;https://expressive-code.com/&quot;&gt;Expressive Code&lt;/a&gt;. The provided examples are based on the official documentation, which you can refer to for further details.&lt;/p&gt;
&lt;h2&gt;Expressive Code&lt;/h2&gt;
&lt;h3&gt;Syntax Highlighting&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://expressive-code.com/key-features/syntax-highlighting/&quot;&gt;Syntax Highlighting&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;Regular syntax highlighting&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;console.log(&apos;This code is syntax highlighted!&apos;)
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Rendering ANSI escape sequences&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;ANSI colors:
- Regular: [31mRed[0m [32mGreen[0m [33mYellow[0m [34mBlue[0m [35mMagenta[0m [36mCyan[0m
- Bold:    [1;31mRed[0m [1;32mGreen[0m [1;33mYellow[0m [1;34mBlue[0m [1;35mMagenta[0m [1;36mCyan[0m
- Dimmed:  [2;31mRed[0m [2;32mGreen[0m [2;33mYellow[0m [2;34mBlue[0m [2;35mMagenta[0m [2;36mCyan[0m

256 colors (showing colors 160-177):
[38;5;160m160 [38;5;161m161 [38;5;162m162 [38;5;163m163 [38;5;164m164 [38;5;165m165[0m
[38;5;166m166 [38;5;167m167 [38;5;168m168 [38;5;169m169 [38;5;170m170 [38;5;171m171[0m
[38;5;172m172 [38;5;173m173 [38;5;174m174 [38;5;175m175 [38;5;176m176 [38;5;177m177[0m

Full RGB colors:
[38;2;34;139;34mForestGreen - RGB(34, 139, 34)[0m

Text formatting: [1mBold[0m [2mDimmed[0m [3mItalic[0m [4mUnderline[0m
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Editor &amp;amp; Terminal Frames&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://expressive-code.com/key-features/frames/&quot;&gt;Editor &amp;amp; Terminal Frames&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;Code editor frames&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;console.log(&apos;Title attribute example&apos;)
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;!-- src/content/index.html --&amp;gt;
&amp;lt;div&amp;gt;File name comment example&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Terminal frames&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;echo &quot;This terminal frame has no title&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;pre&gt;&lt;code&gt;Write-Output &quot;This one has a title!&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Overriding frame types&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;echo &quot;Look ma, no frame!&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;pre&gt;&lt;code&gt;# Without overriding, this would be a terminal frame
function Watch-Tail { Get-Content -Tail 20 -Wait $args }
New-Alias tail Watch-Tail
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Text &amp;amp; Line Markers&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://expressive-code.com/key-features/text-markers/&quot;&gt;Text &amp;amp; Line Markers&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;Marking full lines &amp;amp; line ranges&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;// Line 1 - targeted by line number
// Line 2
// Line 3
// Line 4 - targeted by line number
// Line 5
// Line 6
// Line 7 - targeted by range &quot;7-8&quot;
// Line 8 - targeted by range &quot;7-8&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Selecting line marker types (mark, ins, del)&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;function demo() {
  console.log(&apos;this line is marked as deleted&apos;)
  // This line and the next one are marked as inserted
  console.log(&apos;this is the second inserted line&apos;)

  return &apos;this line uses the neutral default marker type&apos;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Adding labels to line markers&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;// labeled-line-markers.jsx
&amp;lt;button
  role=&quot;button&quot;
  {...props}
  value={value}
  className={buttonClassName}
  disabled={disabled}
  active={active}
&amp;gt;
  {children &amp;amp;&amp;amp;
    !active &amp;amp;&amp;amp;
    (typeof children === &apos;string&apos; ? &amp;lt;span&amp;gt;{children}&amp;lt;/span&amp;gt; : children)}
&amp;lt;/button&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Adding long labels on their own lines&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;// labeled-line-markers.jsx
&amp;lt;button
  role=&quot;button&quot;
  {...props}

  value={value}
  className={buttonClassName}

  disabled={disabled}
  active={active}
&amp;gt;

  {children &amp;amp;&amp;amp;
    !active &amp;amp;&amp;amp;
    (typeof children === &apos;string&apos; ? &amp;lt;span&amp;gt;{children}&amp;lt;/span&amp;gt; : children)}
&amp;lt;/button&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Using diff-like syntax&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;+this line will be marked as inserted
-this line will be marked as deleted
this is a regular line
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;pre&gt;&lt;code&gt;--- a/README.md
+++ b/README.md
@@ -1,3 +1,4 @@
+this is an actual diff file
-all contents will remain unmodified
 no whitespace will be removed either
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Combining syntax highlighting with diff-like syntax&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;  function thisIsJavaScript() {
    // This entire block gets highlighted as JavaScript,
    // and we can still add diff markers to it!
-   console.log(&apos;Old code to be removed&apos;)
+   console.log(&apos;New and shiny code!&apos;)
  }
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Marking individual text inside lines&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;function demo() {
  // Mark any given text inside lines
  return &apos;Multiple matches of the given text are supported&apos;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Regular expressions&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;console.log(&apos;The words yes and yep will be marked.&apos;)
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Escaping forward slashes&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;echo &quot;Test&quot; &amp;gt; /home/test.txt
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Selecting inline marker types (mark, ins, del)&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;function demo() {
  console.log(&apos;These are inserted and deleted marker types&apos;);
  // The return statement uses the default marker type
  return true;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Word Wrap&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://expressive-code.com/key-features/word-wrap/&quot;&gt;Word Wrap&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;Configuring word wrap per block&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;// Example with wrap
function getLongString() {
  return &apos;This is a very long string that will most probably not fit into the available space unless the container is extremely wide&apos;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;pre&gt;&lt;code&gt;// Example with wrap=false
function getLongString() {
  return &apos;This is a very long string that will most probably not fit into the available space unless the container is extremely wide&apos;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Configuring indentation of wrapped lines&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;// Example with preserveIndent (enabled by default)
function getLongString() {
  return &apos;This is a very long string that will most probably not fit into the available space unless the container is extremely wide&apos;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;pre&gt;&lt;code&gt;// Example with preserveIndent=false
function getLongString() {
  return &apos;This is a very long string that will most probably not fit into the available space unless the container is extremely wide&apos;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Collapsible Sections&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://expressive-code.com/plugins/collapsible-sections/&quot;&gt;Collapsible Sections&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// All this boilerplate setup code will be collapsed
import { someBoilerplateEngine } from &apos;@example/some-boilerplate&apos;
import { evenMoreBoilerplate } from &apos;@example/even-more-boilerplate&apos;

const engine = someBoilerplateEngine(evenMoreBoilerplate())

// This part of the code will be visible by default
engine.doSomething(1, 2, 3, calcFn)

function calcFn() {
  // You can have multiple collapsed sections
  const a = 1
  const b = 2
  const c = a + b

  // This will remain visible
  console.log(`Calculation result: ${a} + ${b} = ${c}`)
  return c
}

// All this code until the end of the block will be collapsed again
engine.closeConnection()
engine.freeMemory()
engine.shutdown({ reason: &apos;End of example boilerplate code&apos; })
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Line Numbers&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://expressive-code.com/plugins/line-numbers/&quot;&gt;Line Numbers&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Displaying line numbers per block&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;// This code block will show line numbers
console.log(&apos;Greetings from line 2!&apos;)
console.log(&apos;I am on line 3&apos;)
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;pre&gt;&lt;code&gt;// Line numbers are disabled for this block
console.log(&apos;Hello?&apos;)
console.log(&apos;Sorry, do you know what line I am on?&apos;)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Changing the starting line number&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;console.log(&apos;Greetings from line 5!&apos;)
console.log(&apos;I am on line 6&apos;)
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item></channel></rss>