<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>ʕ•ᴥ•ʔ on yányào.com</title><link>https://xn--ynyo-2nad.com/</link><description>Recent content in ʕ•ᴥ•ʔ on yányào.com</description><generator>Hugo</generator><language>en-US</language><lastBuildDate>Sat, 11 Apr 2026 15:00:00 +0800</lastBuildDate><atom:link href="https://xn--ynyo-2nad.com/index.xml" rel="self" type="application/rss+xml"/><item><title>Codex Plugin for Claude Code and Vibe coding lover</title><link>https://xn--ynyo-2nad.com/posts/codex-plugin-for-claude-code/</link><pubDate>Sat, 11 Apr 2026 15:00:00 +0800</pubDate><guid>https://xn--ynyo-2nad.com/posts/codex-plugin-for-claude-code/</guid><description>&lt;p&gt;用 Claude Code 写代码效率高，但写完谁来 review？OpenAI 开源了 &lt;a href="https://github.com/openai/codex-plugin-cc"&gt;codex-plugin-cc&lt;/a&gt;，把 Codex 嵌到 Claude Code 里做代码审查。今天配了一下，过程比预期曲折。&lt;/p&gt;
&lt;h2 id="起因"&gt;起因&lt;/h2&gt;
&lt;p&gt;今天给项目加了 E2B sandbox 集成（代码执行沙箱），改了七八个文件。写完想 commit，但想先让 AI review 一下再提交。&lt;/p&gt;
&lt;p&gt;之前在 &lt;a href="https://github.com/yanyaoer/research-devflow"&gt;research-devflow&lt;/a&gt; 里写过一个 &lt;code&gt;/review&lt;/code&gt; skill，用规则引擎扫描代码。但那个本质是 Claude 审查自己写的代码，总觉得差点意思。codex-plugin 用的是另一个 AI（Codex）来审查，相当于找了个外部 reviewer。&lt;/p&gt;
&lt;h2 id="折腾-hook-的过程"&gt;折腾 Hook 的过程&lt;/h2&gt;
&lt;p&gt;上手一个想法是在 plan 通过后自动触发 review。Claude Code 有个 hook 系统，可以在特定事件触发 shell 命令。我配了个 PostToolUse hook，监听 ExitPlanMode：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;PostToolUse&amp;#34;&lt;/span&gt;: [{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;matcher&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;ExitPlanMode&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;hooks&amp;#34;&lt;/span&gt;: [{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;command&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;command&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;echo &amp;#39;Run /codex:adversarial-review before implementing.&amp;#39;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;跑了一下，echo 的文字 Claude 确实&amp;quot;看到&amp;quot;了，但它不一定每次都执行对应操作。这个 hook 只能提醒，不能强制。&lt;/p&gt;
&lt;p&gt;然后去翻 codex 插件的源码，发现它自带一个 &lt;code&gt;stop-review-gate-hook.mjs&lt;/code&gt;，做的事情比我想的精巧得多：&lt;/p&gt;</description></item><item><title>sing-box TUN 模式网络慢问题诊断与优化</title><link>https://xn--ynyo-2nad.com/posts/sing-box-tun-network-diagnosis/</link><pubDate>Sat, 10 Jan 2026 23:00:00 +0800</pubDate><guid>https://xn--ynyo-2nad.com/posts/sing-box-tun-network-diagnosis/</guid><description>&lt;p&gt;记录一次 sing-box TUN 模式下网络访问慢的诊断过程&lt;/p&gt;
&lt;h2 id="问题现象"&gt;问题现象&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;环境：macOS + sing-box TUN 模式&lt;/li&gt;
&lt;li&gt;现象：能连接公网，但访问 Google 等网站非常慢或完全无法访问&lt;/li&gt;
&lt;li&gt;国内网站访问正常&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="诊断过程"&gt;诊断过程&lt;/h2&gt;
&lt;h3 id="1-初步测试"&gt;1. 初步测试&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 测试国内网站 - 正常&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;curl -w &lt;span style="color:#e6db74"&gt;&amp;#34;Total: %{time_total}s\n&amp;#34;&lt;/span&gt; -o /dev/null -s https://www.baidu.com
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# Total: 0.086s&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 测试 Google - 失败 (SSL 错误)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;curl -w &lt;span style="color:#e6db74"&gt;&amp;#34;Total: %{time_total}s\n&amp;#34;&lt;/span&gt; -o /dev/null -s https://www.google.com
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# exit code 60, SSL certificate problem&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="2-dns-污染检测"&gt;2. DNS 污染检测&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 系统 DNS 返回错误 IP (Meta 的 IP，不是 Google)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;dig +short www.google.com
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 31.13.94.36&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# sing-box DNS 返回正确 IP&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;dig +short www.google.com @127.0.0.1
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 142.250.194.164&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;发现问题 1&lt;/strong&gt;：系统 DNS 被 GFW 污染，返回了错误的 IP 地址。&lt;/p&gt;</description></item><item><title>vibe coding with Claude</title><link>https://xn--ynyo-2nad.com/posts/vibe-coding-with-claude/</link><pubDate>Sun, 03 Aug 2025 17:28:00 +0800</pubDate><guid>https://xn--ynyo-2nad.com/posts/vibe-coding-with-claude/</guid><description>&lt;h2 id="abstract"&gt;Abstract&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;项目探索: 熟悉陌生项目，节省摸索时间，减轻其他研发的负担&lt;/li&gt;
&lt;li&gt;方案设计: 搜索代码库，提出实现方案，帮助理清思路提供决策参考&lt;/li&gt;
&lt;li&gt;Debug和自动化: 分析日志，快速定位问题跑通测试，自行调用终端工具&lt;/li&gt;
&lt;li&gt;开发效率：快速构建功能原型并迭代创意，避免过早陷入细节&lt;/li&gt;
&lt;li&gt;编码重构: 生成单元测试、优化代码、语法检查和 linting，&lt;strong&gt;代码质量有保障&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src="https://xn--ynyo-2nad.com/images/2025-08-03-17-02-22.png" alt=""&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Claude Code 概述 - Anthropic&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.anthropic.com/claude-code"&gt;https://www.anthropic.com/claude-code&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="sample-project"&gt;Sample Project&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;dab.rs - &lt;a href="https://github.com/yanyaoer/dab.rs"&gt;https://github.com/yanyaoer/dab.rs&lt;/a&gt;
A Unix-style command-line music player built with Rust, featuring streaming playback, local caching, and a terminal user interface inspired by cmus&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-markdown" data-lang="markdown"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;┌─ DAB Music Player ───────────────────────────────────────────────────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ ▶ Anthrax - Madhouse: The Very Best Of Anthrax - Madhouse [02:25/04:17] │
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;├──────────────────────────────────────────────────────────────────────────┤
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ Favorite Albums (16) │ Enter: Play │ l: Album │ h: Discography │ a: Add │
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;├──────────────────────────────────────────────────────────────────────────┤
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ Anthrax - Madhouse: The Very Best Of Anthrax │
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ Megadeth - Rust In Peace (Unknown year) │
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ Jacqueline du Pré - The Heart of the Cello (Unknown year) │
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ Antonio Vivaldi - Great Composers - Vivaldi (Unknown year) │
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ Pantera - Cowboys From Hell (2010-04-17) │
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ Judas Priest - Painkiller (1990-08-01) │
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ Arch Enemy - Deceivers (2022-08-12) │
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ My Dying Bride - 34.788%... Complete (1998-01-01) │
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;│ Amon Amarth - The Great Heathen Army (2022-08-05) │
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;└──────────────────────────────────────────────────────────────────────────┘
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;img src="https://xn--ynyo-2nad.com/images/2025-08-03-17-09-39.png" alt=""&gt;&lt;/p&gt;</description></item><item><title>poorman's ASR solution</title><link>https://xn--ynyo-2nad.com/posts/poormans-asr/</link><pubDate>Sun, 11 May 2025 17:50:56 +0800</pubDate><guid>https://xn--ynyo-2nad.com/posts/poormans-asr/</guid><description>&lt;h2 id="intro"&gt;Intro&lt;/h2&gt;
&lt;p&gt;大概20年h2期间，听闻feishu支持了会议自动转译字幕功能，but
当时私有化部署的版本一直没有支持，于是私下找了语音助手团队的同学企图蹭服务用于自动生成会议纪要，&lt;strong&gt;懒即是原动力&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;再 but 一下，出于服务成本考量没有蹭成功，后来对应的同学也陆续离职就没下文了&lt;/p&gt;
&lt;p&gt;23年大模型开始各种火热起来，于是借助 openai 的 whisper
在本地陆续写了一些音频转文本的小任务，比如 yt-dlp 下载 bilibili
视频后转音频再转文本，个人习惯上阅读的效率还是高于视频形式的&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;[scribe] &lt;a href="https://gist.github.com/yanyaoer/5cc7b0dd6729f306ad3cb740d501cabd"&gt;https://gist.github.com/yanyaoer/5cc7b0dd6729f306ad3cb740d501cabd&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;另外结合语音识别和 LLM 的发散，也试着搓了点语音助手的尝试&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;[voice assistant with computer-use] &lt;a href="https://gist.github.com/yanyaoer/752a73d2d6df5a2aa0de179a0f68e8a1"&gt;https://gist.github.com/yanyaoer/752a73d2d6df5a2aa0de179a0f68e8a1&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[hook for whisper llm-talk] &lt;a href="https://github.com/yanyaoer/whisper.cpp/commit/da85a1b4791e4a7eeb5adb31d47d4c5e53618234"&gt;https://github.com/yanyaoer/whisper.cpp/commit/da85a1b4791e4a7eeb5adb31d47d4c5e53618234&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;但是实时语音识别场景，用 whiper-stream / sense-voice
这类方案还是会有识别不准确、内容丢失的问题存在，调整 step/length
参数效果也不明显，vad 方案延迟也很高&amp;hellip;&lt;/p&gt;
&lt;h2 id="new-solution"&gt;New solution&lt;/h2&gt;
&lt;p&gt;上周忽然想起了 kaldi 项目也蛮经典了，于是就试着用 sherpa-[ncnn|onnx] 尝试了下 demo
sherpa-[ncnn|onnx]-microphone
流式识别输出的整体效果已经很接近把音频文件喂给大模型的质量&lt;/p&gt;
&lt;p&gt;于是联系维护者 @csukuangfj
请教怎么提升识别准确率，大佬过于卷周末还给造了新方案和输出优化，甚至还录了 b
站视频 &lt;a href="https://www.bilibili.com/video/BV1xcEMz8EsX/"&gt;https://www.bilibili.com/video/BV1xcEMz8EsX/&lt;/a&gt;&lt;/p&gt;
&lt;iframe src="//player.bilibili.com/player.html?bvid=BV1xcEMz8EsX&amp;page=1" scrolling="no"
 autoplay="0" border="0" frameborder="no" framespacing="0" allowfullscreen="true"&gt;&lt;/iframe&gt;
&lt;ul&gt;
&lt;li&gt;[Add real-time speech recognition example for SenseVoice. (#2197)] &lt;a href="https://github.com/k2-fsa/sherpa-onnx/commit/53518efd2fe70f49b86f180a4e5b49fdc374da82"&gt;https://github.com/k2-fsa/sherpa-onnx/commit/53518efd2fe70f49b86f180a4e5b49fdc374da82&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[Fix displaying streaming speech recognition results for Python. (#2196)] &lt;a href="https://github.com/k2-fsa/sherpa-onnx/commit/4a833a754743076d68252731c681511e2d9390bd"&gt;https://github.com/k2-fsa/sherpa-onnx/commit/4a833a754743076d68252731c681511e2d9390bd&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;另外也体验到 two-pass 双模型识别的效果，两种方式都能满足俺的使用场景🎉&lt;/p&gt;</description></item><item><title>Pandoc generate pdf from markdown</title><link>https://xn--ynyo-2nad.com/posts/pandoc-md2pdf/</link><pubDate>Thu, 25 Jul 2024 14:52:12 +0800</pubDate><guid>https://xn--ynyo-2nad.com/posts/pandoc-md2pdf/</guid><description>&lt;h2 id="intro"&gt;Intro&lt;/h2&gt;
&lt;p&gt;始终不太习惯 word/wps 类工具编辑文本，再一次尝试用 &lt;code&gt;pandoc&lt;/code&gt; 来生成 pdf，算是初步搞明白一点玩法，本文略过 markdown 的部分主要记录 &lt;code&gt;latex&lt;/code&gt; 相关设定内容。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;wkhtmltopdf&lt;/code&gt; 也是一个选项，但是转 HTML 再生成 pdf 就没啥挑战了额哈哈&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="setup"&gt;Setup&lt;/h2&gt;
&lt;p&gt;首先完整安装 latex 包&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ brew uninstall --cask basictex
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ brew install --cask mactex
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="latex-template"&gt;Latex template&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;---
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;title&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;Your article title here&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;date&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;2023-02-20&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;fontsize&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;12pt&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# fc-list :lang=zh&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#mainfont: &amp;#34;PingFang SC&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;mainfont&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;Sarasa Mono SC&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# monofont: &amp;#34;FantasqueSansM Nerd Font Mono&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;monofont&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;Sarasa Mono SC&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 中文换行支持&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;lang&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;zh-CN&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;geometry&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;margin=2cm&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 设置双栏&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# classoption=twocolumn&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;---
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;在 markdown 文档的最前面加入以上 metadata 简化命令参数设定，实际效果等价于&lt;/p&gt;</description></item><item><title>Flair-58 Espresso Maker</title><link>https://xn--ynyo-2nad.com/posts/flair-58/</link><pubDate>Tue, 08 Feb 2022 15:55:00 +0800</pubDate><guid>https://xn--ynyo-2nad.com/posts/flair-58/</guid><description>&lt;h2 id="flair-58"&gt;flair-58&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://flairespresso.com/product/flair-58/"&gt;https://flairespresso.com/product/flair-58/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://xn--ynyo-2nad.com/flair-coffee.jpg" alt=""&gt;&lt;/p&gt;
&lt;p&gt;周末浪费了2天豆子，终于折腾出比较理想的设定&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;预热：浅烘 = 3档，中烘 = 2档，深烘 = 1档&lt;/li&gt;
&lt;li&gt;磨豆：C40 调到 8 格(浅烘豆 +=1)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;奶泡机没到位，先用娃的小奶锅煮 200ml Oatly 燕麦奶，稍热就好，没有打出泡沫也就无所谓拉花了&lt;br&gt;
PlanB: 微波炉加热 + &lt;a href="https://www.ikea.cn/cn/zh/p/produkt-pu-luo-da-da-mo-qi-hei-se-70301165/"&gt;宜家 ¥9.9 手持奶泡器&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;我买的优化后版本默认配无底手柄 + 58mm 18g粉碗，而上半年批次的好像是 20g粉碗，底部没有凹弧线，然后分水网和冲煮头是一体的，每杯都得拆下来清理，现在只需要拆手柄洗洗粉碗和分水网就好，方便连续出杯(但是对于没有多个手柄和粉碗的初阶用户来说，重新填粉加水的操作并不连续 -.-)&lt;br&gt;
群里有大佬&lt;a href="https://docs.google.com/document/d/1szvhjTE2F7lzhr38phggVUO50fkbddq0/edit?usp=sharing&amp;amp;ouid=115932911354635105266&amp;amp;rtpof=true&amp;amp;sd=true"&gt;改装了底座和支架的方案&lt;/a&gt;，解决下压前倾问题和使用12cm+的秤&lt;/p&gt;
&lt;p&gt;而无底手柄安装还不太熟练，经常要弯腰低头去看小翅膀有没有卡到位，然后注水再安装压力表(顺便当预浸泡)，18g豆出 36g液体，如果粉磨得过细，下压会很费劲&lt;/p&gt;
&lt;p&gt;虽然目前 5-9bar 之间压的曲线还不太稳定，偶尔通道也不太顺滋到杯外，但是香浓的 crema 已然远超预期(其实很容易过萃，但是家属喝不出来😂)&lt;/p&gt;
&lt;p&gt;试了下用冰的屈臣氏做 coffee soda，难喝🤢&lt;/p&gt;
&lt;p&gt;好多想买的配件：拉花奶缸、粉锤、布粉器、鼠尾粉碗、粉饼垃圾盒&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;update: 2022-08-19 14:09:08&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;买了新的拉花缸和称，但是懒到完全不想碰牛奶，only pure coffee and water&amp;hellip;&lt;/p&gt;
&lt;p&gt;早晨的冲煮开始逐渐暴躁，直接磨58g粉分3次装填、下压、出液到一个杯里，再加冰块分装成两份 long black 出门，少洗两次杯子动作也更流畅～大概15-20分钟完成&lt;/p&gt;</description></item><item><title>剁手好物推荐</title><link>https://xn--ynyo-2nad.com/posts/toy/</link><pubDate>Fri, 24 Sep 2021 22:28:00 +0800</pubDate><guid>https://xn--ynyo-2nad.com/posts/toy/</guid><description>&lt;p&gt;&lt;strong&gt;2025-05&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;三月良的杂货铺 - 衣物和背包的剪裁用料都很强&lt;/li&gt;
&lt;li&gt;必迈 - 速干衣、短裤、平价跑鞋&lt;/li&gt;
&lt;li&gt;meathub - 流赭马瑟兰 干红，复杂度、平衡感以及性价比都命中甜区&lt;/li&gt;
&lt;li&gt;vook one - 8公斤出头的国产单盘13速公路车，好骑好维护、需要一点动手能力&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;ul&gt;
&lt;li&gt;Insta360 GO2 拇指运动相机&lt;/li&gt;
&lt;li&gt;巷贩小酒 - 东方甄选金酒&lt;/li&gt;
&lt;li&gt;Reebok royal techque 板鞋&lt;/li&gt;
&lt;li&gt;ALTRA Escalante 2.5 轻量零落差跑鞋&lt;/li&gt;
&lt;li&gt;SENNHEISER IE300 耳机&lt;/li&gt;
&lt;li&gt;PhD 能量棒&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Volvo v60</title><link>https://xn--ynyo-2nad.com/posts/volvo-v60/</link><pubDate>Wed, 30 Jun 2021 21:10:00 +0800</pubDate><guid>https://xn--ynyo-2nad.com/posts/volvo-v60/</guid><description>&lt;p&gt;因为家庭新成员加入，所以买车的优先级提了上来。一开始考虑大尺寸6/7座suv，能装全家人短途出行，比如highlander, outlander, explorer, Pajero&amp;hellip;后来因为今年各种新款上市，到最终提车时间有点晚，再加上城市拥堵和停车问题，回归到最初的选项也是一直种草的旅行车Volvo v60&lt;/p&gt;
&lt;p&gt;中间还去看过Jaguar和Alfa Romeo，可惜后排空间有点小，对外型内饰非常满意，动力和操控也很可以，尤其Julie的前脸颜值太命中我了，一直对mx5这类笑脸无法抗拒…&lt;/p&gt;
&lt;p&gt;V60在4s店试驾的豪华版，刚开始还挺不适应转向手感和油门刹车的，感觉都很沉很重。比起来以前开过的各种小钢炮和家用轿车，沉着有余灵活不够，前期不熟悉的时候操作起来都得小心翼翼。&lt;/p&gt;
&lt;p&gt;最后订车选了致远焰影蓝运动款，因为厂家直销的关系也没讲价，就跟销售要了行车记录仪和儿童座椅。目前开两个月小一千公里的行程，大概总结些点吧&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;外观线条比例，审美观因人而异，但是V60各处都在我的区间内&lt;/li&gt;
&lt;li&gt;nappa皮座椅舒适和支撑都很到位，前排有可调的腿拖和腰撑。对豪华版的实木装饰水晶档杆其实没啥需求，氛围灯也蛮简约，没有那么夜店风。可惜选配的交车时间太长，不然座椅通风、冬季包、米色内饰都想加&lt;/li&gt;
&lt;li&gt;后排空间坐两人还行，但是中间的地台太高，不适合长途5人出行&lt;/li&gt;
&lt;li&gt;后备箱就不用夸了，狗子的航空箱一直塞在里面，出去玩很方便，去宜家就把后座放平。6月份搬家就跑了两趟，上次搬家借老王的a3可拉了56趟&lt;/li&gt;
&lt;li&gt;48v电机+autohold，起步平顺没有纯燃油车型起步轰发动机那个颤抖&lt;/li&gt;
&lt;li&gt;低转油门动力响应略有延迟，升档不算很迅速，不过相比起golf，508要好很多&lt;/li&gt;
&lt;li&gt;油耗市区日常11升百公里，跑机场高速能到6.1左右，平时一个月加一次满箱油，推荐95号&lt;/li&gt;
&lt;li&gt;方向盘虚位明显，过弯会习惯性多打一些位置，转向比hatchback车型都要重许多。前脸两侧的存在感明显，低坐姿的时候会开得谨慎，反而不会觉得屁股有什么阻碍&lt;/li&gt;
&lt;li&gt;底盘确实在开过的车里算得上优秀，过弯和滤震都很扎实。静音实属一般，风噪胎噪在后排(或者车速超过100)尤其明显，所以也就不考虑顶上行李箱&lt;/li&gt;
&lt;li&gt;autopilot 模式在跑高速时非常愉悦，车道保持比我打方向顺滑多了，跟前车保持车距也很可靠，另外养成了并线前一定先打灯的习惯，否则车子会自己修正。能称为瑕疵的就是自动刹车不够线性，乘客会有明显的拉扯感甚至点头；拥堵路段还得切回手动模式，跟车距离在我这边太容易被加塞&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Self Host Maddy Mail Server</title><link>https://xn--ynyo-2nad.com/posts/self-host-maddy-mail-server/</link><pubDate>Tue, 01 Dec 2020 20:34:44 +0800</pubDate><guid>https://xn--ynyo-2nad.com/posts/self-host-maddy-mail-server/</guid><description>&lt;h2 id="maddy"&gt;maddy&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Composable all-in-one mail server. &lt;a href="https://github.com/foxcpp/maddy"&gt;https://github.com/foxcpp/maddy&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;准备自建系列服务替换掉 google 全家桶，先试了传统的 Postfix, Dovecot, OpenDKIM, OpenSPF, OpenDMARC 套餐，但是本人水平菜，机器配置也不高，折腾两天还没跑起来，正好看到订阅的 changelog 推荐了 maddy &lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt; 于是搓搓手气试试这个邮局方案，以下是满足个人喜好的优点&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;基于 golang 生态依赖少，方便打镜像&lt;/li&gt;
&lt;li&gt;验证数据存在 sqlite 里也很轻量&lt;/li&gt;
&lt;li&gt;没有 web 端，只需要 imap + thunderbird 即可&lt;/li&gt;
&lt;li&gt;配置文件相对简单&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="install"&gt;install&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;mkdir -p /data/maddy
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# hard link caddy&amp;#39;s crt and key to maddy&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;ln var/lib/caddy/.local/share/caddy/certificates/acme-v02.api.letsencrypt.org-directory/&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;domain&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;/&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;domain&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;.crt /data/maddy/&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;domain&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;.crt
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;ln var/lib/caddy/.local/share/caddy/certificates/acme-v02.api.letsencrypt.org-directory/&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;domain&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;/&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;domain&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;.key /data/maddy/&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;domain&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;.key
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# foxcpp/maddy:v0.4.2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;podman run &lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; --name maddy &lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; -v /data/maddy:/data &lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; -p 25:25 &lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; -p 143:143 &lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; -p 587:587 &lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; -p 993:993 &lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; -p 465:465 &lt;span style="color:#ae81ff"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; yanyaoer/maddy:master
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# add user&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;podman run --rm -it -v /data/maddy:/data --entrypoint /bin/maddyctl yanyaoer/maddy:master creds create yanyao@mail.yadanhe.com
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;参考文档配置&lt;sup id="fnref:2"&gt;&lt;a href="#fn:2" class="footnote-ref" role="doc-noteref"&gt;2&lt;/a&gt;&lt;/sup&gt; 完后发送邮件对方可收，本地 thunderbird 接收回复邮件时有问题&lt;/p&gt;</description></item><item><title>Utteranc Comments</title><link>https://xn--ynyo-2nad.com/posts/utteranc-comments/</link><pubDate>Fri, 30 Oct 2020 11:49:39 +0800</pubDate><guid>https://xn--ynyo-2nad.com/posts/utteranc-comments/</guid><description>&lt;p&gt;utterances - A lightweight comments widget built on GitHub issues. Use GitHub issues for blog comments, wiki pages and more!&lt;/p&gt;
&lt;h2 id="install"&gt;install&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;install &lt;a href="https://github.com/apps/utterances"&gt;utterances&lt;/a&gt; on your repo&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;add the script to your template&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;lt;script src=&amp;#34;https://utteranc.es/client.js&amp;#34;
 repo=&amp;#34;[ENTER REPO HERE]&amp;#34;
 issue-term=&amp;#34;pathname&amp;#34;
 theme=&amp;#34;github-light&amp;#34;
 crossorigin=&amp;#34;anonymous&amp;#34;
 async&amp;gt;
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;for exsamples &lt;a href="https://github.com/yanyaoer/yanyaoer.github.io/commit/f2508ce7557d372f909f68ee32371f86895fd92f"&gt;https://github.com/yanyaoer/yanyaoer.github.io/commit/f2508ce7557d372f909f68ee32371f86895fd92f&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;done.&lt;/p&gt;</description></item><item><title>Zotero as personal knowledge management</title><link>https://xn--ynyo-2nad.com/posts/zotero/</link><pubDate>Thu, 02 Jul 2020 22:55:53 +0800</pubDate><guid>https://xn--ynyo-2nad.com/posts/zotero/</guid><description>&lt;p&gt;&lt;a href="https://www.zotero.org/"&gt;Zotero&lt;/a&gt; 常用于科研的文献管理，由 firefox 浏览器插件发展到现在有了独立的桌面和&lt;a href="https://github.com/mickstar/Zoo-For-Zotero"&gt;移动客户端&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://xn--ynyo-2nad.com/zotero.png" alt=""&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;本身具备简易的 rss 订阅功能可以用来追踪论文的更新&lt;/li&gt;
&lt;li&gt;注册在线账户后支持导出资料库给其他同学订阅&lt;/li&gt;
&lt;li&gt;浏览器插件 &lt;a href="https://github.com/zotero/zotero-connectors"&gt;zotero connectors&lt;/a&gt; 则类似各类笔记应用的 web clipper，方便导入各种资料。&lt;strong&gt;注意科学上网加载完整页面后再进行保存&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;通过插件可以扩展出许多其他功能，比如文件同步、高级档案管理&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="quickstart"&gt;quickstart&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;brew cask install zotero
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;这里简单用 &lt;a href="https://github.com/yanyaoer/caddy2-webdav"&gt;caddy2 搭建 webdav&lt;/a&gt; 来同步附件，就没用高级的 &lt;a href="http://zotfile.com/"&gt;zotfile&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;至于自带的笔记功能怎么说呢～ 已经适应不能这种风格了&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;add-ons&lt;/th&gt;
 &lt;th&gt;link&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;quicklook&lt;/td&gt;
 &lt;td&gt;&lt;a href="https://github.com/mronkko/ZoteroQuickLook/releases"&gt;https://github.com/mronkko/ZoteroQuickLook/releases&lt;/a&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;markdown&lt;/td&gt;
 &lt;td&gt;&lt;a href="https://addons.thunderbird.net/zh-cn/thunderbird/addon/markdown-here-xul/"&gt;https://addons.thunderbird.net/zh-cn/thunderbird/addon/markdown-here-xul/&lt;/a&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;papersgpt&lt;/td&gt;
 &lt;td&gt;&lt;a href="https://github.com/papersgpt/papersgpt-for-zotero/releases"&gt;https://github.com/papersgpt/papersgpt-for-zotero/releases&lt;/a&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;pdf2zh&lt;/td&gt;
 &lt;td&gt;&lt;a href="https://github.com/guaguastandup/zotero-pdf2zh/releases"&gt;https://github.com/guaguastandup/zotero-pdf2zh/releases&lt;/a&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="subscription"&gt;subscription&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://arxiv.org/list/cs/recent"&gt;https://arxiv.org/list/cs/recent&lt;/a&gt;
康奈尔大学提供的免费论文预览平台，主要订阅 cs.SD 音频相关更新&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://scholar.google.com/"&gt;https://scholar.google.com/&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://academic.microsoft.com/"&gt;https://academic.microsoft.com/&lt;/a&gt;
谷歌学术、微软学术也可以用来搜索一些关键词并订阅推送&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://www.storkapp.me/"&gt;https://www.storkapp.me/&lt;/a&gt; 提供关键词订阅推送到邮箱&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://sci-hub.tw/"&gt;https://sci-hub.tw/&lt;/a&gt; 实在找不到的下载就靠毛子的共享服务&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;将码农常用的文档工具 gitbook 转为 pdf&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;brew cask install calibre
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo npm install -g gitbook-cli
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;gitbook install &lt;span style="color:#75715e"&gt;# for gitbook plugin&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git clone https://github.com/prometheus/docs.git
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;gitbook pdf
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;ps: gitbook 开源版本已经很久不维护了，可以换到 &lt;a href="https://github.com/honkit/honkit"&gt;honkit&lt;/a&gt; fork 的版本&lt;/p&gt;</description></item><item><title>Rss2email</title><link>https://xn--ynyo-2nad.com/posts/rss2email/</link><pubDate>Tue, 23 Jun 2020 18:58:30 +0800</pubDate><guid>https://xn--ynyo-2nad.com/posts/rss2email/</guid><description>&lt;p&gt;距离上次从 &lt;a href="https://blogtrottr.com"&gt;https://blogtrottr.com&lt;/a&gt; 迁移 rss 订阅到 feedly 差不多五六年了，
这会网络不可用的状况又变得严重些，干脆还是用自建服务来接收感兴趣的内容，
当然备选方案也不少:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/miniflux/miniflux"&gt;https://github.com/miniflux/miniflux&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/SSilence/selfoss"&gt;https://github.com/SSilence/selfoss&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/FreshRSS/FreshRSS"&gt;https://github.com/FreshRSS/FreshRSS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://git.tt-rss.org/fox/tt-rss"&gt;https://git.tt-rss.org/fox/tt-rss&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;出于复古心理顺便减少对应的 app 安装选择问题，又选择了回归 email 方式订阅更新&lt;/p&gt;
&lt;h2 id="安装配置"&gt;安装配置&lt;/h2&gt;
&lt;p&gt;rss2email 的安装到简单，参考 &lt;a href="https://github.com/rss2email/rss2email"&gt;官方文档&lt;/a&gt;
直接 &lt;code&gt;apt install rss2email&lt;/code&gt;，默认配置会发送文本邮件，修改 &lt;code&gt;html-mail=True&lt;/code&gt;，
在我的环境里 smtp over sendgrid 很容易超配额，sendmail 基本发送不出去，
就配上 imap.google 账户自己发给自己啦～&lt;/p&gt;
&lt;p&gt;从 feedly 导出 opml 文件然后 &lt;code&gt;r2e opmlimport&lt;/code&gt; 完事大吉&lt;/p&gt;
&lt;p&gt;需要注意的是，在 &lt;code&gt;r2e run&lt;/code&gt; 的执行过程中对配置文件进行修改非常容易被覆盖 &lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt;，不要同时搞太多操作就好，&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;update: 2020-09-18 17:34:49&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;修改参数 &lt;code&gt;force-from = True&lt;/code&gt;，默认会从 feed 里优先提取作者或者发布站点的邮箱，导致 gmail 过滤器失败&lt;/p&gt;
&lt;h2 id="定时任务"&gt;定时任务&lt;/h2&gt;
&lt;p&gt;现代 linux 发行版本(比如这里用的 ubuntu 20.04)，默认不带 cronjob 服务，改为 systemd 来管理各种服务，定时任务的写法稍微麻烦了些，先用当前 user 权限来 &lt;code&gt;$HOME/.config/systemd/user&lt;/code&gt; 写入定时任务配置&lt;/p&gt;</description></item><item><title>Deploy bitwarden_rs with podman</title><link>https://xn--ynyo-2nad.com/posts/bitwarden_rs_with_podman/</link><pubDate>Thu, 04 Jun 2020 19:05:12 +0800</pubDate><guid>https://xn--ynyo-2nad.com/posts/bitwarden_rs_with_podman/</guid><description>&lt;p&gt;bitwarden_rs&lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt; 是个用 rust/rocket 编写的非官方 api 实现，
&lt;a href="https://github.com/bitwarden/server"&gt;dotnet&lt;/a&gt; 版本有点儿不太适合手头的部署环境&lt;/p&gt;
&lt;p&gt;这里用比较现代的 podman&lt;sup id="fnref:2"&gt;&lt;a href="#fn:2" class="footnote-ref" role="doc-noteref"&gt;2&lt;/a&gt;&lt;/sup&gt; 来运行 docker 服务&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;podman run -d --name bitwarden -v /bw-data/:/data/:Z -e ROCKET_PORT&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;8080&lt;/span&gt; -p 8080:8080 bitwardenrs/server:latest
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;podman generate systemd --name bitwarden --files
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;mv container-bitwarden.service /etc/systemd/system/
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;systemctl --user enable /etc/systemd/system/container-bitwarden.service
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;systemctl --user start container-bitwarden.service
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;然后用 nginx 或者 caddy 代理一下 8080 端口即可连接客户端&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;brew install bitwarden-cli &lt;span style="color:#75715e"&gt;# npm install -g @bitwarden/cli&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;bw config server https://bw.myserver.com
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;update 2021-04-01&lt;/strong&gt; build bitwaden_rs from source&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;# install rust
apt install git make gcc libssl-dev pkg-config curl
curl --proto &amp;#39;=https&amp;#39; --tlsv1.2 -sSf https://sh.rustup.rs | sh
source $HOME/.cargo/env

# build bitwarden_rs
git clone https://github.com/dani-garcia/bitwarden_rs/
cd bitwarden_rs/
cargo build --features sqlite --release
cp target/release/bitwarden_rs /usr/local/bin/

# download bw_web_vault from https://github.com/dani-garcia/bw_web_builds/releases
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;edit /etc/systemd/system/bitwarden.service&lt;/p&gt;</description></item><item><title>Minio Storage Service</title><link>https://xn--ynyo-2nad.com/posts/minio-storage-service/</link><pubDate>Tue, 02 Jun 2020 09:47:48 +0800</pubDate><guid>https://xn--ynyo-2nad.com/posts/minio-storage-service/</guid><description>&lt;p&gt;&lt;a href="https://min.io"&gt;min.io&lt;/a&gt; 来自前 glusterFS 团队的分布式存储项目，
兼容 aws s3 / google cloud storage 接口，支持多磁盘、多节点，伸缩扩容方便，
golang 编写+单执行文件部署，非常适合用 k8s 编排复制来搭建私有对象存储服务&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;没有生产环境的使用经验，以下仅用于业余尝鲜&lt;/strong&gt; &lt;del&gt;六一节礼物&lt;/del&gt;&lt;/p&gt;
&lt;h2 id="gnulinux-下载安装"&gt;GNU/Linux 下载安装&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;wget https://dl.min.io/server/minio/release/linux-amd64/minio -O /usr/local/bin/minio
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;chmod +x /user/local/bin/minio
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="添加用户组和配置文件"&gt;添加用户、组和配置文件&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;groupadd --system minio
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;useradd --system --gid minio --shell /usr/sbin/nologin --comment &lt;span style="color:#e6db74"&gt;&amp;#34;Minio file server&amp;#34;&lt;/span&gt; minio
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;mkdir -p /data/minio
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;chown -R minio:minio /data/minio
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# replace minio.service with your own config, eg. User,Group&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;wget https://raw.githubusercontent.com/minio/minio-service/master/linux-systemd/minio.service -O /etc/systemd/system/minio.service
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="配置端口和密钥"&gt;配置端口和密钥&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# optional. run `uuidgen` to creates AK/SK&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cat &lt;span style="color:#e6db74"&gt;&amp;lt;&amp;lt;EOF &amp;gt;&amp;gt; /tmp/minio
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;MINIO_VOLUMES=&amp;#34;/data/minio/&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;MINIO_OPTS=&amp;#34;--address :9199&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;MINIO_ACCESS_KEY=`uuidgen`
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;MINIO_SECRET_KEY=`uuidgen`
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;EOF&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="启动服务"&gt;启动服务&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;systemctl enable minio.service
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;systemctl start minio.service
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;a href="https://docs.min.io/docs/minio-client-complete-guide.html"&gt;客户端 mc&lt;/a&gt;
使用说明参考官方文档好了，和 s3 命令行也没太多区别，
甚至可以用来做 gcs/s3 代理用&lt;/p&gt;</description></item><item><title>Pour Over Coffee Makers</title><link>https://xn--ynyo-2nad.com/posts/pour-over-coffee-makers/</link><pubDate>Fri, 15 May 2020 15:41:01 +0800</pubDate><guid>https://xn--ynyo-2nad.com/posts/pour-over-coffee-makers/</guid><description>&lt;h2 id="办公室日常用品"&gt;办公室日常用品&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;hario v60 2人份玻璃滤杯 &lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;li&gt;hario v60 600ml 云朵分享壶 &lt;sup id="fnref:2"&gt;&lt;a href="#fn:2" class="footnote-ref" role="doc-noteref"&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;li&gt;comandante c40 手摇磨豆机 &lt;sup id="fnref:3"&gt;&lt;a href="#fn:3" class="footnote-ref" role="doc-noteref"&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;li&gt;kalita 700ml 细嘴壶 &lt;sup id="fnref:4"&gt;&lt;a href="#fn:4" class="footnote-ref" role="doc-noteref"&gt;4&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;li&gt;rivers seek 随手杯 &lt;sup id="fnref:5"&gt;&lt;a href="#fn:5" class="footnote-ref" role="doc-noteref"&gt;5&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;2020-0615 新购入 Mr.clever 聪明杯 &lt;sup id="fnref:6"&gt;&lt;a href="#fn:6" class="footnote-ref" role="doc-noteref"&gt;6&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;2020-0622 新购入 hario drip kettle air &lt;sup id="fnref:7"&gt;&lt;a href="#fn:7" class="footnote-ref" role="doc-noteref"&gt;7&lt;/a&gt;&lt;/sup&gt;，
用了两次手感偏轻水流控制得不稳 T_T&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;2020-1027 新购入 fellow ode 电动磨豆机 &lt;sup id="fnref:8"&gt;&lt;a href="#fn:8" class="footnote-ref" role="doc-noteref"&gt;8&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;2020-1109 新购入 fellow stagg ekg 温控壶 &lt;sup id="fnref:9"&gt;&lt;a href="#fn:9" class="footnote-ref" role="doc-noteref"&gt;9&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;2023-half 新购入 hoop 澡盆滤杯 &lt;sup id="fnref:10"&gt;&lt;a href="#fn:10" class="footnote-ref" role="doc-noteref"&gt;10&lt;/a&gt;&lt;/sup&gt;，类似聪明杯但会拉长萃取时间&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;每天一早 &lt;del&gt;中午&lt;/del&gt; 到公司开始烧水，然后吭呲吭呲摇 40g 豆子兑 600ml 左右的水&lt;/p&gt;
&lt;p&gt;手法就比较 &lt;del&gt;随意&lt;/del&gt; 业余啦，主要参考下面两个视频，出品大概率自己都还挺喜欢的
&lt;strong&gt;按比例加注水量翻倍&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id="46-method-by-tetsu-kasuya"&gt;&amp;ldquo;4:6 method&amp;rdquo; by Tetsu Kasuya &lt;sup id="fnref:11"&gt;&lt;a href="#fn:11" class="footnote-ref" role="doc-noteref"&gt;11&lt;/a&gt;&lt;/sup&gt;&lt;/h3&gt;
&lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;"&gt;
 &lt;iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/wmCW8xSWGZY?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"&gt;&lt;/iframe&gt;
 &lt;/div&gt;

&lt;h3 id="the-ultimate-v60-technique-by-james-hoffmann"&gt;&amp;ldquo;The Ultimate V60 Technique&amp;rdquo; by James Hoffmann&lt;/h3&gt;
&lt;div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;"&gt;
 &lt;iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share; fullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/AI4ynXzkSQo?autoplay=0&amp;amp;controls=1&amp;amp;end=0&amp;amp;loop=0&amp;amp;mute=0&amp;amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"&gt;&lt;/iframe&gt;
 &lt;/div&gt;

&lt;h2 id="家庭版"&gt;家庭版&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;baratza encore 电动磨豆器 &lt;sup id="fnref:12"&gt;&lt;a href="#fn:12" class="footnote-ref" role="doc-noteref"&gt;12&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;li&gt;kinto OCT 2人份陶瓷滤杯 &lt;sup id="fnref:13"&gt;&lt;a href="#fn:13" class="footnote-ref" role="doc-noteref"&gt;13&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;li&gt;ikea vardagen 500ml 玻璃量杯 &lt;sup id="fnref:14"&gt;&lt;a href="#fn:14" class="footnote-ref" role="doc-noteref"&gt;14&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;li&gt;muji 万古烧马克杯 &lt;sup id="fnref:15"&gt;&lt;a href="#fn:15" class="footnote-ref" role="doc-noteref"&gt;15&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;ul&gt;
&lt;li&gt;2020-0615 新购入 hario filter-in 冷萃瓶 &lt;del&gt;已碎&lt;/del&gt;，21年夏再次购入 &lt;sup id="fnref:16"&gt;&lt;a href="#fn:16" class="footnote-ref" role="doc-noteref"&gt;16&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;刚开始的时候装备上交了不少学费，比如：&lt;del&gt;电动砍豆机&lt;/del&gt;、&lt;del&gt;廉价手磨&lt;/del&gt;、&lt;del&gt;aeropress&lt;/del&gt;，
虽然不能一概而论，实际上很大程度还是遵循一分钱一分货的原则，性能越好则价格呈指数上涨
条件允许的话尽量选择好一点的设备，毕竟也是天天要用的家伙事&lt;/p&gt;</description></item><item><title>Mastodon</title><link>https://xn--ynyo-2nad.com/posts/mastodon/</link><pubDate>Fri, 15 May 2020 09:45:08 +0800</pubDate><guid>https://xn--ynyo-2nad.com/posts/mastodon/</guid><description>&lt;p&gt;&lt;code&gt;Mastodon 长毛象&lt;/code&gt;&lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt; &amp;ndash; 基于 rubyonrails/reactjs/nodejs 开发的分布式 &amp;amp;
去中心化 twiter clone。利用空闲时间在 aws lightsail 上开了个实例把服务跑了起来&lt;/p&gt;
&lt;p&gt;一开始走了些弯路，因为选机房和省钱的缘故，重建了若干次操作系统，最后的选择是
tokyo+cloudflare，没错我又套了 cdn，实在是海外线路到北京联通不稳定&lt;/p&gt;
&lt;p&gt;安装步骤没有使用 docker 而是参考文档从源码安装&lt;sup id="fnref:2"&gt;&lt;a href="#fn:2" class="footnote-ref" role="doc-noteref"&gt;2&lt;/a&gt;&lt;/sup&gt;，原因和解决方案如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;del&gt;机器用 $3.5/mo 512mem 最便宜的那档消费降级&lt;/del&gt;(512M 内存重启会拉垮弱鸡，服务已迁移到 oraclecloud)，出于 net/io 性能考虑就不使 docker 啦&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;内存问题，&lt;code&gt;RAILS_ENV=production bundle exec rake mastodon:setup&lt;/code&gt;
这一步骤执行到 &lt;code&gt;rails assets:precompile&lt;/code&gt;，
不管是在 docker 里跑还是直接运行都会报 swap 分区不足，找到两个方案来解决:&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# create swapfile &amp;lt;https://linuxize.com/post/create-a-linux-swap-file/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ sudo fallocate -l 2G /swapfile
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ sudo chmod &lt;span style="color:#ae81ff"&gt;600&lt;/span&gt; /swapfile
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ sudo mkswap /swapfile
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ sudo swapon /swapfile
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# verify active&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ sudo swapon --show
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# optional: low value is better for production&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ sudo sysctl vm.swappiness&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="邮件配置"&gt;邮件配置&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# By default the memory limit in Node. js is 512 mb, &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# use command —- max-old-space-size to increase the memory limit&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ NODE_OPTIONS&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;--max-old-space-size=4096&amp;#34;&lt;/span&gt; RAILS_ENV&lt;span style="color:#f92672"&gt;=&lt;/span&gt;production bundle exec rails assets:precompile
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;直接配置 localhost 发送邮件无效，先用 &lt;a href="https://sendgrid.com/"&gt;sendgrid&lt;/a&gt; 免费版顶着, 一天 100 封邮件目前够用&lt;/p&gt;</description></item><item><title>Gitlab Repo</title><link>https://xn--ynyo-2nad.com/posts/gitlab-repo/</link><pubDate>Sat, 09 May 2020 19:34:06 +0800</pubDate><guid>https://xn--ynyo-2nad.com/posts/gitlab-repo/</guid><description>&lt;p&gt;gitlab 里面已经有十来个 group，几百个 project，虽然不一定会每个项目都参与，
但是为了快速同步代码，又捡起了 android 开发常用的 repo 命令来管理多项目代码。
这里使用了 gitlab graphql 接口来遍历项目生成分组的 manifest 文件&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#!/usr/bin/env python&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; argparse
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; json
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; os
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; urllib2
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;GITLAB_HOST &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;gitlab.mydomain.com&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;GITLAB_SSH_URL &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;ssh://git@&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; GITLAB_HOST
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;GITLAB_GRAPHQL_URL &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;https://&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; GITLAB_HOST &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;/api/graphql&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;GITLAB_TOKEN &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;GITLAB_GROUP &lt;span style="color:#f92672"&gt;=&lt;/span&gt; [&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;BLACK_LIST &lt;span style="color:#f92672"&gt;=&lt;/span&gt; (&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt;,)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 以上配置修改为自己的设定&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;template &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&amp;#34;&amp;lt;?xml version=&amp;#34;1.0&amp;#34; encoding=&amp;#34;UTF-8&amp;#34;?&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;&amp;lt;!-- autogen by gen.py, do not edit this file --&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;&amp;lt;manifest&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; &amp;lt;remote name=&amp;#34;origin&amp;#34; fetch=&amp;#34;&lt;/span&gt;&lt;span style="color:#e6db74"&gt;{ssh_url}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34; /&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; &amp;lt;default revision=&amp;#34;master&amp;#34; remote=&amp;#34;origin&amp;#34; sync-c=&amp;#34;true&amp;#34; sync-j=&amp;#34;4&amp;#34; /&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;{content}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;&amp;lt;/manifest&amp;gt;&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;write_file&lt;/span&gt;(content, filename&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;default.xml&amp;#34;&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; _file &lt;span style="color:#f92672"&gt;=&lt;/span&gt; os&lt;span style="color:#f92672"&gt;.&lt;/span&gt;path&lt;span style="color:#f92672"&gt;.&lt;/span&gt;join(os&lt;span style="color:#f92672"&gt;.&lt;/span&gt;path&lt;span style="color:#f92672"&gt;.&lt;/span&gt;dirname(__file__), filename)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;with&lt;/span&gt; open(_file, &lt;span style="color:#e6db74"&gt;&amp;#34;w&amp;#34;&lt;/span&gt;) &lt;span style="color:#66d9ef"&gt;as&lt;/span&gt; f:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; f&lt;span style="color:#f92672"&gt;.&lt;/span&gt;write(template&lt;span style="color:#f92672"&gt;.&lt;/span&gt;format(content&lt;span style="color:#f92672"&gt;=&lt;/span&gt;content, ssh_url&lt;span style="color:#f92672"&gt;=&lt;/span&gt;GITLAB_SSH_URL))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;fetch_project_of_group&lt;/span&gt;(group, write&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;True&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; data &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;{ group(fullPath: &amp;#34;&lt;/span&gt;&lt;span style="color:#e6db74"&gt;%s&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;) { projects { nodes { fullPath } } }}&amp;#39;&lt;/span&gt; &lt;span style="color:#f92672"&gt;%&lt;/span&gt; group
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; req &lt;span style="color:#f92672"&gt;=&lt;/span&gt; urllib2&lt;span style="color:#f92672"&gt;.&lt;/span&gt;Request(
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; GITLAB_GRAPHQL_URL,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; data&lt;span style="color:#f92672"&gt;=&lt;/span&gt;json&lt;span style="color:#f92672"&gt;.&lt;/span&gt;dumps(dict(query&lt;span style="color:#f92672"&gt;=&lt;/span&gt;data)),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; headers&lt;span style="color:#f92672"&gt;=&lt;/span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;Authorization&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;Bearer &amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; GITLAB_TOKEN,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;Content-Type&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;application/json&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; )
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; resp &lt;span style="color:#f92672"&gt;=&lt;/span&gt; json&lt;span style="color:#f92672"&gt;.&lt;/span&gt;load(urllib2&lt;span style="color:#f92672"&gt;.&lt;/span&gt;urlopen(req))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; content &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;\n&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;.&lt;/span&gt;join(
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; [
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;&amp;lt;project path=&amp;#34;&lt;/span&gt;&lt;span style="color:#e6db74"&gt;{d}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34; name=&amp;#34;&lt;/span&gt;&lt;span style="color:#e6db74"&gt;{d}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;/&amp;gt;&amp;#39;&lt;/span&gt;&lt;span style="color:#f92672"&gt;.&lt;/span&gt;format(d&lt;span style="color:#f92672"&gt;=&lt;/span&gt;p[&lt;span style="color:#e6db74"&gt;&amp;#34;fullPath&amp;#34;&lt;/span&gt;])
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; p &lt;span style="color:#f92672"&gt;in&lt;/span&gt; resp[&lt;span style="color:#e6db74"&gt;&amp;#34;data&amp;#34;&lt;/span&gt;][&lt;span style="color:#e6db74"&gt;&amp;#34;group&amp;#34;&lt;/span&gt;][&lt;span style="color:#e6db74"&gt;&amp;#34;projects&amp;#34;&lt;/span&gt;][&lt;span style="color:#e6db74"&gt;&amp;#34;nodes&amp;#34;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; p[&lt;span style="color:#e6db74"&gt;&amp;#34;fullPath&amp;#34;&lt;/span&gt;] &lt;span style="color:#f92672"&gt;not&lt;/span&gt; &lt;span style="color:#f92672"&gt;in&lt;/span&gt; BLACK_LIST
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; )
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; write:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; write_file(content, filename&lt;span style="color:#f92672"&gt;=&lt;/span&gt;group&lt;span style="color:#f92672"&gt;.&lt;/span&gt;replace(&lt;span style="color:#e6db74"&gt;&amp;#34;/&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;-&amp;#34;&lt;/span&gt;) &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;-group.xml&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; content
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;():
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; parser &lt;span style="color:#f92672"&gt;=&lt;/span&gt; argparse&lt;span style="color:#f92672"&gt;.&lt;/span&gt;ArgumentParser(description&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;Process some projects.&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; parser&lt;span style="color:#f92672"&gt;.&lt;/span&gt;add_argument(
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;-G&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;--group&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; help&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;for group/subgroup or all&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; type&lt;span style="color:#f92672"&gt;=&lt;/span&gt;str,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; choices&lt;span style="color:#f92672"&gt;=&lt;/span&gt;ns &lt;span style="color:#f92672"&gt;+&lt;/span&gt; [&lt;span style="color:#e6db74"&gt;&amp;#34;all&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;default&amp;#34;&lt;/span&gt;],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; )
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; arg &lt;span style="color:#f92672"&gt;=&lt;/span&gt; parser&lt;span style="color:#f92672"&gt;.&lt;/span&gt;parse_args()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; arg&lt;span style="color:#f92672"&gt;.&lt;/span&gt;group &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;all&amp;#34;&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; x &lt;span style="color:#f92672"&gt;in&lt;/span&gt; GITLAB_GROUP:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; fetch_project_of_group(x)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; d &lt;span style="color:#f92672"&gt;=&lt;/span&gt; [fetch_project_of_group(x, write&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;False&lt;/span&gt;) &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; x &lt;span style="color:#f92672"&gt;in&lt;/span&gt; GITLAB_GROUP]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; write_file(&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;\n&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;.&lt;/span&gt;join(d))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;elif&lt;/span&gt; arg&lt;span style="color:#f92672"&gt;.&lt;/span&gt;group &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;default&amp;#34;&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; d &lt;span style="color:#f92672"&gt;=&lt;/span&gt; [fetch_project_of_group(x, write&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;False&lt;/span&gt;) &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; x &lt;span style="color:#f92672"&gt;in&lt;/span&gt; GITLAB_GROUP]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; write_file(&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;\n&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;.&lt;/span&gt;join(d))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; fetch_project_of_group(arg&lt;span style="color:#f92672"&gt;.&lt;/span&gt;group)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; __name__ &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;__main__&amp;#34;&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; main()
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;USAGE:&lt;/strong&gt; 创建完 manifest 文件之后提交到仓库就可以愉快的玩耍啦&lt;/p&gt;</description></item><item><title>Dash Replacement with tmux</title><link>https://xn--ynyo-2nad.com/posts/dash-replacement/</link><pubDate>Thu, 07 May 2020 18:54:37 +0800</pubDate><guid>https://xn--ynyo-2nad.com/posts/dash-replacement/</guid><description>&lt;p&gt;通过 tmux 快捷集成替换 dash.app 查询开发文档&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;$ brew install dasht

$ dasht-docsets | tr &amp;#39;A-Z&amp;#39; &amp;#39;a-z&amp;#39;
go
javascript
python_3
rust
tornado
&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;# tmux.conf quick start
bind -n S-up command-prompt -p &amp;#39;docset:&amp;#39; &amp;#34;splitw -h -fb -l 80 dasht &amp;#39;%%&amp;#39;&amp;#34;
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>Cloudflare Gost</title><link>https://xn--ynyo-2nad.com/posts/cloudflare-gost/</link><pubDate>Thu, 07 May 2020 16:00:01 +0800</pubDate><guid>https://xn--ynyo-2nad.com/posts/cloudflare-gost/</guid><description>&lt;p&gt;从清明节开始，稳定运行好几年的 ss 服务器终于阵亡了，所有端口全挂。一直蹭公司的 vpn 查资料也挺到了五一，实在拖延够够的就再另外开了一台机器中转过去迁移数据，不过嘛年纪大了又开始犯懒，企图拯救获得资格认证的机器，通过一番网上冲浪学习到了目前(实测可用)能满足我需求的方案。简单来说就是：cloudflare[后文简称为 cf] + websockets over gost，实际的客户端通过 cdn 代理再接入服务&lt;/p&gt;
&lt;p&gt;有几个需要注意的地方：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;gost 启动时绑定的 localhost 不直接对外访问，走了 caddy 的转发，而这一步和 cf 的 ssl 证书配置会造成不停的重定向跳转，需要将 cf 加密模式配置为 flexible&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;然后修改 caddy 的域名配置为 &lt;a href="http://domain.com"&gt;http://domain.com&lt;/a&gt; &lt;a href="https://domain.com"&gt;https://domain.com&lt;/a&gt; { &amp;hellip; } 阻止 cf 和 caddy 之间的 http -&amp;gt; https&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;gost 服务端监听 ws 协议，本地的 gost 客户端转发 wss 协议连接 cf_domain:443&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;需要鉴权的方案使用 socks5+wss://username:password@domain:port&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;android 客户端的设置，因为使用了 ws 协议，所以需要将域名写入到插件的配置里，直接用域名变量无法解析&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;具体配置参考官方文档，&lt;strong&gt;一切浪费的时间都是源于没认真仔细看文档&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/haoel/haoel.github.io"&gt;https://github.com/haoel/haoel.github.io&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/ginuerzh/gost"&gt;https://github.com/ginuerzh/gost&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/xausky/ShadowsocksGostPlugin"&gt;https://github.com/xausky/ShadowsocksGostPlugin&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;update 2021-03-01&lt;/strong&gt; 由于 shawdowsocks 的 android 客户端升级导致插件不可用，另外部署了 &lt;a href="https://github.com/txthinking/brook"&gt;brook&lt;/a&gt; wsserver 给手机使用&lt;/p&gt;</description></item><item><title>webpack resolve local module</title><link>https://xn--ynyo-2nad.com/posts/webpack-resolve-local-module/</link><pubDate>Fri, 13 Jan 2017 23:19:49 +0000</pubDate><guid>https://xn--ynyo-2nad.com/posts/webpack-resolve-local-module/</guid><description>&lt;p&gt;最近的项目刚开始，设计的目录层级有点深&lt;br&gt;
经常会在好几层本地路径之间互相引用&lt;/p&gt;
&lt;p&gt;&lt;code&gt;import Image from '../../../../components/image'&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;这层层叠叠的路径写起来实在丑陋&lt;br&gt;
不由得想起 Python 从项目根目录引用模块&lt;br&gt;
然后研究了一下 Node.js 里的几种简易实现&lt;/p&gt;
&lt;p&gt;干脆利落的软连接: &lt;code&gt;ln -s node_modules src&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;修改环境变量: &lt;code&gt;NODE_PATH=. node app&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;从本地目录安装:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// package.json 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 需要运行 npm install
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;baz&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;dependencies&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;foo&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;file: ./src&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;另外还有些修改 global，或者引入其他 require 实现的方法就不再一一列出了&lt;br&gt;
最终选择的是修改 webpack 配置&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;// webpack.config.js
resolve: {
 modulesDirectories: [__dirname, &amp;#39;node_modules&amp;#39;],
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;a href="https://gist.github.com/branneman/8048520"&gt;https://gist.github.com/branneman/8048520&lt;/a&gt;
&lt;a href="http://stackoverflow.com/questions/10860244/how-to-make-the-require-in-node-js-to-be-always-relative-to-the-root-folder-of-t/41078266#41078266"&gt;http://stackoverflow.com/questions/10860244/how-to-make-the-require-in-node-js-to-be-always-relative-to-the-root-folder-of-t/41078266#41078266&lt;/a&gt;
&lt;a href="https://webpack.github.io/docs/configuration.html#resolve-modulesdirectories"&gt;https://webpack.github.io/docs/configuration.html#resolve-modulesdirectories&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Leonard Cohen - you want it darker</title><link>https://xn--ynyo-2nad.com/posts/leonard-cohen-you-want-it-darker/</link><pubDate>Tue, 25 Oct 2016 09:21:00 +0000</pubDate><guid>https://xn--ynyo-2nad.com/posts/leonard-cohen-you-want-it-darker/</guid><description>&lt;h2 id="年度最佳"&gt;年度最佳&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://open.spotify.com/album/3jeTB3j3QmUs8SPIVleHtU"&gt;&lt;img src="images/you-want-it-darker.jpg" alt="you want it darker"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://open.spotify.com/album/3jeTB3j3QmUs8SPIVleHtU"&gt;you want it darker&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;循环听了好几天&lt;/p&gt;
&lt;p&gt;干净低沉的嗓音加配乐&lt;/p&gt;
&lt;p&gt;愈发担心以后听不到了怎么办 😢～&lt;/p&gt;</description></item><item><title>web audio</title><link>https://xn--ynyo-2nad.com/posts/web-audio/</link><pubDate>Wed, 15 Jun 2016 14:34:08 +0000</pubDate><guid>https://xn--ynyo-2nad.com/posts/web-audio/</guid><description>&lt;p&gt;照文档撸了一下 AudioContext 可视化音频&lt;br&gt;
桌面浏览器上 Safari 9, Chrome stable 绘制正常&lt;br&gt;
移动端只有微信的 webview 能工作, 纯玩票叻
&lt;img src="https://mdn.mozillademos.org/files/7977/wave.png" alt="wave"&gt;&lt;/p&gt;
&lt;p&gt;ref:
&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API/Visualizations_with_Web_Audio_API"&gt;https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API/Visualizations_with_Web_Audio_API&lt;/a&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-html" data-lang="html"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;html&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;head&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;meta&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;charset&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;utf-8&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;meta&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;viewport&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;content&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;width=device-width, user-scalable=no&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;title&lt;/span&gt;&amp;gt;AV&amp;lt;/&lt;span style="color:#f92672"&gt;title&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;/&lt;span style="color:#f92672"&gt;head&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;body&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;canvas&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;id&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;vis&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style="color:#f92672"&gt;canvas&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;audio&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;id&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;av&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;src&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;YOUR_AUDIO_FILE&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style="color:#f92672"&gt;audio&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;script&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;src&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;index.js&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style="color:#f92672"&gt;script&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;/&lt;span style="color:#f92672"&gt;body&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;/&lt;span style="color:#f92672"&gt;html&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;window.&lt;span style="color:#a6e22e"&gt;AudioContext&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; window.&lt;span style="color:#a6e22e"&gt;AudioContext&lt;/span&gt; &lt;span style="color:#f92672"&gt;||&lt;/span&gt; window.&lt;span style="color:#a6e22e"&gt;webkitAudioContext&lt;/span&gt; &lt;span style="color:#f92672"&gt;||&lt;/span&gt; window.&lt;span style="color:#a6e22e"&gt;mozAudioContext&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;window.&lt;span style="color:#a6e22e"&gt;onload&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;(){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;canvas&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; document.&lt;span style="color:#a6e22e"&gt;getElementById&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;vis&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;canvasCtx&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;canvas&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;getContext&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;2d&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;isPlaying&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;audio&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; document.&lt;span style="color:#a6e22e"&gt;getElementById&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;av&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;audioCtx&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;AudioContext&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;analyser&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;audioCtx&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;createAnalyser&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;audioSrc&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;audioCtx&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;createMediaElementSource&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;audio&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;audioSrc&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;connect&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;analyser&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;analyser&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;connect&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;audioCtx&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;destination&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;analyser&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;fftSize&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2048&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;bufferLength&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;analyser&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;fftSize&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;dataArray&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Uint8Array&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;bufferLength&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;analyser&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;getByteTimeDomainData&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;dataArray&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;WIDTH&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;500&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;HEIGHT&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;150&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;draw&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;requestAnimationFrame&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;draw&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#f92672"&gt;!&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;isPlaying&lt;/span&gt;) &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;analyser&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;getByteTimeDomainData&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;dataArray&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;canvasCtx&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;fillStyle&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;rgb(200, 200, 200)&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;canvasCtx&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;fillRect&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;WIDTH&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;HEIGHT&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;canvasCtx&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;lineWidth&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;canvasCtx&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;strokeStyle&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;rgb(0, 0, 0)&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;canvasCtx&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;beginPath&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;sliceWidth&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;WIDTH&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1.0&lt;/span&gt; &lt;span style="color:#f92672"&gt;/&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;bufferLength&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;x&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;bufferLength&lt;/span&gt;; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;&lt;span style="color:#f92672"&gt;++&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;v&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;dataArray&lt;/span&gt;[&lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;] &lt;span style="color:#f92672"&gt;/&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;128.0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;y&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;v&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;HEIGHT&lt;/span&gt;&lt;span style="color:#f92672"&gt;/&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;i&lt;/span&gt; &lt;span style="color:#f92672"&gt;===&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;canvasCtx&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;moveTo&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;x&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;y&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;canvasCtx&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;lineTo&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;x&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;y&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;x&lt;/span&gt; &lt;span style="color:#f92672"&gt;+=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;sliceWidth&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;canvasCtx&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;lineTo&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;canvas&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;width&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;canvas&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;height&lt;/span&gt;&lt;span style="color:#f92672"&gt;/&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;canvasCtx&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;stroke&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; };
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;draw&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;audio&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;play&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; document.&lt;span style="color:#a6e22e"&gt;body&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;onclick&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;function&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;audio&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;isPlaying&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;isPlaying&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;audio&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;pause&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;isPlaying&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;false&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;audio&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;play&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;isPlaying&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>move to caddy</title><link>https://xn--ynyo-2nad.com/posts/move-to-caddy/</link><pubDate>Tue, 26 Apr 2016 06:41:13 +0000</pubDate><guid>https://xn--ynyo-2nad.com/posts/move-to-caddy/</guid><description>&lt;p&gt;去年用 Hexo 搭建的日志已经好几个月没更新了，最近休假有点空闲就继续更新吧。&lt;br&gt;
先从 Github 迁移回自己的 Linode，然后安装一个 Caddyserver&lt;a href="https://caddyserver.com/"&gt;1&lt;/a&gt; 来渲染 markdown&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Caddy is a unique web server with a modern feature set. Think nginx or Apache, but written in Go. With Caddy, you can serve your websites over HTTP/2. It can act as a reverse proxy and load balancer. Front your PHP apps with it. You can even deploy your site with git push. Cool, right?&lt;a href="https://blog.gopheracademy.com/caddy-a-look-inside/"&gt;2&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="download-and-install-systemd"&gt;Download and install systemd&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;wget -O &lt;span style="color:#e6db74"&gt;&amp;#39;caddy.tar.gz&amp;#39;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;https://caddyserver.com/download/build?os=linux&amp;amp;arch=amd64&amp;amp;features=git%2Cipfilter&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;tar zxf caddy.tar.gz
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;mkdir /opt/caddy
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;mkdir /var/run/caddy/
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;chown caddy:caddy -R /opt/caddy
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;chown caddy:caddy -R /var/run/caddy
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;mv caddy /opt/caddy/
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;useradd -d /var/run/caddy --system caddy
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;chmod &lt;span style="color:#ae81ff"&gt;644&lt;/span&gt; /etc/systemd/system/caddy.service
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;systemctl enable caddy.service
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;systemctl start caddy.service
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;systemctl status caddy.service
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;a href="https://github.com/caddyserver/examples/blob/master/systemd%2Fcaddy.service"&gt;https://github.com/caddyserver/examples/blob/master/systemd%2Fcaddy.service&lt;/a&gt;&lt;/p&gt;</description></item><item><title>mongodb backup</title><link>https://xn--ynyo-2nad.com/posts/mongodb-backup/</link><pubDate>Tue, 22 Dec 2015 13:30:24 +0000</pubDate><guid>https://xn--ynyo-2nad.com/posts/mongodb-backup/</guid><description>&lt;p&gt;有台机器准备2月份下架
记一个 mongodb 备份小脚本 :)&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#!/bin/bash
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# vim: set et sw=2 ts=2 sts=2 ff=unix fenc=utf8:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;MONGO_DATABASE&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;_name_&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;MONGO_HOST&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;_ip_&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;MONGO_PORT&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;_prot_&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;TIMESTAMP&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;`&lt;/span&gt;date +%Y-%m-%dT%H:%M:%S&lt;span style="color:#e6db74"&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;MONGODUMP_PATH&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;/usr/bin/mongodump&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;BACKUPS_DIR&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;/data/dumps/&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;BACKUP_NAME&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;$MONGO_DATABASE&lt;span style="color:#e6db74"&gt;-&lt;/span&gt;$TIMESTAMP&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;while&lt;/span&gt; test $# -gt &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;do&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;case&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;$1&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt; in
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; -m&lt;span style="color:#f92672"&gt;)&lt;/span&gt; echo &lt;span style="color:#e6db74"&gt;&amp;#34;backup mongthly and clear week_dir&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;#rm $BACKUPS_DIR&amp;#34;week/*&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; find $BACKUPS_DIR&lt;span style="color:#e6db74"&gt;&amp;#34;week&amp;#34;&lt;/span&gt; -type f -name &lt;span style="color:#e6db74"&gt;&amp;#39;*.tgz&amp;#39;&lt;/span&gt; -delete
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; tar -czPf $BACKUPS_DIR&lt;span style="color:#e6db74"&gt;&amp;#34;month/&amp;#34;&lt;/span&gt;$BACKUP_NAME.tgz $BACKUPS_DIR$MONGO_DATABASE
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; -w&lt;span style="color:#f92672"&gt;)&lt;/span&gt; echo &lt;span style="color:#e6db74"&gt;&amp;#34;backup weekly&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; echo &lt;span style="color:#e6db74"&gt;&amp;#34;tar -czPf &lt;/span&gt;$BACKUPS_DIR&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;week/&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;$BACKUP_NAME&lt;span style="color:#e6db74"&gt;.tgz &lt;/span&gt;$BACKUPS_DIR$MONGO_DATABASE&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; -d&lt;span style="color:#f92672"&gt;)&lt;/span&gt; echo &lt;span style="color:#e6db74"&gt;&amp;#34;just dump&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; $MONGODUMP_PATH -d $MONGO_DATABASE --out $BACKUPS_DIR
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; *&lt;span style="color:#f92672"&gt;)&lt;/span&gt; echo &lt;span style="color:#e6db74"&gt;&amp;#34;do nothing&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;esac&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; shift
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;done&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code class="language-cronjob" data-lang="cronjob"&gt;# crontab -e
10 3 * * * /bin/bash $HOME/bin/mongobackup.sh -d &amp;gt; /dev/null 2&amp;gt;&amp;amp;1
20 3 * * 1 /bin/bash $HOME/bin/mongobackup.sh -w &amp;gt; /dev/null 2&amp;gt;&amp;amp;1
30 3 1 * * /bin/bash $HOME/bin/mongobackup.sh -m &amp;gt; /dev/null 2&amp;gt;&amp;amp;1
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;每天早上3点按天／周／月分别保存&lt;/p&gt;</description></item><item><title>let's encrypt</title><link>https://xn--ynyo-2nad.com/posts/let-s-encrypt/</link><pubDate>Mon, 14 Dec 2015 23:35:49 +0000</pubDate><guid>https://xn--ynyo-2nad.com/posts/let-s-encrypt/</guid><description>&lt;p&gt;&lt;a href="https://letsencrypt.org"&gt;Let&amp;rsquo;s Encrypt&lt;/a&gt; 已经公开测试，不需要再提交测试域名表单，直接就能申请&lt;br&gt;
小项目以后都能用这玩意开 https 不用花钱买证书哦啦啦&lt;/p&gt;
&lt;p&gt;照 &lt;a href="https://letsencrypt.readthedocs.org/en/latest/using.html"&gt;文档&lt;/a&gt; 做一遍给域名签上证书还挺简单的&lt;/p&gt;
&lt;p&gt;&lt;img src="images/ssl.jpg" alt="ssl"&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 获取项目代码&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git clone https://github.com/letsencrypt/letsencrypt
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cd letsencrypt
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 安装依赖&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;./letsencrypt-auto
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 获取证书&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;./letsencrypt-auto certonly --standalone -d www.example.com -d example.com
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 配置 nginx&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;server &lt;span style="color:#f92672"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; listen &lt;span style="color:#ae81ff"&gt;443&lt;/span&gt; ;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ssl on;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ssl_certificate_key /etc/letsencrypt/live/youdomain/privkey.pem;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ssl_certificate /etc/letsencrypt/live/youdomain/fullchain.pem;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;del&gt;需要注意的是 dnspod 等国内服务解析域名有问题&lt;/del&gt;&lt;br&gt;
我这里直接切回 domains.google.com 就行了&lt;br&gt;
使用 standalone 模式需要先停掉默认的 nginx&lt;br&gt;
文档里提到可以使用 webroot 模式不用停
但我创建验证文件失败了 :(&lt;br&gt;
默认90天过期，建议 crontab 定时更新&lt;/p&gt;
&lt;p&gt;###Update&lt;/p&gt;
&lt;p&gt;使用 &lt;a href="https://github.com/Neilpang/acme.sh"&gt;acme.sh&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;An ACME protocol client written purely in Shell (Unix shell) language.&lt;/li&gt;
&lt;li&gt;Fully ACME protocol implementation.&lt;/li&gt;
&lt;li&gt;Simple, powerful and very easy to use. You only need 3 minutes to learn.&lt;/li&gt;
&lt;li&gt;Bash, dash and sh compatible.&lt;/li&gt;
&lt;li&gt;Simplest shell script for Let&amp;rsquo;s Encrypt free certificate client.&lt;/li&gt;
&lt;li&gt;Purely written in Shell with no dependencies on python or Let&amp;rsquo;s Encrypt official client.&lt;/li&gt;
&lt;li&gt;Just one script, to issue, renew and install your certificates automatically.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;或者 &lt;a href="https://caddyserver.com"&gt;caddyserver&lt;/a&gt;&lt;/p&gt;</description></item><item><title>simple crawler</title><link>https://xn--ynyo-2nad.com/posts/simple-nodejs-crawler/</link><pubDate>Sat, 17 Oct 2015 12:06:21 +0000</pubDate><guid>https://xn--ynyo-2nad.com/posts/simple-nodejs-crawler/</guid><description>&lt;p&gt;半夜看了本&lt;a href="http://www.qidian.com/Book/3313422.aspx"&gt;小说&lt;/a&gt;觉得翻页太累&lt;/p&gt;
&lt;p&gt;首先要解决的问题是找一个质量还过得去的小说站
然后写个&lt;a href="https://github.com/yanyaoer/crawler"&gt;脚本&lt;/a&gt;去把它爬下来章节合并到一起&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;fs&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;fs&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; { &lt;span style="color:#a6e22e"&gt;argv&lt;/span&gt; } &lt;span style="color:#a6e22e"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;process&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;request&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;request&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;cheerio&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;cheerio&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;iconv&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;iconv-lite&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;sanitize&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;sanitize-html&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;constructor&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Object.&lt;span style="color:#a6e22e"&gt;assign&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;, {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;path&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;./chapter.json&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;html&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;./reader.html&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;url&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;list&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;http://www.piaotian.net/html/6/6658/&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;store&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; []
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; })
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;fetch&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;url&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;callback&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;request&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;get&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;url&lt;/span&gt;, {&lt;span style="color:#a6e22e"&gt;encoding&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;null&lt;/span&gt;}, (&lt;span style="color:#a6e22e"&gt;error&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;response&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;body&lt;/span&gt;)=&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#f92672"&gt;!&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;error&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;response&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;statusCode&lt;/span&gt; &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;200&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;cheerio&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;load&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;iconv&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;decode&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;body&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;GBK&amp;#39;&lt;/span&gt;));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;callback&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;$&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;body&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;url&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; })
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;runchapter&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;store&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;map&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;d&lt;/span&gt;=&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#f92672"&gt;!&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;d&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;content&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;fetch&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;url&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;list&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;d&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;href&lt;/span&gt;, (&lt;span style="color:#a6e22e"&gt;$&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;body&lt;/span&gt;)=&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;content&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;iconv&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;decode&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;body&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;GBK&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;d&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;content&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;sanitize&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;content&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;save&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; })
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;runchapter fail: &amp;#39;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;d&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;id&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;d&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;title&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; })
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;output&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;output&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//let content = this.store.slice(0, 2)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;content&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;store&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;map&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;d&lt;/span&gt;=&amp;gt; &lt;span style="color:#a6e22e"&gt;d&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;content&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;join&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;&amp;lt;hr /&amp;gt;&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;html&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;`&amp;lt;html&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; &amp;lt;head&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; &amp;lt;meta charset=&amp;#34;utf8&amp;#34; /&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; &amp;lt;style&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; ul, table, div {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; display: none;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; hr {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; height: 1px;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; margin: 4rem 0;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; body {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; padding: 0 20%;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; font:24px/1.5 &amp;#39;Songti Sc&amp;#39;;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; &amp;lt;/style&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; &amp;lt;/head&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; &amp;lt;body&amp;gt;&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;content&lt;/span&gt;&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;`&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;fs&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;writeFileSync&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;html&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;html&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;utf8&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;reload&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;fetch&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;url&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;list&lt;/span&gt;, (&lt;span style="color:#a6e22e"&gt;$&lt;/span&gt;)=&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;store&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; [];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;$&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;.mainbody .centent ul li a&amp;#39;&lt;/span&gt;).&lt;span style="color:#a6e22e"&gt;map&lt;/span&gt;((&lt;span style="color:#a6e22e"&gt;id&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;d&lt;/span&gt;)=&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;el&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;$&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;d&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;href&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;el&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;attr&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;href&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#f92672"&gt;!&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;href&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;endsWith&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;.html&amp;#39;&lt;/span&gt;)) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;store&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;push&lt;/span&gt;({ &lt;span style="color:#a6e22e"&gt;id&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;href&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;title&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;el&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;text&lt;/span&gt;() })
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; })
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;save&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;runchapter&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; })
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;config&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;force&lt;/span&gt;){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;force&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;reload&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } &lt;span style="color:#a6e22e"&gt;esle&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;text&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;fs&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;readFileSync&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;path&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;utf8&amp;#39;&lt;/span&gt;).&lt;span style="color:#a6e22e"&gt;toString&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;store&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;JSON&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;parse&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;text&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;runchapter&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;save&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;fs&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;writeFileSync&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;path&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;JSON&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;stringify&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;store&lt;/span&gt;), &lt;span style="color:#e6db74"&gt;&amp;#39;utf8&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;init&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;force&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;argv&lt;/span&gt;[&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;] &lt;span style="color:#f92672"&gt;===&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;-f&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;run: &amp;#39;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;argv&lt;/span&gt;[&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;], &lt;span style="color:#a6e22e"&gt;force&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;config&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;force&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;().&lt;span style="color:#a6e22e"&gt;init&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;于是就水出来一篇日志啦&lt;/p&gt;</description></item><item><title>send notification when task finish</title><link>https://xn--ynyo-2nad.com/posts/send-notification-after-task-end/</link><pubDate>Sun, 11 Oct 2015 00:38:23 +0000</pubDate><guid>https://xn--ynyo-2nad.com/posts/send-notification-after-task-end/</guid><description>&lt;p&gt;终端里运行长时间任务(比如 &lt;code&gt;make systemimage&lt;/code&gt;)的时候经常会切换到其他环境做别的事情
容易忘记查看之前的任务是否完成, 查到一些方法用在任务结束时发出通知&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#C-z 切到后台运行&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;fg; tput bel
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# Mac OS X&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#系统弹窗&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;osascript -e &lt;span style="color:#e6db74"&gt;&amp;#39;tell app &amp;#34;System Events&amp;#34; to display alert &amp;#34;Build Completed&amp;#34; message &amp;#34;The checkout and build have completed.&amp;#34;&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;say &lt;span style="color:#e6db74"&gt;&amp;#34;Job finished&amp;#34;&lt;/span&gt; &lt;span style="color:#75715e"&gt;#语音播报&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#notification center&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;osascript -e &lt;span style="color:#e6db74"&gt;&amp;#39;display notification &amp;#34;Job finished&amp;#34; with title &amp;#34;Alert&amp;#34;&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo gem install terminal-notifier
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;terminal-notifier -message &lt;span style="color:#e6db74"&gt;&amp;#34;Job finished!&amp;#34;&lt;/span&gt; -title &lt;span style="color:#e6db74"&gt;&amp;#34;Alert&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# Ubuntu&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;notify-send &lt;span style="color:#e6db74"&gt;&amp;#34;Job finished!&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# KDE&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;kdialog --passivepopup &lt;span style="color:#e6db74"&gt;&amp;#39;Job finished&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;还有 &lt;a href="https://iterm2.com/documentation-triggers.html"&gt;iterm2 trigger&lt;/a&gt; 也能用来触发通知, 高亮文字&lt;/p&gt;</description></item><item><title>create CNAME with internationalized domain name</title><link>https://xn--ynyo-2nad.com/posts/cname-with-yanyao-com/</link><pubDate>Sun, 04 Oct 2015 20:52:56 +0000</pubDate><guid>https://xn--ynyo-2nad.com/posts/cname-with-yanyao-com/</guid><description>&lt;p&gt;前段时间买了个 &lt;a href="https://en.wikipedia.org/wiki/Internationalized_domain_name"&gt;idn&lt;/a&gt;: yányào.com 闲置了很长时间没动
趁着十一长假无所事事的机会, 把玩了一下 &lt;a href="https://hexo.io"&gt;hexo&lt;/a&gt; 挂到 yanyaoer.github.io&lt;/p&gt;
&lt;p&gt;然后 CNAME 的时候掉坑了, 看到有人说30分钟生效傻傻等就不提了
实际上这个域名的 CNAME 内容应该用编码后的字符串而不是 yányào.com&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/yanyaoer/yanyaoer.github.io/commit/7c0e4e6863904442d368e3ad5c822f8f189bb7fc#diff-adc4bfdb0829dae99e3699393e3fbaa4"&gt;https://github.com/yanyaoer/yanyaoer.github.io/commit/7c0e4e6863904442d368e3ad5c822f8f189bb7fc#diff-adc4bfdb0829dae99e3699393e3fbaa4&lt;/a&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-diff" data-lang="diff"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;diff --git a/CNAME b/CNAME
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;index 6cb647c..92d166c 100644
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;--- a/CNAME
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;+++ b/CNAME
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;@@ -1 +1 @@
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;-yányào.com
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;+xn--ynyo-2nad.com
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>xtag-and-shadowdom</title><link>https://xn--ynyo-2nad.com/posts/xtag-and-shadowdom/</link><pubDate>Sun, 04 Oct 2015 12:20:52 +0000</pubDate><guid>https://xn--ynyo-2nad.com/posts/xtag-and-shadowdom/</guid><description>&lt;p&gt;最近在做的项目重构, 原本打算用 reactjs, 写了一些实验代码后心累无爱
找了个 domdiff 配合自定义标签和 shadowdom 的独有作用域也是爽 YY&lt;/p&gt;
&lt;p&gt;可惜的是测试红米上的 android webview 版本(32?)不支持 ::shadow 伪类
inline 方式覆盖样式略嫌繁琐&lt;/p&gt;
&lt;h2 id="示例代码"&gt;示例代码&lt;/h2&gt;
&lt;h3 id="xtagjs"&gt;xtag.js&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;dom&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;shadow&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;el&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;el&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;createShadowRoot&lt;/span&gt; &lt;span style="color:#f92672"&gt;?&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;el&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;createShadowRoot&lt;/span&gt;() &lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;el&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;webkitCreateShadowRoot&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;attr&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;el&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;prefix&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;&amp;#39;&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; Object.&lt;span style="color:#a6e22e"&gt;keys&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;el&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;dataset&lt;/span&gt;).&lt;span style="color:#a6e22e"&gt;map&lt;/span&gt;((&lt;span style="color:#a6e22e"&gt;d&lt;/span&gt;)=&amp;gt; &lt;span style="color:#e6db74"&gt;`&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;prefix&lt;/span&gt;&lt;span style="color:#e6db74"&gt;}${&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;d&lt;/span&gt;&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;=&amp;#34;&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;el&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;dataset&lt;/span&gt;[&lt;span style="color:#a6e22e"&gt;d&lt;/span&gt;]&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;`&lt;/span&gt;).&lt;span style="color:#a6e22e"&gt;join&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39; &amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;document.&lt;span style="color:#a6e22e"&gt;registerElement&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;x-image&amp;#39;&lt;/span&gt;, {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;prototype&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; Object.&lt;span style="color:#a6e22e"&gt;create&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;HTMLElement&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;prototype&lt;/span&gt;, {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;createdCallback&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;value&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//xtag 嵌套时这里读不到attr, 放到 attach
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;onCreate::image&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;attachedCallback&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;value&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;onAttach::image&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;shadow&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;dom&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;shadow&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;shadow&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;innerHTML&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;`&amp;lt;style&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; img { max-width: 100%; }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; &amp;lt;/style&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; &amp;lt;img &lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;dom&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;attr&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;)&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt; /&amp;gt;`&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;onclick&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;e&lt;/span&gt;) =&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; })
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;});
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// other x-tag;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="indexjs"&gt;index.js&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;babel/polyfill&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;./xtag.js&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;BaseView&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;constructor&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;opt&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Object.&lt;span style="color:#a6e22e"&gt;assign&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;, {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;root&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;dom&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;#app&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }, &lt;span style="color:#a6e22e"&gt;opt&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;mount&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;event::mount&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;onCreate&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;event::create&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;onUpdate&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;event::update&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;export&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;default&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;BannerView&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;extends&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;BaseView&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;init&lt;/span&gt;(...&lt;span style="color:#a6e22e"&gt;args&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;mount&lt;/span&gt;(...&lt;span style="color:#a6e22e"&gt;args&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;render&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#e6db74"&gt;`&amp;lt;x-image data-src=&amp;#34;&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;src&lt;/span&gt;&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; data-href=&amp;#34;&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;redirect_url&lt;/span&gt;&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34; /&amp;gt;`&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="links"&gt;links&lt;/h2&gt;
&lt;p&gt;&lt;a href="http://www.html5rocks.com/en/tutorials/webcomponents/customelements/"&gt;http://www.html5rocks.com/en/tutorials/webcomponents/customelements/&lt;/a&gt;
&lt;a href="http://www.html5rocks.com/en/tutorials/webcomponents/shadowdom-301/"&gt;http://www.html5rocks.com/en/tutorials/webcomponents/shadowdom-301/&lt;/a&gt;&lt;/p&gt;</description></item><item><title>remote pbcopy with netcat</title><link>https://xn--ynyo-2nad.com/posts/remote-pbcopy-with-netcat/</link><pubDate>Tue, 20 Jan 2015 11:45:53 +0000</pubDate><guid>https://xn--ynyo-2nad.com/posts/remote-pbcopy-with-netcat/</guid><description>&lt;h2 id="quick-start"&gt;Quick start&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;while&lt;/span&gt; &lt;span style="color:#f92672"&gt;(&lt;/span&gt;true&lt;span style="color:#f92672"&gt;)&lt;/span&gt;; &lt;span style="color:#66d9ef"&gt;do&lt;/span&gt; nc -l &lt;span style="color:#ae81ff"&gt;2224&lt;/span&gt; | pbcopy; &lt;span style="color:#66d9ef"&gt;done&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#If your laptop is running linux, replacing pbcopy with xcopy should work:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#while (true); do nc -l 2224 | xcopy; done&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;echo &lt;span style="color:#e6db74"&gt;&amp;#34;This text gets sent to clipboard&amp;#34;&lt;/span&gt; | nc localhost &lt;span style="color:#ae81ff"&gt;2224&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;echo &lt;span style="color:#e6db74"&gt;&amp;#34;RemoteForward 2224 localhost:2224&amp;#34;&lt;/span&gt; &amp;gt;&amp;gt; ~/.ssh/config
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;ssh remote -t &lt;span style="color:#e6db74"&gt;&amp;#39;cat blablabla | nc -q0 localhost 2224&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="daemonizing-pbcopy"&gt;Daemonizing pbcopy&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;launchctl load ~/Library/LaunchAgents/local.pbcopy.plist&lt;/code&gt;&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-plist" data-lang="plist"&gt;&amp;lt;?xml version=&amp;#34;1.0&amp;#34; encoding=&amp;#34;UTF-8&amp;#34;?&amp;gt;
&amp;lt;!DOCTYPE plist PUBLIC &amp;#34;-//Apple Computer//DTD PLIST 1.0//EN&amp;#34; &amp;#34;http://www.apple.com/DTDs/PropertyList-1.0.dtd&amp;#34;&amp;gt;
&amp;lt;plist version=&amp;#34;1.0&amp;#34;&amp;gt;
&amp;lt;dict&amp;gt;
 &amp;lt;key&amp;gt;Label&amp;lt;/key&amp;gt;
 &amp;lt;string&amp;gt;localhost.pbcopy&amp;lt;/string&amp;gt;
 &amp;lt;key&amp;gt;ProgramArguments&amp;lt;/key&amp;gt;
 &amp;lt;array&amp;gt;
 &amp;lt;string&amp;gt;/usr/bin/pbcopy&amp;lt;/string&amp;gt;
 &amp;lt;/array&amp;gt;
 &amp;lt;key&amp;gt;inetdCompatibility&amp;lt;/key&amp;gt;
 &amp;lt;dict&amp;gt;
 &amp;lt;key&amp;gt;Wait&amp;lt;/key&amp;gt;
 &amp;lt;false/&amp;gt;
 &amp;lt;/dict&amp;gt;
 &amp;lt;key&amp;gt;Sockets&amp;lt;/key&amp;gt;
 &amp;lt;dict&amp;gt;
 &amp;lt;key&amp;gt;Listeners&amp;lt;/key&amp;gt;
 &amp;lt;dict&amp;gt;
 &amp;lt;key&amp;gt;SockServiceName&amp;lt;/key&amp;gt;
 &amp;lt;string&amp;gt;2224&amp;lt;/string&amp;gt;
 &amp;lt;key&amp;gt;SockNodeName&amp;lt;/key&amp;gt;
 &amp;lt;string&amp;gt;127.0.0.1&amp;lt;/string&amp;gt;
 &amp;lt;/dict&amp;gt;
 &amp;lt;/dict&amp;gt;
&amp;lt;/dict&amp;gt;
&amp;lt;/plist&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="remote-pbcopy"&gt;Remote pbcopy&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;scp pbcopy remote:/path_to/pbcopy
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;chmod a+x path_to/pbcopy
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#!/bin/bash&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt; -n &lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;$SSH_CLIENT&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;]&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; SESSION_TYPE&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;remote&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; &lt;span style="color:#f92672"&gt;[[&lt;/span&gt; $SESSION_TYPE &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;remote&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;]]&lt;/span&gt;; &lt;span style="color:#66d9ef"&gt;then&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; cat | nc -q0 localhost &lt;span style="color:#ae81ff"&gt;2224&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;else&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; cat | pbcopy
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;fi&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="links"&gt;links&lt;/h2&gt;
&lt;p&gt;&lt;a href="http://brettterpstra.com/2014/02/19/remote-pbcopy-on-os-x-systems/"&gt;http://brettterpstra.com/2014/02/19/remote-pbcopy-on-os-x-systems/&lt;/a&gt;&lt;/p&gt;</description></item><item><title>forward email by postfix</title><link>https://xn--ynyo-2nad.com/posts/postfix-forward-mail/</link><pubDate>Mon, 06 Oct 2014 01:25:06 +0000</pubDate><guid>https://xn--ynyo-2nad.com/posts/postfix-forward-mail/</guid><description>&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo aptitude install postfix
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;hostname -f
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# sudo vim /etc/postfix/main.cf&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;myhostname &lt;span style="color:#f92672"&gt;=&lt;/span&gt; example.com
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;myorigin &lt;span style="color:#f92672"&gt;=&lt;/span&gt; example.com
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;mydestination &lt;span style="color:#f92672"&gt;=&lt;/span&gt; example1.com, example2.com, ...
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;virtual_alias_maps &lt;span style="color:#f92672"&gt;=&lt;/span&gt; hash:/etc/postfix/virtual
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# sudo vim /etc/postfix/virtual&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;@example1.com name@forward.com
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;@example2.com name@forward.com
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo postmap /etc/postfix/virtual
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo /etc/init.d/postfix reload
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;a href="https://wiki.debian.org/Postfix#Forward_Emails"&gt;https://wiki.debian.org/Postfix#Forward_Emails&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.linode.com/docs/email/postfix/basic-postfix-email-gateway-on-debian-6-squeeze"&gt;https://www.linode.com/docs/email/postfix/basic-postfix-email-gateway-on-debian-6-squeeze&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.debian-administration.org/article/243/Handling_mail_for_multiple_virtual_domains_with_postfix"&gt;https://www.debian-administration.org/article/243/Handling_mail_for_multiple_virtual_domains_with_postfix&lt;/a&gt;&lt;/p&gt;</description></item><item><title>mitmproxy</title><link>https://xn--ynyo-2nad.com/posts/mitmproxy/</link><pubDate>Wed, 20 Aug 2014 12:05:38 +0000</pubDate><guid>https://xn--ynyo-2nad.com/posts/mitmproxy/</guid><description>&lt;p&gt;&lt;a href="http://mitmproxy.org"&gt;mitmproxy&lt;/a&gt; 是个命令行下查看/修改 http 请求的交互式工具&lt;/p&gt;
&lt;p&gt;#截图
&lt;img src="http://mitmproxy.org/doc/screenshots/mitmproxy.png" alt="screenshoot"&gt;
&lt;img src="http://mitmproxy.org/doc/screenshots/mitmproxy-flowview.png" alt="screenshoot"&gt;&lt;/p&gt;
&lt;p&gt;#安装&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo apt-get install python-dev libffi-dev
pip install mitmproxy
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;#使用&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ubuntu 上启动 mitmproxy&lt;/strong&gt;&lt;br&gt;
mitmproxy &amp;ndash;host&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;手机 设置 -&amp;gt; WLAN -&amp;gt; 代理&lt;/strong&gt;&lt;br&gt;
主机名: ubuntu 的 ip&lt;br&gt;
端口: 8080&lt;/p&gt;
&lt;p&gt;然后访问网络就会在 mitmproxy 里看到请求记录(如截图)&lt;/p&gt;
&lt;p&gt;#快捷键&lt;/p&gt;
&lt;p&gt;j,k 上下移动&lt;br&gt;
enter 进入&lt;br&gt;
tab 切换 request/response&lt;/p&gt;
&lt;p&gt;#参考
&lt;a href="http://mitmproxy.org/doc/mitmproxy.html"&gt;http://mitmproxy.org/doc/mitmproxy.html&lt;/a&gt;&lt;br&gt;
&lt;a href="http://blog.philippheckel.com/2013/07/01/how-to-use-mitmproxy-to-read-and-modify-https-traffic-of-your-phone/"&gt;http://blog.philippheckel.com/2013/07/01/how-to-use-mitmproxy-to-read-and-modify-https-traffic-of-your-phone/&lt;/a&gt;&lt;/p&gt;</description></item><item><title>brick intro</title><link>https://xn--ynyo-2nad.com/posts/brick-intro/</link><pubDate>Wed, 28 Aug 2013 10:47:17 +0000</pubDate><guid>https://xn--ynyo-2nad.com/posts/brick-intro/</guid><description>&lt;p&gt;#Introducing Brick: Minimal-markup Web Components for Faster App Development
#介绍 brick: 用于快速开发 webapp 的自定义标签组件&lt;/p&gt;
&lt;p&gt;&lt;a href="https://hacks.mozilla.org/2013/08/introducing-brick-minimal-markup-web-components-for-faster-app-development/"&gt;https://hacks.mozilla.org/2013/08/introducing-brick-minimal-markup-web-components-for-faster-app-development/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Those of you on the cutting HTML5 edge may have already heard of the exciting Web Components specification. If you haven’t, you’ll probably want to read up on what makes this so exciting, but long story short, Web Components promise to open up a new realm of development by letting web developers write custom, reusable HTML tags. Think of them as JavaScript plugins without the need for additional code initialization or boilerplate markup/styling.&lt;/p&gt;</description></item><item><title>my osx setup</title><link>https://xn--ynyo-2nad.com/posts/my-osx-setup/</link><pubDate>Sun, 09 Jun 2013 12:05:50 +0000</pubDate><guid>https://xn--ynyo-2nad.com/posts/my-osx-setup/</guid><description>&lt;p&gt;#setting&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;# Enable full keyboard access for all controls
defaults write NSGlobalDomain AppleKeyboardUIMode -int 3

# Disable menu bar transparency
defaults write NSGlobalDomain AppleEnableMenuBarTransparency -bool false

# Allow quitting Finder via ⌘ + Q; doing so will also hide desktop icons
defaults write com.apple.finder QuitMenuItem -bool true

# Avoid creating .DS_Store files on network volumes
defaults write com.apple.desktopservices DSDontWriteNetworkStores -bool true

# Disable the warning when changing a file extension
defaults write com.apple.finder FXEnableExtensionChangeWarning -bool false

# Enable tap to click (Trackpad)
defaults write com.apple.driver.AppleBluetoothMultitouch.trackpad Clicking -bool true

# Enable Safari’s debug menu
defaults write com.apple.Safari IncludeInternalDebugMenu -bool true

# To pin the dock to the right bottom
defaults write com.apple.dock pinning -string end
defaults write com.apple.dock orientation -string right

# Only Show Open Applications In The Dock
defaults write com.apple.dock static-only -bool true

defaults write com.apple.dock tilesize -int 24
defaults write com.apple.finder QLEnableTextSelection -bool true

# disable dashboard
defaults write com.apple.dashboard mcx-disabled -boolean true
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;#&lt;a href="http://itunes.apple.com/us/app/xcode/"&gt;xcode&lt;/a&gt; with &lt;a href="https://developer.apple.com/downloads"&gt;Command Line Tools&lt;/a&gt;&lt;/p&gt;</description></item></channel></rss>